diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..4269d47c09fece0728393f7a0e3489702d53c0bc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,482 @@ + +## 1.2.9 (2019-06-11) + + +#### Bug Fixes + +* should call showNormal() to raise window ([39d9bc12](https://github.com/linuxdeepin/deepin-editor/commit/39d9bc1248803b93cfe6f23cdf51490eb9bb156c)) +* do not overwrite the cursorFlashTime of QGuiApplication ([ed5700d5](https://github.com/linuxdeepin/deepin-editor/commit/ed5700d5410f87f09e89c97c8340967145931fcc)) +* crash if DDE file select dialog is not available to use ([4db075d0](https://github.com/linuxdeepin/deepin-editor/commit/4db075d0cb347f1092045ccb6015f11fdff4f6d2)) + + + + +## 1.2.8 (2019-05-23) + + +#### Bug Fixes + +* no longer designate clang++ as compiler ([36022f04](https://github.com/linuxdeepin/deepin-editor/commit/36022f046dd44f4f681019636ecd216d111da284)) + +#### Features + +* set default open dir as QStandardPaths::DocumentsLocation ([69ed1ded](https://github.com/linuxdeepin/deepin-editor/commit/69ed1dedf6dda48162efb09dddf18cf87d3a68a0)) + + + + +## 1.2.7.3 (2019-04-19) + + +#### Bug Fixes + +* activate window when opening files ([437e8d72](https://github.com/linuxdeepin/deepin-editor/commit/437e8d72470343a9249a6b41312cc0bebd836abb)) + + + + +## 1.2.7.2 (2019-04-10) + + + + + +## 1.2.7.1 (2019-04-08) + + +#### Features + +* display word count from status bar (#37) ([af90d45f](https://github.com/linuxdeepin/deepin-editor/commit/af90d45ff61bffd9bad4f52a2a625b1dc034a532)) + +#### Bug Fixes + +* reduce minimum window size (#38) ([9e514d19](https://github.com/linuxdeepin/deepin-editor/commit/9e514d1950e682ff27f63c1f9045f92a49fcf936)) + + + + +## 1.2.7 (2019-03-27) + + + + + +## 1.2.6.3 (2019-01-25) + + + + + +## 1.2.6.2 (2019-01-15) + + +#### Bug Fixes + +* chinese garbled ([75f76e68](https://github.com/linuxdeepin/deepin-editor/commit/75f76e68ced88d58a9ade66b974c835ea5cf3001)) + + + + +## 1.2.6.1 (2019-01-10) + + +#### Bug Fixes + +* disconnect when object got destroyed ([7fe6c1ef](https://github.com/linuxdeepin/deepin-editor/commit/7fe6c1efb56ce6294b3c5728eb9e1e8d0f4589c2)) + + + + +## 1.2.6 (2019-01-03) + + +#### Features + +* support x-wine-extension-ini ([a71e1415](https://github.com/linuxdeepin/deepin-editor/commit/a71e141553ab4308eb13fdb0cc7fe9e90d1096d7)) +* **textedit:** optimized touch screen. ([b0bed762](https://github.com/linuxdeepin/deepin-editor/commit/b0bed7621d6676d95d80063ddf2259c79e449991)) + +#### Bug Fixes + +* open current file. ([b3fec2c8](https://github.com/linuxdeepin/deepin-editor/commit/b3fec2c8154618753df9b2517bc58e08280acfd1)) +* do not accept rich text. ([5bbdea90](https://github.com/linuxdeepin/deepin-editor/commit/5bbdea905e5f7d418b60ad27178bffa0ab4b01ab)) +* **themepanel:** optimize the selected effect. ([e4e04f20](https://github.com/linuxdeepin/deepin-editor/commit/e4e04f20408445dabde9aee2012cdf75937c7e19)) + + + + +## 1.2.5 (2018-12-21) + + +#### Bug Fixes + +* support m3u8 file open ([2af2d49c](https://github.com/linuxdeepin/deepin-editor/commit/2af2d49c2ad279313db00d412d674d8e24e03fee)) +* dedit args. ([db75ba6b](https://github.com/linuxdeepin/deepin-editor/commit/db75ba6b5824fa962d32d6a3cd18d17d42623e74)) +* save as file name format. ([e2a07a4c](https://github.com/linuxdeepin/deepin-editor/commit/e2a07a4cf73a509fac68bc2dafc70b31a6befe5f)) + +#### Features + +* support for application/x-mpegURL. ([a31ab8d0](https://github.com/linuxdeepin/deepin-editor/commit/a31ab8d03eb98dac58f1873dc4555ef1a1caa1d3)) +* support for devanagari. ([865b2921](https://github.com/linuxdeepin/deepin-editor/commit/865b2921b804cbbd20e1400b5906500ce580aeaa)) +* add dedit ([c282e683](https://github.com/linuxdeepin/deepin-editor/commit/c282e683b19f87c886ed75033688e7382540618c)) + + + + +## 1.2.4 (2018-12-18) + + +#### Features + +* **tabbar:** change read-only attribute. ([df24648c](https://github.com/linuxdeepin/deepin-editor/commit/df24648c0ddaf3a0370a20605cbf84f7ff4adaba)) + +#### Bug Fixes + +* save as crash. ([b7b50838](https://github.com/linuxdeepin/deepin-editor/commit/b7b508389b8f7431ba959d6dd831198a4a5b37e7)) + + + + +## 1.2.3 (2018-12-14) + + +#### Bug Fixes + +* reconnect save as signal ([68e7dd0a](https://github.com/linuxdeepin/deepin-editor/commit/68e7dd0a1b9edf3c80ed0e059dc0490d52ccfe41)) + + + + +## 1.2.2 (2018-12-14) + + +#### Bug Fixes + +* hide toast after refresh. ([c2b07f4f](https://github.com/linuxdeepin/deepin-editor/commit/c2b07f4f09bf50154ce33d930aa668309bf70d6a)) +* save as file will be lost. ([b54f1c5f](https://github.com/linuxdeepin/deepin-editor/commit/b54f1c5fa994ad3bd1fbbf65e047c36a1b9cdcb2)) +* draft file does not check reload. ([95e74191](https://github.com/linuxdeepin/deepin-editor/commit/95e7419176f2728f8d7780382b3aaa743528437e)) + +#### Features + +* monitor file removed. ([27c6b2ea](https://github.com/linuxdeepin/deepin-editor/commit/27c6b2ea9cfc8aec4cb905c584df56d8c502d346)) +* support touch gesture. ([4160be0d](https://github.com/linuxdeepin/deepin-editor/commit/4160be0d46f4c2ce0a318d75fdb3e5632ff9ab00)) + + + + +## 1.2.1 (2018-12-11) + + + + + +## 1.2.0 (2018-12-11) + + +#### Features + +* monitor file modification. ([9dbde37d](https://github.com/linuxdeepin/deepin-editor/commit/9dbde37d7b8605401ad6c535e09c9e67e2a7abf6)) +* **settings_dialog:** support for preview fonts. ([f49315ca](https://github.com/linuxdeepin/deepin-editor/commit/f49315ca991bde6547c16f5c6cf221721f8f45aa)) + +#### Bug Fixes + +* check reload crash. ([4eb94e7b](https://github.com/linuxdeepin/deepin-editor/commit/4eb94e7b605175dc69dc233f6894c03625dd4bb1)) +* open duplicates. ([04ca82d2](https://github.com/linuxdeepin/deepin-editor/commit/04ca82d21f27290844cbde7431ea855c08b826f8)) +* **toast:** adjust position when resize. ([4523ea74](https://github.com/linuxdeepin/deepin-editor/commit/4523ea7476690a238c17c0788d474d3652b6af6a)) + + + + +## 1.10 (2018-12-07) + + +#### Bug Fixes + +* drop down menu position ([5f458836](https://github.com/linuxdeepin/deepin-editor/commit/5f4588369b0f8368782ec4fed90b0c643ddcefa3)) +* find matches highlight. ([807cf9dd](https://github.com/linuxdeepin/deepin-editor/commit/807cf9ddbca7b40272f651e9827f92f547cba20a)) +* cannot find the end bracket to not need to highlight. ([716b1cc1](https://github.com/linuxdeepin/deepin-editor/commit/716b1cc1a4c1f39344425b84139b0b800e765853)) +* settings dialog to restore default theme. ([89ef418b](https://github.com/linuxdeepin/deepin-editor/commit/89ef418b9e3b3551e4b7d2517d3735f32e22786f)) +* switch theme update extension selection. ([b6b652d8](https://github.com/linuxdeepin/deepin-editor/commit/b6b652d8f1863ecc4c09eee349000ef9059ca334)) +* update theme panel geometry ([29c4563c](https://github.com/linuxdeepin/deepin-editor/commit/29c4563c1e4c9b73bd5e428d375f76f70b5f161c)) +* optimize find keyword color. ([adcae0e3](https://github.com/linuxdeepin/deepin-editor/commit/adcae0e31d631650cb77e0f46caa8ec4358d8fe7)) +* draft modify codec. ([182cb4ef](https://github.com/linuxdeepin/deepin-editor/commit/182cb4efb7281a3c8f92f2ef178783562032be20)) +* optimize bottom bar text color. ([53e7453c](https://github.com/linuxdeepin/deepin-editor/commit/53e7453cfd85c760d7ed875ad7a54f9c7342de8b)) +* encode bobox adaptive width. ([1eecb09b](https://github.com/linuxdeepin/deepin-editor/commit/1eecb09b41181ab1b742a2101c00806084197d41)) +* word wrap to line wrap. ([5f591a12](https://github.com/linuxdeepin/deepin-editor/commit/5f591a126cd90ad5348f906a1ae4a808051cd886)) +* draft document save file name is incorrect. ([c2c1592d](https://github.com/linuxdeepin/deepin-editor/commit/c2c1592d7605b1fda2f2f437cfc8b4140ae6a530)) +* highlight brackets will modify the document status. ([7aeec31b](https://github.com/linuxdeepin/deepin-editor/commit/7aeec31b77234e6bb5a0483ca809d7a8216f4c05)) +* support for custom highlight bracket color. ([78d6528b](https://github.com/linuxdeepin/deepin-editor/commit/78d6528bfc98eca295237e44a13cb56c483da09d)) +* highlight current line and highlight bracket conflicts. ([5db54adb](https://github.com/linuxdeepin/deepin-editor/commit/5db54adb6acc182ae20634b4b679c3bc698b4306)) +* restore the value of the scrollbar when refresh. ([d453f875](https://github.com/linuxdeepin/deepin-editor/commit/d453f87513984749c41cebaf107bc9a46f81cd37)) +* open crash ([5df794c7](https://github.com/linuxdeepin/deepin-editor/commit/5df794c76479dce5edaeb86fbc38b5fbcabe6db8)) +* desktop file encoding detection error. ([57ad5195](https://github.com/linuxdeepin/deepin-editor/commit/57ad5195cac518ebb4e76a2a365787ef6016d3ba)) +* theme panel y offset value. ([1c5f6b9f](https://github.com/linuxdeepin/deepin-editor/commit/1c5f6b9fa0c785ce9eac6102bed3141dd47ae44f)) +* optimize theme panel popup. ([ce01f2fa](https://github.com/linuxdeepin/deepin-editor/commit/ce01f2faf667496c4ed2196fc4b370a01aeab2c9)) +* cursor is incorrect. ([a8ffa9f6](https://github.com/linuxdeepin/deepin-editor/commit/a8ffa9f6a92e2cf771a9a1cdf2f9ecbed12183df)) +* exit file dialog causes window to close. ([74f01aaf](https://github.com/linuxdeepin/deepin-editor/commit/74f01aafe039a506195d7ae35c08d3ab280176db)) +* modify open and save logic. ([f3984dde](https://github.com/linuxdeepin/deepin-editor/commit/f3984dde7fcb1156f98eb8347ba2e6a5489b3211)) +* use universal coding probe. ([0eec6314](https://github.com/linuxdeepin/deepin-editor/commit/0eec63143994894b2c049c4887fb283b489930c8)) +* **encoding:** support russian in cyrllic. ([85f5b870](https://github.com/linuxdeepin/deepin-editor/commit/85f5b870fd5e560e95df916efd5b2e5d8910442a)) +* **tabbar:** draft document modified status. ([6f2054e1](https://github.com/linuxdeepin/deepin-editor/commit/6f2054e1d018fa4f7d69009baa1ebdf4204c8abe)) + +#### Features + +* add highlight menu to bottombar. ([19a0fbe2](https://github.com/linuxdeepin/deepin-editor/commit/19a0fbe21c3dd967bb97f5b6e2b458eb1fd6adca)) +* add cursor mode to the bottom bar. ([2135d2e0](https://github.com/linuxdeepin/deepin-editor/commit/2135d2e0f727de7c6025e5726f4746ee525bfc35)) +* add drop down menu widget. ([13e8600e](https://github.com/linuxdeepin/deepin-editor/commit/13e8600ec23df0085263568508d6308f9a3f48d5)) +* add bottom bar. ([c9931de1](https://github.com/linuxdeepin/deepin-editor/commit/c9931de15ba5e63eeadb17f9459b75462af224c5)) +* add highlight brackets. ([bd138944](https://github.com/linuxdeepin/deepin-editor/commit/bd138944596a0f4ddd0882459f918ff6172248a2)) +* add refresh function. ([44a8f882](https://github.com/linuxdeepin/deepin-editor/commit/44a8f882f877bb5fd1686f8c5ea165495f86e838)) +* add find and replace options to the main menu. ([e418e977](https://github.com/linuxdeepin/deepin-editor/commit/e418e977be502eb83b2e80cd9a2e36e88d207a49)) +* open new file will not create a new tab in a new blank document in draft. ([272c10e6](https://github.com/linuxdeepin/deepin-editor/commit/272c10e6499a92b33ba8e89d1db8bfdc7b22e893)) +* add word wrap setting options. ([b6b871ad](https://github.com/linuxdeepin/deepin-editor/commit/b6b871adef2b7c0fcc3766fca7ae35e667934de0)) +* **bottombar:** support encoding selections. ([341e7c37](https://github.com/linuxdeepin/deepin-editor/commit/341e7c378350a725d554e9883838c4e8db9f81b7)) +* **tabbar:** add file read-only info. ([1ad8e437](https://github.com/linuxdeepin/deepin-editor/commit/1ad8e43727aedafecb2c1aa480ffdcee43836845)) + + + + +## 1.1.3 (2018-11-23) + + +#### Bug Fixes + +* update ts config. ([408b97e2](https://github.com/linuxdeepin/deepin-editor/commit/408b97e240e0131fd75178a6f5fa2b708ec46c02)) + +#### Features + +* support overwrite mode. ([bc57fd98](https://github.com/linuxdeepin/deepin-editor/commit/bc57fd98307cc8af61189006d2086b402c466ad5)) +* support the recent file spec. ([122722b8](https://github.com/linuxdeepin/deepin-editor/commit/122722b8e86e54c5beec49cc91f26c2cae6f5bde)) +* **desktop:** add generic name. ([d29ccc06](https://github.com/linuxdeepin/deepin-editor/commit/d29ccc06988393467a8dba82c0978493f40ad12d)) +* **tabbar:** add document modification status. ([8fbdf34c](https://github.com/linuxdeepin/deepin-editor/commit/8fbdf34ce4c9988271129786d13dfe910b839166)) + + + + +## 1.1.2 (2018-11-13) + + +#### Bug Fixes + +* drag and drop crash under loongson. ([0dc5d62c](https://github.com/linuxdeepin/deepin-editor/commit/0dc5d62c300e102cf62d397e7163d8223b6a21af)) +* icon is incorrect ([f395cacc](https://github.com/linuxdeepin/deepin-editor/commit/f395caccf146e47ae38bf368e7cb9ae1429f8c35)) + +#### Features + +* add two mime types. ([14d1860e](https://github.com/linuxdeepin/deepin-editor/commit/14d1860e05db1052738f6bf1d41bf77f983be7ba)) + + + + +## 1.1.1 (2018-10-26) + + +#### Features + +* update mime type. ([b0e5c0a5](https://github.com/linuxdeepin/deepin-editor/commit/b0e5c0a55d64363fc234fd7f25fb466419b60adf)) +* **theme_panel:** modify the animation easing curve. ([f81a04e3](https://github.com/linuxdeepin/deepin-editor/commit/f81a04e355f1ca47d649786975c0cc27628d9f3d)) + +#### Bug Fixes + +* right menu under arch crashes. ([f08c9e26](https://github.com/linuxdeepin/deepin-editor/commit/f08c9e26a3fe538e3ad896974a55086919b2ed06)) +* drag and drop the window is not activated. ([a199cec2](https://github.com/linuxdeepin/deepin-editor/commit/a199cec2f4207a11fb57cda9bbfcf94e783e6a47)) +* a typo ([ea615971](https://github.com/linuxdeepin/deepin-editor/commit/ea615971c279e6d075f9671ddd18422ffea594a5)) + + + + +## 1.1 (2018-10-11) + + +#### Bug Fixes + +* fix: input text can be read-only mode. ([fe4e93f](https://github.com/linuxdeepin/deepin-editor/commit/7e690af0fbda19735e4790e40adfe381f382aa57)) + + + + +## 1.0 (2018-10-10) + + +#### Bug Fixes + +* multi-screen new window position is incorrect. ([f34ef80c](https://github.com/linuxdeepin/deepin-editor/commit/f34ef80c0842d331fad95cba6dd58eada2a0e379)) +* cannot preview shortcuts in read-only mode ([507edc2e](https://github.com/linuxdeepin/deepin-editor/commit/507edc2ed09063100fd01379a527b552ab1e81b6)) +* optimize close tabs func. ([e1e573b0](https://github.com/linuxdeepin/deepin-editor/commit/e1e573b08921c06cf2cfef0f3fd3debf317f6736)) +* no translation files included ([a6231c42](https://github.com/linuxdeepin/deepin-editor/commit/a6231c4210ea99fa7b0b17c5dcf161242271b02b)) +* tab drag out only disconnect the window siganl. ([da27ede7](https://github.com/linuxdeepin/deepin-editor/commit/da27ede799af5f05ec34be11b69debad8badc158)) +* drag tab to anther window signal is incorrect. ([08c5b927](https://github.com/linuxdeepin/deepin-editor/commit/08c5b92764a92a6949fddd1036e12f4e1cd3599b)) +* no highlight current line ([a3391be5](https://github.com/linuxdeepin/deepin-editor/commit/a3391be5be423701c2abd7d4b1ac265aae34d33c)) +* use fixed byte detection encoding. ([a0dd1cb5](https://github.com/linuxdeepin/deepin-editor/commit/a0dd1cb51fc48ee03a7bc61b03b6c86f7a1b0181)) +* ensure that the file is written to disk ([a036a13b](https://github.com/linuxdeepin/deepin-editor/commit/a036a13b77a47b5175272037b22c07059b6100e8)) +* line number padding. ([ed30c88b](https://github.com/linuxdeepin/deepin-editor/commit/ed30c88b0cd8b8e2ed30772b0db0da16a50d216a)) +* read-only mode cannot drag text. ([a3e4398b](https://github.com/linuxdeepin/deepin-editor/commit/a3e4398b60628db9db2e03177fa5c83ea10a1082)) +* **menu:** + * change the highlight order ([1e90cbcc](https://github.com/linuxdeepin/deepin-editor/commit/1e90cbcc9a52df537fcf0fdf2c1677bde4d436f9)) + * set minimum width ([47a0b06d](https://github.com/linuxdeepin/deepin-editor/commit/47a0b06d76289e7a06d591b8b46a3301db3b48d1)) + +#### Features + +* add abbreviated name. ([3250f36c](https://github.com/linuxdeepin/deepin-editor/commit/3250f36c6bc2980599a58565008436e24628cd22)) +* close tabs prompted to save the file. ([e54bdc99](https://github.com/linuxdeepin/deepin-editor/commit/e54bdc99de05210a16bcc0b002999d2469e42b65)) +* optimize file loading speed. ([286db0fc](https://github.com/linuxdeepin/deepin-editor/commit/286db0fc8092dcd6098ed8dc27430e2339c3fb41)) +* use cmake ([a56c06fb](https://github.com/linuxdeepin/deepin-editor/commit/a56c06fb04bf8d48d0aa28cd49b407641a0b2470)) +* add highlight right option ([501f7795](https://github.com/linuxdeepin/deepin-editor/commit/501f77958ccc62050dc1c756b9272355e5191f61)) +* **tabbar:** add right menu. ([053ec629](https://github.com/linuxdeepin/deepin-editor/commit/053ec62953415ebc912712abd7dd4e69e10d8b69)) + + + + +## 0.5 (2018-09-21) + + +#### Bug Fixes + +* don't blank the cursor when selecting text ([8cf929f9](https://github.com/linuxdeepin/deepin-editor/commit/8cf929f9854bc4cf7e82c10a6c1b2e8898847c5a)) +* no permissions to read file without create new tab. ([bc4039e2](https://github.com/linuxdeepin/deepin-editor/commit/bc4039e2ddd522a7dcd5dd1bca74436a3b18ba77)) +* open invalid prompt ([7c81857e](https://github.com/linuxdeepin/deepin-editor/commit/7c81857eee11e6cdc8addc21ca881f31520477c4)) +* kill backward & forward word. ([47a566bb](https://github.com/linuxdeepin/deepin-editor/commit/47a566bba4af04f2dde610649ea096acf3f30f71)) +* can't replace all empty ([9b83f153](https://github.com/linuxdeepin/deepin-editor/commit/9b83f153bc607460a747c64365cae0b8fe833526)) +* no history filepath saved when closing other tabs. ([adff4cf5](https://github.com/linuxdeepin/deepin-editor/commit/adff4cf5138b0863c00cf5197dbb318e4efc26dd)) +* sort shortcuts ([6487ccf5](https://github.com/linuxdeepin/deepin-editor/commit/6487ccf52214423e55f3d4d4d0a3599beaeed288)) +* open again will create a new window ([7ed3ce95](https://github.com/linuxdeepin/deepin-editor/commit/7ed3ce95db97599fee198c93ee184c37618a75d3)) +* toggle find & replace bar focus ([e8370db4](https://github.com/linuxdeepin/deepin-editor/commit/e8370db401649bd9f9669dbefc611b94e102790e)) +* cannot be replaced after undo ([6fcab391](https://github.com/linuxdeepin/deepin-editor/commit/6fcab391ec2da47a4356ca396ad748f4776a43f6)) +* shortcut viewer translation. ([0d408be2](https://github.com/linuxdeepin/deepin-editor/commit/0d408be276587b75cbf57598e40291c6f358069e)) +* window size. ([15a3c805](https://github.com/linuxdeepin/deepin-editor/commit/15a3c805f581282f39a7567187cbce9d101d09ad)) +* goto next & previous word. ([b3440462](https://github.com/linuxdeepin/deepin-editor/commit/b3440462922997593847dc583465424d6344bc5c)) +* add tab space minimum value ([35ef2b9b](https://github.com/linuxdeepin/deepin-editor/commit/35ef2b9bcb4732c5b4653172ca0815935bcc3bda)) +* can be infinitely replaced next ([e249dc39](https://github.com/linuxdeepin/deepin-editor/commit/e249dc39538ab53c3d479c306974b1b43987e369)) +* replace text is empty. ([d6872e1f](https://github.com/linuxdeepin/deepin-editor/commit/d6872e1fd200d6fb14f238dcf62d91765693c43b)) +* do not restore tab when restoring pos ([d86ec9f0](https://github.com/linuxdeepin/deepin-editor/commit/d86ec9f0eb6b0203608020e963f61d3c52976095)) +* save prompt error ([5992d3ae](https://github.com/linuxdeepin/deepin-editor/commit/5992d3ae028197f78832c9ebccd763444f72f518)) +* new tab does not scroll the latest index. ([1aee05af](https://github.com/linuxdeepin/deepin-editor/commit/1aee05af722f1313ca966722b6d6d484186bcc4e)) +* printer output format ([5c37338f](https://github.com/linuxdeepin/deepin-editor/commit/5c37338f01620a2735785d349e067f9637629bb1)) +* new blank document cannot be saved. ([b5902cfe](https://github.com/linuxdeepin/deepin-editor/commit/b5902cfe607265273211c7cc65b743359d843ca9)) +* don't display horizontal scrollbar. ([328e221b](https://github.com/linuxdeepin/deepin-editor/commit/328e221bb05ad94fa6bc9313975df3670c446659)) +* blank document close without prompting to save. ([48578887](https://github.com/linuxdeepin/deepin-editor/commit/4857888738bfd50c96695fdffa13281c5e15d028)) +* font debug prompt. ([98f6eb40](https://github.com/linuxdeepin/deepin-editor/commit/98f6eb406ec85b75d3a69a44850a0ad66455e1e8)) +* draft file default save directory. ([aac54afc](https://github.com/linuxdeepin/deepin-editor/commit/aac54afcb1e5616672ea047b4c38a96d0ced422e)) +* scroll line incorrect. ([e5f832ce](https://github.com/linuxdeepin/deepin-editor/commit/e5f832cec1c8cef3d16db839aaddb94f462389d8)) +* file not finish loadding cannot be saved. ([2e75eabc](https://github.com/linuxdeepin/deepin-editor/commit/2e75eabc5743e17434815f0e5f1f24b87ffecf1e)) +* does not support highlight do not reload. ([e5bf3942](https://github.com/linuxdeepin/deepin-editor/commit/e5bf39422744c0b8b5a289e0896e7f98b6843339)) +* response esc keymap. ([55b9611a](https://github.com/linuxdeepin/deepin-editor/commit/55b9611a1e966d8dce366508ad012d747cc6f151)) +* save the file priority. ([382c58a0](https://github.com/linuxdeepin/deepin-editor/commit/382c58a0910dab5287dff8c93ee95a4ffbf0ab18)) +* popup the theme panel slow. ([719f1c29](https://github.com/linuxdeepin/deepin-editor/commit/719f1c295a3676fcb702c32bab4abf4ef0b96367)) +* don't show the toast when saving. ([5c3eb6af](https://github.com/linuxdeepin/deepin-editor/commit/5c3eb6af46c1d820439f2999b894e8a6a8be6f49)) +* best encoding it has guessed ([cda92ee7](https://github.com/linuxdeepin/deepin-editor/commit/cda92ee71e03e7e15c127f93015a66ef3b834965)) +* first theme panel popuped up, correct item is not selected. ([0323074c](https://github.com/linuxdeepin/deepin-editor/commit/0323074c33d695d4964112c157f30315c5520616)) +* save root file garbled. ([720b7ec7](https://github.com/linuxdeepin/deepin-editor/commit/720b7ec73a419e0a19aebd4f7222dede7b502a41)) +* determine whether writable. ([dac3c01c](https://github.com/linuxdeepin/deepin-editor/commit/dac3c01c58408c7aa763b670d2e0799e1db8f95c)) +* right click selection color. ([28f91304](https://github.com/linuxdeepin/deepin-editor/commit/28f91304c0f81a1f7ccb6128b5258171ef3669a9)) +* save as correct encoding. ([3693b410](https://github.com/linuxdeepin/deepin-editor/commit/3693b410f37c3083d07c2bb09a8764e695e12360)) +* save set encoding. ([3355588e](https://github.com/linuxdeepin/deepin-editor/commit/3355588eece2c2a88b1a9fabb286a070948341e0)) +* best encoding it has guessed so far. ([52aa370a](https://github.com/linuxdeepin/deepin-editor/commit/52aa370a7c5571fb910c696ad1a8801a093a163e)) +* drag move event crash ([9db195cd](https://github.com/linuxdeepin/deepin-editor/commit/9db195cd4a9b37132c37e2c3e4f6f5706ae6c21d)) +* save root file logic. ([e17002ea](https://github.com/linuxdeepin/deepin-editor/commit/e17002ea20daa014d6f336a679b04e40e526ed29)) +* pro file installs script ([cf6e0b7a](https://github.com/linuxdeepin/deepin-editor/commit/cf6e0b7afdca248de86cb9995b6bb76b081b0cdb)) +* save root file crash ([e1a6b660](https://github.com/linuxdeepin/deepin-editor/commit/e1a6b66060dee283a0d306c3e0b836e213629adb)) +* prompt to save the draft document. ([3232017b](https://github.com/linuxdeepin/deepin-editor/commit/3232017ba94783b2460e80cefbc1bafb0fdf23db)) +* restore cursor ([0c8123c9](https://github.com/linuxdeepin/deepin-editor/commit/0c8123c94c5e41c18d4928b29153b5932f45804e)) +* switch theme to scroll to the next line. ([abde4fac](https://github.com/linuxdeepin/deepin-editor/commit/abde4fac67410a28b12c7c462c3ae6b490f01279)) +* some themes do not highlight. ([15fd8fbd](https://github.com/linuxdeepin/deepin-editor/commit/15fd8fbde04fb81fa13f3f0d46ae20efefc153ad)) +* remove loadding cursor ([c96e9642](https://github.com/linuxdeepin/deepin-editor/commit/c96e9642f5f4eb991463aa2c349cff4c39bd8c9a)) +* move document thread ([862499bf](https://github.com/linuxdeepin/deepin-editor/commit/862499bf997a8bef3999d21c29be33621b60b42a)) +* do not create new QTextDocument. ([c143fd34](https://github.com/linuxdeepin/deepin-editor/commit/c143fd34d33a3a73ba65b967ab526bb8d11593ea)) +* open blank files of last session may cause window flash ([480caa69](https://github.com/linuxdeepin/deepin-editor/commit/480caa6918c982cafb87086ff4a8479d1015c217)) +* open blank files of last session may cause window flash. ([08d04190](https://github.com/linuxdeepin/deepin-editor/commit/08d041906cac46a2589d2b552d2b708d59ba74bb)) +* clear blank files that have no content. ([956b9e06](https://github.com/linuxdeepin/deepin-editor/commit/956b9e066260983cccc74d1db6a7b9a14fbeaa40)) +* if close the tab, delete the blank file. ([67f0ab17](https://github.com/linuxdeepin/deepin-editor/commit/67f0ab179203531d2f6c7d44a4cdd063288e3374)) +* findbar press ESC is invalid ([d900a205](https://github.com/linuxdeepin/deepin-editor/commit/d900a205968aaa2284100ac618229368cbfb5d4e)) +* texteditor does not have focus after switching tabs ([c2dc270e](https://github.com/linuxdeepin/deepin-editor/commit/c2dc270e9a0570f5d5c868f001792fe6db198c12)) +* use build version ([30fb5769](https://github.com/linuxdeepin/deepin-editor/commit/30fb5769fc19f2216f296629fe880af435b20738)) +* tab drag leave not close is incorrect. ([1b49bcef](https://github.com/linuxdeepin/deepin-editor/commit/1b49bcef26a46a51567e238351125b2a97696c78)) +* connection repeat slot functions. ([1c2b4ade](https://github.com/linuxdeepin/deepin-editor/commit/1c2b4ade3ac668bf87b169523fd074268e19c29f)) +* drag a window does not close properly when ([7a9c8bdc](https://github.com/linuxdeepin/deepin-editor/commit/7a9c8bdc7bd96906328669bea8490fdb45f3ffaf)) +* cursor stops being redrawn when QPlainTextEdit::dropEvent() overrided... ([fea5a7e7](https://github.com/linuxdeepin/deepin-editor/commit/fea5a7e7898146dd3385af64db8b36b8e353a769)) +* drag and drop tab index is incorrect ([04916d14](https://github.com/linuxdeepin/deepin-editor/commit/04916d14e7bbea469790d00ed37d2038af70cba9)) +* set window minimum size. ([a1d3b21b](https://github.com/linuxdeepin/deepin-editor/commit/a1d3b21b0a9218120ddf293ca3ca443a0c9602fe)) +* close event ([eafc9523](https://github.com/linuxdeepin/deepin-editor/commit/eafc95236a7ad5c3e401be7c5af65d66b45bf934)) +* no need to adjust scrollbar margins if reach last line ([4c56f4f1](https://github.com/linuxdeepin/deepin-editor/commit/4c56f4f1dc6860b6b3a8a3cdc4613121f9b6b1f0)) +* not release memory when close tab. ([52f0ea3f](https://github.com/linuxdeepin/deepin-editor/commit/52f0ea3f2fc835fae7cb84ac5e26c273cec28019)) +* tabbar stylesheet ([4aeea8a0](https://github.com/linuxdeepin/deepin-editor/commit/4aeea8a04feea2980ddf959730e4ad4dbe1088e3)) +* all window switching theme. ([46818c99](https://github.com/linuxdeepin/deepin-editor/commit/46818c995444ee18bd71101df52906f90635edc2)) +* theme setting background invalid. ([5a856d34](https://github.com/linuxdeepin/deepin-editor/commit/5a856d34580785e6f0a49ddc71d8ea872427eadc)) +* remove english completer menu. ([54e30108](https://github.com/linuxdeepin/deepin-editor/commit/54e3010819214b76a41dcf38890fb2476dde4046)) +* copying to clipboard text is incorrect. ([28a73ada](https://github.com/linuxdeepin/deepin-editor/commit/28a73adaa098fc95743ae21f2ecac5bbbb4d79a2)) +* window flashing. ([c55c5e42](https://github.com/linuxdeepin/deepin-editor/commit/c55c5e42713cc26a4699d79c18ed31105cdd17e0)) +* do not generate BOM. ([fec6fa62](https://github.com/linuxdeepin/deepin-editor/commit/fec6fa6224d252a3b1df43c2ba10741b97ca34e8)) +* read-only mode moving cursor crashes. ([5042c39e](https://github.com/linuxdeepin/deepin-editor/commit/5042c39ef5a9ccaa2c71d3604b131a23b3e2a838)) +* save the correct encoding ([a9e92874](https://github.com/linuxdeepin/deepin-editor/commit/a9e92874e4e25e1ea99362fa42bb27ff1b1f5901)) +* crash when drag tab on high qt version ([1cecc879](https://github.com/linuxdeepin/deepin-editor/commit/1cecc879b238b1a2fd1e8092a1d79537a5dc6fa3)) +* **SettingsDialog:** + * no update tab space number. ([d44b100b](https://github.com/linuxdeepin/deepin-editor/commit/d44b100b9eb9c4269a06fc916876de53898196af)) + * font is empty after recovery. ([2683caea](https://github.com/linuxdeepin/deepin-editor/commit/2683caeac5611b43a1a9cfe0bfe7850ace6ac0e9)) +* **config:** desktop translation ([15b4f878](https://github.com/linuxdeepin/deepin-editor/commit/15b4f87857fd6c87e30f21f2fc6cdc10625aa5e9)) +* **find:** makes find match only complete words. ([c2de5c36](https://github.com/linuxdeepin/deepin-editor/commit/c2de5c364b84a8f6648c4e789e1c742475814014)) +* **find_bar:** text display is incomplete, increase height. ([f282ab24](https://github.com/linuxdeepin/deepin-editor/commit/f282ab249196a9ac19d1a224077aa2f9d8f5deac)) +* **read_only_mode:** empty text moving cursor crashes. ([f60be78e](https://github.com/linuxdeepin/deepin-editor/commit/f60be78e47e11680156bcc2bc6fb515c229e2955)) +* **tabbar:** + * close tab without reminder. ([c846f6e9](https://github.com/linuxdeepin/deepin-editor/commit/c846f6e974c97af4d57e903f2677516ece4d0013)) + * handleTabDroped() type conversion error. ([a1796f93](https://github.com/linuxdeepin/deepin-editor/commit/a1796f93adf45982ab70c53e0b0fb4ac370ce9fc)) + * dnd background error ([8934d1e9](https://github.com/linuxdeepin/deepin-editor/commit/8934d1e965ffba5134c1c20291ab9d310edebe3a)) + * did not call closeFile() after dragging out. ([33687534](https://github.com/linuxdeepin/deepin-editor/commit/336875340ed0f05c627e40f650ab01c061c865cd)) +* **texteditor:** some colors is incorrect. ([ba094484](https://github.com/linuxdeepin/deepin-editor/commit/ba094484a7c06bc0a3a3b38171f48e087ac9f785)) +* **toast:** possible memory leak ([4b01a349](https://github.com/linuxdeepin/deepin-editor/commit/4b01a349bd1d2dfc7e8297b68b3b5d2726d770fb)) + +#### Features + +* optimize emacs mode. ([dbc5d021](https://github.com/linuxdeepin/deepin-editor/commit/dbc5d0210eb55bb8923e28e262507ffcbcb82808)) +* sort theme list by lightness. ([8e15694c](https://github.com/linuxdeepin/deepin-editor/commit/8e15694cd0a97bd9cc4204846010132e917be4be)) +* add atom dark theme. ([f523c1aa](https://github.com/linuxdeepin/deepin-editor/commit/f523c1aa11f122b335b7ce4a1fdbec73c5dde75a)) +* support Ctrl + wheel to adjust font size. ([7873a610](https://github.com/linuxdeepin/deepin-editor/commit/7873a610cc974b4829de32a6967d45fd341b7e65)) +* delayed loadding highlight. ([4b0b87ea](https://github.com/linuxdeepin/deepin-editor/commit/4b0b87eac4f896766cdca32751016beb3d9b1b88)) +* close window prompt to save all files. ([b3b8cd9f](https://github.com/linuxdeepin/deepin-editor/commit/b3b8cd9f35c6469241971f7d548fd1b394c3c224)) +* support open srt files. ([9f33d6e8](https://github.com/linuxdeepin/deepin-editor/commit/9f33d6e82d6d1e0b37c7d8a5dd3906ee27481d25)) +* remove document margin. ([adb8ca94](https://github.com/linuxdeepin/deepin-editor/commit/adb8ca94f2db0cceec823ff9d60f981f14528db3)) +* intelligent judge whether to support comments. ([ead6f1d8](https://github.com/linuxdeepin/deepin-editor/commit/ead6f1d8cd7fab011faf0ae0ba3105542a896f3b)) +* support open bak files. ([54c6259c](https://github.com/linuxdeepin/deepin-editor/commit/54c6259cb50db2d1fd5725bb8bd62090ec09cb0b)) +* optimize theme panel selection effect. ([7b4cf4b6](https://github.com/linuxdeepin/deepin-editor/commit/7b4cf4b67ea72b4a9e75b8083e5073dc1bb31c02)) +* add solarized dark theme. ([22781ac6](https://github.com/linuxdeepin/deepin-editor/commit/22781ac60d503ba699e9d8661e5f055cd2d392a8)) +* prompt whether to save as when saving fails. ([b19cd092](https://github.com/linuxdeepin/deepin-editor/commit/b19cd092d63337be601dac986575a04b51dce6dc)) +* optimize load file ([adb356a5](https://github.com/linuxdeepin/deepin-editor/commit/adb356a521747329fe5b673e9093f7b5d69e5b26)) +* tabbar release changes window position. ([992f5415](https://github.com/linuxdeepin/deepin-editor/commit/992f5415158a8f3d2c7b7a89a10e8c9e62a7864e)) +* support multi-thraded read fiels. ([d4de7431](https://github.com/linuxdeepin/deepin-editor/commit/d4de743195567e7ee1b3211d92432645edc8bdc3)) +* change cursor when saving ([456230bc](https://github.com/linuxdeepin/deepin-editor/commit/456230bc42dd0f9f4c96ff3320f7e6dc882f5b7e)) +* add load mouse style. ([9ea1f8d7](https://github.com/linuxdeepin/deepin-editor/commit/9ea1f8d70e5682d7bbdb840fdcbeeab1c6112207)) +* add solarized-light theme ([3341f0fa](https://github.com/linuxdeepin/deepin-editor/commit/3341f0fa5b2c6ab15fddefa9d03590a2c358cd36)) +* can change the titlebar background color. ([37002495](https://github.com/linuxdeepin/deepin-editor/commit/37002495f56fbe21ee481a1c95754434f5459831)) +* optimize modification state. ([003db509](https://github.com/linuxdeepin/deepin-editor/commit/003db509fc12d519237b1c0afad022bc07ca7889)) +* align the top of the line numbers. ([4b0e41aa](https://github.com/linuxdeepin/deepin-editor/commit/4b0e41aadb235cd0f5314c2ec631ce5ee389033f)) +* support drag and drop the web url text. ([dc8413ab](https://github.com/linuxdeepin/deepin-editor/commit/dc8413ab10aaed5e0272b1d3472725801d4705a4)) +* save the file dialog history directory. ([1f28e873](https://github.com/linuxdeepin/deepin-editor/commit/1f28e873379a647239c30124e2da3cbd3e75e0b0)) +* update MimeType of desktop file ([0712e2fc](https://github.com/linuxdeepin/deepin-editor/commit/0712e2fcecf3e48526e02e1e12d41e0eff3540fd)) +* optimize startup speed. ([d7006a9c](https://github.com/linuxdeepin/deepin-editor/commit/d7006a9cece07800e0918d14863394516c756838)) +* select current directory when saving ([c370010f](https://github.com/linuxdeepin/deepin-editor/commit/c370010fde4e276d154effe96232cc6a966cae01)) +* supports drag files to window ([1af5c0f6](https://github.com/linuxdeepin/deepin-editor/commit/1af5c0f62b2347411508d44b918b8abfcdd7f424)) +* support open the desktop & yml files. ([1f6d3ae8](https://github.com/linuxdeepin/deepin-editor/commit/1f6d3ae8ace858ceb750c89f278f5785ac0f0d02)) +* save the correct newline. ([29e93136](https://github.com/linuxdeepin/deepin-editor/commit/29e93136aaf6633650e88f85ebefbca0383a4df6)) +* **IndentText:** optimize cursor blink. ([0175b85a](https://github.com/linuxdeepin/deepin-editor/commit/0175b85aaa771dcdc13a01e0ecf797f5b9f0704f)) +* **TextEdit:** auto adjust scrollbar margins. ([92559757](https://github.com/linuxdeepin/deepin-editor/commit/92559757731578a54abc8b4fad077d28d806e539)) +* **ThemeView:** auto adjust scrollbar margins. ([8e817ec4](https://github.com/linuxdeepin/deepin-editor/commit/8e817ec40627c8325f432ab8465bd4a9d3c3a621)) +* **findbar:** select all text when get focus. ([4a36520c](https://github.com/linuxdeepin/deepin-editor/commit/4a36520cb6c6a991dff8d6e8ed3464ae70814298)) +* **printDialog:** set output file name ([8d7d077d](https://github.com/linuxdeepin/deepin-editor/commit/8d7d077d9a1cda0ed95406b1cd86d73c159a1007)) +* **save:** correct toast content ([0c938f1f](https://github.com/linuxdeepin/deepin-editor/commit/0c938f1f3b849c2357dcc0db9fa568e3540dc388)) +* **search:** case insensitive. ([0a549e93](https://github.com/linuxdeepin/deepin-editor/commit/0a549e935565b767c882cac9df10cb311bd0658d)) +* **tabbar:** support background gradient. ([279dffa1](https://github.com/linuxdeepin/deepin-editor/commit/279dffa1199883bf9d4e3fae99884fdf49bee566)) + + + +### 0.0.5 (2018-05-23) +- Tag for archlinux. + +### 0.0.4 (2018-05-17) +- Tag for archlinux. + +### 0.0.3 (2018-05-14) +- Fixed many bugs since 0.0.2 + +### 0.0.2 (2018-05-10) +- First release for arch. + +### 0.0.1 (2018-01-22) +- Init tag diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..78af98f48899b81f5ae42697d0b6a69bfd6ab089 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 3.7) + +set(VERSION "6.0.0" CACHE STRING "Application version") + +project(deepin-editor + VERSION ${VERSION} + DESCRIPTION "Text editor for DDE" + HOMEPAGE_URL "https://github.com/linuxdeepin/deepin-editor" + LANGUAGES CXX C +) + +#set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + +if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "sw_64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mieee") +endif () + +# 设置软件版本 +include_directories(${PROJECT_BINARY_DIR}) +configure_file(${PROJECT_SOURCE_DIR}/src/environments.h.in ${PROJECT_BINARY_DIR}/environments.h @ONLY) + +add_subdirectory(src) + +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + add_subdirectory(tests) +endif() diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + (at your option) 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSES/CC-BY-4.0.txt b/LICENSES/CC-BY-4.0.txt new file mode 100644 index 0000000000000000000000000000000000000000..13ca539f377dc705af32b8d2ce89262298ea2f06 --- /dev/null +++ b/LICENSES/CC-BY-4.0.txt @@ -0,0 +1,156 @@ +Creative Commons Attribution 4.0 International + + Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. + +Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors. + +Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public. + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. + +Section 1 – Definitions. + + a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + + d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License. + + g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights under this Public License. + + i. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. + +Section 2 – Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. + + 3. Term. The term of this Public License is specified in Section 6(a). + + 4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. Downstream recipients. + + A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. + + B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. + + 6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). + +b. Other rights. + + 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. + +Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + + B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. + + 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. + +Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; + + b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. +For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. + + a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You. + + b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You. + + c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. + + a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + c. For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. + + d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. + + e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. + +Section 8 – Interpretation. + + a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. + + c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. + + d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. + +Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt new file mode 100644 index 0000000000000000000000000000000000000000..0e259d42c996742e9e3cba14c677129b2c1b6311 --- /dev/null +++ b/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 0000000000000000000000000000000000000000..17cb286430a4d8094e473d06bd7f50f40438ddba --- /dev/null +++ b/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,117 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author + + 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 2 of the License, or (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice diff --git a/LICENSES/GPL-3.0-or-later.txt b/LICENSES/GPL-3.0-or-later.txt new file mode 100644 index 0000000000000000000000000000000000000000..d41c0bd98feb776ef7d81efbc1b5447e0284a187 --- /dev/null +++ b/LICENSES/GPL-3.0-or-later.txt @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 (at your option) 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 . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000000000000000000000000000000000000..2071b23b0e08594ea6bc99ac71129ef992abf498 --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..14943bd47632dea11df0ed2cebd7233001f8bbdb --- /dev/null +++ b/README.md @@ -0,0 +1,87 @@ +# Deepin Editor + +Deepin Editor is a desktop text editor that supports common text editing features. + +## Dependencies + +_The **master** branch is current development branch, build dependencies may changes without update README.md, refer to `./debian/control` for a working build depends list_ + +* libqt5widgets5 +* libdtkcore-dev +* libdtkwidget-dev +* qt5-default +* libpolkit-qt5-1-dev +* libkf5syntaxhighlighting-dev +* libkf5codecs-dev +* qttools5-dev-tools +* qtbase5-private-dev +* libxcb-util0-dev +* libdtkwm-dev +* libxtst-dev + +## Installation + +1. Make sure you have installed all dependencies. + +_Package name may be different between distros, if deepin-editor is available from your distro, check the packaging script delivered from your distro is a better idea._ + +Assume you are using [Deepin](https://distrowatch.com/table.php?distribution=deepin) or other debian-based distro which got deepin-editor delivered: + +``` shell +$ sudo apt-get build-dep deepin-edtor +``` + +2. Build editor daemon + +``` +sudo cp com.deepin.editor.policy /usr/share/polkit-1/actions +sudo cp com.deepin.editor.conf /usr/share/dbus-1/system.d/ +sudo cp com.deepin.editor.daemon.service /usr/share/dbus-1/system-services + +cd ./daemon +mkdir build +cd build +qmake .. +make +sudo ./deepin-editor-daemon +``` + +3. Build editor + +``` +cd deepin-editor +mkdir build +cd build +cmake .. +make +./deepin-editor +``` + +4. Install editor: + +``` +$ sudo make install +``` + +## Config file + +configure save at: ~/.config/deepin/deepin-editor/config.conf + +## Getting help + +Any usage issues can ask for help via + +* [Gitter](https://gitter.im/orgs/linuxdeepin/rooms) +* [IRC channel](https://webchat.freenode.net/?channels=deepin) +* [Forum](https://bbs.deepin.org) +* [WiKi](http://wiki.deepin.org/) + +## Getting involved + +We encourage you to report issues and contribute changes + +* [Contribution guide for developers](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en). + +## License + +Deepin Editor is licensed under [GPL-3.0-or-later](LICENSE.txt). diff --git a/README.zh_CN.md b/README.zh_CN.md new file mode 100644 index 0000000000000000000000000000000000000000..0fb778dcf473fe42d0c085f30a5275e47c8d9668 --- /dev/null +++ b/README.zh_CN.md @@ -0,0 +1,88 @@ +# Deepin Editor + +文本编辑器是一个简单的文本编辑工具。您可以用它书写简单的文本文档,也可以使用它的高级特性,让它成为一个代码编辑工具,支持代码语法高亮。 + +## 依赖 + +_**master**分支是当前开发分支,编译依赖可能在未更新README.md文件的情况下变更,请参考./debian/control文件获取有效的编译依赖列表_ + +* libqt5widgets5 +* libdtkcore-dev +* libdtkwidget-dev +* qt5-default +* libpolkit-qt5-1-dev +* libkf5syntaxhighlighting-dev +* libkf5codecs-dev +* qttools5-dev-tools +* qtbase5-private-dev +* libxcb-util0-dev +* libdtkwm-dev +* libxtst-dev + +## 安装 + +1. 确保已安装所有依赖库. + + +_不同发行版的软件包名称可能不同,如果您的发行版提供了deepin-editor,请检查发行版提供的打包脚本。_ + +如果你使用的是 [Deepin](https://distrowatch.com/table.php?distribution=deepin) 或者其它提供了deepin-editor的发行版: + +``` shell +$ sudo apt-get build-dep deepin-edtor +``` + +2. 构建 editor daemon + +``` +sudo cp com.deepin.editor.policy /usr/share/polkit-1/actions +sudo cp com.deepin.editor.conf /usr/share/dbus-1/system.d/ +sudo cp com.deepin.editor.daemon.service /usr/share/dbus-1/system-services + +cd ./daemon +mkdir build +cd build +qmake .. +make +sudo ./deepin-editor-daemon +``` + +3. 构建 editor + +``` +cd deepin-editor +mkdir build +cd build +cmake .. +make +./deepin-editor +``` + +4. 安装 editor: + +``` +$ sudo make install +``` + +## 配置文件 + +配置文件位于: ~/.config/deepin/deepin-editor/config.conf + +## 帮助 + +任何使用问题都可以通过以下方式寻求帮助: + +* [Gitter](https://gitter.im/orgs/linuxdeepin/rooms) +* [IRC channel](https://webchat.freenode.net/?channels=deepin) +* [Forum](https://bbs.deepin.org) +* [WiKi](http://wiki.deepin.org/) + +## 贡献指南 + +我们鼓励您报告问题并做出更改 + +* [开发者代码贡献指南](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers) + +## 开源许可证 + +Deepin Editor 在 [GPL-3.0-or-later](LICENSE.txt) 下发布 diff --git a/com.deepin.editor.conf b/com.deepin.editor.conf new file mode 100644 index 0000000000000000000000000000000000000000..42f098f0a05c008b0d1958b658e0431cd0842b45 --- /dev/null +++ b/com.deepin.editor.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.deepin.editor.daemon.service b/com.deepin.editor.daemon.service new file mode 100644 index 0000000000000000000000000000000000000000..3112e6d82829530f8c805ba05622ce7640df0789 --- /dev/null +++ b/com.deepin.editor.daemon.service @@ -0,0 +1,4 @@ +[D-BUS Service] +User=root +Name=com.deepin.editor.daemon +Exec=/usr/bin/deepin-editor-daemon \ No newline at end of file diff --git a/com.deepin.editor.policy b/com.deepin.editor.policy new file mode 100644 index 0000000000000000000000000000000000000000..0240563c99f499f77b4b78469ef36455f6f93269 --- /dev/null +++ b/com.deepin.editor.policy @@ -0,0 +1,14 @@ + + + + + Save file with administrator privilege + Save file with administrator privilege + + no + auth_admin + + + diff --git a/daemon/deepin-editor-daemon.pro b/daemon/deepin-editor-daemon.pro new file mode 100644 index 0000000000000000000000000000000000000000..3f560f73e5a4060ce86267a7a8f14fdadb274c08 --- /dev/null +++ b/daemon/deepin-editor-daemon.pro @@ -0,0 +1,32 @@ +###################################################################### +# Automatically generated by qmake (3.0) ?? 2? 4 17:49:37 2017 +###################################################################### + +TEMPLATE = app +TARGET = deepin-editor-daemon + +CONFIG += link_pkgconfig +CONFIG += c++11 +PKGCONFIG += dtkwidget polkit-qt5-1 + +# Input +HEADERS += src/dbusadaptor.h \ + src/dbus.h \ + src/utils.h \ + src/policykithelper.h + +SOURCES += src/dbusadaptor.cpp \ + src/dbus.cpp \ + src/utils.cpp \ + src/main.cpp \ + src/policykithelper.cpp + +QT += core +QT += dbus + +QMAKE_CXXFLAGS += -g + +isEmpty(BINDIR):BINDIR=/usr/bin +target.path = $$INSTROOT$$BINDIR + +INSTALLS += target diff --git a/daemon/src/dbus.cpp b/daemon/src/dbus.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f8a670c24697b9466a3055603c75e0cb6a59f8d --- /dev/null +++ b/daemon/src/dbus.cpp @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "policykithelper.h" +#include "dbus.h" +#include "utils.h" + +#include +#include +#include +#include + +DBus::DBus(QObject *parent) : QObject(parent) +{ +} + +bool DBus::saveFile(const QByteArray &path, const QByteArray &text, const QByteArray &encoding) +{ + const QString filepath = QString::fromUtf8(path); + + if (PolicyKitHelper::instance()->checkAuthorization("com.deepin.editor.saveFile", getpid())) { + // Create file if filepath is not exists. + if (!Utils::fileExists(filepath)) { + QString directory = QFileInfo(filepath).dir().absolutePath(); + + QDir().mkpath(directory); + if (QFile(filepath).open(QIODevice::ReadWrite)) { + qDebug() << QString("File %1 not exists, create one.").arg(filepath); + } + } + + // Save content to file. + QFile file(filepath); + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)){ + qDebug() << "Can't write file: " << filepath; + + return false; + } + + QTextStream out(&file); + out.setCodec(encoding); + out << text; + file.close(); + + return true; + } else{ + return false; + } +} diff --git a/daemon/src/dbus.h b/daemon/src/dbus.h new file mode 100644 index 0000000000000000000000000000000000000000..2dc8423eec6e1b7b9560edbd343743e43642665a --- /dev/null +++ b/daemon/src/dbus.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef DBUS_H +#define DBUS_H + +#include + +class DBus : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface","com.deepin.editor.daemon") + +public: + DBus(QObject* parent = nullptr); + +public Q_SLOTS: + bool saveFile(const QByteArray &path, const QByteArray &text, const QByteArray &encoding); +}; + + +#endif //DBUS_H diff --git a/daemon/src/dbusadaptor.cpp b/daemon/src/dbusadaptor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1fa0d0c021e1927eeadca29923d45e747fce895c --- /dev/null +++ b/daemon/src/dbusadaptor.cpp @@ -0,0 +1,47 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp com.deepin.editor.daemon -a dbusadaptor + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "dbusadaptor.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * Implementation of adaptor class DaemonAdaptor + */ +DbusAdaptor::DbusAdaptor(QObject *parent) : QDBusAbstractAdaptor(parent) +{ + // constructor + setAutoRelaySignals(true); +} + +DbusAdaptor::~DbusAdaptor() +{ + // destructor +} + +bool DbusAdaptor::saveFile(const QByteArray &filepath, const QByteArray &text, const QByteArray &encoding) +{ + // handle method call com.deepin.editor.daemon.saveFile. + + bool returnResult; + QMetaObject::invokeMethod(parent(), "saveFile", Q_RETURN_ARG(bool, returnResult), + Q_ARG(QByteArray, filepath), + Q_ARG(QByteArray, text), + Q_ARG(QByteArray, encoding)); + + return returnResult; +} diff --git a/daemon/src/dbusadaptor.h b/daemon/src/dbusadaptor.h new file mode 100644 index 0000000000000000000000000000000000000000..b5b899625c4afad4830bd68830deef323f06df7b --- /dev/null +++ b/daemon/src/dbusadaptor.h @@ -0,0 +1,55 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp com.deepin.editor.daemon -a dbusadaptor + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#ifndef DBUSADAPTOR_H +#define DBUSADAPTOR_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QByteArray; +template class QList; +template class QMap; +class QString; +class QStringList; +class QVariant; +QT_END_NAMESPACE + +/* + * Adaptor class for interface com.deepin.editor.daemon + */ +class DbusAdaptor: public QDBusAbstractAdaptor { + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "com.deepin.editor.daemon") + Q_CLASSINFO("D-Bus Introspection", "" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "") +public: + DbusAdaptor(QObject *parent); + virtual ~DbusAdaptor(); + +public: // PROPERTIES + +public Q_SLOTS: // METHODS + bool saveFile(const QByteArray &filepath, const QByteArray &text, const QByteArray &encoding); + +Q_SIGNALS: // SIGNALS +}; + +#endif diff --git a/daemon/src/main.cpp b/daemon/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42d0677dc64e1c2372d1bb34b94dc5d150c5080c --- /dev/null +++ b/daemon/src/main.cpp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "dbus.h" +#include "dbusadaptor.h" + +#include +#include + +int main(int argc, char **argv) +{ + QCoreApplication app(argc, argv); + + DBus *dbus1 = new DBus; + new DbusAdaptor(dbus1); + + QDBusConnection connection = QDBusConnection::systemBus(); + if (connection.isConnected()) { + qDebug() << "Build deepin-editor daemon success."; + } + + if(!connection.registerService("com.deepin.editor.daemon") || + !connection.registerObject("/", dbus1)){ + qDebug() << connection.lastError(); + + app.exit(1); + return 1; + } + + return app.exec(); +} diff --git a/daemon/src/policykithelper.cpp b/daemon/src/policykithelper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9c482656ce58a1a6b32e25904b10d48afac5e17 --- /dev/null +++ b/daemon/src/policykithelper.cpp @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "policykithelper.h" + +bool PolicyKitHelper::checkAuthorization(const QString& actionId, qint64 applicationPid) +{ + Authority::Result result; + + result = Authority::instance()->checkAuthorizationSync( + actionId, + UnixProcessSubject(applicationPid), + Authority::AllowUserInteraction); + + return result == Authority::Yes; +} + +PolicyKitHelper::PolicyKitHelper() +{ + +} + +PolicyKitHelper::~PolicyKitHelper() +{ + +} diff --git a/daemon/src/policykithelper.h b/daemon/src/policykithelper.h new file mode 100644 index 0000000000000000000000000000000000000000..aa6479f9a65768b748eeedcd2696f091889da89a --- /dev/null +++ b/daemon/src/policykithelper.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef POLICYKITHELPER_H +#define POLICYKITHELPER_H + +#include + +using namespace PolkitQt1; + +class PolicyKitHelper { +public: + inline static PolicyKitHelper* instance(){ + static PolicyKitHelper instance; + return &instance; + } + + bool checkAuthorization(const QString& actionId, qint64 applicationPid); + +private: + PolicyKitHelper(); + ~PolicyKitHelper(); + + Q_DISABLE_COPY(PolicyKitHelper) +}; + + +#endif //POLICYKITHELPER_H diff --git a/daemon/src/utils.cpp b/daemon/src/utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..13ff7fec56cc9ea03163ce4583ddbee6bec27031 --- /dev/null +++ b/daemon/src/utils.cpp @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "utils.h" + +#include +#include + +bool Utils::fileExists(QString path) { + QFileInfo check_file(path); + + // check if file exists and if yes: Is it really a file and no directory? + return check_file.exists() && check_file.isFile(); +} + +bool Utils::fileIsWritable(QString path) +{ + QFileDevice::Permissions permissions = QFile(path).permissions(); + + return permissions & QFileDevice::WriteUser; +} diff --git a/daemon/src/utils.h b/daemon/src/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..17504ec040b8ad09a703a2842a17b9454c9ff4d4 --- /dev/null +++ b/daemon/src/utils.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +class Utils : public QObject +{ + Q_OBJECT + +public: + static bool fileExists(QString path); + static bool fileIsWritable(QString path); +}; diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000000000000000000000000000000000000..0843f15e8de2245fe4457361eb6ac882d83176af --- /dev/null +++ b/debian/changelog @@ -0,0 +1,75 @@ +deepin-editor (6.0.6) unstable; urgency=medium + + * fix: 修复使用特殊字体时,序号显示不全(Bug: 188417)(Influence: 序号显示) + * fix: 修复加载完小文件时,行号显示不全问题(Influence: 行号显示) + * fix: 修复GB18030部分编码转换错误问题(Influence: 编码转换) + * fix: 修复源编码为UTF-8时编码转换空白的问题(Influence: 编码转换) + * feat: 适配GB18030-2022规范兼容2005标准(Bug: 193311)(Influence: 编码转换 GB18030显示 另存) + * fix: 更新翻译显示(Bug: 110761) + + -- Deepin Packages Builder Thu, 13 Apr 2023 13:51:25 +0800 + +deepin-editor (6.0.5) unstable; urgency=medium + + * Fix application palette change bug. + + -- Deepin Packages Builder Thu, 16 Mar 2023 09:42:02 +0800 + +deepin-editor (6.0.4) unstable; urgency=medium + + * Update version to distinguish pro/community. + * Fix cursor position error when editing multi-byte encoding text. + + -- Deepin Packages Builder Fri, 10 Mar 2023 10:19:21 +0800 + +deepin-editor (6.0.3) unstable; urgency=medium + + * Improve GB18030 text encoding recognition rate. + * Fix print large document bug. + + -- Deepin Packages Builder Tue, 07 Mar 2023 10:43:27 +0800 + +deepin-editor (6.0.2) unstable; urgency=medium + + * Improve text search and highlight color. + + -- renbin Thu, 16 Feb 2023 14:42:04 +0800 + +deepin-editor (6.0.1) unstable; urgency=medium + + * Improve convert text encoding. + * Adaptor V23 DDE DBus interface. + * Fix debian rules error. + + -- renbin Tue, 14 Feb 2023 15:04:06 +0800 + +deepin-editor (6.0.0) unstable; urgency=low + + * New version 6.0.0 + * Sync v23 source code from gerrit. + + -- renbin Wed, 11 Jan 2023 14:04:01 +0000 + +deepin-editor (5.10.13) unstable; urgency=low + + [ Hu Feng Fri, 19 Feb 2021 15:32:28 +0800 ] + * debian/control + + Add Hu Feng to the uploaders list. + + Delete libdtkwm-dev in Build-Depends. + + Delete libxcb-util0-dev in Build-Depends. + + Delete libxcb1-dev in Build-Depends. + + Delete libxext-dev in Build-Depends. + + Delete libxtst-dev in Build-Depends. + + Add libdframeworkdbus-dev to Build-Depends. + + Add libgmock-dev to Build-Depends. + + Add libgtest-dev to Build-Depends. + + Add deepin-desktop-base to Depends in deepin-editor package. + + Add dde-qt5integration to Depends in deepin-editor package. + + [ Clay Stan ] + * debian/copyright: Update license information. + + [ Ma Aiguo ] + * Initial package (Closes: #897571) + + -- Ma Aiguo Wed, 02 Jun 2021 16:53:34 +0800 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000000000000000000000000000000000000..4c003294bfd8a08d77ebbc484d1fbe4022e28acc --- /dev/null +++ b/debian/control @@ -0,0 +1,41 @@ +Source: deepin-editor +Section: editors +Priority: optional +Maintainer: Debian Deepin Packaging Team +Uploaders: Ma Aiguo , +Build-Depends: + cmake, + debhelper-compat (= 12), + pkg-config, + libqt5widgets5, + libdtkcore-dev, + libdtkwidget-dev, + libpolkit-qt5-1-dev, + libkf5syntaxhighlighting-dev, + libkf5codecs-dev, + qttools5-dev-tools, + qtbase5-private-dev, + libdframeworkdbus-dev, + libgtest-dev, + libgmock-dev, + libchardet-dev, + libuchardet-dev (>= 0.0.6), + libicu-dev +Rules-Requires-Root: no +Standards-Version: 4.5.1 +Homepage: https://github.com/linuxdeepin/deepin-editor + +Package: deepin-editor +Architecture: any +Depends: + dde-qt5integration, + ${shlibs:Depends}, + ${misc:Depends}, + libdtkwidget5 (>= 5.4.11), + libuchardet0 (>= 0.0.6), + libchardet1 +Description: Text editor for DDE (Deepin Desktop Environment) + Advanced text editor based on dtk. + . + This package is part of DDE (Deepin Desktop Environment). +Recommends: uos-reporter, deepin-event-log \ No newline at end of file diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000000000000000000000000000000000000..4f92c6b442d7193676fac1319e3f96fe4e74a12f --- /dev/null +++ b/debian/copyright @@ -0,0 +1,135 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: deepin-editor +Source: https://github.com/linuxdeepin/deepin-editor +Upstream-Contact: https://github.com/linuxdeepin/deepin-editor/issues + +# ci +Files: .github/* +Copyright: UnionTech Software Technology Co., Ltd. +License: CC0-1.0 + +# gitignore +Files: .gitignore +Copyright: None +License: CC0-1.0 + +# .gitmodules +Files: .gitmodules +Copyright: None +License: CC0-1.0 + +# xml toml json conf yaml sh ini h.in +Files: *.toml *.json *conf *.yaml *.sh *.ini *.h.in +Copyright: UnionTech Software Technology Co., Ltd. +License: CC0-1.0 + +# debian +Files: debian/* +Copyright: UnionTech Software Technology Co., Ltd. +License: CC0-1.0 + +# rpm +Files: rpm/* +Copyright: UnionTech Software Technology Co., Ltd. +License: CC0-1.0 + +# Project file +Files: *.pro *.prf *.pri *.qrc *CMakeLists.txt .tx/* +Copyright: UnionTech Software Technology Co., Ltd. +License: CC0-1.0 + +# config files +Files: com.deepin.editor.daemon.service com.deepin.editor.policy deepin-editor.desktop +Copyright: UnionTech Software Technology Co., Ltd. +License: CC0-1.0 + +# README +Files: README.md README.zh_CN.md CHANGELOG.md +Copyright: UnionTech Software Technology Co., Ltd. +License: CC-BY-4.0 + +# assets +Files: src/assets/* src/images/* src/themes/* src/qss/* tests/src/themes/* +Copyright: UnionTech Software Technology Co., Ltd. +License: CC-BY-4.0 + +# translations +Files: translations/* +Copyright: UnionTech Software Technology Co., Ltd. +License: GPL-3.0-or-later + +# src +Files: src/* daemon/src/* tests/src/* +Copyright: UnionTech Software Technology Co., Ltd. +License: GPL-3.0-or-later + +# encoding +Files: src/common/encoding.* +Copyright: 2014-2020 Pedram Pourang (aka Tsu Jan) +License: GPL-2.0-or-later + +# cpp-stub +Files: tests/src/stub.h +Copyright: 2019 coolxv +License: MIT + + +License: GPL-3.0-or-later + This package 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 + (at your option) any later version. + . + This package 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 + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". + +License:GPL-2.0-or-later + 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 2 of the License, or (at your option) 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 package; if not, write to the Free + Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU General Public + License version 2 can be found in the file + `/usr/share/common-licenses/GPL-2'. + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sub license, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial portions + of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/debian/deepin-editor.1 b/debian/deepin-editor.1 new file mode 100644 index 0000000000000000000000000000000000000000..502ce5afa7bb311a8c048c9634152bf42f7abd1d --- /dev/null +++ b/debian/deepin-editor.1 @@ -0,0 +1,28 @@ +.\" This file is processed to generate manpages in the +.\" build diretory. +.TH deepin-editor 1 "2020-11-17" "Deepin" +.SH NAME +deepin-editor \- the Text editor from UOS +.SH SYNOPSIS +.B deepin-editor +[\fIPATH\fR] +.SH DESCRIPTION +Text editor for DDE (Deepin Desktop Environment). +.PP +This program does not accept any command line options. +If the \fIPATH\fR is specified, open that file with . +If the \fIPATH\fR is omitted, open deepin-editor and show nothing. +If deepin-editor has been launched, open the Text with deepin-editor. +Otherwise, launch deepin-editor and open the Text with it. +.SH SEE ALSO +https://www.deepin.org/en/original/deepin-editor/ +.SH AUTHOR +.PP +.B deepin-editor +is written by Deepin Technology Co., Ltd. +.PP +This manual page was written by +.MT tuqinggang@\:uniontech.com +Tu Qinggang +.ME +for the Debian Project (but may be used by others). diff --git a/debian/manpages b/debian/manpages new file mode 100644 index 0000000000000000000000000000000000000000..84fa7c6e97526a01ffa8512fb141d7cb8a12bb6a --- /dev/null +++ b/debian/manpages @@ -0,0 +1 @@ +debian/deepin-editor.1 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000000000000000000000000000000000000..865c6aa489923e19c5a3b12f9e64156d0ad509d2 --- /dev/null +++ b/debian/rules @@ -0,0 +1,21 @@ +#!/usr/bin/make -f + +export QT_SELECT=5 +include /usr/share/dpkg/default.mk + +DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) + +VERSION = $(DEB_VERSION_UPSTREAM) +PACK_VER = $(shell echo $(VERSION) | awk -F'[+_~-]' '{print $$1}') + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +%: + dh $@ + +override_dh_auto_configure: + dh_auto_configure -- \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SAFETYTEST_ARG="CMAKE_SAFETYTEST_ARG_OFF" \ + -DVERSION=$(PACK_VER) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000000000000000000000000000000000000..163aaf8d82b6c54f23c45f32895dbdfdcc27b047 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/upstream/metadata b/debian/upstream/metadata new file mode 100644 index 0000000000000000000000000000000000000000..8f8d54867e953975e85927d9bcf15e7808f0473e --- /dev/null +++ b/debian/upstream/metadata @@ -0,0 +1,4 @@ +Bug-Database: https://github.com/linuxdeepin/deepin-editor/issues +Bug-Submit: https://github.com/linuxdeepin/deepin-editor/issues/new +Repository: https://github.com/linuxdeepin/deepin-editor.git +Repository-Browse: https://github.com/linuxdeepin/deepin-editor diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000000000000000000000000000000000000..791832b69a1eda7fdcf5d8856994ea5903afb00b --- /dev/null +++ b/debian/watch @@ -0,0 +1,8 @@ +# Compulsory line, this is a version 4 file +version=4 + +# GitHub hosted projects +opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%deepin-editor-$1.tar.gz%" \ + https://github.com/linuxdeepin/deepin-editor/tags \ + (?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate + diff --git a/deepin-editor-6.0.6.tar.gz b/deepin-editor-6.0.6.tar.gz deleted file mode 100644 index 4e03d61bacca7953fe1568a250b9daa4633d21a5..0000000000000000000000000000000000000000 Binary files a/deepin-editor-6.0.6.tar.gz and /dev/null differ diff --git a/deepin-editor.desktop b/deepin-editor.desktop new file mode 100644 index 0000000000000000000000000000000000000000..5398cdd9333c02cb5df2a4ab2a2ef1c20f8c9303 --- /dev/null +++ b/deepin-editor.desktop @@ -0,0 +1,109 @@ +[Desktop Entry] +Categories=Utility;TextEditor; +Comment=Simple and easy to use text editor +Exec=deepin-editor %F +Icon=deepin-editor +Name=Text Editor +GenericName=Text Editor +StartupNotify=false +Type=Application +X-Deepin-AppID=deepin-editor +X-MultipleArgs=false +X-Deepin-CreatedBy=com.deepin.dde.daemon.Launcher +X-Deepin-Vendor=deepin +# Translations: +# Do not manually modify! +Comment[ar]=محرر النصوص بسيط وسهل الاستخدام +Comment[bo]=སྟབས་བདེ་ལ་སྤྱོད་བདེ་བའི་ཡིག་ཆ་རྩོམ་སྒྲིག་ཆས། +Comment[br]=An aozer testennoù simpl hag aes d'ober gantañ +Comment[ca]=Editor de text simple i fàcil d'usar +Comment[cs]=Jednoduchý a snadno se používající textový editor +Comment[da]=Simpel og letanvendelig teksteditor +Comment[de]=Einfacher, leicht zu bedienender Texteditor +Comment[es]=Editor de texto simple y fácil de usar +Comment[et]=Lihtne ja kergesti kasutatav tekstiredaktor +Comment[fi]=Yksinkertainen ja helppokäyttöinen tekstieditori +Comment[fr]=Éditeur de texte simple et facile à utiliser +Comment[gl_ES]=Editor de texto sinxelo e fácil de usar +Comment[hr]=Jednostavan i lagan za korištenje uređivač teksta +Comment[hu]=Letisztult és könnyen használható szövegszerkesztő +Comment[it]=Editor di testo semplice e facile da usare. Localizzazione italiana a cura di Massimo A. Carofano. +Comment[ko]=단순하고 사용하기 쉬운 텍스트 편집기 +Comment[lt]=Paprastas ir lengvas naudoti tekstų redaktorius +Comment[ms]=Penyunting teks yang ringkas dan mudah digunakan +Comment[nl]=Eenvoudig te gebruiken tekstbewerker +Comment[pl]=Prosty i łatwy w użyciu edytor tekstu +Comment[pt]=Editor de texto simples e fácil de usar +Comment[pt_BR]=Um editor de texto simples e fácil de usar +Comment[ru]=Простой и удобный текстовый редактор +Comment[sq]=Përpunues tekstesh i thjeshtë dhe i kollajtë për t’u përdorur +Comment[sr]=Уењђивач текста који је једноставан за употребу +Comment[tr]=Basit ve kullanımı kolay metin düzenleyici +Comment[ug]=ئاددىي، قوللىنىشچان تېكىست تەھرىرلىگۈچ +Comment[uk]=Простий і доступний текстовий редактор +Comment[zh_CN]=简单好用的文本编辑器 +Comment[zh_HK]=簡單好用的文本編輯器 +Comment[zh_TW]=簡單好用的文字編輯器 +GenericName[ar]=محرر النصوص +GenericName[bo]=ཡིག་ཆ་རྩོམ་སྒྲུག་ཆས། +GenericName[br]=Aozer testennoù +GenericName[ca]=Editor de text +GenericName[cs]=Textový editor +GenericName[da]=Teksteditor +GenericName[de]=Text Editor +GenericName[es]=Editor de texto +GenericName[et]=Tekstiredaktor +GenericName[fi]=Tekstieditori +GenericName[fr]=Éditeur de texte +GenericName[gl_ES]=Editor de texto +GenericName[hr]=Uređivač teksta +GenericName[hu]=Szövegszerkesztő +GenericName[it]=Editor di Testo +GenericName[ko]=텍스트 편집기 +GenericName[lt]=Tekstų redaktorius +GenericName[ms]=Penyunting Teks +GenericName[nl]=Tekstbewerker +GenericName[pl]=Edytor tekstu +GenericName[pt]=Editor de texto +GenericName[pt_BR]=Editor de Textos +GenericName[ru]=Текстовый редактор +GenericName[sq]=Përpunues Tekstesh +GenericName[sr]=Уређивач Текста +GenericName[tr]=Metin Düzenleyici +GenericName[ug]=تېكىست تەھرىرلىگۈچ +GenericName[uk]=Текстовий редактор +GenericName[zh_CN]=文本编辑器 +GenericName[zh_HK]=文本編輯器 +GenericName[zh_TW]=文字編輯器 +MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-patch;text/x-adasrc;text/x-chdr;text/x-csrc;text/css;application/x-desktop;text/x-patch;text/x-fortran;text/html;text/x-java;text/x-tex;text/x-makefile;text/x-objcsrc;text/x-pascal;application/x-perl;application/x-perl;application/x-php;text/vnd.wap.wml;text/x-python;application/x-ruby;text/sgml;application/xml;model/vrml;image/svg+xml;application/json; +Name[ar]=محرر نصوص ديبين +Name[bo]=གཏིང་ཟབ་ཡིག་ཆ་རྩོམ་སྒྲིག་ཆས། +Name[br]=Aozer testennoù Deepin +Name[ca]=Editor de text del Deepin +Name[cs]=Deepin textový editor +Name[da]=Deepin teksteditor +Name[de]=Deepin Text Editor +Name[es]=Editor de texto +Name[et]=Deepin tekstiredaktor +Name[fi]=Deepin tekstieditori +Name[fr]=Éditeur de texte Deepin +Name[gl_ES]=Editor de texto Deepin +Name[hr]=Deepin uređivač teksta +Name[hu]=Deepin® Szövegszerkesztő +Name[it]=Editor di Testo di Deepin +Name[ko]=Deepin 텍스트 편집기 +Name[lt]=Deepin tekstų redaktorius +Name[ms]=Penyunting Teks Deepin +Name[nl]=Deepin Tekstbewerker +Name[pl]=Edytor Tekstu Deepin +Name[pt]=Editor de texto Deepin +Name[pt_BR]=deepin Editor de Textos +Name[ru]=Текстовый Редактор Deepin +Name[sq]=Përpunues Tekstesh Deepin +Name[sr]=Дипин Уређивач Текста +Name[tr]=Deepin Metin Düzenleyici +Name[ug]=Deepin تېكىست تەھرىرلىگۈچ +Name[uk]=Текстовий редактор Deepin +Name[zh_CN]=文本编辑器 +Name[zh_HK]=Deepin 文本編輯器 +Name[zh_TW]=Deepin 文字編輯器 diff --git a/install.pri b/install.pri new file mode 100644 index 0000000000000000000000000000000000000000..3688d4d8e9d72bea99953c0865423c25fa31ca94 --- /dev/null +++ b/install.pri @@ -0,0 +1,32 @@ +isEmpty(PREFIX){ + PREFIX = /usr +} + +# Automating generation .qm files from .ts files +CONFIG(release, debug|release) { + !system($$PWD/translate_generation.sh): error("Failed to generate translation") +} + +target.path = $${PREFIX}/bin/ + +desktop_files.path = $${PREFIX}/share/applications/ +desktop_files.files = $$PWD/*.desktop + +services.path = $${PREFIX}/share/dbus-1/system-services +services.files = $$PWD/*.service + +policy.path = $${PREFIX}/share/polkit-1/actions/ +policy.files = $${PWD}/*.policy + +config.path = $${PREFIX}/share/dbus-1/system.d/ +config.files = $${PWD}/*.conf + +dman.path = $${PREFIX}/share/dman/ +dman.files = $$PWD/dman/* + +translations.path = $${PREFIX}/share/$${TARGET}/translations +translations.files = $$PWD/translations/*.qm + +INSTALLS += target translations desktop_files services dman config policy + + diff --git a/linglong.yaml b/linglong.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6cc535433765dad83f3bead345c9fa07e226065c --- /dev/null +++ b/linglong.yaml @@ -0,0 +1,47 @@ +package: + id: org.deepin.editor + name: "deepin-editor" + version: 5.10.13 + kind: app + description: | + editor for deepin os. + +runtime: + id: org.deepin.Runtime + version: 23.0.0 + +depends: + - id: "dde-qt-dbus-factory" + version: 5.5.12 + type: runtime + - id: libchardet + version: 1.0.4 + type: runtime + - id: kcodecs + version: 5.54.0 + type: runtime + - id: "ksyntax-highlighting" + version: 5.54.0 + type: runtime + - id: googletest + version: 1.8.1 + - id: xcb-util + type: runtime +variables: + extra_args: | + -DVERSION=${VERSION} +source: + kind: local + + +build: + kind: manual + manual: + configure: | + mkdir build + cd build + cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} ${extra_args} .. + make -j6 + #make test -j6 + #test 用例包含从/usr/share读取内容,会导致失败 + make -j install diff --git a/misc/configs/org.deepin.editor.json b/misc/configs/org.deepin.editor.json new file mode 100644 index 0000000000000000000000000000000000000000..5eb700c608c11c064361562232040c2a94c94e31 --- /dev/null +++ b/misc/configs/org.deepin.editor.json @@ -0,0 +1,17 @@ +{ + "magic":"dsg.config.meta", + "version":"1.0", + "contents":{ + "disableImproveGB18030":{ + "value":false, + "serial":0, + "flags":[], + "name":"屏蔽提高GB18030编码识别率", + "name[zh_CN]":"屏蔽提高GB18030编码识别率", + "description[zh_CN]":"屏蔽提高中文环境下GB18030编码的识别率的策略,默认不屏蔽", + "description":"Block the strategy to improve the recognition rate of GB18030 encoding in the Chinese environment, the default is not blocked", + "permissions":"readwrite", + "visibility":"private" + } + } +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..39102571705327df7abe0cd00b344ec0aaffc227 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,112 @@ +if (NOT (${CMAKE_BUILD_TYPE} MATCHES "Debug")) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") + # generate qm files + execute_process(COMMAND bash "${CMAKE_SOURCE_DIR}/translate_generation.sh" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) +endif () + +# Sources files +file(GLOB HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "encodes/*.h" "common/*.h" "controls/*.h" "editor/*.h" "thememodule/*.h" "widgets/*.h") +file(GLOB SRCS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "encodes/*.cpp" "common/*.cpp" "controls/*.cpp" "editor/*.cpp" "thememodule/*.cpp" "widgets/*.cpp") + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/encodes) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/controls) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/editor) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thememodule) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/widgets) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/lib/include) + +# Find the library +find_package(PkgConfig REQUIRED) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5DBus REQUIRED) +find_package(Qt5Concurrent REQUIRED) +find_package(Qt5PrintSupport REQUIRED) +find_package(Qt5Gui REQUIRED) +find_package(DtkWidget REQUIRED) +find_package(DtkCore REQUIRED) +find_package(KF5SyntaxHighlighting) +find_package(KF5Codecs) +find_package(DFrameworkdbus REQUIRED) +find_package(Qt5Xml REQUIRED) +find_package(Qt5Svg REQUIRED) +find_package(ICU COMPONENTS i18n uc REQUIRED) +include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) + +pkg_check_modules(chardet REQUIRED chardet) +include_directories(${chardet_INCLUDE_DIRS}) +link_directories(${chardet_LIBRARY_DIRS}) + +# Tell CMake to create the executable +add_executable(deepin-editor ${SRCS} deepin-editor.qrc) +target_link_libraries(deepin-editor + ${DtkWidget_LIBRARIES} + ${DtkCore_LIBRARIES} + ${Qt5Widgets_LIBRARIES} + ${Qt5DBus_LIBRARIES} + ${Qt5PrintSupport_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + ${DFrameworkdbus_LIBRARIES} + ${Qt5Xml_LIBRARIES} + ${Qt5Svg_LIBRARIES} + ${chardet_LIBRARY_DIRS} + KF5::Codecs + KF5::SyntaxHighlighting + ICU::i18n + ICU::uc + -lm + uchardet + chardet +) + +if(DEFINED ENV{PREFIX}) + set(CMAKE_INSTALL_PREFIX $ENV{PREFIX}) +else() + set(CMAKE_INSTALL_PREFIX /usr) +endif() +add_definitions(-DLINGLONG_PREFIX=\"${CMAKE_INSTALL_PREFIX}/\") + +# Install qm files +file(GLOB QM_FILES "${CMAKE_SOURCE_DIR}/translations/*.qm") +install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-editor/translations/) +install(FILES ${APP_ICONPATH} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/) +install(FILES ${CMAKE_SOURCE_DIR}/src/images/deepin-editor.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps/) + +#代码覆盖率开关 +if(CMAKE_COVERAGE_ARG STREQUAL "CMAKE_COVERAGE_ARG_ON") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -fprofile-arcs -ftest-coverage") +endif() + +# Install help manual +#if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64") +# install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/assets/loongarch64/deepin-editor DESTINATION /usr/share/deepin-manual/manual-assets/application/) +if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "sw_64") + if(DEFINED ENV{PREFIX}) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/assets/loongarch64/deepin-editor DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets/application/) + else() + install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/assets/loongarch64/deepin-editor DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets/application/) + endif() +else() + if(DEFINED ENV{PREFIX}) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/assets/deepin-editor DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets/application/) + else() + install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/assets/deepin-editor DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-manual/manual-assets/application/) + endif() +endif() + +install(TARGETS deepin-editor DESTINATION bin/) +install(FILES ${CMAKE_SOURCE_DIR}/deepin-editor.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications/) +install(DIRECTORY ${CMAKE_SOURCE_DIR}/src/themes DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepin-editor/) + +# 安装 DConfig 配置文件,1040及以下的默认DTK环境不支持DConfig +set(DCONFIG_APPID org.deepin.editor) +file(GLOB DCONFIG_FILES "${CMAKE_SOURCE_DIR}/misc/configs/*.json") +if(DEFINED DSG_DATA_DIR) + dconfig_meta_files(APPID ${DCONFIG_APPID} FILES ${DCONFIG_FILES}) + message("-- DConfig is supported by DTK") +else() + install(FILES ${DCONFIG_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/dsg/configs/${DCONFIG_APPID}) + message("-- DConfig is not supported by DTK") +endif() diff --git a/src/assets/deepin-editor/editor/common/+.svg b/src/assets/deepin-editor/editor/common/+.svg new file mode 100755 index 0000000000000000000000000000000000000000..886d90a83e33497d134bdb3dcc864a5c2df53f20 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/+.svg @@ -0,0 +1,13 @@ + + + + + + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/-.svg b/src/assets/deepin-editor/editor/common/-.svg new file mode 100755 index 0000000000000000000000000000000000000000..594bc2ea751b91367ea2f591570a8dd11665af0d --- /dev/null +++ b/src/assets/deepin-editor/editor/common/-.svg @@ -0,0 +1,13 @@ + + + + - + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/0.svg b/src/assets/deepin-editor/editor/common/0.svg new file mode 100755 index 0000000000000000000000000000000000000000..aa142654920e12798821847ee94c8befaaf646bc --- /dev/null +++ b/src/assets/deepin-editor/editor/common/0.svg @@ -0,0 +1,12 @@ + + + + 0 + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/A.svg b/src/assets/deepin-editor/editor/common/A.svg new file mode 100755 index 0000000000000000000000000000000000000000..909d1da3e635a9773456570aa8e60dde4594b21c --- /dev/null +++ b/src/assets/deepin-editor/editor/common/A.svg @@ -0,0 +1,13 @@ + + + + A + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/Alt.svg b/src/assets/deepin-editor/editor/common/Alt.svg new file mode 100755 index 0000000000000000000000000000000000000000..5903a36f213ff9139f202fd40d321eeccc49775c --- /dev/null +++ b/src/assets/deepin-editor/editor/common/Alt.svg @@ -0,0 +1,15 @@ + + + + Alt + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/C.svg b/src/assets/deepin-editor/editor/common/C.svg new file mode 100755 index 0000000000000000000000000000000000000000..c1540bf04cc6cbcbc2fa3a932986b24f5277a97a --- /dev/null +++ b/src/assets/deepin-editor/editor/common/C.svg @@ -0,0 +1,13 @@ + + + + C + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/Ctrl.svg b/src/assets/deepin-editor/editor/common/Ctrl.svg new file mode 100755 index 0000000000000000000000000000000000000000..a2bb6738b2825beac7f2239a80b084919d82a780 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/Ctrl.svg @@ -0,0 +1,16 @@ + + + + Ctrl + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/Enter.svg b/src/assets/deepin-editor/editor/common/Enter.svg new file mode 100755 index 0000000000000000000000000000000000000000..1994b268ad19ddbc1bca8156aaea6fdb2734e9bf --- /dev/null +++ b/src/assets/deepin-editor/editor/common/Enter.svg @@ -0,0 +1,17 @@ + + + + Enter + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/Esc.svg b/src/assets/deepin-editor/editor/common/Esc.svg new file mode 100755 index 0000000000000000000000000000000000000000..ad8e4937c4a44195ae96a61aaef035250262b3d7 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/Esc.svg @@ -0,0 +1,15 @@ + + + + Esc + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/F.svg b/src/assets/deepin-editor/editor/common/F.svg new file mode 100755 index 0000000000000000000000000000000000000000..781b440c8e5893a922ca485c468fe39a007d5b5b --- /dev/null +++ b/src/assets/deepin-editor/editor/common/F.svg @@ -0,0 +1,13 @@ + + + + F + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/F2.svg b/src/assets/deepin-editor/editor/common/F2.svg new file mode 100755 index 0000000000000000000000000000000000000000..051adae452a5fd25d55b6df9ec3d34fb99589788 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/F2.svg @@ -0,0 +1,14 @@ + + + + F2 + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/G.svg b/src/assets/deepin-editor/editor/common/G.svg new file mode 100755 index 0000000000000000000000000000000000000000..b57ed109bda0d42386f01c481e160fc0cd2f9083 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/G.svg @@ -0,0 +1,13 @@ + + + + G + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/H.svg b/src/assets/deepin-editor/editor/common/H.svg new file mode 100755 index 0000000000000000000000000000000000000000..9542c98f0ce653729556a204e2a93a7c9f10f951 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/H.svg @@ -0,0 +1,13 @@ + + + + H + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/L.svg b/src/assets/deepin-editor/editor/common/L.svg new file mode 100755 index 0000000000000000000000000000000000000000..bb0619d791ff2629b925023301668a356b6be906 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/L.svg @@ -0,0 +1,13 @@ + + + + L + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/N.svg b/src/assets/deepin-editor/editor/common/N.svg new file mode 100755 index 0000000000000000000000000000000000000000..b7033ae0f1c987ed23028f806a287b47aa8d3383 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/N.svg @@ -0,0 +1,13 @@ + + + + N + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/O.svg b/src/assets/deepin-editor/editor/common/O.svg new file mode 100755 index 0000000000000000000000000000000000000000..db272edec6ee99dbc68e8dc03d70ee82d41f6b5d --- /dev/null +++ b/src/assets/deepin-editor/editor/common/O.svg @@ -0,0 +1,13 @@ + + + + O + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/P.svg b/src/assets/deepin-editor/editor/common/P.svg new file mode 100755 index 0000000000000000000000000000000000000000..8b549241262a344de3ff84b7b27f7998fc1c1fd3 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/P.svg @@ -0,0 +1,13 @@ + + + + P + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/QM.svg b/src/assets/deepin-editor/editor/common/QM.svg new file mode 100755 index 0000000000000000000000000000000000000000..8b2af9aa6298185307895e429aaf6b4fffe6c57f --- /dev/null +++ b/src/assets/deepin-editor/editor/common/QM.svg @@ -0,0 +1,13 @@ + + + + QM + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/S.svg b/src/assets/deepin-editor/editor/common/S.svg new file mode 100755 index 0000000000000000000000000000000000000000..8272a7858f352ed776a1a62eb4f74ebdf2bf82bd --- /dev/null +++ b/src/assets/deepin-editor/editor/common/S.svg @@ -0,0 +1,13 @@ + + + + S + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/Shift.svg b/src/assets/deepin-editor/editor/common/Shift.svg new file mode 100755 index 0000000000000000000000000000000000000000..cdc7ce5f0034473065cbd73a45c316e180d3b2c0 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/Shift.svg @@ -0,0 +1,18 @@ + + + + Shift + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/T.svg b/src/assets/deepin-editor/editor/common/T.svg new file mode 100755 index 0000000000000000000000000000000000000000..9bc555095472c66c1e811da3899418644a2e79b5 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/T.svg @@ -0,0 +1,13 @@ + + + + T + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/U.svg b/src/assets/deepin-editor/editor/common/U.svg new file mode 100755 index 0000000000000000000000000000000000000000..c6c24af89cb8dd344c3bad3243f5a440c344032b --- /dev/null +++ b/src/assets/deepin-editor/editor/common/U.svg @@ -0,0 +1,13 @@ + + + + U + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/W.svg b/src/assets/deepin-editor/editor/common/W.svg new file mode 100755 index 0000000000000000000000000000000000000000..cb22b6f4a4ac4b7c6ddf42366ba6e222b33bc9ec --- /dev/null +++ b/src/assets/deepin-editor/editor/common/W.svg @@ -0,0 +1,13 @@ + + + + W + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/Z.svg b/src/assets/deepin-editor/editor/common/Z.svg new file mode 100755 index 0000000000000000000000000000000000000000..574de2344bd49e866aa3eeb1f71e6a036191fd36 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/Z.svg @@ -0,0 +1,13 @@ + + + + Z + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/attention.svg b/src/assets/deepin-editor/editor/common/attention.svg new file mode 100755 index 0000000000000000000000000000000000000000..23149c05873259cd39721b8ee9c3ab7db86d64c5 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/attention.svg @@ -0,0 +1,9 @@ + + + attention + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/bookmark_normal_light.svg b/src/assets/deepin-editor/editor/common/bookmark_normal_light.svg new file mode 100755 index 0000000000000000000000000000000000000000..6076d18b77121724a2860fd23b7a703718bdf927 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/bookmark_normal_light.svg @@ -0,0 +1,13 @@ + + + + bookmark_normal_light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/bookmarkbig_checked_light.svg b/src/assets/deepin-editor/editor/common/bookmarkbig_checked_light.svg new file mode 100755 index 0000000000000000000000000000000000000000..d00210a172c209246dd1a23ed78e9c4fbba82508 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/bookmarkbig_checked_light.svg @@ -0,0 +1,24 @@ + + + + bookmarkbig_checked_light + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/close_icon.svg b/src/assets/deepin-editor/editor/common/close_icon.svg new file mode 100755 index 0000000000000000000000000000000000000000..9047265ccb0b8c83821e9059d80a56054121b02a --- /dev/null +++ b/src/assets/deepin-editor/editor/common/close_icon.svg @@ -0,0 +1,15 @@ + + + + Rectangle 9 + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/deepin-editor.svg b/src/assets/deepin-editor/editor/common/deepin-editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..a8e6fb96946f0b97e35383bf77a1f457e93aef4e --- /dev/null +++ b/src/assets/deepin-editor/editor/common/deepin-editor.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/deepin-editor/editor/common/deepin_editor.svg b/src/assets/deepin-editor/editor/common/deepin_editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..ffb562a44c5c648709f9fa5e3cb1baf677e7200b --- /dev/null +++ b/src/assets/deepin-editor/editor/common/deepin_editor.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/deepin-editor/editor/common/deepin_launcher.svg b/src/assets/deepin-editor/editor/common/deepin_launcher.svg new file mode 100755 index 0000000000000000000000000000000000000000..5793b3846b7fe6a5758379591215b16c7f9e1b52 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/deepin_launcher.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/deepin-editor/editor/common/icon_menu.svg b/src/assets/deepin-editor/editor/common/icon_menu.svg new file mode 100755 index 0000000000000000000000000000000000000000..35dd6eacc54a933dc9ebc3f3010edfa7363fecc0 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/icon_menu.svg @@ -0,0 +1,84 @@ + + + + + + image/svg+xml + + img_upload + + + + + + img_upload + Created with Sketch. + + + + + + + + + + + + + diff --git a/src/assets/deepin-editor/editor/common/next.svg b/src/assets/deepin-editor/editor/common/next.svg new file mode 100755 index 0000000000000000000000000000000000000000..ba61fc3e5f99464e7dec7b166beb64d40641b0cf --- /dev/null +++ b/src/assets/deepin-editor/editor/common/next.svg @@ -0,0 +1,11 @@ + + + + next + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/next_down.svg b/src/assets/deepin-editor/editor/common/next_down.svg new file mode 100755 index 0000000000000000000000000000000000000000..95baac3db611107248dc47f19ecf596aca8059aa --- /dev/null +++ b/src/assets/deepin-editor/editor/common/next_down.svg @@ -0,0 +1,15 @@ + + + + +next +Created with Sketch. + + + + + diff --git a/src/assets/deepin-editor/editor/common/notes.svg b/src/assets/deepin-editor/editor/common/notes.svg new file mode 100755 index 0000000000000000000000000000000000000000..e9a3aa60a51404c9390bfbea8d8ff09edc0e2e32 --- /dev/null +++ b/src/assets/deepin-editor/editor/common/notes.svg @@ -0,0 +1,11 @@ + + + notes + + + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/common/plus_icon.svg b/src/assets/deepin-editor/editor/common/plus_icon.svg new file mode 100755 index 0000000000000000000000000000000000000000..6b69c7bc64ec9640a82bd3aac6a85939760d84df --- /dev/null +++ b/src/assets/deepin-editor/editor/common/plus_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/assets/deepin-editor/editor/common/tips.svg b/src/assets/deepin-editor/editor/common/tips.svg new file mode 100755 index 0000000000000000000000000000000000000000..011c05f4b8f296867cd408a339230323fcbb28dd --- /dev/null +++ b/src/assets/deepin-editor/editor/common/tips.svg @@ -0,0 +1,9 @@ + + + tips + + + + + + \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/en_US/editor.md b/src/assets/deepin-editor/editor/en_US/editor.md new file mode 100644 index 0000000000000000000000000000000000000000..a35fe6917118cc9052064104aab454bb1f8ef210 --- /dev/null +++ b/src/assets/deepin-editor/editor/en_US/editor.md @@ -0,0 +1,299 @@ +# Text Editor|deepin-editor| + +## Overview + +Text Editor is a simple text editing tool. You can use it to write a simple text document, or make it a code editing tool with its advanced features which support code syntax highlighting. + +![overview](fig/overview.png) + +## Guide + +### Run Text Editor + +1. Click the Launcher icon ![deepin_launcher](../common/deepin_launcher.svg) in the Dock to enter the Launcher interface. +2. Locate Text Editor ![deepin_editor](../common/deepin_editor.svg)by scrolling the mouse wheel or searching "text editor" in the Launcher interface and click it to run. +3. In Launcher, right-click Text Editor and you can: + + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix it in the Dock. + - Click **Add to startup** to add it to startup and it will automatically run when system boots. + +### Exit Text Editor + +- On the Text Editor interface, click ![close](../common/close_icon.svg) to exit. +- On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg) > **Exit** to exit. +- Right-click ![deepin_editor](../common/deepin_editor.svg) in the Dock and select **Close All** to exit. + +### View Shortcuts + +On the Text Editor Interface, press **Ctrl + Shift + ?** to view all the shortcuts. You can also check shortcuts in Settings. Proficiency in shortcuts will greatly improve your efficiency. + +![1|hotkey](fig/hotkey.png) + +## Basic Operations + +### Manage Tabs + +- Create New Tabs/Windows + - Click ![plus_icon](../common/+.svg)or ![icon_menu](../common/icon_menu.svg)> **New tab** on the title bar or press **Ctrl + T** to create a new tab. + - Click ![icon_menu](../common/icon_menu.svg)> **New window** or press **Ctrl + N** to create a new window. + +- Adjust Tabs/Windows + - Drag the tab in the same window to reorder tabs. + - Scroll the mouse wheel on the title of a tab to reorder tabs in the same window. + - Move the tab out of the window to create a new window or move the tab from one window to another. + +- Close Tabs /Windows + + The window will be closed as well when there is only one tab in the window. + + - Press **Ctrl + W** to close the file on the file interface. + - Move the cursor to the file title, and click the ![close](../common/close_icon.svg) icon there or the mouse middle button to close the file. + - Right-click the file title and select **Close tab** or **Close other tabs** or **More options** to close the tabs. + +> ![notes](../common/notes.svg) Notes: If you make changes to the file but does not save it, you will be prompted by Text Editor to save before closing the file. + +### Open Files + +You can open one or multiple text files at one time in the following ways, and the selected file will open in the new tab: + +- Drag the file directly to the Text Editor interface or the Text Editor icon. +- Right-click the file and select **Open with** > **Text Editor**. After selecting Text Editor as the default application for text files in Control Center, you can double-click the file to open it directly. +- On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg)> **Open file**, or use the shortcuts **Ctrl + O** to open the file in File Manager. + +### Save Files + +- Press **Ctrl + S** or click ![icon_menu](../common/icon_menu.svg)> **Save** to save the current document. +- Press **Ctrl + Shift + S** or click ![icon_menu](../common/icon_menu.svg)> **Save as** to save the file as a new one. + +### Print Files + +To print a file in Text Editor, you should connect and set up the printer first. + +1. Click ![icon_menu](../common/icon_menu.svg)> **Print**, or press **Ctrl + P** to open the print preview interface. +2. On the preview interface, preview the document,select a printer and set the printing page. +3. Click the **Advanced** option on the preview interface to select parameters including paper size and layout. +4. Click **Print** to start printing. + +![preview](fig/preview.png) + +![pagesetup](fig/advanced-preview.png) + +## Edit Texts + +### Move Cursor + +In addition to the arrow keys and mouse clicks, you can also use the following shortcuts to move the cursor quickly: + +| Function | Shortcuts | +| --------------- | ------------ | +| Save cursor position | Ctrl + Shift + > | +| Reset cursor position (Jump to cursor last saving position) | Ctrl + Shift + < | +| Forward one word (Jump forward over one word) | Ctrl + Right | +| Backward one word (Jump backward over one word) | Ctrl + Left | +| Move to end of line | End | +| Move to start of line | Home | +| Move to end of text | Ctrl + End | +| Move to start of text | Ctrl + Home | +| Move to line indentation | Ctrl + M | +| Forward over a pair (Jump forward after the right parenthesis) | Alt + P | +| Backward over a pair (Jump backward before the left parenthesis) | Alt + N | + +### Change Cases + +It helps you change the case of selected text. You can change it to lowercase, uppercase, or capitalize the initial. + +1. Select the text. +2. Right-click and select **Change Case**. +3. Choose **Upper Case**, **Lower Case**, or **Capitalize**. The changes will take effect immediately. + +You can also use **Alt** + **U / L / C** to quickly switch the cases. + +![changecase](fig/d_changecase.png) + +### Highlight Texts +Text Editor supports highlighting different kinds of texts. + +Click the triangle symbol at the far right corner of the status bar at the bottom, and select the type of text you want to highlight. The corresponding contents in the text will be highlighted automatically. + +![highlight](fig/highlight.png) + +### Delete Texts + +In addition to deleting characters one by one, you can quickly delete characters by using the following shortcuts: + +| Function | Shortcuts | +| --------------- | ------------ | +| Delete to end of line | Ctrl + K | +| Delete current line | Ctrl + Shift + K | +| Delete one word backward | Alt + Shift + N | +| Delete one word forward | Alt + Shift + M | + +### Undo + +If you make an incorrect operation, press **Ctrl + Z** to undo it, or right-click to select **Undo**. + +### Find Texts + +1. Click ![menu](../common/icon_menu.svg) and select **Find**, or press **Ctrl** + **F** to open the "Find" box below. +2. Input the text you want to find. +3. Click **Previous** /**Next** to find each match, or press the **Enter** key to find the next match. +4. Press the **Esc** key or click the close icon to close the dialog box. + +> ![tips](../common/tips.svg)Tips: Select the text and conduct search. The text selected will be automatically displayed in the **Find** box. + +### Replace Texts +1. Click ![menu](../common/icon_menu.svg), and select **Replace**, or press **Ctrl + H** to open the **Replace** box below. +2. Input the text to be replaced and the new text. +3. Click **Replace** to replace the matches one by one and click **Replace Rest** and **Replace All** to replace the rest or all the matches at once. Click **Skip** to skip the current matching text. +4. Press **Esc** or click the close icon to close the dialog box. + +### Go to Line +Use Go to Line to jump to the specific line directly. +Right-click and select **Go to Line**, or press **Ctrl + G** and then input the line number to go to that line. + +### Edit Line + +Use the shortcuts below to edit lines easily: + +| Function | Shortcuts | +| ------------ | ------------ | +| New line above (Insert one line above) | Ctrl + Enter | +| New line below (Insert one line below) | Ctrl + Shift + Enter | +| Duplicate line | Ctrl + Shift + D | +| Swap line up (Swap the current line with above line) | Ctrl + Shift + Up | +| Swap line down (Swap the current line with below line) | Ctrl + Shift + Down | +| Scroll up one line | Super + Shift + Up | +| Scroll down one line | Super + Shift + Down | +| Mark | Alt + H | +| Unmark | Alt + Shift + H | +| Copy line | Super + C | +| Cut line | Super + X | +| Merge lines | Ctrl + J | + +### Enable/Disable Read-only Mode + +1. Open the document with Text Editor and right-click to select **Turn on Read-only Mode**. + +![readonly](fig/d_readonly.png) +              + +2. Right-click to select **Turn off Read-only Mode** under the read-only mode. + +![read-only](fig/d_turnoffreadonly.png) +              + +### Use Column Mode + +Press and hold the **Alt** key on the keyboard, drag the mouse to select multiple lines, and edit the identical contents in multiple lines of codes efficiently by using the column mode function. + +![mode](fig/column mode.png) + +### Color Mark + +Select the text to be marked in Text Editor, right-click to select **Color Mark** and select the corresponding options in the drop-down list as needed. + +![colormark](fig/d_colormark.png) +              + +- Select **Mark** to mark a certain line or a paragraph of texts. You can choose from 8 colors displayed through icons. + - Place the cursor at any line and you can mark the current line. + - Select a paragraph of texts and you can mark the selected texts. +- Select **Mark All** to mark all the contents in Text Editor, or mark all the matching contents of selected texts in Text Editor. You can choose from 8 colors displayed through icons. + - Place the cursor at any line and you can mark all contents. + - Select any content and you can mark the same content in the whole document. +- Select **Clear Last Mark** to cancel the last mark operation. +- Select **Clear All Marks** to cancel all the current marks. + + +### Manage Bookmarks + +Check **Show bookmarks icon** in **Settings** and you can add a bookmark for any line on the Text Editor interface. The icon ![icon](../common/bookmark_normal_light.svg) shows up when you move the cursor to any line in the left column, and the icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) will appear after a bookmark is successfully added. + +- Add bookmarks + + + Click ![icon](../common/bookmark_normal_light.svg) to add a bookmark for the line. + + Right-click ![icon](../common/bookmark_normal_light.svg) and select **Add bookmark** to add a bookmark for the line. + + Place the cursor on any line and press **Ctrl + F2** to add a bookmark for the line. + +- Delete bookmarks + + + Click the colored bookmark icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) to delete the bookmark of the line directly. + + Right-click the colored bookmark icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) to select **Remove Bookmark** to delete the bookmark in the line. + + Right-click a bookmark to select **Remove All Bookmarks** to delete all the bookmarks in the text. + >![Notes](../common/notes.svg)Notes: The bookmark icon appears only when cursor is hovered over to the left of the line number in the left column; when it's moved beyond the left bookmark column, the bookmark icon will disappear. The bookmark icon will always be displayed after being added. + + +### Manage Comments + +You can add comments to any text with a code type suffix, such as cpp and java, among others. + +- Add comments + - Select the text needed and right-click to select **Add Comment**. + - Select the text needed and press **Alt + A** to add comments. + +- Cancel comments + - Select the text with comments, and right-click to select **Remove Comment**. +- Select the text with comments, and press **Alt + Z** to cancel comments. + + +> ![notes](../common/notes.svg)Notes: This supports comments in different languages. Please refer to actual conditions for detailed information. For example, comment symbol for C, C# and Java is // and comment symbol for Python is #. + +## Main Menu + +On the main menu, you can Create New Windows, Create New Files, [Find Texts](#Find Texts), [Replace Texts](#Replace Texts), [Save Files](#Save Files), switch window themes, view help manual, and get more information about Text Editor. + +### Settings + +You can set the basic information, shortcuts and advanced information in settings. + +#### Basic Settings + +Click ![icon_menu](../common/icon_menu.svg)> **Settings** and you can perform the following in the Settings window: + +- Select the Font and Font Size. +- Check or uncheck **Word wrap**. +- Check **Code folding flag** and ![next](../common/next.svg) or ![next](../common/next_down.svg) are displayed in the edit area. Right-click to select **Fold/Unfold Current Level** or **Fold/Unfold All** to perform the corresponding operations. +- Check **Show line numbers** to display the line number in the edit area. +- Check **Highlight current line** to highlight the current line. +- Check **Show bookmarks icon** to display the bookmarks in the text. +- Check **Show whitespaces and tabs** to display all the white spaces and tabs. You can also input or delete white spaces and tabs manually. + +> ![tips](../common/tips.svg)Tips: You can also use **Ctrl + “+”/ “-”** to adjust the font size, and press **Ctrl + 0** to restore default font size. + +#### Shortcuts Settings +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** to view the current shortcut in the **Shortcuts** option. +2. Select a keymap in **Shortcuts** and view the shortcuts. +3. You can click and customize new shortcuts. + +> ![notes](../common/notes.svg)Notes: You can choose a proper keymap to fit your habits, including standard keymap, Emacs keymap, or customize it as you like. + +#### Advanced Settings + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings**. +2. In the **Advanced** option, you can set: + - Window size: Normal, Maximum, or Full screen; + - Tab width: The indentation width when pressing Tab. + + +### Theme + +The window theme provides three theme types, namely Light Theme, Dark Theme and System Theme. + +1. On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg). +2. Click **Theme** to select one theme. + +### Help + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Select **Help** to view the manual of Text Editor. + +### About + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Select **About** to view the version and introduction of Text Editor. + +### Exit + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Click **Exit** to exit Text Editor. diff --git a/src/assets/deepin-editor/editor/en_US/fig/advanced-preview.png b/src/assets/deepin-editor/editor/en_US/fig/advanced-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..b12ff1347c2ff1fc6d17805d44cc215b9b234d81 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/advanced-preview.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/changecase.png b/src/assets/deepin-editor/editor/en_US/fig/changecase.png new file mode 100644 index 0000000000000000000000000000000000000000..0f94f0f94b70e3a1e65bba684599dffda3985870 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/changecase.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/colormark.png b/src/assets/deepin-editor/editor/en_US/fig/colormark.png new file mode 100644 index 0000000000000000000000000000000000000000..ed393530f486cfd88c0e53881cbc6e1862edb8fb Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/colormark.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/column mode.png b/src/assets/deepin-editor/editor/en_US/fig/column mode.png new file mode 100644 index 0000000000000000000000000000000000000000..bc478448411363235bb3294c199cafe260b817ac Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/column mode.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/d_changecase.png b/src/assets/deepin-editor/editor/en_US/fig/d_changecase.png new file mode 100644 index 0000000000000000000000000000000000000000..53176e9378f77cac57e98266633c28c3bb5ebc90 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/d_changecase.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/d_colormark.png b/src/assets/deepin-editor/editor/en_US/fig/d_colormark.png new file mode 100644 index 0000000000000000000000000000000000000000..ee19302f254db85d79cd7a1dbf3920533ee83875 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/d_colormark.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/d_readonly.png b/src/assets/deepin-editor/editor/en_US/fig/d_readonly.png new file mode 100644 index 0000000000000000000000000000000000000000..13c25165f661754080ac0b8fbace48e935ed1138 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/d_readonly.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/d_turnoffreadonly.png b/src/assets/deepin-editor/editor/en_US/fig/d_turnoffreadonly.png new file mode 100644 index 0000000000000000000000000000000000000000..12a65856d37692ad03e203507ed05ada144afd21 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/d_turnoffreadonly.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/highlight.png b/src/assets/deepin-editor/editor/en_US/fig/highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..0b561fa4cf89da7627d88279df78209384d1538e Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/highlight.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/hotkey.png b/src/assets/deepin-editor/editor/en_US/fig/hotkey.png new file mode 100644 index 0000000000000000000000000000000000000000..d046a1d3d405db2050d1a3dec831906c6c50f2f1 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/hotkey.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/mark.png b/src/assets/deepin-editor/editor/en_US/fig/mark.png new file mode 100644 index 0000000000000000000000000000000000000000..2d49df34f09e43372b9478381969d3d19102555b Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/mark.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/overview.png b/src/assets/deepin-editor/editor/en_US/fig/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..ce8e1b6c31ae66c186b22a30e67e98809495d5c9 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/overview.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/overviewx2.jpg b/src/assets/deepin-editor/editor/en_US/fig/overviewx2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..626835806e1f4751970f9de1f083246c28b655c0 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/overviewx2.jpg differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/pagesetup.png b/src/assets/deepin-editor/editor/en_US/fig/pagesetup.png new file mode 100644 index 0000000000000000000000000000000000000000..af37bba809612860509fddb4cb33aa4ad5075e79 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/pagesetup.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/preview.png b/src/assets/deepin-editor/editor/en_US/fig/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..88ad6e0b5735bbd793a89aac5dfc4162c1f16f7a Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/preview.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/printer.png b/src/assets/deepin-editor/editor/en_US/fig/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..e7e386de11866008179399223b542ab1952be2bb Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/printer.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/read_only.png b/src/assets/deepin-editor/editor/en_US/fig/read_only.png new file mode 100644 index 0000000000000000000000000000000000000000..6a67a2375e880e366cdd397fb79c81a86d6c5469 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/read_only.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/read_only_02.png b/src/assets/deepin-editor/editor/en_US/fig/read_only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..8dac668ec8614d9c8a6b954eab16c830e37b168a Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/read_only_02.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/reading.png b/src/assets/deepin-editor/editor/en_US/fig/reading.png new file mode 100644 index 0000000000000000000000000000000000000000..0089c2cf21bb0247ffbea65eead4b7798d9819cc Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/reading.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/shortcuts.jpg b/src/assets/deepin-editor/editor/en_US/fig/shortcuts.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a109071e5aec5af0e6f8dcb18ec923c0812b07ce Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/shortcuts.jpg differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/shortcutsx2.jpg b/src/assets/deepin-editor/editor/en_US/fig/shortcutsx2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d595feed21482567d3dc5383ef39452c58574c85 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/shortcutsx2.jpg differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/texttospeech.png b/src/assets/deepin-editor/editor/en_US/fig/texttospeech.png new file mode 100644 index 0000000000000000000000000000000000000000..41c37956862e9948f322891fc630f1643b7e950e Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/texttospeech.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/translate.png b/src/assets/deepin-editor/editor/en_US/fig/translate.png new file mode 100644 index 0000000000000000000000000000000000000000..7c2999b7c5378109de08573a245be9a3f69db7b4 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/translate.png differ diff --git a/src/assets/deepin-editor/editor/en_US/fig/translation.png b/src/assets/deepin-editor/editor/en_US/fig/translation.png new file mode 100644 index 0000000000000000000000000000000000000000..6b401d0b3033a8eb4c1a34269751f711bf783ca0 Binary files /dev/null and b/src/assets/deepin-editor/editor/en_US/fig/translation.png differ diff --git a/src/assets/deepin-editor/editor/en_US/p_editor.md b/src/assets/deepin-editor/editor/en_US/p_editor.md new file mode 100644 index 0000000000000000000000000000000000000000..477b41ff72fe9b88c2f305dcc75a2499b697e315 --- /dev/null +++ b/src/assets/deepin-editor/editor/en_US/p_editor.md @@ -0,0 +1,310 @@ +# Text Editor|deepin-editor| + +## Overview + +Text Editor is a simple text editing tool. You can use it to write a simple text document, or make it a code editing tool with its advanced features which support code syntax highlighting. + +![overview](fig/overview.png) + +## Guide + +### Run Text Editor + +1. Click the Launcher icon ![deepin_launcher](../common/deepin_launcher.svg) in the Dock to enter the Launcher interface. +2. Locate Text Editor ![deepin_editor](../common/deepin_editor.svg) by scrolling the mouse wheel or searching "text editor" in the Launcher interface, and click it to run. +3. In Launcher, right-click Text Editor to: + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix it in the Dock. + - Click **Add to startup** to add the application to startup, and it will automatically run when the system starts up. + +### Exit Text Editor + +- On the Text Editor interface, click ![close](../common/close_icon.svg) to exit. +- On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg)> **Exit** to exit. +- Right-click ![deepin_editor](../common/deepin_editor.svg) in the Dock, and select **Close All** to exit. + +### View Shortcuts + +On the Text Editor Interface, press **Ctrl** + **Shift** + **?** to view all the shortcuts. You can also check shortcuts in the Settings. Proficiency in shortcuts will greatly improve your efficiency. + +![1|hotkey](fig/hotkey.png) + +## Basic Operations + +### Manage Tabs + +- Create New Tabs/Windows + - Click ![plus_icon](../common/+.svg)or ![icon_menu](../common/icon_menu.svg)> **New tab** on the title bar or press **Ctrl + T** to create a new tab. + - Click ![icon_menu](../common/icon_menu.svg)> **New window** or press **Ctrl + N** to create a new window. + +- Adjust Tabs/Windows + - Drag the tab in the same window to reorder tabs. + - Scroll the mouse wheel on the title of a tab to reorder tabs in the same window. + - Move the tab out of the window to create a new window or move the tab from one window to another. + +- Close Tabs /Windows + + The window will be closed as well when there is only one tab in the window. + + - Press **Ctrl + W** to close the file on the file interface. + - Move the cursor to the file title, and click the ![close](../common/close_icon.svg) icon there or the mouse middle button to close the file. + - Right-click the file title and select **Close tab** or **Close other tabs** or **More options** to close the tabs. + +> ![notes](../common/notes.svg) Notes: If you make changes to the file but does not save it, you will be prompted by Text Editor to save before closing the file. + +### Open Files + +You can open one or multiple text files at one time in the following ways, and the selected file will open in the new tab: + +- Drag the file directly to the Text Editor interface or the Text Editor icon. +- Right-click the file and select **Open with** > **Text Editor**. After selecting Text Editor as the default application for text files in Control Center, you can double-click the file to open it directly. +- On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg)> **Open file**, or use the shortcuts **Ctrl + O** to open the file in File Manager. + +### Save Files + +- Press **Ctrl + S** or click ![icon_menu](../common/icon_menu.svg)> **Save** to save the current document. +- Press **Ctrl + Shift + S** or click ![icon_menu](../common/icon_menu.svg)> **Save as** to save the file as a new one. + +### Print Files + +To print a file in the Text Editor interface, you should connect and set up the printer first. + +1. Click ![icon_menu](../common/icon_menu.svg)> **Print**, or press **Ctrl + P** to open the print preview interface. +2. On the preview interface, preview the document, select a printer, and set the printing page. +3. Click the **Advanced** option on the preview interface to select parameters including paper size and layout. +4. Click **Print** to start printing at the printer selected. + +![preview](fig/preview.png) + +![pagesetup](fig/advanced-preview.png) + +## Edit Texts + +### Move Cursor + +In addition to the arrow keys and mouse clicks, you can also use the following shortcuts to move the cursor quickly: + +| Function | Shortcuts | +| --------------- | ------------ | +| Save cursor position | Ctrl + Shift + > | +| Reset cursor position (Jump to cursor last saving position) | Ctrl + Shift + < | +| Forward one word (Jump forward over one word) | Ctrl + Right | +| Backward one word (Jump backward over one word) | Ctrl + Left | +| Move to end of line | End | +| Move to start of line | Home | +| Move to end of text | Ctrl + End | +| Move to start of text | Ctrl + Home | +| Move to line indentation | Ctrl + M | +| Forward over a pair (Jump forward after the right parenthesis) | Alt + P | +| Backward over a pair (Jump backward before the left parenthesis) | Alt + N | + +### Change Cases + +It helps you change the case of selected text. You can change it to lowercase, uppercase, or capitalize the initial. + +1. Select the text. +2. Right-click and select **Change Case**. +3. Choose **Upper Case**, **Lower Case**, or **Capitalize**. The changes will take effect immediately. + +You can also use **Alt** + **U/L/C** to quickly switch the cases. + +![changecase](fig/changecase.png) + +### Highlight Texts +Text Editor supports highlighting different kinds of texts. + +Click the triangle symbol at the far right corner of the status bar at the bottom, and select the type of text you want to highlight. The corresponding contents in the text will be highlighted automatically. + +![highlight](fig/highlight.png) + +### Delete Texts + +In addition to deleting characters one by one, you can quickly delete characters by using the following shortcuts: + +| Function | Shortcuts | +| --------------- | ------------ | +| Delete to end of line | Ctrl + K | +| Delete current line | Ctrl + Shift + K | +| Delete one word backward | Alt + Shift + N | +| Delete one word forward | Alt + Shift + M | + +### Undo + +If you make an incorrect operation, press **Ctrl + Z** to undo it, or right-click and select **Undo**. + +### Find Texts + +1. Click ![menu](../common/icon_menu.svg) > **Find**, or press **Ctrl + F** to open the **Find** box in the bottom of the Text Editor interface. +2. Input the text you want to find. +3. Click **Previous**/**Next** to find each match, or press the **Enter** key to find the next match. +4. Press the **Esc** key or click the close icon to close the dialog box. + +> ![tips](../common/tips.svg)Tips: Select the text and conduct search. The text selected will be automatically displayed in the **Find** box. + +### Replace Texts +1. Click ![menu](../common/icon_menu.svg) > **Replace**, or press **Ctrl + H** to open the **Replace** box in the bottom of the Text Editor interface. +2. Input the text to be replaced and the new text. +3. Click **Replace** to replace the matches one by one, and click **Replace Rest** and **Replace All** to replace the rest or all the matches at once. Click **Skip** to skip the current matching text. +4. Press **Esc** or click the close icon to close the dialog box. + +### Go to Line +Use Go to Line to jump to the specific line directly. + +Right-click and select **Go to Line**; or press **Ctrl + G**, and then input the line number to go to that line. + +### Edit Line + +Use the shortcuts below to edit lines easily: + +| Function | Shortcuts | +| ------------ | ------------ | +| New line above (Insert one line above) | Ctrl + Enter | +| New line below (Insert one line below) | Ctrl + Shift + Enter | +| Duplicate line | Ctrl + Shift + D | +| Swap line up (Swap the current line with above line) | Ctrl + Shift + Up | +| Swap line down (Swap the current line with below line) | Ctrl + Shift + Down | +| Scroll up one line | Super + Shift + Up | +| Scroll down one line | Super + Shift + Down | +| Mark | Alt + H | +| Unmark | Alt + Shift + H | +| Copy line | Super + C | +| Cut line | Super + X | +| Merge lines | Ctrl + J | + +### Enable/Disable Read-only Mode + +1. Open the document with Text Editor, right-click on the Text Editor interface, and select **Turn on Read-Only mode**. + +![readonly](fig/read_only.png) +              + +2. Right-click on the Text Editor interface, and select **Turn off Read-Only mode** under the read-only mode. + +![read-only](fig/read_only_02.png) + +### Text to Speech + +You can perform the following operations after enabling the Text to Speech and Speech to Text features in the Control Center. + +1. Right-click and select **Speech to Text**. The input voices through microphone will be converted to texts and can be edited in the document. +2. Select a paragraph of texts. Right-click it and select **Text to Speech**. The texts selected will be broadcast. + +> ![notes](../common/notes.svg) Notes: The **Text to Speech** option in the right-click menu is grayed out and cannot be activated when no text is selected. + +![speech](fig/texttospeech.png) + +### Translate + +1. Enable **Translation** in **Control Center** > **Assistive Tools** and set the corresponding language pairs according to your needs. +2. Select the texts to be translated in Text Editor. Right-click and select **Translate**, and the texts selected will be translated into the target language. + +![translate](fig/translate.png) + +### Use Column Mode + +Press and hold the **Alt** key on the keyboard, drag the mouse to select multiple lines, and edit the identical contents in multiple lines of codes efficiently by using the column mode function. + +![mode](fig/column mode.png) + +### Color Mark + +Select the text to be marked in Text Editor, right-click to select **Color Mark**, and select the corresponding options in the drop-down list as needed. + +![colormark](fig/colormark.png) +              + +- Select **Mark** to mark a certain line or a paragraph of texts. You can choose from 8 colors displayed through icons. + - Place the cursor at any line and you can mark the current line. + - Select a paragraph of texts and you can mark the selected texts. +- Select **Mark All** to mark all the contents in Text Editor, or mark all the matching contents of selected texts in Text Editor. You can choose from 8 colors displayed through icons. + - Place the cursor at any line and you can mark all contents. + - Select any content and you can mark the same content in the whole document. +- Select **Clear Last Mark** to cancel the last mark operation. +- Select **Clear All Marks** to cancel all the current marks. + +### Manage Bookmarks + +Check **Show bookmarks icon** in **Settings** and you can add a bookmark for any current line on the Text Editor interface. The icon ![icon](../common/bookmark_normal_light.svg) shows up when you move the cursor to any line in the left column, and the icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) will appear after a bookmark is successfully added. + +- Add bookmarks + + Click ![icon](../common/bookmark_normal_light.svg) to add a bookmark for the line. + + Right-click ![icon](../common/bookmark_normal_light.svg) and select **Add bookmark** to add a bookmark for the line. + + Place the cursor on any line, and press **Ctrl + F2** to add a bookmark for the line. + +- Delete bookmarks + + Click the colored bookmark icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) to delete the bookmark of the line directly. + + Right-click the colored bookmark icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) , and select **Remove Bookmark** to delete the bookmark in the line. + + Right-click a bookmark, and select **Remove All Bookmarks** to delete all the bookmarks in the text. + >![Notes](../common/notes.svg) Notes: The bookmark icon appears only when cursor is hovered over to the left of the line number in the left column; when it's moved beyond the left bookmark column, the bookmark icon will disappear. The bookmark icon will always be displayed after being added. + +### Manage Comments + +You can add comments to any text with a code type suffix, such as cpp and java, among others. + +- Add comments + - Select the text needed, and right-click to select **Add Comment**. + - Select the text needed, and press **Alt + A** to add comments. + +- Cancel comments + - Select the text with comments, and right-click to select **Remove Comment**. + - Select the text with comments, and press **Alt + Z** to cancel comments. + +> ![notes](../common/notes.svg) Notes: This supports comments in different languages. Please refer to actual conditions for detailed information. For example, comment symbol for C, C# and Java is //, and comment symbol for Python is #. + +## Main Menu + +On the main menu, you can Create New Windows, Create New Files, [Find Texts](#Find Texts), [Replace Texts](#Replace Texts), [Save Files](#Save Files), switch window themes, view help manual, and get more information about Text Editor. + +### Settings + +You can set the basic information, shortcuts, and advanced information in settings. + +#### Basic Settings + +Click ![icon_menu](../common/icon_menu.svg)> **Settings** and you can perform the following in the **Basic** option: + +- Select the Font and Font Size. +- Check or uncheck **Word wrap**. +- Check **Code folding flag** and ![next](../common/next.svg) or ![next](../common/next_down.svg) are displayed in the edit area. Right-click and select **Fold/Unfold Current Level** or **Fold/Unfold All** to perform the corresponding operations. +- Check **Show line numbers** to display the line number in the edit area. +- Check **Highlight current line** to highlight the current line. +- Check **Show bookmarks icon** to display the bookmarks in the text. +- Check **Show whitespaces and tabs** to display all the white spaces and tabs. You can also input or delete white spaces and tabs manually. + +> ![tips](../common/tips.svg) Tips: You can also use **Ctrl + “+”/ “-”** to adjust the font size, and press **Ctrl + 0** to restore to default font size. + +#### Shortcuts Settings +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** to view the current shortcut in the **Shortcuts** option. +2. Select a keymap in **Shortcuts** and view the shortcuts. +3. You can click and customize new shortcuts. + +> ![notes](../common/notes.svg) Notes: You can choose a proper keymap to fit your habits, including standard keymap, Emacs keymap, or customize it as you like. + +#### Advanced Settings + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings**. +2. In the **Advanced** option, you can set: + - Window size: Normal, Maximum, or Fullscreen; + - Tab width: The width of a tab character. + +### Theme + +The window theme provides three theme types, namely Light Theme, Dark Theme, and System Theme. + +1. On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg). +2. Click **Theme** to select one theme. + +### Help + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Select **Help** to view the manual of Text Editor. + +### About + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Select **About** to view the version and introduction of Text Editor. + +### Exit + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Click **Exit** to exit Text Editor. \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/zh_CN/editor.md b/src/assets/deepin-editor/editor/zh_CN/editor.md new file mode 100755 index 0000000000000000000000000000000000000000..507a1c3e4ad00bc116f70adc07b2631313ed802c --- /dev/null +++ b/src/assets/deepin-editor/editor/zh_CN/editor.md @@ -0,0 +1,322 @@ +# 文本编辑器|deepin-editor| + +## 概述 + +文本编辑器是一个简单的文本编辑工具。您可以用它书写简单的文本文档,也可以使用它的高级特性,让它成为一个代码编辑工具,支持代码语法高亮。 + +![overview](fig/overview.png) + +## 使用入门 + +### 运行文本编辑器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文本编辑器图标 ![deepin_editor](../common/deepin_editor.svg),单击运行。 +3. 右键单击![deepin_editor](../common/deepin_editor.svg),您可以: + + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +### 退出文本编辑器 + +- 在文本编辑器界面,单击 ![close_icon](../common/close_icon.svg),退出文本编辑器。 +- 在文本编辑器界面,单击主菜单 ![icon_menu](../common/icon_menu.svg) > **退出** ,退出文本编辑器。 +- 在任务栏右键单击 ![deepin_editor](../common/deepin_editor.svg),选择 **关闭所有** ,退出文本编辑器。 + + +### 查看快捷键 + +在文本编辑器界面,使用快捷键 **Ctrl + Shift + ?** 打开快捷键预览界面,您也可以在设置界面查看快捷键。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理标签页 + +- 新建标签页/窗口 + + - 单击标签页上的按钮 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **新标签页** 或使用快捷键 **Ctrl + T** 创建一个新的标签页。 + - 单击![icon_menu](../common/icon_menu.svg) > **新窗口** 或使用快捷键 **Ctrl + N** 创建一个新的窗口。 + +- 调整标签页/窗口 + + - 拖拽同一窗口内的标签页重新排序。 + - 滚动鼠标切换同一窗口内的标签页。 + - 移出标签页创建一个新的窗口,或者从一个窗口移到另外一个窗口中。 + +- 关闭标签页/窗口 + + 当窗口中仅有一个标签页时,关闭标签页的同时也会关闭窗口。 + - 使用快捷键 **Ctrl + W** 关闭当前标签页。 + - 单击标签页上的按钮 ![close_icon](../common/close_icon.svg) 或者单击鼠标中键,关闭当前标签页。 + - 右键单击标签页,选择 **关闭标签页** 、**关闭其他标签页** 或 **更多关闭方式** 来关闭标签页。 + + > ![notes](../common/notes.svg)说明:如果您的文件发生了变化而没有保存,文本编辑器会在关闭前提示您保存更改。 + + + +### 打开文件 + + +您可以采用以下方式打开一个或同时打开多个文本文件,选中的文件将会在新标签页打开: + +- 直接拖动文件到文本编辑器界面或其图标上。 +- 右键单击文件,选择 **打开方式** > **文本编辑器**。选择文本编辑器为默认打开程序后,可直接双击打开。 +- 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg) > **打开文件** 或使用快捷键 **Ctrl + O**,在弹出的窗口中选择文件。 + + + +### 保存文件 +- 单击 ![icon_menu](../common/icon_menu.svg) > **保存** 或使用快捷键 **Ctrl + S**,保存当前文件。 +- 单击 ![icon_menu](../common/icon_menu.svg) > **另存为** 或使用快捷键 **Ctrl + Shift + S**,另存当前文件。 + + + +### 打印文件 + +在文本编辑器中使用打印,需要您连接并配置好打印机。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **打印** 或使用快捷键 **Ctrl + P** 打开打印预览。 +2. 在打印预览界面,您可以预览文件,选择打印机并设置打印页面。 +3. 在打印预览界面,单击 **高级设置**,可配置纸张大小、打印方式等相关参数。 +4. 单击 **打印** 即可将文件发送到打印机打印。 + +![pagesetup](fig/printer.png) + +![printer](fig/printer_setting.png) + + + +## 编辑文本 + +### 移动光标 + +除了使用方向键和鼠标点击移动光标,您还可以使用以下快捷键迅速移动光标: + +| 功能 | 快捷键 | +| --------------- | ------------ | +| 保存光标位置 | Ctrl + Shift + > | +| 重置光标位置(跳转到上次光标保存的位置) | Ctrl + Shift + < | +| 右移一个词 (光标向右跳过一个词) | Ctrl + 右方向键 | +| 左移一个词 (光标向左跳过一个词) | Ctrl + 左方向键 | +| 移动到行尾 | End | +| 移动到行头 | Home | +| 移动到文本结尾 | Ctrl + End | +| 移动到文本开头 | Ctrl + Home | +| 移动到行缩进 | Ctrl + M | +| 向右匹配 (光标移动到右括号的后面) | Alt + P | +| 向左匹配(光标移动到左括号的前面) | Alt + N | + +### 切换大小写 + +切换大小写功能可以将选中的文本全部改为大写字母、小写字母或者让首字母大写。 + +1. 选中待更改的文本内容。 +2. 单击右键,选择 **切换大小写**。 +3. 选择 **大写**/**小写**/**首字母大写** 选项,更改会立即生效。 + +您也可以使用快捷键 **Alt + U/ L/ C** 迅速切换大小写。 + +![toggle_case](fig/d_toggle_case.png) + +### 高亮文本 + +文本编辑器支持高亮不同类型的文本。 +单击底部状态栏最右侧的三角符号, 选择某种文本类型。若文本中有相应内容则会自动高亮。 + +![highlight](fig/highlight.png) + +### 删除文本 +除了向左或向右逐个删除字符外,您还可以使用以下快捷键迅速删除字符: + +| 功能 | 快捷键 | +| --------------- | ------------ | +| 删除到行尾 | Ctrl + K | +| 删除当前行 | Ctrl + Shift + K | +| 向左删除一个词 | Alt + Shift + N | +| 向右删除一个词 | Alt + Shift + M | + +### 撤销操作 + +如果在编辑文本时发生误操作,可以使用快捷键 **Ctrl + Z** 撤销操作,或者在右键菜单中选择 **撤销**。 + +### 查找文本 + +1. 单击 ![menu](../common/icon_menu.svg) > **查找** 或使用快捷键 **Ctrl + F**,打开查找窗口。 +2. 在查找窗口中,输入要搜索的文本。 +3. 单击 **下一个**、**上一个** 逐个查找,或使用 **Enter** 键查找下一个匹配项。 +4. 按下 **Esc** 键或单击关闭按钮,关闭查找窗口。 + +> ![tips](../common/tips.svg)窍门:选中一段文本后再进行查找,则这段文本会自动出现在查找窗口中。 + +### 替换文本 +1. 单击 ![menu](../common/icon_menu.svg) > **替换** 或使用快捷键 **Ctrl + H** ,打开替换窗口。 +2. 在替换窗口中,输入要替换的文本以及新文本。 +3. 单击 **替换** 逐个替换;单击 **剩余替换**、**全部替换** 一次性替换剩余的或所有的匹配文本;单击 **跳过** 不替换当前匹配的文本。 +4. 按下 **Esc** 键或单击关闭按钮,关闭搜索窗口。 + +### 跳到行 +使用该功能可以迅速跳转到任一行。 +在右键菜单中选择 **跳到行** 或者使用快捷键 **Ctrl + G** ,输入行号即可跳转到相应行。 + +### 编辑行 + +您可以使用以下快捷键迅速编辑行: + +| 功能 | 快捷键 | +| ------------ | ------------ | +| 向上插入一行(在上方插入一行) | Ctrl + Enter | +| 向下插入一行(在下方插入一行) | Ctrl + Shift + Enter | +| 复制并粘贴当前行 | Ctrl + Shift + D | +| 上移一行(与上一行交换位置) | Ctrl + Shift + Up | +| 下移一行(与下一行交换位置) | Ctrl + Shift + Down | +| 向上滚动一行 | Super + Shift + Up | +| 向下滚动一行 | Super + Shift + Down | +| 设置标记 | Alt + H | +| 取消标记 | Alt + Shift + H | +| 复制行 | Super + C | +| 剪切行 | Super + X | +| 合并行 | Ctrl + J | + +### 开启/关闭只读模式 + +1. 使用文本编辑器打开文档,单击右键,选择 **开启只读模式**。 +2. 在只读模式下,单击右键,选择 **关闭只读模式**。 + +![read_only](fig/d_read_only.png) + +![read_only](fig/d_read_only02.png) + + +### 列编辑 + +在文本编辑器界面,按住 **Alt** 键不放,鼠标左键单击多列启动列编辑模式,为多行代码同时编辑相同的内容,提高工作效率。 + +![mode](fig/column_mode.png) + + + +### 颜色标记 + +在文本编辑器界面,单击鼠标右键选择 **颜色标记**,在其下拉列表中进行选择。 + +![color](fig/d_colortag.png) + + - **添加标记**:对某一行或某一段文本内容添加颜色标记;有8种颜色按钮可供选择。 + + 将光标定在某一行,标记当前所在的行。 + + 选中一段文本内容后,标记选中的文本内容。 + - **标记所有**:将文本内容全部标记或对已选中的文本内容,在全文中标记匹配项;有8种颜色按钮可供选择。 + + 将光标定在任意一行,将文本内容全部标记。 + + 选中一段文本内容,在全文中标记匹配项。 + + - **清除上次标记**:清除上次标记操作。 + - **清除所有标记**:清除当前所有标记。 + + + +### 书签管理 + +在文本编辑器设置界面,勾选 **显示书签图标** 后,您可以为任意一行的文本内容添加书签。将鼠标指针移至左侧栏任意行号前面会显示图标 ![icon](../common/bookmark_normal_light.svg),添加成功后该行的书签图标会变为蓝色填充的图标 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加书签 + + + 鼠标左键单击 ![icon](../common/bookmark_normal_light.svg),为该行添加书签。 + + 鼠标右键单击 ![icon](../common/bookmark_normal_light.svg),选择 **添加书签**,为该行添加一个书签。 + + 将光标定在文本中任意一行,使用快捷键 **Ctrl + F2** 为该行添加一个书签。 + + +- 删除书签 + + + 鼠标左键单击已填充颜色的书签图标,直接删除该行书签。 + + 鼠标右键单击已填充颜色的书签图标,选择 **清除书签**,删除该行书签。 + + 鼠标右键单击书签图标,选择 **清除所有书签**,删除该文本的全部书签。 + + >![icon](../common/notes.svg)说明:鼠标移到左侧行号前面才会显示书签图标,移出书签区域,书签图标消失。添加书签后,该图标一直显示。 + + + +### 注释管理 + +在文本编辑器界面,您可以对扩展名为.cpp 、.java 、.py等代码类型的文件进行添加注释的操作。 + +- 添加注释 + + 选中一段文本内容,单击右键并选择 **添加注释**。 + + 选中一段文本内容,使用快捷键 **Alt + A** 添加注释。 + +- 取消注释 + + 选中一段已添加注释的文本内容,单击右键并选择 **取消注释**。 + + 选中一段已添加注释的文本内容,使用快捷键 **Alt + Z** 取消注释。 + + >![notes](../common/notes.svg)说明:支持不同代码语言的注释,具体以实际为主。例如C,C#,Java注释符号为 //,Python 注释符号为 #。 + + + +## 主菜单 + +在主菜单中,您可以新建窗口、新建标签页、[查找文本](#查找文本)、[替换文本](#替换文本)、保存文件、切换窗口主题、查看帮助手册,了解文本编辑器的更多信息。 + +### 设置 + +您可以对基础信息、快捷键和高级信息进行设置。 + +#### 基础设置 + +1. 单击![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在基础设置选项,您可以选择: + - 设置字体样式和字号大小。 + - 勾选 **自动换行**,在编辑区自动换行。 + - 勾选 **代码折叠标志**,在左侧栏显示按钮![next](../common/next.svg)或者![next](../common/next_down.svg) ,右键单击按钮选择折叠/展开当前层次或所有层次。 + - 勾选 **显示行号**,在左侧栏显示行号。 + - 勾选 **当前行高亮**,光标所在的行高亮显示。 + - 勾选 **显示书签图标**,在左侧栏显示书签图标。 + - 勾选 **显示空白制符/制表符**,显示文本中的空白字符和制表符,您也可以手动输入或删除空白字符和制表符。 + + > ![tips](../common/tips.svg)窍门:您还可以使用 **Ctrl + “+”/ “-”** 来调节文本编辑器的默认字号。使用 **Ctrl + 0** 恢复默认字号。 + + + +#### 快捷键设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **设置**,在 **快捷键** 选项查看当前快捷键。 +2. 选择一种快捷键映射。 +3. 您可以单击并重新输入快捷键,自定义快捷键。 + + > ![notes](../common/notes.svg)说明: 快捷键映射允许您选择某一种键盘快捷键。您可以使用标准快捷键,Emacs快捷键,或自定义快捷键,以符合您的使用习惯。 + + +#### 高级设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在 **高级设置** 选项,您可以设置: + - 窗口状态:正常窗口,最大化或全屏。 + - Tab字符宽度:Tab缩进所占用的空间大小。 + + + +### 主题 + +窗口主题包含浅色主题、深色主题和系统主题。 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题颜色。 + +### 帮助 + +查看帮助手册,进一步了解和使用文本编辑器。 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文本编辑器的帮助手册。 + +### 关于 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文本编辑器的版本和介绍。 + +### 退出 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/close.png b/src/assets/deepin-editor/editor/zh_CN/fig/close.png new file mode 100755 index 0000000000000000000000000000000000000000..eb5704b81bca1efccd06786eb2a324c63b3edcf0 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/close.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/colortag.png b/src/assets/deepin-editor/editor/zh_CN/fig/colortag.png new file mode 100755 index 0000000000000000000000000000000000000000..5b64f60d1096bbfc488196af98b4c546e64ff20d Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/colortag.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/column_mode.png b/src/assets/deepin-editor/editor/zh_CN/fig/column_mode.png new file mode 100755 index 0000000000000000000000000000000000000000..52ec0e407f09e3db763f9c17b0c39a52e9ca54fd Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/column_mode.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/d_colortag.png b/src/assets/deepin-editor/editor/zh_CN/fig/d_colortag.png new file mode 100755 index 0000000000000000000000000000000000000000..f7021f8e32c0237bd8cf2500545428ef5573ecd1 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/d_colortag.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/d_column_mode.png b/src/assets/deepin-editor/editor/zh_CN/fig/d_column_mode.png new file mode 100755 index 0000000000000000000000000000000000000000..76ee58b8e34c2ffc15d3a034d0399bbb401f8a80 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/d_column_mode.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/d_read_only.png b/src/assets/deepin-editor/editor/zh_CN/fig/d_read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..384de02df149c88f91608b2787589a89b7dcbeb6 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/d_read_only.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/d_read_only02.png b/src/assets/deepin-editor/editor/zh_CN/fig/d_read_only02.png new file mode 100755 index 0000000000000000000000000000000000000000..f3200d80ae77470ca94e77561727ac1e1119e106 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/d_read_only02.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/d_toggle_case.png b/src/assets/deepin-editor/editor/zh_CN/fig/d_toggle_case.png new file mode 100755 index 0000000000000000000000000000000000000000..05733d417f05b52435eb62310f6b7f635439e66b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/d_toggle_case.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/editer.psd b/src/assets/deepin-editor/editor/zh_CN/fig/editer.psd new file mode 100755 index 0000000000000000000000000000000000000000..d68083edaf82a349425c63540ac895a3dfa4bb5b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/editer.psd differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/highlight.png b/src/assets/deepin-editor/editor/zh_CN/fig/highlight.png new file mode 100755 index 0000000000000000000000000000000000000000..955ff0130d4ade9801a58c4821aab115a0b64b77 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/highlight.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/hotkey.png b/src/assets/deepin-editor/editor/zh_CN/fig/hotkey.png new file mode 100755 index 0000000000000000000000000000000000000000..37e87eebeddeb9c6628793abbe1ef9cc4067f260 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/hotkey.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/listen.png b/src/assets/deepin-editor/editor/zh_CN/fig/listen.png new file mode 100755 index 0000000000000000000000000000000000000000..d397f90eaad0909f49535c74cb5cb58d949b2f2b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/listen.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/overview.png b/src/assets/deepin-editor/editor/zh_CN/fig/overview.png new file mode 100755 index 0000000000000000000000000000000000000000..56e6ef348cb76f88f29dae3c3cbaa93e706260fd Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/overview.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/printer.png b/src/assets/deepin-editor/editor/zh_CN/fig/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..e2f66f6cde42daa99f466bdfea82e06927ef1f47 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/printer.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/printer_setting.png b/src/assets/deepin-editor/editor/zh_CN/fig/printer_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..984eee2f24f282dfb78878bddab5ca3afb72ce21 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/printer_setting.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/read_only.png b/src/assets/deepin-editor/editor/zh_CN/fig/read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..9d26b1e1e316a68c0abee8e3ad751078bfb0a427 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/read_only.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/read_only_02.png b/src/assets/deepin-editor/editor/zh_CN/fig/read_only_02.png new file mode 100755 index 0000000000000000000000000000000000000000..960b5a350fa3ab4dcf7917aa37101d8045b5c843 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/read_only_02.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/reading.png b/src/assets/deepin-editor/editor/zh_CN/fig/reading.png new file mode 100755 index 0000000000000000000000000000000000000000..7dbbeed5c8c7cb8933856dcdec4ec92e36b09ed1 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/reading.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/text_translation.png b/src/assets/deepin-editor/editor/zh_CN/fig/text_translation.png new file mode 100755 index 0000000000000000000000000000000000000000..890ecd017a37cc38886ab90c129cbd834137ffa1 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/text_translation.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/fig/togglecase.png b/src/assets/deepin-editor/editor/zh_CN/fig/togglecase.png new file mode 100755 index 0000000000000000000000000000000000000000..63ac808ab35ececc3d630fda919d7a7b1609d896 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_CN/fig/togglecase.png differ diff --git a/src/assets/deepin-editor/editor/zh_CN/p_editor.md b/src/assets/deepin-editor/editor/zh_CN/p_editor.md new file mode 100755 index 0000000000000000000000000000000000000000..ba0119d7ff8de9bf8cdc400beb9c59234bb1f257 --- /dev/null +++ b/src/assets/deepin-editor/editor/zh_CN/p_editor.md @@ -0,0 +1,330 @@ +# 文本编辑器|deepin-editor| + +## 概述 + +文本编辑器是一个简单的文本编辑工具。您可以用它书写简单的文本文档,也可以使用它的高级特性,让它成为一个代码编辑工具,支持代码语法高亮。 + +![overview](fig/overview.png) + +## 使用入门 + +### 运行文本编辑器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文本编辑器图标 ![deepin_editor](../common/deepin_editor.svg),单击运行。 +3. 右键单击 ![deepin_editor](../common/deepin_editor.svg),您可以: + + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +### 退出文本编辑器 + +- 在文本编辑器界面,单击 ![close_icon](../common/close_icon.svg),退出文本编辑器。 +- 在文本编辑器界面,单击主菜单 ![icon_menu](../common/icon_menu.svg) > **退出** ,退出文本编辑器。 +- 在任务栏右键单击 ![deepin_editor](../common/deepin_editor.svg),选择 **关闭所有** ,退出文本编辑器。 + + +### 查看快捷键 + +在文本编辑器界面,使用快捷键 **Ctrl + Shift + ?** 打开快捷键预览界面,您也可以在设置界面查看快捷键。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理标签页 + +- 新建标签页/窗口 + + - 单击标签页上的 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **新标签页** 或使用快捷键 **Ctrl + T** 创建一个新的标签页。 + - 单击![icon_menu](../common/icon_menu.svg) > **新窗口** 或使用快捷键 **Ctrl + N** 创建一个新的窗口。 + +- 调整标签页/窗口 + + - 拖拽同一窗口内的标签页重新排序。 + - 滚动鼠标切换同一窗口内的标签页。 + - 移出标签页创建一个新的窗口,或者从一个窗口移到另外一个窗口中。 + +- 关闭标签页/窗口 + + 当窗口中仅有一个标签页时,关闭标签页的同时也会关闭窗口。 + - 使用 **Ctrl + W** 组合键关闭当前标签页。 + - 单击标签页上的按钮 ![close_icon](../common/close_icon.svg) 或者单击鼠标中键,关闭当前标签页。 + - 右键单击标签页,选择 **关闭标签页** 、**关闭其他标签页** 或 **更多关闭方式** 来关闭标签页。 + + > ![notes](../common/notes.svg)说明:如果您的文件发生了变化而没有保存,文本编辑器会在关闭前提示您保存更改。 + +### 打开文件 + +您可以采用以下方式打开一个或同时打开多个文本文件,选中的文件将会在新标签页打开: + +- 直接拖动文件到文本编辑器界面或其图标上。 +- 右键单击文件,选择 **打开方式** > **文本编辑器**。选择文本编辑器为默认打开程序后,可以直接双击打开。 +- 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg) > **打开文件** 或使用快捷键 **Ctrl + O**,在弹出的窗口中选择文件打开。 + +### 保存文件 +- 单击 ![icon_menu](../common/icon_menu.svg) > **保存** 或使用快捷键 **Ctrl + S**,保存当前文件。 +- 单击 ![icon_menu](../common/icon_menu.svg) > **另存为** 或使用快捷键 **Ctrl + Shift + S**,另存当前文件。 + + +### 打印文件 + +在文本编辑器中使用打印,需要提前连接并配置好打印机。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **打印**,也可以使用快捷键 **Ctrl + P** 打开打印预览。 +2. 在打印预览界面,您可以预览文件,选择打印机并设置打印页面。 +3. 在打印预览界面,单击 **高级设置**,可配置纸张大小、打印方式等相关参数。 +4. 单击 **打印** 即可将文件发送到打印机打印。 + +![pagesetup](fig/printer.png) + +![printer](fig/printer_setting.png) + + + +## 编辑文本 + +### 移动光标 + +除了使用方向键和鼠标点击移动光标,您还可以使用以下快捷键迅速移动光标: + +| 功能 | 快捷键 | +| --------------- | ------------ | +| 保存光标位置 | Ctrl + Shift + > | +| 重置光标位置(跳转到上次光标保存的位置) | Ctrl + Shift + < | +| 右移一个词 (光标向右跳过一个词) | Ctrl + 右方向键 | +| 左移一个词 (光标向左跳过一个词) | Ctrl + 左方向键 | +| 移动到行尾 | End | +| 移动到行头 | Home | +| 移动到文本结尾 | Ctrl + End | +| 移动到文本开头 | Ctrl + Home | +| 移动到行缩进 | Ctrl + M | +| 向右匹配 (光标移动到右括号的后面) | Alt + P | +| 向左匹配(光标移动到左括号的前面) | Alt + N | + +### 切换大小写 + +切换大小写功能可以将选中的文本全部改为大写字母、小写字母或者让首字母大写。 + +1. 选中待更改的文本内容。 +2. 单击右键,选择 **切换大小写**。 +3. 选择 **大写**/**小写**/**首字母大写** 选项,更改会立即生效。 + +您也可以使用快捷键 **Alt + U/ L/ C** 迅速切换大小写。 + +![togglecase](fig/togglecase.png) + +### 高亮文本 + +文本编辑器支持高亮不同类型的文本。 +单击底部状态栏最右侧的三角符号, 选择某种文本类型。若文本中有相应内容则会自动高亮。 + +![highlight](fig/highlight.png) + +### 删除文本 +除了向左或向右逐个删除字符外,您还可以使用以下快捷键迅速删除字符: + +| 功能 | 快捷键 | +| --------------- | ------------ | +| 删除到行尾 | Ctrl + K | +| 删除当前行 | Ctrl + Shift + K | +| 向左删除一个词 | Alt + Shift + N | +| 向右删除一个词 | Alt + Shift + M | + +### 撤销操作 + +如果在编辑文本时发生误操作,可以使用快捷键 **Ctrl + Z** 撤销操作,或者在右键菜单中选择 **撤销**。 + +### 查找文本 + +1. 单击 ![menu](../common/icon_menu.svg) > **查找** 或使用快捷键 **Ctrl + F** ,打开查找窗口。 +2. 在查找窗口中,输入要搜索的文本。 +3. 单击 **下一个**、**上一个** 逐个查找,或使用 **Enter** 键查找下一个匹配项。 +4. 按下 **Esc** 键或单击关闭按钮,关闭查找窗口。 + +> ![tips](../common/tips.svg)窍门:选中一段文本后再进行查找,则这段文本会自动出现在查找窗口中。 + +### 替换文本 +1. 单击 ![menu](../common/icon_menu.svg) > **替换** 或使用快捷键 **Ctrl + H** ,打开替换窗口。 +2. 在替换窗口中,输入要替换的文本以及新文本。 +3. 单击 **替换** 逐个替换,单击 **剩余替换**、**全部替换** 一次性替换剩余的或所有的匹配文本;单击 **跳过** 不替换当前匹配的文本。 +4. 按下 **Esc** 键或单击关闭按钮,关闭搜索窗口。 + +### 跳到行 +使用该功能可以迅速跳转到任一行。 +在右键菜单中选择 **跳到行** 或者使用快捷键 **Ctrl + G** ,输入行号即可跳转到相应行。 + +### 编辑行 + +您可以使用以下快捷键迅速编辑行: + +| 功能 | 快捷键 | +| ------------ | ------------ | +| 向上插入一行(在上方插入一行) | Ctrl + Enter | +| 向下插入一行(在下方插入一行) | Ctrl + Shift + Enter | +| 复制并粘贴当前行 | Ctrl + Shift + D | +| 上移一行(与上一行交换位置) | Ctrl + Shift + Up | +| 下移一行(与下一行交换位置) | Ctrl + Shift + Down | +| 向上滚动一行 | Super + Shift + Up | +| 向下滚动一行 | Super + Shift + Down | +| 设置标记 | Alt + H | +| 取消标记 | Alt + Shift + H | +| 复制行 | Super + C | +| 剪切行 | Super + X | +| 合并行 | Ctrl + J | + +### 开启/关闭只读模式 + +1. 使用文本编辑器打开文档,单击右键,选择 **开启只读模式**。 +2. 在只读模式下,单击右键,选择 **关闭只读模式**。 + +![read-only](fig/read_only.png) + +![read-only](fig/read_only_02.png) + +### 语音朗读 + +在“控制中心”>“辅助功能”中开启语音朗读、语音听写功能后,可以执行如下操作。 + +1. 单击右键,选择 **语音听写**,通过麦克风语音输入后,转译文字将被编辑在文档中。 +2. 选择一段文字后,单击右键,选择 **语音朗读**,语音播报选中的文字。 + + > ![notes](../common/notes.svg)说明:当未选择文字时,右键菜单中 **语音朗读** 不可激活,处置灰状态。 + +![read-only](fig/reading.png) + +### 文本翻译 + +在“控制中心”>“辅助功能”中开启文本翻译并选择语言后,可以执行以下操作。 + +1. 在文本编辑器界面选择一段文本后,单击右键,选择 **文本翻译**,可将该段文本内容翻译成目标语言。 + +![text](fig/text_translation.png) + +### 列编辑 + +在文本编辑器界面,按住键盘上的 **Alt** 键不放,鼠标左键单击多列启动列编辑模式,为多行代码同时编辑相同的内容,提高工作效率。 + +![mode](fig/column_mode.png) + + + +### 颜色标记 + +在文本编辑器界面,单击鼠标右键选择 **颜色标记**,在其下拉列表中进行选择。 + +![color](fig/colortag.png) + + - **添加标记**:对某一行或某一段文本内容添加颜色标记;有8种颜色按钮可供选择。 + + 将光标定在某一行,标记当前所在的行。 + + 选中一段文本内容后,标记选中的文本内容。 + - **标记所有**:将文本内容全部标记或对已选中的文本内容,在全文中标记匹配项;有8种颜色按钮可供选择。 + + 将光标定在任意一行,将文本内容全部标记。 + + 选中一段文本内容,在全文中标记匹配项。 + + - **清除上次标记**:清除上次标记操作。 + - **清除所有标记**:清除当前所有标记。 + +### 书签管理 + +在文本编辑器设置界面,勾选 **显示书签图标** 后,您可以为任意一行的文本内容添加书签。将鼠标指针移至左侧栏任意行号前面会显示图标 ![icon](../common/bookmark_normal_light.svg),添加成功后该行的书签图标会变为蓝色填充的图标 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加书签 + + + 鼠标左键单击 ![icon](../common/bookmark_normal_light.svg),为该行添加书签。 + + 鼠标右键单击 ![icon](../common/bookmark_normal_light.svg),选择 **添加书签**,为该行添加一个书签。 + + 将光标定在文本中任意一行,使用快捷键 **Ctrl + F2** 为该行添加一个书签。 + +- 删除书签 + + + 鼠标左键单击已填充颜色的书签图标,直接删除该行书签。 + + 鼠标右键单击已填充颜色的书签图标,选择 **清除书签**,删除该行书签。 + + 鼠标右键单击书签图标,选择 **清除所有书签**,删除该文本的全部书签。 + + >![icon](../common/notes.svg)说明:鼠标移到左侧行号前面才会显示书签图标,移出书签区域,书签图标消失。添加书签后,该图标一直显示。 + + + +### 注释管理 + +在文本编辑器界面,您可以对扩展名为.cpp 、.java 、.py等代码类型的文件进行添加注释的操作。 + +- 添加注释 + + 选中一段文本内容,单击右键并选择 **添加注释**。 + + 选中一段文本内容,使用组合键 **Alt + A** 添加注释。 + +- 取消注释 + + 选中一段已添加注释的文本内容,单击右键并选择 **取消注释**。 + + 选中一段已添加注释的文本内容,使用快捷键 **Alt + Z** 取消注释。 + + >![notes](../common/notes.svg)说明:支持不同代码语言的注释,具体以实际为主。例如C,C#,Java注释符号为 //,Python 注释符号为 #。 + + + +## 主菜单 + +在主菜单中,您可以新建窗口、新建标签页、[查找文本](#查找文本)、[替换文本](#替换文本)、保存文件、切换窗口主题、查看帮助手册、进一步了解文本编辑器的更多信息。 + +### 设置 + +您可以对基础信息、快捷键和高级信息进行设置。 + +#### 基础设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg)> **设置**。 +2. 在基础设置选项,您可以选择: + - 设置字体样式和字号大小。 + - 勾选 **自动换行**,在编辑区自动换行。 + - 勾选 **代码折叠标志**,在左侧栏显示按钮 ![next](../common/next.svg) 或者 ![next](../common/next_down.svg),右键单击按钮选择折叠/展开当前层次或所有层次。 + - 勾选 **显示行号**,在左侧栏显示行号。 + - 勾选 **当前行高亮**,光标所在的行高亮显示。 + - 勾选 **显示书签图标**,在左侧栏显示书签图标。 + - 勾选 **显示空白制符/制表符**,显示文本中的空白字符和制表符,您也可以手动输入或删除空白字符和制表符。 + + > ![tips](../common/tips.svg)窍门:在文本编辑器中,使用 **Ctrl + “+”/ “-”** 调节字号,使用 **Ctrl + 0** 恢复默认字号。 + + + +#### 快捷键设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **设置**,在 **快捷键** 选项查看当前快捷键。 +2. 选择一种快捷键映射。 +3. 您可以单击快捷键编辑区域,自定义快捷键。 + + > ![notes](../common/notes.svg)说明: 快捷键映射允许您选择某一种键盘快捷键。可以使用标准快捷键,Emacs快捷键,或自定义快捷键,以符合您的使用习惯。 + + +#### 高级设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg) >**设置**。 +2. 在 **高级设置** 选项,您可以设置: + - 窗口状态:正常窗口,最大化或全屏。 + - Tab字符宽度:Tab缩进所占用的空间大小。 + + +### 主题 + +窗口主题包含浅色主题、深色主题和系统主题。 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题颜色。 + +### 帮助 + +查看帮助手册,进一步了解和使用文本编辑器。 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文本编辑器的帮助手册。 + +### 关于 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文本编辑器的版本和介绍。 + +### 退出 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/zh_HK/editor.md b/src/assets/deepin-editor/editor/zh_HK/editor.md new file mode 100755 index 0000000000000000000000000000000000000000..983546b6967ae7beaf416bbe2060f56d321eb47a --- /dev/null +++ b/src/assets/deepin-editor/editor/zh_HK/editor.md @@ -0,0 +1,310 @@ +# 文本編輯器|deepin-editor| + +## 概述 + +文本編輯器是一個簡單的文本編輯工具。您可以用它書寫簡單的文本文檔,也可以使用它的高級特性,讓它成為一個代碼編輯工具,支持代碼語法高亮。 + +![overview](fig/overview.png) + +## 使用入門 + +### 運行文本編輯器 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到文本編輯器圖標![deepin_editor](../common/deepin_editor.svg),單擊運行。 +3. 右鍵單擊![deepin_editor](../common/deepin_editor.svg),您可以: + + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +### 關閉文本編輯器 + +- 在文本編輯器界面,單擊 ![close_icon](../common/close_icon.svg),關閉文本編輯器。 +- 在文本編輯器界面,單擊主菜單 ![icon_menu](../common/icon_menu.svg) > **退出** ,關閉文本編輯器。 +- 在任務欄右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),選擇 **關閉所有** ,關閉文本編輯器。 + + +### 查看快捷鍵 + +在文本編輯器界面,使用快捷鍵 **Ctrl + Shift + ?** 打開快捷鍵預覽界面,您也可以在設置界面查看快捷鍵。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理標籤頁 + +- 新建標籤頁/窗口 + + - 單擊標籤頁上的 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **新標籤頁** 或使用快捷鍵 **Ctrl + T** 創建一個新的標籤頁。 + - 單擊![icon_menu](../common/icon_menu.svg) > **新窗口** 或使用快捷鍵 **Ctrl + N** 創建一個新的窗口。 + +- 調整標籤頁/窗口 + + - 拖拽同一窗口內的標籤頁重新排序。 + - 滾動鼠標切換同一窗口內的標籤頁。 + - 移出標籤頁創建一個新的窗口,或者從一個窗口移到另外一個窗口中。 + +- 關閉標籤頁/窗口 + + 當窗口中僅有一個標籤頁時,關閉標籤頁的同時也會關閉窗口。 + - 使用快捷鍵 **Ctrl + W** 關閉當前標籤頁。 + - 單擊標籤頁上的按鈕 ![close_icon](../common/close_icon.svg) 或者單擊鼠標中鍵,關閉當前標籤頁。 + - 右鍵單擊標籤頁,選擇 **關閉標籤頁** 、**關閉其他標籤頁** 或 **更多關閉方式** 來關閉標籤頁。 + + > ![notes](../common/notes.svg)說明:如果您的文件發生了變化而沒有保存,文本編輯器會在關閉前提示您保存更改。 + + +### 打開文件 + +您可以採用以下方式打開一個或同時打開多個文本文件,選中的文件將會在新標籤頁中打開: + +- 直接拖動文件到文本編輯器界面或其圖標上。 +- 右鍵單擊文件,選擇 **打開方式** > **文本編輯器**。選擇文本編輯器為默認打開程序後,可直接雙擊打開。 +- 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg) > **打開文件** 或使用快捷鍵 **Ctrl + O**,在彈出的窗口中選擇文件打開。 + + +### 保存文件 +- 單擊 ![icon_menu](../common/icon_menu.svg) > **保存** 或使用快捷鍵 **Ctrl + S**,保存當前文件。 +- 單擊 ![icon_menu](../common/icon_menu.svg) > **另存為** 或使用快捷鍵 **Ctrl + Shift + S**,另存當前文件。 + + +### 打印文件 + +在文本編輯器中使用打印,需要您連接並配置好打印機。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **打印**,也可以使用快捷鍵 **Ctrl + P** 打開打印預覽。 +2. 在打印預覽界面,您可以預覽文件,選擇打印機並設置打印頁面。 +3. 在打印預覽界面,單擊 **高級設置**,可配置紙張大小、打印方式等相關參數。 +4. 單擊 **打印** 即可將文件發送到打印機打印。 + + + +## 編輯文本 + +### 移動光標 + +除了使用方向鍵和鼠標單擊移動光標,您還可以使用以下快捷鍵迅速移動光標: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 保存光標位置 | Ctrl + Shift + > | +| 重置光標位置(跳轉到上次光標保存的位置) | Ctrl + Shift + < | +| 右移一個詞 (光標向右跳過一個詞) | Ctrl + 右方向鍵 | +| 左移一個詞 (光標向左跳過一個詞) | Ctrl + 左方向鍵 | +| 移動到行尾 | End | +| 移動到行頭 | Home | +| 移動到文本結尾 | Ctrl + End | +| 移動到文本開頭 | Ctrl + Home | +| 移動到行縮進 | Ctrl + M | +| 向右匹配 (光標移動到右括號的後面) | Alt + P | +| 向左匹配(光標移動到左括號的前面) | Alt + N | + +### 切換大小寫 + +切換大小寫功能可以將選中的文本全部改為大寫字母、小寫字母或者讓首字母大寫。 + +1. 選中待更改的文本內容。 +2. 單擊右鍵,選擇 **切換大小寫**。 +3. 選擇 **大寫**/**小寫**/**首字母大寫** 選項,更改會立即生效。 + +您也可以使用快捷鍵 **Alt + U/ L/ C** 迅速切換大小寫。 + +![toggle_case](fig/d_toggle_case.png) + +### 高亮文本 + +文本編輯器支持高亮不同類型的文本。 +單擊底部狀態欄最右側的三角符號, 選擇某種文本類型。若文本中有相應內容則會自動高亮。 + +![highlight](fig/highlight.png) + +### 刪除文本 +除了向左或向右逐個刪除字符外,您還可以使用以下快捷鍵迅速刪除字符: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 刪除到行尾 | Ctrl + K | +| 刪除當前行 | Ctrl + Shift + K | +| 向左刪除一個詞 | Alt + Shift + N | +| 向右刪除一個詞 | Alt + Shift + M | + +### 撤銷操作 + +如果在編輯文本時發生誤操作, 可以使用快捷鍵 **Ctrl + Z** 撤銷操作, 或者在右鍵菜單中選擇 **撤銷**。 + +### 查找文本 + +1. 單擊 ![menu](../common/icon_menu.svg) > **查找** 或使用快捷鍵 **Ctrl + F** 打開查找窗口。 +2. 在查找窗口中,輸入要搜索的文本。 +3. 單擊 **下一個**、**上一個** 逐個查找,或使用 **Enter** 鍵查找下一個匹配項。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉查找窗口。 + +> ![tips](../common/tips.svg)竅門:選中一段文本後再進行搜索,則這段文本會自動出現在查找窗口中。 + +### 替換文本 +1. 單擊 ![menu](../common/icon_menu.svg) > **替換** 或使用快捷鍵 **Ctrl + H** 打開替換窗口。 +2. 在替換窗口中,輸入要替換的文本以及新文本。 +3. 單擊 **替換** 逐個替換,單擊 **剩餘替換**、**全部替換** 一次性替換剩餘的或所有的匹配文本。單擊 **跳過** 不替換當前匹配的文本。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉搜索窗口。 + +### 跳到行 +使用該功能可以迅速跳轉到任一行。 +在右鍵菜單中選擇 **跳到行** 或者使用快捷鍵 **Ctrl + G** ,輸入行號即可跳轉到相應行。 + +### 編輯行 + +您可以使用以下快捷鍵迅速編輯行: + +| 功能 | 快捷鍵 | +| ------------ | ------------ | +| 向上插入一行(在上方插入一行) | Ctrl + Enter | +| 向下插入一行(在下方插入一行) | Ctrl + Shift + Enter | +| 複製並黏貼當前行 | Ctrl + Shift + D | +| 上移一行(與上一行交換位置) | Ctrl + Shift + Up | +| 下移一行(與下一行交換位置) | Ctrl + Shift + Down | +| 向上滾動一行 | Super + Shift + Up | +| 向下滾動一行 | Super + Shift + Down | +| 設置標記 | Alt + H | +| 取消標記 | Alt + Shift + H | +| 複製行 | Super + C | +| 剪切行 | Super + X | +| 合併行 | Ctrl + J | + +### 開啟/關閉只讀模式 + +1. 使用文本編輯器打開文檔,單擊右鍵,選擇 **開啟只讀模式**。 +2. 在只讀模式下,單擊右鍵,選擇 **關閉只讀模式**。 + +![read_only](fig/d_read_only.png) + +![read_only](fig/d_read_only02.png) + + + +### 列編輯 + +在文本編輯器界面,按住鍵盤上的 **Alt** 鍵不放,鼠標左鍵單擊多列啟動列編輯模式,為多行代碼同時編輯相同的內容,提高工作效率。 + +![mode](fig/column_mode.png) + +### 顏色標記 + +在文本編輯器界面,單擊鼠標右鍵選擇 **顏色標記**,在其下拉列表中進行選擇。 + +![color](fig/d_color_tag.png) + + - **設置標記**:對某一行或某一段文本內容添加顏色標記;有8種顏色按鈕可供選擇。 + + 將光標定在某一行,標記當前所在的行。 + + 選中一段文本內容後,標記選中的文本內容。 + - **標記所有**:將文本內容全部標記或對已選中的文本內容,在全文中標記匹配項;有8種顏色按鈕可供選擇。 + + 將光標定在任意一行,將文本內容全部標記。 + + 選中一段文本內容,在全文中標記匹配項。 + - **清除上次標記**:清除上次標記操作。 + - **清除所有標記**:清除當前所有標記。 + + + + +### 書籤管理 + +在文本編輯器設置界面,勾選 **顯示書籤圖標** 後,您可以為任意一行的文本內容添加一個書籤。將鼠標指針移至左側欄任意行號前面會顯示圖標 ![icon](../common/bookmark_normal_light.svg),添加成功後該行的書籤圖標會變為藍色填充的圖標 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加書籤 + + + 鼠標左鍵單擊 ![icon](../common/bookmark_normal_light.svg),為該行添加書籤。 + + 鼠標右鍵單擊![icon](../common/bookmark_normal_light.svg),選擇 **添加書籤**,為該行添加一個書籤。 + + 將光標定在文本中任意一行,使用快捷鍵 **Ctrl + F2** 為該行添加一個書籤。 + +- 刪除書籤 + + + 鼠標左鍵單擊已填充顏色的書籤圖標,直接刪除該行書籤。 + + 鼠標右鍵單擊已填充顏色的書籤圖標,選擇 **清除書籤**,刪除該行書籤。 + + 鼠標右鍵單擊書籤圖標,選擇 **清除所有書籤**,刪除該文本的全部書籤。 + + >![icon](../common/notes.svg)說明:鼠標移到左側行號前面才會顯示書籤圖標,移出書籤區域,書籤圖標消失。添加書籤後,該圖標一直顯示。 + + + +### 注釋管理 + +在文本編輯器界面,您可對擴展名為.cpp 、.java 、.py等代碼類型的文件進行添加注釋的操作。 +- 添加注釋 + + 選中一段文本內容,在右鍵菜單中選擇 **添加注釋**。 + + 選中一段文本內容,使用快捷鍵 **Alt + A** 添加注釋。 + +- 取消注釋 + + 選中一段已添加注釋的文本內容,在右鍵菜單中選擇 **取消注釋**。 + + 選中一段已添加注釋的文本內容,使用快捷鍵 **Alt + Z** 取消注釋。 + + >![notes](../common/notes.svg)說明:支持不同代碼語言的注釋,具體以實際為主。例如C,C#,Java注釋符號為 //,Python 注釋符號為 #。 + + + +## 主菜單 + +在主菜單中,您可以新建窗口、新建標籤頁、[查找文本](#查找文本)、[替換文本](#替換文本)、保存文件、切換窗口主題、查看幫助手冊,了解文本編輯器的更多訊息。 + +### 設置 + +您可以對基礎訊息、快捷鍵和高級訊息進行設置。 + +#### 基礎設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)> **設置**。 +2. 在基礎設置選項,您可以選擇: + - 設置字體樣式和字號大小。 + - 勾選 **自動換行**,在編輯區自動換行。 + - 勾選 **顯示代碼摺疊標誌**,在左側欄顯示![next](../common/next.svg)或者![next](../common/next_down.svg)按鈕,右鍵單擊按鈕選擇摺疊/展開當前層次或所有層次。 + - 勾選 **顯示行號**,在左側欄顯示行號。 + - 勾選 **當前行高亮**,光標所在的行高亮顯示。 + - 勾選 **顯示書籤圖標**,在左側欄顯示書籤圖標。 + - 勾選 **顯示空白制符/製表符**,顯示文本中的空白字符和製表符,您也可手動輸入或刪除空白字符和製表符。 + + > ![tips](../common/tips.svg)竅門:您還可以使用 **Ctrl + 「+」/ 「-」** 來調節文本編輯器的默認字號。使用 **Ctrl + 0** 恢復默認字號。 + + +#### 快捷鍵設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)> **設置**,在 **快捷鍵** 選項查看當前快捷鍵。 +2. 選擇一種快捷鍵映射。 +3. 單擊快捷鍵編輯框 ,可以自定義快捷鍵。 + + > ![notes](../common/notes.svg)說明: 快捷鍵映射允許您選擇某一種鍵盤快捷鍵。您可以使用標準快捷鍵,Emacs快捷鍵,或自定義快捷鍵,以符合您的使用習慣。 + + +#### 高級設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)>**設置**。 +2. 在 **高級設置** 選項,您可以設置: + - 窗口狀態:正常窗口,最大化或全螢幕。 + - Tab字符寬度:Tab縮進所佔用的空間大小。 + + + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在文本編輯器界面,單擊![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題顏色。 + +### 幫助 + +查看幫助手冊,進一步了解和使用文本編輯器。 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **幫助**。 +3. 查看文本編輯器的幫助手冊。 + +### 關於 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看文本編輯器的版本和介紹。 + +### 退出 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **退出**。 \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/close.png b/src/assets/deepin-editor/editor/zh_HK/fig/close.png new file mode 100755 index 0000000000000000000000000000000000000000..eb5704b81bca1efccd06786eb2a324c63b3edcf0 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/close.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/color_tag.png b/src/assets/deepin-editor/editor/zh_HK/fig/color_tag.png new file mode 100755 index 0000000000000000000000000000000000000000..aa8b20067d4b65afa7cdb4f0ca21c1628240bfec Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/color_tag.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/column_mode.png b/src/assets/deepin-editor/editor/zh_HK/fig/column_mode.png new file mode 100755 index 0000000000000000000000000000000000000000..8d55fc7aa995f012faabb4139da55a9f3771a2c3 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/column_mode.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/d_color_tag.png b/src/assets/deepin-editor/editor/zh_HK/fig/d_color_tag.png new file mode 100755 index 0000000000000000000000000000000000000000..24a393283d28e2805018c16203220ba1afb82b9c Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/d_color_tag.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/d_read_only.png b/src/assets/deepin-editor/editor/zh_HK/fig/d_read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..e5cdf3ab18903e84ce507aa386934cbdcf7ddca8 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/d_read_only.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/d_read_only02.png b/src/assets/deepin-editor/editor/zh_HK/fig/d_read_only02.png new file mode 100755 index 0000000000000000000000000000000000000000..c140b8083c385c43e57b059136137824704d77f4 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/d_read_only02.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/d_toggle_case.png b/src/assets/deepin-editor/editor/zh_HK/fig/d_toggle_case.png new file mode 100755 index 0000000000000000000000000000000000000000..bbe4afb482256cdcd5e5b761127506c57bab6b3b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/d_toggle_case.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/highlight.png b/src/assets/deepin-editor/editor/zh_HK/fig/highlight.png new file mode 100755 index 0000000000000000000000000000000000000000..9ec23d428c003591fd448c0be2ce2d5c89e72089 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/highlight.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/hotkey.png b/src/assets/deepin-editor/editor/zh_HK/fig/hotkey.png new file mode 100755 index 0000000000000000000000000000000000000000..84c50b0cf0b2cf8007c6e7c671fa8455292f84a6 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/hotkey.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/listen.png b/src/assets/deepin-editor/editor/zh_HK/fig/listen.png new file mode 100755 index 0000000000000000000000000000000000000000..d397f90eaad0909f49535c74cb5cb58d949b2f2b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/listen.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/overview.png b/src/assets/deepin-editor/editor/zh_HK/fig/overview.png new file mode 100755 index 0000000000000000000000000000000000000000..b20ade6435cee3855c8c36ad28f241c8ec71ceb0 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/overview.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/read_only.png b/src/assets/deepin-editor/editor/zh_HK/fig/read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..e9ecb117bce231c927a54769d8446bc9f3a56092 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/read_only.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/read_only02.png b/src/assets/deepin-editor/editor/zh_HK/fig/read_only02.png new file mode 100755 index 0000000000000000000000000000000000000000..fe3fdee35c4d37144555001b17a2c51f14019afb Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/read_only02.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/reading.png b/src/assets/deepin-editor/editor/zh_HK/fig/reading.png new file mode 100755 index 0000000000000000000000000000000000000000..12ae8421d68a9b4c19d2600e111a879e3f7cbfdb Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/reading.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/toggle_case.png b/src/assets/deepin-editor/editor/zh_HK/fig/toggle_case.png new file mode 100755 index 0000000000000000000000000000000000000000..e7d395f2710ebf8247a5f9d6561c4415dd2f29e5 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/toggle_case.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/fig/translation.png b/src/assets/deepin-editor/editor/zh_HK/fig/translation.png new file mode 100755 index 0000000000000000000000000000000000000000..b522e244afa264a01d52ccd08852cc6ca0ef826c Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_HK/fig/translation.png differ diff --git a/src/assets/deepin-editor/editor/zh_HK/p_editor.md b/src/assets/deepin-editor/editor/zh_HK/p_editor.md new file mode 100755 index 0000000000000000000000000000000000000000..52c628392068da1747658f6cb395ef2cf9cf2303 --- /dev/null +++ b/src/assets/deepin-editor/editor/zh_HK/p_editor.md @@ -0,0 +1,330 @@ +# 文本編輯器|deepin-editor| + +## 概述 + +文本編輯器是一個簡單的文本編輯工具。您可以用它書寫簡單的文本文檔,也可以使用它的高級特性,讓它成為一個代碼編輯工具,支持代碼語法高亮。 + +![overview](fig/overview.png) + +## 使用入門 + +### 運行文本編輯器 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到文本編輯器圖標 ![deepin_editor](../common/deepin_editor.svg),單擊運行。 +3. 右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),您可以: + + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +### 關閉文本編輯器 + +- 在文本編輯器界面,單擊 ![close_icon](../common/close_icon.svg),關閉文本編輯器。 +- 在文本編輯器界面,單擊主菜單 ![icon_menu](../common/icon_menu.svg) > **退出** ,關閉文本編輯器。 +- 在任務欄右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),選擇 **關閉所有** ,關閉文本編輯器。 + + +### 查看快捷鍵 + +在文本編輯器界面,使用快捷鍵 **Ctrl + Shift + ?** 打開快捷鍵預覽界面,您也可以在設置界面查看快捷鍵。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理標籤頁 + +- 新建標籤頁/窗口 + + - 單擊標籤頁上的按鈕 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **新標籤頁** 或使用快捷鍵 **Ctrl + T** 創建一個新的標籤頁。 + - 單擊 ![icon_menu](../common/icon_menu.svg) > **新窗口** 或使用快捷鍵 **Ctrl + N** 創建一個新的窗口。 + +- 調整標籤頁/窗口 + + - 拖拽同一窗口內的標籤頁重新排序。 + - 滾動鼠標切換同一窗口內的標籤頁。 + - 移出標籤頁創建一個新的窗口,或者從一個窗口移到另外一個窗口中。 + +- 關閉標籤頁/窗口 + + 當窗口中僅有一個標籤頁時,關閉標籤頁的同時也會關閉窗口。 + - 使用快捷鍵 **Ctrl + W** 關閉當前標籤頁。 + - 單擊標籤頁上的 ![close_icon](../common/close_icon.svg) 按鈕或者單擊鼠標中鍵,關閉當前標籤頁。 + - 右鍵單擊標籤頁,選擇 **關閉標籤頁** 、**關閉其他標籤頁** 或 **更多關閉方式** 來關閉標籤頁。 + + > ![notes](../common/notes.svg)說明:如果您的文件發生了變化而沒有保存,文本編輯器會在關閉前提示您保存更改。 + + +### 打開文件 + +您可以採用以下方式打開一個或同時打開多個文本文件,選中的文件將會在新標籤頁中打開: + +- 直接拖動文件到文本編輯器界面或其圖標上。 +- 右鍵單擊文件,選擇 **打開方式** > **文本編輯器**。選擇文本編輯器為默認打開程序後,可直接雙擊打開。 +- 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg) > **打開文件** 或使用快捷鍵 **Ctrl + O**,在彈出的窗口中選擇文件打開。 + + +### 保存文件 +- 單擊 ![icon_menu](../common/icon_menu.svg) > **保存** 或使用快捷鍵 **Ctrl + S**,保存當前文件。 +- 單擊 ![icon_menu](../common/icon_menu.svg) > **另存為** 或使用快捷鍵 **Ctrl + Shift + S**,另存當前文件。 + + + +### 打印文件 + +在文本編輯器中使用打印,需要您連接並配置好打印機。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **打印**,也可以使用快捷鍵 **Ctrl + P** 打開打印預覽。 +2. 在打印預覽界面,您可以預覽文件,選擇打印機並設置打印頁面。 +3. 在打印預覽界面,單擊 **高級設置**,可配置紙張大小、打印方式等相關參數。 +4. 單擊 **打印** 即可將文件發送到打印機打印。 + + + +## 編輯文本 + +### 移動光標 + +除了使用方向鍵和鼠標單擊移動光標,您還可以使用以下快捷鍵迅速移動光標: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 保存光標位置 | Ctrl + Shift + > | +| 重置光標位置(跳轉到上次光標保存的位置) | Ctrl + Shift + < | +| 右移一個詞 (光標向右跳過一個詞) | Ctrl + 右方向鍵 | +| 左移一個詞 (光標向左跳過一個詞) | Ctrl + 左方向鍵 | +| 移動到行尾 | End | +| 移動到行頭 | Home | +| 移動到文本結尾 | Ctrl + End | +| 移動到文本開頭 | Ctrl + Home | +| 移動到行縮進 | Ctrl + M | +| 向右匹配 (光標移動到右括號的後面) | Alt + P | +| 向左匹配(光標移動到左括號的前面) | Alt + N | + +### 切換大小寫 + +切換大小寫功能可以將選中的文本全部改為大寫字母、小寫字母或者讓首字母大寫。 + +1. 選中待更改的文本內容。 +2. 單擊右鍵,選擇 **切換大小寫**。 +3. 選擇 **大寫**/**小寫**/**首字母大寫** 選項,更改會立即生效。 + +您也可以使用快捷鍵 **Alt + U/ L/ C** 迅速切換大小寫。 + +![toggle_case](fig/toggle_case.png) + +### 高亮文本 + +文本編輯器支持高亮不同類型的文本。 +單擊底部狀態欄最右側的三角符號, 選擇某種文本類型。若文本中有相應內容則會自動高亮。 + +![highlight](fig/highlight.png) + +### 刪除文本 +除了向左或向右逐個刪除字符外,您還可以使用以下快捷鍵迅速刪除字符: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 刪除到行尾 | Ctrl + K | +| 刪除當前行 | Ctrl + Shift + K | +| 向左刪除一個詞 | Alt + Shift + N | +| 向右刪除一個詞 | Alt + Shift + M | + +### 撤銷操作 + +如果在編輯文本時發生誤操作,可以使用快捷鍵 **Ctrl + Z** 撤銷操作,或者在右鍵菜單中選擇 **撤銷**。 + +### 查找文本 + +1. 單擊 ![menu](../common/icon_menu.svg) > **查找** 或使用快捷鍵 **Ctrl + F** 打開查找窗口。 +2. 在查找窗口中,輸入要搜索的文本。 +3. 單擊 **下一個**、**上一個** 逐個查找,或使用 **Enter** 鍵查找下一個匹配項。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉查找窗口。 + +> ![tips](../common/tips.svg)竅門:選中一段文本後再進行搜索,則這段文本會自動出現在查找窗口中。 + +### 替換文本 +1. 單擊 ![menu](../common/icon_menu.svg) > **替換** 或使用快捷鍵 **Ctrl + H** 打開替換窗口。 +2. 在替換窗口中,輸入要替換的文本以及新文本。 +3. 單擊 **替換** 逐個替換,單擊 **剩餘替換**、**全部替換** 一次性替換剩餘的或所有的匹配文本。單擊 **跳過** 不替換當前匹配的文本。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉搜索窗口。 + +### 跳到行 +使用該功能可以迅速跳轉到任一行。 +在右鍵菜單中選擇 **跳到行** 或者使用快捷鍵 **Ctrl + G** ,輸入行號即可跳轉到相應行。 + +### 編輯行 + +您可以使用以下快捷鍵迅速編輯行: + +| 功能 | 快捷鍵 | +| ------------ | ------------ | +| 向上插入一行(在上方插入一行) | Ctrl + Enter | +| 向下插入一行(在下方插入一行) | Ctrl + Shift + Enter | +| 複製並黏貼當前行 | Ctrl + Shift + D | +| 上移一行(與上一行交換位置) | Ctrl + Shift + Up | +| 下移一行(與下一行交換位置) | Ctrl + Shift + Down | +| 向上滾動一行 | Super + Shift + Up | +| 向下滾動一行 | Super + Shift + Down | +| 設置標記 | Alt + H | +| 取消標記 | Alt + Shift + H | +| 複製行 | Super + C | +| 剪切行 | Super + X | +| 合併行 | Ctrl + J | + +### 開啟/關閉只讀模式 + +1. 使用文本編輯器打開文檔,單擊右鍵,選擇 **開啟只讀模式**。 +2. 在只讀模式下,單擊右鍵,選擇 **關閉只讀模式**。 + +![read_only](fig/read_only.png) + +![read_only](fig/read_only02.png) + +### 語音朗讀 + +在 **控制中心 > 輔助功能** 中開啟語音朗讀、語音聽寫功能後,可以執行如下操作。 + +1. 單擊右鍵,選擇 **語音聽寫**,通過麥克風語音輸入後,轉譯文字將被編輯在文檔中 +2. 選擇一段文字後,單擊右鍵,選擇 **語音朗讀**,語音播報選中的文字。 + + > ![notes](../common/notes.svg)說明:當未選擇文字時,右鍵菜單中 **語音朗讀** 不可啟動,處置灰狀態。 + + +![read_only](fig/reading.png) + +### 文本翻譯 + +在 **控制中心 > 輔助功能** 中開啟文本翻譯並選擇語言後,可以執行以下操作。 + +1. 在文本編輯器界面選擇一段文本後,單擊右鍵,選擇 **文本翻譯**,可將該段文本內容翻譯成目標語言。 + +![text](fig/translation.png) + + + +### 列編輯 + +在文本編輯器界面,按住鍵盤上的 **Alt** 鍵不放,鼠標左鍵單擊多列啟動列編輯模式,為多行代碼同時編輯相同的內容,提高工作效率。 + +![mode](fig/column_mode.png) + +### 顏色標記 + +在文本編輯器界面,單擊鼠標右鍵選擇 **顏色標記**,在其下拉列表中進行選擇。 + +![color](fig/color_tag.png) + + - **設置標記**:對某一行或某一段文本內容添加顏色標記;有8種顏色按鈕可供選擇。 + + 將光標定在某一行,標記當前所在的行。 + + 選中一段文本內容後,標記選中的文本內容。 + - **標記所有**:將文本內容全部標記或對已選中的文本內容,在全文中標記匹配項;有8種顏色按鈕可供選擇。 + + 將光標定在任意一行,將文本內容全部標記。 + + 選中一段文本內容,在全文中標記匹配項。 + - **清除上次標記**:清除上次標記操作。 + - **清除所有標記**:清除當前所有標記。 + + + +### 書籤管理 + +在文本編輯器設置界面,勾選 **顯示書籤圖標** 後,您可以為任意一行的文本內容添加一個書籤。將鼠標指針移至左側欄任意行號前面會顯示圖標 ![icon](../common/bookmark_normal_light.svg),添加成功後該行的書籤圖標會變為藍色填充的圖標 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加書籤 + + + 鼠標左鍵單擊 ![icon](../common/bookmark_normal_light.svg),為該行添加書籤。 + + 鼠標右鍵單擊 ![icon](../common/bookmark_normal_light.svg),選擇 **添加書籤**,為該行添加一個書籤。 + + 將光標定在文本中任意一行,使用快捷鍵 **Ctrl + F2** 為該行添加一個書籤。 + +- 刪除書籤 + + + 鼠標左鍵單擊已填充顏色的書籤圖標,直接刪除該行書籤。 + + 鼠標右鍵單擊已填充顏色的書籤圖標,選擇 **清除書籤**,刪除該行書籤。 + + 鼠標右鍵單擊書籤圖標,選擇 **清除所有書籤**,刪除該文本的全部書籤。 + + >![icon](../common/notes.svg)說明:鼠標移到左側行號前面才會顯示書籤圖標,移出書籤區域,書籤圖標消失。添加書籤後,該圖標一直顯示。 + + + +### 注釋管理 + +在文本編輯器界面,您可對擴展名為.cpp 、.java 、.py等代碼類型的文件進行添加注釋的操作。 +- 添加注釋 + + 選中一段文本內容,在右鍵菜單中選擇 **添加注釋**。 + + 選中一段文本內容,使用快捷鍵 **Alt + A** 添加注釋。 + +- 取消注釋 + + 選中一段已添加注釋的文本內容,在右鍵菜單中選擇 **取消注釋**。 + + 選中一段已添加注釋的文本內容,使用快捷鍵 **Alt + Z** 取消注釋。 + + >![notes](../common/notes.svg)說明:支持不同代碼語言的注釋,具體以實際為主。例如C,C#,Java注釋符號為 //,Python 注釋符號為 #。 + + + +## 主菜單 + +在主菜單中,您可以新建窗口、新建標籤頁、[查找文本](#查找文本)、[替換文本](#替換文本)、保存文件、切換窗口主題、查看幫助手冊,了解文本編輯器的更多訊息。 +### 設置 + +您可以對基礎訊息、快捷鍵和高級訊息進行設置。 + +#### 基礎設置 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設置**。 +2. 在基礎設置選項,您可以選擇: + - 設置字體樣式和字號大小。 + - 勾選 **自動換行**,在編輯區自動換行。 + - 勾選 **顯示代碼摺疊標誌**,在左側欄顯示 ![next](../common/next.svg)或者![next](../common/next_down.svg)按鈕,右鍵單擊按鈕選擇摺疊/展開當前層次或所有層次。 + - 勾選 **顯示行號**,在左側欄顯示行號。 + - 勾選 **當前行高亮**,光標所在的行高亮顯示。 + - 勾選 **顯示書籤圖標**,在左側欄顯示書籤圖標。 + - 勾選 **顯示空白制符/製表符**,顯示文本中的空白字符和製表符,您也可手動輸入或刪除空白字符和製表符。 + + > ![tips](../common/tips.svg)竅門:您還可以使用 **Ctrl + 「+」/ 「-」** 來調節文本編輯器的默認字號。使用 **Ctrl + 0** 恢復默認字號。 + + + +#### 快捷鍵設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)> **設置**,在 **快捷鍵** 選項查看當前快捷鍵。 +2. 選擇一種快捷鍵映射。 +3. 單擊快捷鍵編輯框 ,可以自定義快捷鍵。 + + > ![notes](../common/notes.svg)說明: 快捷鍵映射允許您選擇某一種鍵盤快捷鍵。您可以使用標準快捷鍵,Emacs快捷鍵,或自定義快捷鍵,以符合您的使用習慣。 + + +#### 高級設置 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) >**設置**。 +2. 在 **高級設置** 選項,您可以設置: + - 窗口狀態:正常窗口,最大化或全螢幕。 + - Tab字符寬度:Tab縮進所佔用的空間大小。 + + + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題顏色。 + +### 幫助 + +查看幫助手冊,進一步了解和使用文本編輯器。 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **幫助**。 +3. 查看文本編輯器的幫助手冊。 + +### 關於 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看文本編輯器的版本和介紹。 + +### 退出 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **退出**。 \ No newline at end of file diff --git a/src/assets/deepin-editor/editor/zh_TW/editor.md b/src/assets/deepin-editor/editor/zh_TW/editor.md new file mode 100644 index 0000000000000000000000000000000000000000..cfa889ae5107711a3401071c8ee26f40ca7079d5 --- /dev/null +++ b/src/assets/deepin-editor/editor/zh_TW/editor.md @@ -0,0 +1,307 @@ +# 文字編輯器|deepin-editor| + +## 概述 + +文字編輯器是一個簡單的文字編輯工具。您可以用它書寫簡單的文字檔案,也可以使用它的進階特性,讓它成為一個程式碼編輯工具,支援程式碼語法突顯。 + +![overview](fig/overview.png) + +## 使用入門 + +### 執行文字編輯器 + +1. 單擊任務欄上的啟動器圖示 ![deepin_launcher](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋,找到文字編輯器圖示![deepin_editor](../common/deepin_editor.svg),單擊執行。 +3. 右鍵單擊![deepin_editor](../common/deepin_editor.svg),您可以: + + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +### 關閉文字編輯器 + +- 在文字編輯器介面,單擊 ![close_icon](../common/close_icon.svg),關閉文字編輯器。 +- 在文字編輯器介面,單擊主選單 ![icon_menu](../common/icon_menu.svg)> **退出**, 關閉文字編輯器。 +- 在Dock上右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),選擇 **全部關閉**, 關閉文字編輯器。 + + +### 查看快捷鍵 + +在文字編輯器介面,使用快捷鍵 **Ctrl + Shift + ?** 打開快捷鍵預覽介面。您也可以在設定介面查看快捷鍵。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理標籤頁 + +- 建立標籤頁/視窗 + + - 單擊標籤頁上的 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **建立新標籤頁** 或使用快捷鍵 **Ctrl + T** 建立一個新的標籤頁。 + - 單擊![icon_menu](../common/icon_menu.svg) > **建立新視窗** 或使用快捷鍵 **Ctrl + N** 建立一個新的視窗。 + +- 調整標籤頁/視窗 + + - 拖曳同一視窗內的標籤頁重新排序。 + - 滾動滑鼠切換同一視窗內的標籤頁。 + - 移出標籤頁建立一個新的視窗,或者從一個視窗移到另外一個視窗中。 + +- 關閉標籤頁/視窗 + + 當視窗中僅有一個標籤頁時,關閉標籤頁的同時也會關閉視窗。 + + - 使用 快捷鍵**Ctrl + W** 關閉目前標籤頁。 + - 單擊標籤頁上的 ![close_icon](../common/close_icon.svg) 按鈕或者單擊滑鼠中鍵,關閉目前標籤頁。 + - 右鍵單擊標籤頁,選擇 **關閉標籤頁** 、**關閉其他標籤頁** 或 **更多關閉方式** 來關閉標籤頁。 + + > ![notes](../common/notes.svg)說明:如果您的檔案發生了變化而沒有儲存,文字編輯器會在關閉前提示您儲存更改。 + +### 開啟檔案 + +您可採用以下方式開啟一個或同時開啟多個文字檔案,選中的檔案將會在新標籤頁開啟: + +- 直接拖動檔案到文字編輯器介面或其圖示上。 +- 右鍵單擊檔案,選擇 **用其他程式開啟** > **文字編輯器**。選擇文字編輯器為預設開啟程式後,可直接雙擊檔案開啟。 +- 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **開啟檔案** 或使用快捷鍵 **Ctrl + O**,在彈出的視窗中選擇檔案。 + +### 儲存檔案 +- 單擊 ![icon_menu](../common/icon_menu.svg)> **儲存** 或使用快捷鍵 **Ctrl + S** ,儲存目前檔案。 +- 單擊 ![icon_menu](../common/icon_menu.svg)> **另存新檔** 或使用快捷鍵 **Ctrl + Shift + S**, 另存目前檔案。 + + +### 列印檔案 + +在文字編輯器中使用列印,需要您連接並配置好印表機。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **列印** 或使用快捷鍵 **Ctrl + P** 打開列印預覽。 +2. 在列印預覽介面,您可以預覽檔案,選擇印表機並設定列印頁面。 +3. 在列印預覽介面,單擊 **進階設定**,可配置紙張大小、列印方式等相關參數。 +4. 單擊 **列印** 即可將檔案發送到印表機列印。 + +![print](fig/print_setting.png) + +![print](fig/advanced_setting.png) + +## 編輯文字 + +### 移動游標 + +除了使用方向鍵和滑鼠單擊移動游標,您還可以使用以下快捷鍵迅速移動游標: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 儲存游標位置 | Ctrl + Shift + > | +| 重設游標位置(跳轉到上次游標儲存的位置) | Ctrl + Shift + < | +| 後一個字詞 (游標向右跳過一個字詞) | Ctrl + 右方向鍵 | +| 前一個字詞 (游標向左跳過一個字詞) | Ctrl + 左方向鍵 | +| 移動到行結尾 | End | +| 移動到行開頭 | Home | +| 移動到文字結尾 | Ctrl + End | +| 移動到文字開頭 | Ctrl + Home | +| 移到行縮排區塊 | Ctrl + M | +| 往後一對 (游標移動到右括號的後面) | Alt + P | +| 往前一對(游標移動到左括號的前面) | Alt + N | + +### 切換大小寫 + +切換大小寫功能可以將選中文字全部改為大寫字母、小寫字母或者首字母大寫。 + +1. 選中待更改的文字內容。 +2. 單擊右鍵,選擇 **變更大小寫**。 +3. 選擇 **大寫**/**小寫**/**首字母大寫** 選項。文字格式的更改會立即生效。 + +您也可以使用快捷鍵 **Alt + U/L/C** 迅速切換大小寫。 + +![toggle_case](fig/d_toggle_case.png) + +### 突顯文字 + +文字編輯器支援突顯不同類型的文字。單擊底部狀態欄最右側的三角符號, 選擇某種文字類型。若文字中有相應內容則會自動突顯。 + +![highlight](fig/highlight.png) + +### 刪除文字 +除了向左或向右逐個刪除字元外,您還可以使用以下快捷鍵迅速刪除字元: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 刪除至行結尾所有字元 | Ctrl + K | +| 刪除目前整行 | Ctrl + Shift + K | +| 刪除前一個字詞 | Alt + Shift + N | +| 刪除後一個字詞 | Alt + Shift + M | + +### 復原操作 + +如果在文字編輯時發生誤操作,您可以使用快捷鍵 **Ctrl + Z** 撤銷操作, 或者在右鍵選單中選擇 **復原**。 + +### 尋找文字 + +1. 單擊 ![menu](../common/icon_menu.svg)> **尋找** 或使用快捷鍵 **Ctrl + F** ,打開尋找視窗。 +2. 在尋找視窗中,輸入要搜尋的文字。 +3. 單擊 **上一個**、**下一個** 逐個尋找,或使用 **Enter** 鍵尋找下一個匹配項。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉尋找視窗。 + +> ![tips](../common/tips.svg)竅門:選中一段文字,再選擇尋找,則這段文字會自動出現在尋找視窗中。 + +### 取代文字 +1. 單擊 ![menu](../common/icon_menu.svg)> **取代** 或使用快捷鍵 **Ctrl + H**,打開取代視窗。 +2. 在取代為視窗中,輸入要取代的文字以及新文字。 +3. 單擊 **取代** 逐個取代,單擊 **取代剩餘部份**、**全部取代** 一次性取代剩餘的或所有的匹配文字。單擊 **跳過** 不取代目前匹配的文字。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉取代視窗。 + +### 前往該行 +使用該功能可以迅速前往到任一行。在右鍵選單中選擇 **前往該行** 或者使用快捷键 **Ctrl + G**,輸入行號即可前往到相應行。 + +### 編輯行 + +您可以使用以下快捷鍵迅速編輯行: + +| 功能 | 快捷鍵 | +| ------------ | ------------ | +| 於上方換行(在上方插入一行) | Ctrl + Enter | +| 於下方換行(在下方插入一行) | Ctrl + Shift + Enter | +| 複製一行 | Ctrl + Shift + D | +| 切到上一行(與上一行交換位置) | Ctrl + Shift + Up | +| 切到下一行(與下一行交換位置) | Ctrl + Shift + Down | +| 捲到上一行 | Super + Shift + Up | +| 捲到下一行 | Super + Shift + Down | +| 標記 | Alt + H | +| 取消標記 | Alt + Shift + H | +| 複製一行 | Super + C | +| 剪下一行 | Super + X | +| 合併一行 | Ctrl + J | + +### 開啟/關閉唯讀模式 + +1. 使用文字編輯器打開檔案,單擊右鍵,選擇 **開啟唯讀模式**。 +2. 在唯讀模式下,單擊右鍵,選擇 **關閉唯讀模式**。 + +![read_only](fig/d_read_only.png) + +![read_only](fig/d_read_only_02.png) + + +### 列编辑 +在文字編輯器介面,按住鍵盤上的 **Alt** 鍵不放,滑鼠左鍵單擊多列啟動列編輯模式,為多行程式碼同時編輯相同的內容,提高工作效率。 + +![column mode](fig/column mode.png) + +### 顏色標記 + +在文字編輯器介面,單擊滑鼠右鍵選擇 **顏色標記**,在其下拉選單中進行選擇。 + +![color](fig/d_color_tag.png) + + - **標記**:對某一行或某一段文字內容添加顏色標記;有8種顏色按鈕可供選擇。 + + 將游標定在某一行,標記目前所在的行。 + + 選中一段文字內容後,標記選中的文字內容。 + - **標記所有**:將文字內容全部標記或對已選中的文字內容,在全文中標記匹配項;有8種顏色按鈕可供選擇。 + + 將游標定在任意一行,將文字內容全部標記。 + + 選中一段文字內容,在全文中標記匹配項。 + - **清除上次標記**:清除上次標記操作。 + - **清除所有標記**:清除目前所有標記。 + + + +### 書籤管理 + +在文字編輯器設定介面,勾選 **顯示書籤圖標** 後,您可以為任意一行的文字內容添加書籤,將滑鼠遊標移至左側欄任意一行處會顯示 ![icon](../common/bookmark_normal_light.svg),添加成功後該行的書籤圖示會變為藍色填充的圖示 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加書籤 + + + 滑鼠左鍵單擊 ![icon](../common/bookmark_normal_light.svg),為該行添加書籤。 + + 滑鼠右鍵單擊 ![icon](../common/bookmark_normal_light.svg),選擇 **添加書籤**,為該行添加書籤。 + + 將游標定在文字中任意一行,使用快捷鍵 **Ctrl + F2** 為該行添加書籤。 + +- 刪除書籤 + + + 滑鼠左鍵單擊已填充顏色的書籤圖示,直接刪除該行書籤。 + + 滑鼠右鍵單擊已填充顏色的書籤圖示,選擇 **清除書籤**,刪除該行書籤。 + + 滑鼠右鍵單擊書籤圖示,選擇 **清除所有書籤**,刪除該文字的全部書籤。 + + >![icon](../common/notes.svg)說明:滑鼠移到左側行號前面才會顯示書籤圖示,移出書籤區域,書籤圖示消失。添加書籤後,該圖示一直顯示。 + + + +### 注釋管理 + +在文字編輯器介面,您可以對副檔名為cpp 、java 、py等程式碼類型的檔案進行添加注釋的操作。 + +- 添加注釋 + + 選中一段文字內容,單擊右鍵並選擇 **添加注釋**。 + + 選中一段文字內容,使用快捷鍵 **Alt + A** 添加注釋。 + +- 取消注釋 + + 選中一段已添加注釋的文字內容,單擊右鍵並選擇 **取消注釋**。 + + 選中一段已添加注釋的文字內容,使用快捷鍵 **Alt + Z** 取消注釋。 + + >![notes](../common/notes.svg)說明:支援不同程式碼語言的注釋,具體以實際為主。例如C,C#,Java注釋符號為 //,Python 注釋符號為 #。 + + + +## 主選單 + +在主選單中,您可以 建立新視窗、建立新標籤頁、[尋找文字](#尋找文字)、[取代文字](#取代文字)、儲存檔案、切換視窗主題、查看說明手冊,了解文字編輯器的更多訊息。 + +### 設定 +您可以對基本訊息、快捷鍵和進階訊息進行設定。 + +#### 基本設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**。 +2. 在基本設定選項,您可以選擇: + - 設定字體樣式,選擇字體和字體大小。 + - 勾選 **文字換行**,在編輯區自動換行。 + - 勾選 **顯示代碼摺疊標誌**,在左側欄顯示![next](../common/next.svg)或者![next](../common/next_down.svg)按鈕,右鍵單擊按鈕選擇摺疊/展開目前層次或所有層次。 + - 勾選 **顯示行號**,在左側欄顯示行號。 + - 勾選**當前行高亮**,游標所在的行突顯顯示。 + - 勾選 **顯示書籤圖示**,在左側欄顯示書籤圖示。 + - 勾選 **顯示空白制符/制表符**,顯示文字中的空白字符和制表符,您也可以手動輸入或刪除空白字符和制表符。 + > ![tips](../common/tips.svg)竅門:您還可以使用 **Ctrl + 「+」/ 「-」** 來調節文字編輯器的預設字號。使用 **Ctrl + 0** 復原預設字號。 + + + +#### 快捷鍵設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**,在 **快捷鍵** 選項查看目前快捷鍵。 +2. 選擇一種按鍵映射。 +3. 單擊並重新輸入快捷鍵,可以自訂快捷鍵。 + + > ![notes](../common/notes.svg)說明: 按鍵映射允許您選擇某一種鍵盤快捷鍵。您可以使用標準快捷鍵、Emacs快捷鍵、或自訂快捷鍵,以符合您的使用習慣。 + + +#### 進階設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**。 +2. 在 **進階設定** 選項,您可以設定: + - 視窗大小:一般、最大或全螢幕。 + - Tab寬度:Tab縮排所占用的空間大小。 + + + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在文字編輯器介面,單擊![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題顏色。 + +### 說明 + +查看說明手冊,進一步了解和使用文字編輯器。 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看文字編輯器的說明手冊。 + +### 關於 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看文字編輯器的版本和介紹。 + +### 退出 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **退出**。 + diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/advanced_setting.png b/src/assets/deepin-editor/editor/zh_TW/fig/advanced_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..7ecf14a7f1162b7c2ad15102f66f03ed97d62263 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/advanced_setting.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/close.png b/src/assets/deepin-editor/editor/zh_TW/fig/close.png new file mode 100644 index 0000000000000000000000000000000000000000..eb5704b81bca1efccd06786eb2a324c63b3edcf0 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/close.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/color_tag.png b/src/assets/deepin-editor/editor/zh_TW/fig/color_tag.png new file mode 100644 index 0000000000000000000000000000000000000000..31ebc41567d152199195fbc33b07d52a60b55df5 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/color_tag.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/column mode.png b/src/assets/deepin-editor/editor/zh_TW/fig/column mode.png new file mode 100644 index 0000000000000000000000000000000000000000..efeb5f854f7f16c90b298e3473dd4a9724c4a1cd Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/column mode.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/d_color_tag.png b/src/assets/deepin-editor/editor/zh_TW/fig/d_color_tag.png new file mode 100644 index 0000000000000000000000000000000000000000..a5923c736852e1e1e59160a5b733a6d579c0c247 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/d_color_tag.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/d_read-only_02.png b/src/assets/deepin-editor/editor/zh_TW/fig/d_read-only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..db0fa12522ccc61290002dae7a524cd5a0727d19 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/d_read-only_02.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/d_read_only.png b/src/assets/deepin-editor/editor/zh_TW/fig/d_read_only.png new file mode 100644 index 0000000000000000000000000000000000000000..af2fcf4fa489ca5e4b178973601efe48467c4f95 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/d_read_only.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/d_read_only_02.png b/src/assets/deepin-editor/editor/zh_TW/fig/d_read_only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..022dba9fb5956aef8851d907e6270673c3736413 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/d_read_only_02.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/d_toggle_case.png b/src/assets/deepin-editor/editor/zh_TW/fig/d_toggle_case.png new file mode 100644 index 0000000000000000000000000000000000000000..be9bdc902c80095e57d5c4dc0b50eb94a6bd8159 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/d_toggle_case.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/editer.psd b/src/assets/deepin-editor/editor/zh_TW/fig/editer.psd new file mode 100644 index 0000000000000000000000000000000000000000..d68083edaf82a349425c63540ac895a3dfa4bb5b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/editer.psd differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/highlight.png b/src/assets/deepin-editor/editor/zh_TW/fig/highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..f16308bd678e8650e3701ed9a994a8e7202c9072 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/highlight.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/hotkey.png b/src/assets/deepin-editor/editor/zh_TW/fig/hotkey.png new file mode 100644 index 0000000000000000000000000000000000000000..e3225d97e31be3827dc2b4bb222b097e61493c94 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/hotkey.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/listen.png b/src/assets/deepin-editor/editor/zh_TW/fig/listen.png new file mode 100644 index 0000000000000000000000000000000000000000..d397f90eaad0909f49535c74cb5cb58d949b2f2b Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/listen.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/overview.png b/src/assets/deepin-editor/editor/zh_TW/fig/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..764cf82fcfce532c908bb8f38df53f6013bdab41 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/overview.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/print_setting.png b/src/assets/deepin-editor/editor/zh_TW/fig/print_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..9d08dc8e9097beb003a7f5b9d5d13cb2e54c103a Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/print_setting.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/read_only.png b/src/assets/deepin-editor/editor/zh_TW/fig/read_only.png new file mode 100644 index 0000000000000000000000000000000000000000..96658be2ad45d728b8780d9ec4658b72bd56dd86 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/read_only.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/read_only_02.png b/src/assets/deepin-editor/editor/zh_TW/fig/read_only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..a5f735b475e7c695f9c56c426a82616eb25c0525 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/read_only_02.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/reading.png b/src/assets/deepin-editor/editor/zh_TW/fig/reading.png new file mode 100644 index 0000000000000000000000000000000000000000..7fe6846cd99c737fe62a3b29e48e76576f170b4e Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/reading.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/text translation.png b/src/assets/deepin-editor/editor/zh_TW/fig/text translation.png new file mode 100644 index 0000000000000000000000000000000000000000..f76230034be4aecffeed0ee1c6129efd60590c47 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/text translation.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/fig/toggle_case.png b/src/assets/deepin-editor/editor/zh_TW/fig/toggle_case.png new file mode 100644 index 0000000000000000000000000000000000000000..32351990a6966c71870ccfadedfcca381f573b75 Binary files /dev/null and b/src/assets/deepin-editor/editor/zh_TW/fig/toggle_case.png differ diff --git a/src/assets/deepin-editor/editor/zh_TW/p_editor.md b/src/assets/deepin-editor/editor/zh_TW/p_editor.md new file mode 100644 index 0000000000000000000000000000000000000000..615b5138145d800070a47c25dfec04933cf82d9f --- /dev/null +++ b/src/assets/deepin-editor/editor/zh_TW/p_editor.md @@ -0,0 +1,326 @@ +# 文字編輯器|deepin-editor| + +## 概述 + +文字編輯器是一個簡單的文字編輯工具。您可以用它書寫簡單的文字檔案,也可以使用它的進階特性,讓它成為一個程式碼編輯工具,支援程式碼語法突顯。 + +![overview](fig/overview.png) + +## 使用入門 + +### 執行文字編輯器 + +1. 單擊任務欄上的啟動器圖示 ![deepin_launcher](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋,找到文字編輯器圖示 ![deepin_editor](../common/deepin_editor.svg)并打開。 +3. 在啟動器中,右鍵單擊![deepin_editor](../common/deepin_editor.svg),您可以: + + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +### 關閉文字編輯器 + +- 在文字編輯器介面,單擊 ![close_icon](../common/close_icon.svg),關閉文字編輯器。 +- 在文字編輯器介面,單擊主選單 ![icon_menu](../common/icon_menu.svg)> **退出**, 關閉文字編輯器。 +- 在Dock上右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),選擇 **全部關閉**, 關閉文字編輯器。 + + +### 查看快捷鍵 + +在文字編輯器介面上,使用快捷鍵 **Ctrl + Shift + ?** 打開快捷鍵預覽介面。您也可以在設定介面查看快捷鍵。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理標籤頁 + +- 建立標籤頁/視窗 + + - 單擊標籤頁上的 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **建立新標籤頁** 或使用組合鍵 **Ctrl + T** 建立一個新的標籤頁。 + - 單擊![icon_menu](../common/icon_menu.svg) > **建立新視窗** 或使用組合鍵 **Ctrl + N** 建立一個新的視窗。 + +- 調整標籤頁/視窗 + + - 拖曳同一視窗內的標籤頁重新排序。 + - 滾動滑鼠切換同一視窗內的標籤頁。 + - 移出標籤頁建立一個新的視窗,或者從一個視窗移到另外一個視窗中。 + +- 關閉標籤頁/視窗 + + 當視窗中僅有一個標籤頁時,關閉標籤頁的同時也會關閉視窗。 + + - 使用快捷鍵 **Ctrl + W** 關閉目前標籤頁。 + - 單擊標籤頁上的 ![close_icon](../common/close_icon.svg) 按鈕或者單擊滑鼠中鍵,關閉目前標籤頁。 + - 右鍵單擊標籤頁,選擇 **關閉標籤頁** 、**關閉其他標籤頁** 或 **更多關閉方式** 關閉標籤頁。 + + > ![notes](../common/notes.svg)說明:如果您的檔案發生了變化而沒有儲存,文字編輯器會在關閉前提示您儲存更改。 + +### 開啟檔案 + +您可採用以下方式開啟一個或同時開啟多個文字檔案,選中的檔案將會在新標籤頁開啟: + +- 直接拖動檔案到文字編輯器介面或其圖示上。 +- 右鍵單擊檔案,選擇 **用其他程式開啟** > **文字編輯器**。選擇文字編輯器為預設開啟程式後,可直接雙擊檔案開啟。 +- 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **開啟檔案** 或使用快捷鍵 **Ctrl + O**,在彈出的視窗中選擇檔案。 + +### 儲存檔案 +- 單擊 ![icon_menu](../common/icon_menu.svg)> **儲存**或使用快捷鍵 **Ctrl + S**,儲存目前檔案。 +- 單擊 ![icon_menu](../common/icon_menu.svg)> **另存新檔** 或 使用快捷鍵**Ctrl + Shift + S**, 另存目前檔案。 + + +### 列印檔案 + +在文字編輯器中使用列印,需要您連接並配置好印表機。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **列印**,也可以使用快捷鍵 **Ctrl + P** 打開列印預覽。 +2. 在列印預覽介面,您可以預覽檔案,選擇印表機並設定列印頁面。 +3. 在列印預覽介面,單擊 **進階設定**,可配置紙張大小、列印方式等相關參數。 +4. 單擊 **列印** 即可將檔案發送到印表機列印。 + +![print](fig/print_setting.png) + +![print](fig/advanced_setting.png) + +## 編輯文字 + +### 移動游標 + +除使用方向鍵和滑鼠單擊移動游標,您還可以使用以下快捷鍵迅速移動游標: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 儲存游標位置 | Ctrl + Shift + > | +| 重設游標位置(跳轉到上次游標儲存的位置) | Ctrl + Shift + < | +| 後一個字詞 (游標向右跳過一個字詞) | Ctrl + 右方向鍵 | +| 前一個字詞 (游標向左跳過一個字詞) | Ctrl + 左方向鍵 | +| 移動到行結尾 | End | +| 移動到行開頭 | Home | +| 移動到文字結尾 | Ctrl + End | +| 移動到文字開頭 | Ctrl + Home | +| 移到行縮排區塊 | Ctrl + M | +| 往後一對 (游標移動到右括號的後面) | Alt + P | +| 往前一對(游標移動到左括號的前面) | Alt + N | + +### 切換大小寫 + +切換大小寫功能可以將選中文字全部改為大寫字母、小寫字母或者首字母大寫。 + +1. 選中待更改的文字內容。 +2. 單擊右鍵,選擇 **變更大小寫**。 +3. 選擇 **大寫**/**小寫**/**首字母大寫** 選項。文字格式的更改會立即生效。 + +您也可以使用快捷鍵 **Alt + U/L/C** 迅速切換大小寫。 + +![toggle_case](fig/toggle_case.png) + +### 突顯文字 + +文字編輯器支援突顯不同類型的文字。單擊底部狀態欄最右側的三角符號, 選擇某種文字類型。若文字中有相應內容則會自動突顯。 + +![highlight](fig/highlight.png) + +### 刪除文字 +除了向左或向右逐個刪除字元外,您還可以使用以下快捷鍵迅速刪除字元: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 刪除至行結尾所有字元 | Ctrl + K | +| 刪除目前整行 | Ctrl + Shift + K | +| 刪除前一個字詞 | Alt + Shift + N | +| 刪除後一個字詞 | Alt + Shift + M | + +### 復原操作 + +如果在文字編輯時發生誤操作,您可以使用快捷鍵 **Ctrl + Z** 撤銷操作, 或者在右鍵選單中選擇 **復原**。 + +### 尋找文字 + +1. 單擊 ![menu](../common/icon_menu.svg)> **尋找** 或使用組合鍵 **Ctrl + F**,打開尋找視窗。 +2. 在尋找視窗中,輸入要搜尋的文字。 +3. 單擊 **上一個**、**下一個** 逐個尋找,或使用 **Enter** 鍵尋找下一個匹配項。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉尋找視窗。 + +> ![tips](../common/tips.svg)竅門:選中一段文字,再進行搜尋,則這段文字會自動出現在尋找視窗中。 + +### 取代文字 +1. 單擊 ![menu](../common/icon_menu.svg)> **取代** 或使用組合鍵 **Ctrl + H**,打開取代視窗。 +2. 在取代視窗中,輸入要取代的文字以及新文字。 +3. 單擊 **取代** 逐個取代,單擊 **取代剩餘部份**、**全部取代** 一次性取代剩餘的或所有的匹配文字。單擊 **跳過** 不取代目前匹配的文字。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉取代視窗。 + +### 前往該行 +使用該功能可以迅速前往到任一行。在右鍵選單中選擇 **前往該行** 或者使用组合键 **Ctrl + G**,輸入行號即可前往到相應行。 + +### 編輯行 + +您可以使用以下快捷鍵迅速編輯行: + +| 功能 | 快捷鍵 | +| ------------ | ------------ | +| 於上方換行(在上方插入一行) | Ctrl + Enter | +| 於下方換行(在下方插入一行) | Ctrl + Shift + Enter | +| 複製一行 | Ctrl + Shift + D | +| 切到上一行(與上一行交換位置) | Ctrl + Shift + Up | +| 切到下一行(與下一行交換位置) | Ctrl + Shift + Down | +| 捲到上一行 | Super + Shift + Up | +| 捲到下一行 | Super + Shift + Down | +| 標記 | Alt + H | +| 取消標記 | Alt + Shift + H | +| 複製一行 | Super + C | +| 剪下一行 | Super + X | +| 合併一行 | Ctrl + J | + +### 開啟/關閉唯讀模式 + +1. 使用文字編輯器打開檔案,單擊右鍵,選擇 **開啟唯讀模式**。 +2. 在唯讀模式下,單擊右鍵,選擇 **關閉唯讀模式**。 + +![read_only](fig/read_only.png) + +![read_only](fig/read_only_02.png) + +### 語音朗讀 + +在「控制中心」>「輔助功能」中開啟語音朗讀、語音聽寫功能後,可以執行如下操作。 + +1. 單擊右鍵,選擇 **語音聽寫**,使用者透過麥克風語音輸入後,轉譯文字將被編輯在檔案中。 +2. 選擇一段文字後,單擊右鍵,選擇 **語音朗讀**,語音播報選中的文字。 + + > ![notes](../common/notes.svg)說明:當未選擇文字時,右鍵選單中 **語音朗讀** 不可啟動,處置灰狀態。 + + +![read_only](fig/reading.png) + +### 文字翻譯 + +在「控制中心」>「輔助功能」中開啟文字翻譯並選擇語言後,可以執行如下操作。 + +1. 在文字編輯器介面選擇一段文字後,單擊右鍵,選擇 **文字翻譯**,可將該段文字內容翻譯成目標語言。 + +![text](fig/text translation.png) + + +### 列编辑 +在文字編輯器介面,按住鍵盤上的 **Alt** 鍵不放,滑鼠左鍵單擊多列啟動列編輯模式,為多行程式碼同時編輯相同的內容,提高工作效率。 + +![column mode](fig/column mode.png) + +### 顏色標記 + +在文字編輯器介面,滑鼠右鍵選擇 **顏色標記**,在其下拉選單中進行選擇。 + +![color](fig/color_tag.png) + + - **添加標記**:對某一行或某一段文字內容添加顏色標記;有8種顏色按鈕可供選擇。 + + 將游標定在某一行,標記目前所在的行。 + + 選中一段文字內容後,標記選中的文字內容。 + - **標記所有**:將文字內容全部標記或對已選中的文字內容,在全文中標記匹配項;有8種顏色按鈕可供選擇。 + + 將游標定在任意一行,將文字內容全部標記。 + + 選中一段文字內容,在全文中標記匹配項。 + - **清除上次標記**:清除上次標記操作。 + - **清除所有標記**:清除目前所有標記。 + + + +### 書籤管理 + +在文字編輯器設定介面,勾選 **顯示書籤圖標** 後,您可以為任意一行的文字內容添加書籤,將滑鼠遊標移至左側欄任意一行處會顯示 ![icon](../common/bookmark_normal_light.svg),添加成功後該行的書籤圖示會變為藍色填充的圖示 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加書籤 + + + 滑鼠左鍵單擊 ![icon](../common/bookmark_normal_light.svg),為該行添加書籤。 + + 滑鼠右鍵單擊 ![icon](../common/bookmark_normal_light.svg),選擇 **添加書籤**,為該行添加一個書籤。 + + 將游標定在文字中任意一行,使用組合鍵 **Ctrl + F2** 為該行添加一個書籤。 + +- 刪除書籤 + + + 滑鼠左鍵單擊已填充顏色的書籤圖示,直接刪除該行書籤。 + + 滑鼠右鍵單擊已填充顏色的書籤圖示,選擇 **清除書籤**,刪除該行書籤。 + + 滑鼠右鍵單擊書籤圖示,選擇 **清除所有書籤**,刪除該文字的全部書籤。 + + >![icon](../common/notes.svg)說明:滑鼠移到左側行號前面才會顯示書籤圖示,移出書籤區域,書籤圖示消失。添加書籤後,該圖示一直顯示。 + + + +### 注釋管理 + +在文字編輯器介面,您可對副檔名為cpp 、java 、py等程式碼類型的檔案進行添加注釋的操作。 + +- 添加注釋 + + 選中一段文字內容,在右鍵選單選擇 **添加注釋**。 + + 選中一段文字內容,使用組合鍵 **Alt + A** 添加注釋。 + +- 取消注釋 + + 選中一段已添加注釋的文字內容,在右鍵選單中選擇 **取消注釋**。 + + 選中一段已添加注釋的文字內容,使用組合鍵 **Alt + Z** 取消注釋。 + + >![notes](../common/notes.svg)說明:支援不同程式碼語言的注釋,具體以實際為主。例如C,C#,Java注釋符號為 //,Python 注釋符號為 #。 + + + +## 主選單 + +在主選單中,您可以 建立新視窗、建立新標籤頁、[尋找文字](#尋找文字)、[取代文字](#取代文字)、儲存檔案、切換視窗主題、查看說明手冊,了解文字編輯器的更多訊息。 + +### 設定 +您可以對基本訊息、快捷鍵和進階訊息進行設定。 + +#### 基本設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**。 +2. 在基本設定選項,您可以選擇: + - 設定字體樣式,選擇字體樣式和字體大小。 + - 勾選 **文字換行**,在編輯區自動換行。 + - 勾選 **顯示代碼摺疊標誌**,在左側欄顯示![next](../common/next.svg)或者![next](../common/next_down.svg)按鈕,右鍵單擊按鈕選擇摺疊/展開目前層次或所有層次。 + - 勾選 **顯示行號**,在左側欄顯示行號。 + - 勾選**當前行高亮**,游標所在的行突顯顯示。 + - 勾選 **顯示書籤圖標**,在左側欄顯示書籤圖標。 + - 勾選 **顯示空白制符/制表符**,顯示文字中的空白字符和制表符,您也可手動輸入或刪除空白字符和制表符。 + > ![tips](../common/tips.svg)竅門:您還可以使用 **Ctrl + 「+」/ 「-」** 調節文字編輯器的預設字號。使用 **Ctrl + 0** 復原預設字號。 + + + +#### 快捷鍵設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**,在 **快捷鍵** 選項查看目前快捷鍵。 +2. 選擇一種按鍵映射。 +3. 單擊並重新輸入快捷鍵,可以自訂快捷鍵。 + + > ![notes](../common/notes.svg)說明: 按鍵映射允許您選擇某一種鍵盤快捷鍵。您可以使用標準快捷鍵、Emacs快捷鍵、或自訂快捷鍵,以符合您的使用習慣。 + + +#### 進階設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**。 +2. 在 **進階設定** 選項,您可以設定: + - 視窗大小:一般、最大或全螢幕。 + - Tab寬度:Tab縮排所占用的空間大小。 + + + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在文字編輯器介面,單擊![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題顏色。 + +### 說明 + +查看說明手冊,進一步了解和使用文字編輯器。 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看文字編輯器的說明手冊。 + +### 關於 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看文字編輯器的版本和介紹。 + +### 退出 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **退出**。 \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/+.svg b/src/assets/loongarch64/deepin-editor/editor/common/+.svg new file mode 100755 index 0000000000000000000000000000000000000000..886d90a83e33497d134bdb3dcc864a5c2df53f20 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/+.svg @@ -0,0 +1,13 @@ + + + + + + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/-.svg b/src/assets/loongarch64/deepin-editor/editor/common/-.svg new file mode 100755 index 0000000000000000000000000000000000000000..594bc2ea751b91367ea2f591570a8dd11665af0d --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/-.svg @@ -0,0 +1,13 @@ + + + + - + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/0.svg b/src/assets/loongarch64/deepin-editor/editor/common/0.svg new file mode 100755 index 0000000000000000000000000000000000000000..aa142654920e12798821847ee94c8befaaf646bc --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/0.svg @@ -0,0 +1,12 @@ + + + + 0 + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/A.svg b/src/assets/loongarch64/deepin-editor/editor/common/A.svg new file mode 100755 index 0000000000000000000000000000000000000000..909d1da3e635a9773456570aa8e60dde4594b21c --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/A.svg @@ -0,0 +1,13 @@ + + + + A + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/Alt.svg b/src/assets/loongarch64/deepin-editor/editor/common/Alt.svg new file mode 100755 index 0000000000000000000000000000000000000000..5903a36f213ff9139f202fd40d321eeccc49775c --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/Alt.svg @@ -0,0 +1,15 @@ + + + + Alt + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/C.svg b/src/assets/loongarch64/deepin-editor/editor/common/C.svg new file mode 100755 index 0000000000000000000000000000000000000000..c1540bf04cc6cbcbc2fa3a932986b24f5277a97a --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/C.svg @@ -0,0 +1,13 @@ + + + + C + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/Ctrl.svg b/src/assets/loongarch64/deepin-editor/editor/common/Ctrl.svg new file mode 100755 index 0000000000000000000000000000000000000000..a2bb6738b2825beac7f2239a80b084919d82a780 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/Ctrl.svg @@ -0,0 +1,16 @@ + + + + Ctrl + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/Enter.svg b/src/assets/loongarch64/deepin-editor/editor/common/Enter.svg new file mode 100755 index 0000000000000000000000000000000000000000..1994b268ad19ddbc1bca8156aaea6fdb2734e9bf --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/Enter.svg @@ -0,0 +1,17 @@ + + + + Enter + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/Esc.svg b/src/assets/loongarch64/deepin-editor/editor/common/Esc.svg new file mode 100755 index 0000000000000000000000000000000000000000..ad8e4937c4a44195ae96a61aaef035250262b3d7 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/Esc.svg @@ -0,0 +1,15 @@ + + + + Esc + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/F.svg b/src/assets/loongarch64/deepin-editor/editor/common/F.svg new file mode 100755 index 0000000000000000000000000000000000000000..781b440c8e5893a922ca485c468fe39a007d5b5b --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/F.svg @@ -0,0 +1,13 @@ + + + + F + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/F2.svg b/src/assets/loongarch64/deepin-editor/editor/common/F2.svg new file mode 100755 index 0000000000000000000000000000000000000000..051adae452a5fd25d55b6df9ec3d34fb99589788 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/F2.svg @@ -0,0 +1,14 @@ + + + + F2 + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/G.svg b/src/assets/loongarch64/deepin-editor/editor/common/G.svg new file mode 100755 index 0000000000000000000000000000000000000000..b57ed109bda0d42386f01c481e160fc0cd2f9083 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/G.svg @@ -0,0 +1,13 @@ + + + + G + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/H.svg b/src/assets/loongarch64/deepin-editor/editor/common/H.svg new file mode 100755 index 0000000000000000000000000000000000000000..9542c98f0ce653729556a204e2a93a7c9f10f951 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/H.svg @@ -0,0 +1,13 @@ + + + + H + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/L.svg b/src/assets/loongarch64/deepin-editor/editor/common/L.svg new file mode 100755 index 0000000000000000000000000000000000000000..bb0619d791ff2629b925023301668a356b6be906 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/L.svg @@ -0,0 +1,13 @@ + + + + L + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/N.svg b/src/assets/loongarch64/deepin-editor/editor/common/N.svg new file mode 100755 index 0000000000000000000000000000000000000000..b7033ae0f1c987ed23028f806a287b47aa8d3383 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/N.svg @@ -0,0 +1,13 @@ + + + + N + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/O.svg b/src/assets/loongarch64/deepin-editor/editor/common/O.svg new file mode 100755 index 0000000000000000000000000000000000000000..db272edec6ee99dbc68e8dc03d70ee82d41f6b5d --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/O.svg @@ -0,0 +1,13 @@ + + + + O + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/P.svg b/src/assets/loongarch64/deepin-editor/editor/common/P.svg new file mode 100755 index 0000000000000000000000000000000000000000..8b549241262a344de3ff84b7b27f7998fc1c1fd3 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/P.svg @@ -0,0 +1,13 @@ + + + + P + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/QM.svg b/src/assets/loongarch64/deepin-editor/editor/common/QM.svg new file mode 100755 index 0000000000000000000000000000000000000000..8b2af9aa6298185307895e429aaf6b4fffe6c57f --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/QM.svg @@ -0,0 +1,13 @@ + + + + QM + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/S.svg b/src/assets/loongarch64/deepin-editor/editor/common/S.svg new file mode 100755 index 0000000000000000000000000000000000000000..8272a7858f352ed776a1a62eb4f74ebdf2bf82bd --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/S.svg @@ -0,0 +1,13 @@ + + + + S + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/Shift.svg b/src/assets/loongarch64/deepin-editor/editor/common/Shift.svg new file mode 100755 index 0000000000000000000000000000000000000000..cdc7ce5f0034473065cbd73a45c316e180d3b2c0 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/Shift.svg @@ -0,0 +1,18 @@ + + + + Shift + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/T.svg b/src/assets/loongarch64/deepin-editor/editor/common/T.svg new file mode 100755 index 0000000000000000000000000000000000000000..9bc555095472c66c1e811da3899418644a2e79b5 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/T.svg @@ -0,0 +1,13 @@ + + + + T + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/U.svg b/src/assets/loongarch64/deepin-editor/editor/common/U.svg new file mode 100755 index 0000000000000000000000000000000000000000..c6c24af89cb8dd344c3bad3243f5a440c344032b --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/U.svg @@ -0,0 +1,13 @@ + + + + U + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/W.svg b/src/assets/loongarch64/deepin-editor/editor/common/W.svg new file mode 100755 index 0000000000000000000000000000000000000000..cb22b6f4a4ac4b7c6ddf42366ba6e222b33bc9ec --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/W.svg @@ -0,0 +1,13 @@ + + + + W + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/Z.svg b/src/assets/loongarch64/deepin-editor/editor/common/Z.svg new file mode 100755 index 0000000000000000000000000000000000000000..574de2344bd49e866aa3eeb1f71e6a036191fd36 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/Z.svg @@ -0,0 +1,13 @@ + + + + Z + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/attention.svg b/src/assets/loongarch64/deepin-editor/editor/common/attention.svg new file mode 100755 index 0000000000000000000000000000000000000000..23149c05873259cd39721b8ee9c3ab7db86d64c5 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/attention.svg @@ -0,0 +1,9 @@ + + + attention + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/bookmark_normal_light.svg b/src/assets/loongarch64/deepin-editor/editor/common/bookmark_normal_light.svg new file mode 100755 index 0000000000000000000000000000000000000000..6076d18b77121724a2860fd23b7a703718bdf927 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/bookmark_normal_light.svg @@ -0,0 +1,13 @@ + + + + bookmark_normal_light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/bookmarkbig_checked_light.svg b/src/assets/loongarch64/deepin-editor/editor/common/bookmarkbig_checked_light.svg new file mode 100755 index 0000000000000000000000000000000000000000..d00210a172c209246dd1a23ed78e9c4fbba82508 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/bookmarkbig_checked_light.svg @@ -0,0 +1,24 @@ + + + + bookmarkbig_checked_light + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/close_icon.svg b/src/assets/loongarch64/deepin-editor/editor/common/close_icon.svg new file mode 100755 index 0000000000000000000000000000000000000000..9047265ccb0b8c83821e9059d80a56054121b02a --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/close_icon.svg @@ -0,0 +1,15 @@ + + + + Rectangle 9 + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/deepin-editor.svg b/src/assets/loongarch64/deepin-editor/editor/common/deepin-editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..a8e6fb96946f0b97e35383bf77a1f457e93aef4e --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/deepin-editor.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/loongarch64/deepin-editor/editor/common/deepin_editor.svg b/src/assets/loongarch64/deepin-editor/editor/common/deepin_editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..ffb562a44c5c648709f9fa5e3cb1baf677e7200b --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/deepin_editor.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/loongarch64/deepin-editor/editor/common/deepin_launcher.svg b/src/assets/loongarch64/deepin-editor/editor/common/deepin_launcher.svg new file mode 100755 index 0000000000000000000000000000000000000000..5793b3846b7fe6a5758379591215b16c7f9e1b52 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/deepin_launcher.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/loongarch64/deepin-editor/editor/common/icon_menu.svg b/src/assets/loongarch64/deepin-editor/editor/common/icon_menu.svg new file mode 100755 index 0000000000000000000000000000000000000000..35dd6eacc54a933dc9ebc3f3010edfa7363fecc0 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/icon_menu.svg @@ -0,0 +1,84 @@ + + + + + + image/svg+xml + + img_upload + + + + + + img_upload + Created with Sketch. + + + + + + + + + + + + + diff --git a/src/assets/loongarch64/deepin-editor/editor/common/next.svg b/src/assets/loongarch64/deepin-editor/editor/common/next.svg new file mode 100755 index 0000000000000000000000000000000000000000..ba61fc3e5f99464e7dec7b166beb64d40641b0cf --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/next.svg @@ -0,0 +1,11 @@ + + + + next + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/next_down.svg b/src/assets/loongarch64/deepin-editor/editor/common/next_down.svg new file mode 100755 index 0000000000000000000000000000000000000000..95baac3db611107248dc47f19ecf596aca8059aa --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/next_down.svg @@ -0,0 +1,15 @@ + + + + +next +Created with Sketch. + + + + + diff --git a/src/assets/loongarch64/deepin-editor/editor/common/notes.svg b/src/assets/loongarch64/deepin-editor/editor/common/notes.svg new file mode 100755 index 0000000000000000000000000000000000000000..e9a3aa60a51404c9390bfbea8d8ff09edc0e2e32 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/notes.svg @@ -0,0 +1,11 @@ + + + notes + + + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/common/plus_icon.svg b/src/assets/loongarch64/deepin-editor/editor/common/plus_icon.svg new file mode 100755 index 0000000000000000000000000000000000000000..6b69c7bc64ec9640a82bd3aac6a85939760d84df --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/plus_icon.svg @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/assets/loongarch64/deepin-editor/editor/common/tips.svg b/src/assets/loongarch64/deepin-editor/editor/common/tips.svg new file mode 100755 index 0000000000000000000000000000000000000000..011c05f4b8f296867cd408a339230323fcbb28dd --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/common/tips.svg @@ -0,0 +1,9 @@ + + + tips + + + + + + \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/editor.md b/src/assets/loongarch64/deepin-editor/editor/en_US/editor.md new file mode 100644 index 0000000000000000000000000000000000000000..d352e2b72f9dd98ff74fb0c4b785db3212e55b21 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/en_US/editor.md @@ -0,0 +1,299 @@ +# Text Editor|deepin-editor| + +## Overview + +Text Editor is a simple text editing tool. You can use it to write a simple text document, or make it a code editing tool with its advanced features which support code syntax highlighting. + +![overview](fig/overview.png) + +## Guide + +### Run Text Editor + +1. Click the Launcher icon ![deepin_launcher](../common/deepin_launcher.svg) in the Dock to enter the Launcher interface. +2. Locate Text Editor ![deepin_editor](../common/deepin_editor.svg)by scrolling the mouse wheel or searching "text editor" in the Launcher interface and click it to run. +3. In Launcher, right-click Text Editor and you can: + + - Click **Send to desktop** to create a desktop shortcut. + - Click **Send to dock** to fix it in the Dock. + - Click **Add to startup** to add it to startup and it will automatically run when system boots. + +### Exit Text Editor + +- On the Text Editor interface, click ![close](../common/close_icon.svg) to exit. +- On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg) > **Exit** to exit. +- Right-click ![deepin_editor](../common/deepin_editor.svg) in the Dock and select **Close All** to exit. + +### View Shortcuts + +On the Text Editor Interface, press **Ctrl + Shift + ?** to view all the shortcuts. You can also check shortcuts in Settings. Proficiency in shortcuts will greatly improve your efficiency. + +![1|hotkey](fig/hotkey.png) + +## Basic Operations + +### Manage Tabs + +- Create New Tabs/Windows + - Click ![plus_icon](../common/+.svg) or ![icon_menu](../common/icon_menu.svg)> **New tab** on the title bar or press **Ctrl + T** to create a new tab. + - Click ![icon_menu](../common/icon_menu.svg)> **New window** or press **Ctrl + N** to create a new window. + +- Adjust Tabs/Windows + - Drag the tab in the same window to reorder tabs. + - Scroll the mouse wheel on the title of a tab to reorder tabs in the same window. + - Move the tab out of the window to create a new window or move the tab from one window to another. + +- Close Tabs /Windows + + The window will be closed as well when there is only one tab in the window. + + - Press **Ctrl + W** to close the file on the file interface. + - Move the cursor to the file title, and click the ![close](../common/close_icon.svg) icon there or the mouse middle button to close the file. + - Right-click the file title and select **Close tab** or **Close other tabs** or **More options** to close the tabs. + +> ![notes](../common/notes.svg) Notes: If you make changes to the file but does not save it, you will be prompted by Text Editor to save before closing the file. + +### Open Files + +You can open one or multiple text files at one time in the following ways, and the selected file will open in the new tab: + +- Drag the file directly to the Text Editor interface or the Text Editor icon. +- Right-click the file and select **Open with** > **Text Editor**. After selecting Text Editor as the default application for text files in Control Center, you can double-click the file to open it directly. +- On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg)> **Open file**, or use the shortcuts **Ctrl + O** to open the file in File Manager. + +### Save Files + +- Press **Ctrl + S** or click ![icon_menu](../common/icon_menu.svg)> **Save** to save the current document. +- Press **Ctrl + Shift + S** or click ![icon_menu](../common/icon_menu.svg)> **Save as** to save the file as a new one. + +### Print Files + +To print a file in Text Editor, you should connect and set up the printer first. + +1. Click ![icon_menu](../common/icon_menu.svg)> **Print**, or press **Ctrl + P** to open the print preview interface. +2. On the preview interface, preview the document,select a printer and set the printing page. +3. Click the **Advanced** option on the preview interface to select parameters including paper size and layout. +4. Click **Print** to start printing. + +![preview](fig/preview.png) + +![pagesetup](fig/advanced-preview.png) + +## Edit Texts + +### Move Cursor + +In addition to the arrow keys and mouse clicks, you can also use the following shortcuts to move the cursor quickly: + +| Function | Shortcuts | +| --------------- | ------------ | +| Save cursor position | Ctrl + Shift + > | +| Reset cursor position (Jump to cursor last saving position) | Ctrl + Shift + < | +| Forward one word (Jump forward over one word) | Ctrl + Right | +| Backward one word (Jump backward over one word) | Ctrl + Left | +| Move to end of line | End | +| Move to start of line | Home | +| Move to end of text | Ctrl + End | +| Move to start of text | Ctrl + Home | +| Move to line indentation | Ctrl + M | +| Forward over a pair (Jump forward after the right parenthesis) | Alt + P | +| Backward over a pair (Jump backward before the left parenthesis) | Alt + N | + +### Change Cases + +It helps you change the case of selected text. You can change it to lowercase, uppercase, or capitalize the initial. + +1. Select the text. +2. Right-click and select **Change Case**. +3. Choose **Upper Case**, **Lower Case**, or **Capitalize**. The changes will take effect immediately. + +You can also use **Alt** + **U / L / C** to quickly switch the cases. + +![changecase](fig/d_changecase.png) + +### Highlight Texts +Text Editor supports highlighting different kinds of texts. + +Click the triangle symbol at the far right corner of the status bar at the bottom, and select the type of text you want to highlight. The corresponding contents in the text will be highlighted automatically. + +![highlight](fig/highlight.png) + +### Delete Texts + +In addition to deleting characters one by one, you can quickly delete characters by using the following shortcuts: + +| Function | Shortcuts | +| --------------- | ------------ | +| Delete to end of line | Ctrl + K | +| Delete current line | Ctrl + Shift + K | +| Delete one word backward | Alt + Shift + N | +| Delete one word forward | Alt + Shift + M | + +### Undo + +If you make an incorrect operation, press **Ctrl + Z** to undo it, or right-click to select **Undo**. + +### Find Texts + +1. Click ![menu](../common/icon_menu.svg) and select **Find**, or press **Ctrl** + **F** to open the "Find" box below. +2. Input the text you want to find. +3. Click **Previous** /**Next** to find each match, or press the **Enter** key to find the next match. +4. Press the **Esc** key or click the close icon to close the dialog box. + +> ![tips](../common/tips.svg)Tips: Select the text and conduct search. The text selected will be automatically displayed in the **Find** box. + +### Replace Texts +1. Click ![menu](../common/icon_menu.svg), and select **Replace**, or press **Ctrl + H** to open the **Replace** box below. +2. Input the text to be replaced and the new text. +3. Click **Replace** to replace the matches one by one and click **Replace Rest** and **Replace All** to replace the rest or all the matches at once. Click **Skip** to skip the current matching text. +4. Press **Esc** or click the close icon to close the dialog box. + +### Go to Line +Use Go to Line to jump to the specific line directly. +Right-click and select **Go to Line**, or press **Ctrl + G** and then input the line number to go to that line. + +### Edit Line + +Use the shortcuts below to edit lines easily: + +| Function | Shortcuts | +| ------------ | ------------ | +| New line above (Insert one line above) | Ctrl + Enter | +| New line below (Insert one line below) | Ctrl + Shift + Enter | +| Duplicate line | Ctrl + Shift + D | +| Swap line up (Swap the current line with above line) | Ctrl + Shift + Up | +| Swap line down (Swap the current line with below line) | Ctrl + Shift + Down | +| Scroll up one line | Super + Shift + Up | +| Scroll down one line | Super + Shift + Down | +| Mark | Alt + H | +| Unmark | Alt + Shift + H | +| Copy line | Super + C | +| Cut line | Super + X | +| Merge lines | Ctrl + J | + +### Enable/Disable Read-only Mode + +1. Open the document with Text Editor and right-click to select **Turn on Read-only Mode**. + +![readonly](fig/d_readonly.png) +              + +2. Right-click to select **Turn off Read-only Mode** under the read-only mode. + +![read-only](fig/d_turnoffreadonly.png) +              + +### Use Column Mode + +Press and hold the **Alt** key on the keyboard, drag the mouse to select multiple lines, and edit the identical contents in multiple lines of codes efficiently by using the column mode function. + +![mode](fig/column mode.png) + +### Color Mark + +Select the text to be marked in Text Editor, right-click to select **Color Mark** and select the corresponding options in the drop-down list as needed. + +![colormark](fig/d_colormark.png) +              + +- Select **Mark** to mark a certain line or a paragraph of texts. You can choose from 8 colors displayed through icons. + - Place the cursor at any line and you can mark the current line. + - Select a paragraph of texts and you can mark the selected texts. +- Select **Mark All** to mark all the contents in Text Editor, or mark all the matching contents of selected texts in Text Editor. You can choose from 8 colors displayed through icons. + - Place the cursor at any line and you can mark all contents. + - Select any content and you can mark the same content in the whole document. +- Select **Clear Last Mark** to cancel the last mark operation. +- Select **Clear All Marks** to cancel all the current marks. + + +### Manage Bookmarks + +Check **Show bookmarks icon** in **Settings** and you can add a bookmark for any line on the Text Editor interface. The icon ![icon](../common/bookmark_normal_light.svg) shows up when you move the cursor to any line in the left column, and the icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) will appear after a bookmark is successfully added. + +- Add bookmarks + + + Click ![icon](../common/bookmark_normal_light.svg) to add a bookmark for the line. + + Right-click ![icon](../common/bookmark_normal_light.svg) and select **Add bookmark** to add a bookmark for the line. + + Place the cursor on any line and press **Ctrl + F2** to add a bookmark for the line. + +- Delete bookmarks + + + Click the colored bookmark icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) to delete the bookmark of the line directly. + + Right-click the colored bookmark icon ![bookmarkbig](../common/bookmarkbig_checked_light.svg) to select **Remove Bookmark** to delete the bookmark in the line. + + Right-click a bookmark to select **Remove All Bookmarks** to delete all the bookmarks in the text. + >![Notes](../common/notes.svg)Notes: The bookmark icon appears only when cursor is hovered over to the left of the line number in the left column; when it's moved beyond the left bookmark column, the bookmark icon will disappear. The bookmark icon will always be displayed after being added. + + +### Manage Comments + +You can add comments to any text with a code type suffix, such as cpp and java, among others. + +- Add comments + - Select the text needed and right-click to select **Add Comment**. + - Select the text needed and press **Alt + A** to add comments. + +- Cancel comments + - Select the text with comments, and right-click to select **Remove Comment**. +- Select the text with comments, and press **Alt + Z** to cancel comments. + + +> ![notes](../common/notes.svg)Notes: This supports comments in different languages. Please refer to actual conditions for detailed information. For example, comment symbol for C, C# and Java is // and comment symbol for Python is #. + +## Main Menu + +On the main menu, you can Create New Windows, Create New Files, [Find Texts](#Find Texts), [Replace Texts](#Replace Texts), [Save Files](#Save Files), switch window themes, view help manual, and get more information about Text Editor. + +### Settings + +You can set the basic information, shortcuts and advanced information in settings. + +#### Basic Settings + +Click ![icon_menu](../common/icon_menu.svg)> **Settings** and you can perform the following in the Settings window: + +- Select the Font and Font Size. +- Check or uncheck **Word wrap**. +- Check **Code folding flag** and ![next](../common/next.svg) or ![next](../common/next_down.svg) are displayed in the edit area. Right-click to select **Fold/Unfold Current Level** or **Fold/Unfold All** to perform the corresponding operations. +- Check **Show line numbers** to display the line number in the edit area. +- Check **Highlight current line** to highlight the current line. +- Check **Show bookmarks icon** to display the bookmarks in the text. +- Check **Show whitespaces and tabs** to display all the white spaces and tabs. You can also input or delete white spaces and tabs manually. + +> ![tips](../common/tips.svg)Tips: You can also use **Ctrl + “+”/ “-”** to adjust the font size, and press **Ctrl + 0** to restore default font size. + +#### Shortcuts Settings +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings** to view the current shortcut in the **Shortcuts** option. +2. Select a keymap in **Shortcuts** and view the shortcuts. +3. You can click and customize new shortcuts. + +> ![notes](../common/notes.svg)Notes: You can choose a proper keymap to fit your habits, including standard keymap, Emacs keymap, or customize it as you like. + +#### Advanced Settings + +1. Click ![icon_menu](../common/icon_menu.svg)> **Settings**. +2. In the **Advanced** option, you can set: + - Window size: Normal, Maximum, or Full screen; + - Tab width: The indentation width when pressing Tab. + + +### Theme + +The window theme provides three theme types, namely Light Theme, Dark Theme and System Theme. + +1. On the Text Editor interface, click ![icon_menu](../common/icon_menu.svg). +2. Click **Theme** to select one theme. + +### Help + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Select **Help** to view the manual of Text Editor. + +### About + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Select **About** to view the version and introduction of Text Editor. + +### Exit + +1. On the Text Editor interface, click ![menu](../common/icon_menu.svg). +2. Click **Exit** to exit Text Editor. diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/advanced-preview.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/advanced-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..b12ff1347c2ff1fc6d17805d44cc215b9b234d81 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/advanced-preview.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/changecase.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/changecase.png new file mode 100644 index 0000000000000000000000000000000000000000..0f94f0f94b70e3a1e65bba684599dffda3985870 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/changecase.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/colormark.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/colormark.png new file mode 100644 index 0000000000000000000000000000000000000000..ed393530f486cfd88c0e53881cbc6e1862edb8fb Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/colormark.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/column mode.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/column mode.png new file mode 100644 index 0000000000000000000000000000000000000000..bc478448411363235bb3294c199cafe260b817ac Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/column mode.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_changecase.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_changecase.png new file mode 100644 index 0000000000000000000000000000000000000000..53176e9378f77cac57e98266633c28c3bb5ebc90 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_changecase.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_colormark.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_colormark.png new file mode 100644 index 0000000000000000000000000000000000000000..ee19302f254db85d79cd7a1dbf3920533ee83875 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_colormark.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_readonly.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_readonly.png new file mode 100644 index 0000000000000000000000000000000000000000..13c25165f661754080ac0b8fbace48e935ed1138 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_readonly.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_turnoffreadonly.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_turnoffreadonly.png new file mode 100644 index 0000000000000000000000000000000000000000..12a65856d37692ad03e203507ed05ada144afd21 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/d_turnoffreadonly.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/highlight.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..0b561fa4cf89da7627d88279df78209384d1538e Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/highlight.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/hotkey.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/hotkey.png new file mode 100644 index 0000000000000000000000000000000000000000..d046a1d3d405db2050d1a3dec831906c6c50f2f1 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/hotkey.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/mark.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/mark.png new file mode 100644 index 0000000000000000000000000000000000000000..2d49df34f09e43372b9478381969d3d19102555b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/mark.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/overview.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..ce8e1b6c31ae66c186b22a30e67e98809495d5c9 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/overview.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/overviewx2.jpg b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/overviewx2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..626835806e1f4751970f9de1f083246c28b655c0 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/overviewx2.jpg differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/pagesetup.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/pagesetup.png new file mode 100644 index 0000000000000000000000000000000000000000..af37bba809612860509fddb4cb33aa4ad5075e79 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/pagesetup.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/preview.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..88ad6e0b5735bbd793a89aac5dfc4162c1f16f7a Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/preview.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/printer.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..e7e386de11866008179399223b542ab1952be2bb Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/printer.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/read_only.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/read_only.png new file mode 100644 index 0000000000000000000000000000000000000000..6a67a2375e880e366cdd397fb79c81a86d6c5469 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/read_only_02.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/read_only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..8dac668ec8614d9c8a6b954eab16c830e37b168a Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/read_only_02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/reading.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/reading.png new file mode 100644 index 0000000000000000000000000000000000000000..0089c2cf21bb0247ffbea65eead4b7798d9819cc Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/reading.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/shortcuts.jpg b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/shortcuts.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a109071e5aec5af0e6f8dcb18ec923c0812b07ce Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/shortcuts.jpg differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/shortcutsx2.jpg b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/shortcutsx2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d595feed21482567d3dc5383ef39452c58574c85 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/shortcutsx2.jpg differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/texttospeech.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/texttospeech.png new file mode 100644 index 0000000000000000000000000000000000000000..41c37956862e9948f322891fc630f1643b7e950e Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/texttospeech.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/translate.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/translate.png new file mode 100644 index 0000000000000000000000000000000000000000..7c2999b7c5378109de08573a245be9a3f69db7b4 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/translate.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/en_US/fig/translation.png b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/translation.png new file mode 100644 index 0000000000000000000000000000000000000000..6b401d0b3033a8eb4c1a34269751f711bf783ca0 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/en_US/fig/translation.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/editor.md b/src/assets/loongarch64/deepin-editor/editor/zh_CN/editor.md new file mode 100755 index 0000000000000000000000000000000000000000..400afe05dd62a80753dcfafb3299ceb89084195d --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/zh_CN/editor.md @@ -0,0 +1,324 @@ +# 文本编辑器|deepin-editor| + +## 概述 + +文本编辑器是一个简单的文本编辑工具。您可以用它书写简单的文本文档,也可以使用它的高级特性,让它成为一个代码编辑工具,支持代码语法高亮。 + +![overview](fig/overview.png) + +## 使用入门 + +通过以下方式运行或关闭文本编辑器,或者创建文本编辑器的快捷方式。 + +### 运行文本编辑器 + +1. 单击任务栏上的启动器图标 ![deepin_launcher](../common/deepin_launcher.svg),进入启动器界面。 +2. 上下滚动鼠标滚轮浏览或通过搜索,找到文本编辑器图标 ![deepin_editor](../common/deepin_editor.svg),单击运行。 +3. 右键单击![deepin_editor](../common/deepin_editor.svg),您可以: + + - 单击 **发送到桌面**,在桌面创建快捷方式。 + - 单击 **发送到任务栏**,将应用程序固定到任务栏。 + - 单击 **开机自动启动**,将应用程序添加到开机启动项,在电脑开机时自动运行该应用。 + +### 退出文本编辑器 + +- 在文本编辑器界面,单击 ![close_icon](../common/close_icon.svg),退出文本编辑器。 +- 在文本编辑器界面,单击主菜单 ![icon_menu](../common/icon_menu.svg) > **退出** ,退出文本编辑器。 +- 在任务栏右键单击 ![deepin_editor](../common/deepin_editor.svg),选择 **关闭所有** ,退出文本编辑器。 + + +### 查看快捷键 + +在文本编辑器界面,使用快捷键 **Ctrl + Shift + ?** 打开快捷键预览界面,您也可以在设置界面查看快捷键。熟练地使用快捷键,将大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理标签页 + +- 新建标签页/窗口 + + - 单击标签页上的按钮 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **新标签页** 或使用快捷键 **Ctrl + T** 创建一个新的标签页。 + - 单击![icon_menu](../common/icon_menu.svg) > **新窗口** 或使用快捷键 **Ctrl + N** 创建一个新的窗口。 + +- 调整标签页/窗口 + + - 拖拽同一窗口内的标签页重新排序。 + - 滚动鼠标切换同一窗口内的标签页。 + - 移出标签页创建一个新的窗口,或者从一个窗口移到另外一个窗口中。 + +- 关闭标签页/窗口 + + 当窗口中仅有一个标签页时,关闭标签页的同时也会关闭窗口。 + - 使用快捷键 **Ctrl + W** 关闭当前标签页。 + - 单击标签页上的按钮 ![close_icon](../common/close_icon.svg) 或者单击鼠标中键,关闭当前标签页。 + - 右键单击标签页,选择 **关闭标签页** 、**关闭其他标签页** 或 **更多关闭方式** 来关闭标签页。 + + > ![notes](../common/notes.svg)说明:如果您的文件发生了变化而没有保存,文本编辑器会在关闭前提示您保存更改。 + + + +### 打开文件 + + +您可以采用以下方式打开一个或同时打开多个文本文件,选中的文件将会在新标签页打开: + +- 直接拖动文件到文本编辑器界面或其图标上。 +- 右键单击文件,选择 **打开方式** > **文本编辑器**。选择文本编辑器为默认打开程序后,可直接双击打开。 +- 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg) > **打开文件** 或使用快捷键 **Ctrl + O**,在弹出的窗口中选择文件。 + + + +### 保存文件 +- 单击 ![icon_menu](../common/icon_menu.svg) > **保存** 或使用快捷键 **Ctrl + S**,保存当前文件。 +- 单击 ![icon_menu](../common/icon_menu.svg) > **另存为** 或使用快捷键 **Ctrl + Shift + S**,另存当前文件。 + + + +### 打印文件 + +在文本编辑器中使用打印,需要您连接并配置好打印机。 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **打印** 或使用快捷键 **Ctrl + P** 打开打印预览。 +2. 在打印预览界面,您可以预览文件,选择打印机并设置打印页面。 +3. 在打印预览界面,单击 **高级设置**,可配置纸张大小、打印方式等相关参数。 +4. 单击 **打印** 即可将文件发送到打印机打印。 + +![pagesetup](fig/printer.png) + +![printer](fig/printer_setting.png) + + + +## 编辑文本 + +### 移动光标 + +除了使用方向键和鼠标点击移动光标,您还可以使用以下快捷键迅速移动光标: + +| 功能 | 快捷键 | +| --------------- | ------------ | +| 保存光标位置 | Ctrl + Shift + > | +| 重置光标位置(跳转到上次光标保存的位置) | Ctrl + Shift + < | +| 右移一个词 (光标向右跳过一个词) | Ctrl + 右方向键 | +| 左移一个词 (光标向左跳过一个词) | Ctrl + 左方向键 | +| 移动到行尾 | End | +| 移动到行头 | Home | +| 移动到文本结尾 | Ctrl + End | +| 移动到文本开头 | Ctrl + Home | +| 移动到行缩进 | Ctrl + M | +| 向右匹配 (光标移动到右括号的后面) | Alt + P | +| 向左匹配(光标移动到左括号的前面) | Alt + N | + +### 切换大小写 + +切换大小写功能可以将选中的文本全部改为大写字母、小写字母或者让首字母大写。 + +1. 选中待更改的文本内容。 +2. 单击右键,选择 **切换大小写**。 +3. 选择 **大写**/**小写**/**首字母大写** 选项,更改会立即生效。 + +您也可以使用快捷键 **Alt + U/ L/ C** 迅速切换大小写。 + +![toggle_case](fig/d_toggle_case.png) + +### 高亮文本 + +文本编辑器支持高亮不同类型的文本。 +单击底部状态栏最右侧的三角符号, 选择某种文本类型。若文本中有相应内容则会自动高亮。 + +![highlight](fig/highlight.png) + +### 删除文本 +除了向左或向右逐个删除字符外,您还可以使用以下快捷键迅速删除字符: + +| 功能 | 快捷键 | +| --------------- | ------------ | +| 删除到行尾 | Ctrl + K | +| 删除当前行 | Ctrl + Shift + K | +| 向左删除一个词 | Alt + Shift + N | +| 向右删除一个词 | Alt + Shift + M | + +### 撤销操作 + +如果在编辑文本时发生误操作,可以使用快捷键 **Ctrl + Z** 撤销操作,或者在右键菜单中选择 **撤销**。 + +### 查找文本 + +1. 单击 ![menu](../common/icon_menu.svg) > **查找** 或使用快捷键 **Ctrl + F**,打开查找窗口。 +2. 在查找窗口中,输入要搜索的文本。 +3. 单击 **下一个**、**上一个** 逐个查找,或使用 **Enter** 键查找下一个匹配项。 +4. 按下 **Esc** 键或单击关闭按钮,关闭查找窗口。 + +> ![tips](../common/tips.svg)窍门:选中一段文本后再进行查找,则这段文本会自动出现在查找窗口中。 + +### 替换文本 +1. 单击 ![menu](../common/icon_menu.svg) > **替换** 或使用快捷键 **Ctrl + H** ,打开替换窗口。 +2. 在替换窗口中,输入要替换的文本以及新文本。 +3. 单击 **替换** 逐个替换;单击 **剩余替换**、**全部替换** 一次性替换剩余的或所有的匹配文本;单击 **跳过** 不替换当前匹配的文本。 +4. 按下 **Esc** 键或单击关闭按钮,关闭搜索窗口。 + +### 跳到行 +使用该功能可以迅速跳转到任一行。 +在右键菜单中选择 **跳到行** 或者使用快捷键 **Ctrl + G** ,输入行号即可跳转到相应行。 + +### 编辑行 + +您可以使用以下快捷键迅速编辑行: + +| 功能 | 快捷键 | +| ------------ | ------------ | +| 向上插入一行(在上方插入一行) | Ctrl + Enter | +| 向下插入一行(在下方插入一行) | Ctrl + Shift + Enter | +| 复制并粘贴当前行 | Ctrl + Shift + D | +| 上移一行(与上一行交换位置) | Ctrl + Shift + Up | +| 下移一行(与下一行交换位置) | Ctrl + Shift + Down | +| 向上滚动一行 | Super + Shift + Up | +| 向下滚动一行 | Super + Shift + Down | +| 设置标记 | Alt + H | +| 取消标记 | Alt + Shift + H | +| 复制行 | Super + C | +| 剪切行 | Super + X | +| 合并行 | Ctrl + J | + +### 开启/关闭只读模式 + +1. 使用文本编辑器打开文档,单击右键,选择 **开启只读模式**。 +2. 在只读模式下,单击右键,选择 **关闭只读模式**。 + +![read_only](fig/d_read_only.png) + +![read_only](fig/d_read_only02.png) + + +### 列编辑 + +在文本编辑器界面,按住 **Alt** 键不放,鼠标左键单击多列启动列编辑模式,为多行代码同时编辑相同的内容,提高工作效率。 + +![mode](fig/column_mode.png) + + + +### 颜色标记 + +在文本编辑器界面,单击鼠标右键选择 **颜色标记**,在其下拉列表中进行选择。 + +![color](fig/d_colortag.png) + + - **添加标记**:对某一行或某一段文本内容添加颜色标记;有8种颜色按钮可供选择。 + + 将光标定在某一行,标记当前所在的行。 + + 选中一段文本内容后,标记选中的文本内容。 + - **标记所有**:将文本内容全部标记或对已选中的文本内容,在全文中标记匹配项;有8种颜色按钮可供选择。 + + 将光标定在任意一行,将文本内容全部标记。 + + 选中一段文本内容,在全文中标记匹配项。 + + - **清除上次标记**:清除上次标记操作。 + - **清除所有标记**:清除当前所有标记。 + + + +### 书签管理 + +在文本编辑器设置界面,勾选 **显示书签图标** 后,您可以为任意一行的文本内容添加书签。将鼠标指针移至左侧栏任意行号前面会显示图标 ![icon](../common/bookmark_normal_light.svg),添加成功后该行的书签图标会变为蓝色填充的图标 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加书签 + + + 鼠标左键单击 ![icon](../common/bookmark_normal_light.svg),为该行添加书签。 + + 鼠标右键单击 ![icon](../common/bookmark_normal_light.svg),选择 **添加书签**,为该行添加一个书签。 + + 将光标定在文本中任意一行,使用快捷键 **Ctrl + F2** 为该行添加一个书签。 + + +- 删除书签 + + + 鼠标左键单击已填充颜色的书签图标,直接删除该行书签。 + + 鼠标右键单击已填充颜色的书签图标,选择 **清除书签**,删除该行书签。 + + 鼠标右键单击书签图标,选择 **清除所有书签**,删除该文本的全部书签。 + + >![icon](../common/notes.svg)说明:鼠标移到左侧行号前面才会显示书签图标,移出书签区域,书签图标消失。添加书签后,该图标一直显示。 + + + +### 注释管理 + +在文本编辑器界面,您可以对扩展名为.cpp 、.java 、.py等代码类型的文件进行添加注释的操作。 + +- 添加注释 + + 选中一段文本内容,单击右键并选择 **添加注释**。 + + 选中一段文本内容,使用快捷键 **Alt + A** 添加注释。 + +- 取消注释 + + 选中一段已添加注释的文本内容,单击右键并选择 **取消注释**。 + + 选中一段已添加注释的文本内容,使用快捷键 **Alt + Z** 取消注释。 + + >![notes](../common/notes.svg)说明:支持不同代码语言的注释,具体以实际为主。例如C,C#,Java注释符号为 //,Python 注释符号为 #。 + + + +## 主菜单 + +在主菜单中,您可以新建窗口、新建标签页、[查找文本](#查找文本)、[替换文本](#替换文本)、保存文件、切换窗口主题、查看帮助手册,了解文本编辑器的更多信息。 + +### 设置 + +您可以对基础信息、快捷键和高级信息进行设置。 + +#### 基础设置 + +1. 单击![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在基础设置选项,您可以选择: + - 设置字体样式和字号大小。 + - 勾选 **自动换行**,在编辑区自动换行。 + - 勾选 **代码折叠标志**,在左侧栏显示按钮![next](../common/next.svg)或者![next](../common/next_down.svg) ,右键单击按钮选择折叠/展开当前层次或所有层次。 + - 勾选 **显示行号**,在左侧栏显示行号。 + - 勾选 **当前行高亮**,光标所在的行高亮显示。 + - 勾选 **显示书签图标**,在左侧栏显示书签图标。 + - 勾选 **显示空白制符/制表符**,显示文本中的空白字符和制表符,您也可以手动输入或删除空白字符和制表符。 + + > ![tips](../common/tips.svg)窍门:您还可以使用 **Ctrl + “+”/ “-”** 来调节文本编辑器的默认字号。使用 **Ctrl + 0** 恢复默认字号。 + + + +#### 快捷键设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **设置**,在 **快捷键** 选项查看当前快捷键。 +2. 选择一种快捷键映射。 +3. 您可以单击并重新输入快捷键,自定义快捷键。 + + > ![notes](../common/notes.svg)说明: 快捷键映射允许您选择某一种键盘快捷键。您可以使用标准快捷键,Emacs快捷键,或自定义快捷键,以符合您的使用习惯。 + + +#### 高级设置 + +1. 单击 ![icon_menu](../common/icon_menu.svg) > **设置**。 +2. 在 **高级设置** 选项,您可以设置: + - 窗口状态:正常窗口,最大化或全屏。 + - Tab字符宽度:Tab缩进所占用的空间大小。 + + + +### 主题 + +窗口主题包含浅色主题、深色主题和系统主题。 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **主题**,选择一个主题颜色。 + +### 帮助 + +查看帮助手册,进一步了解和使用文本编辑器。 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **帮助**。 +3. 查看文本编辑器的帮助手册。 + +### 关于 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **关于**。 +3. 查看文本编辑器的版本和介绍。 + +### 退出 + +1. 在文本编辑器界面,单击 ![icon_menu](../common/icon_menu.svg)。 +2. 选择 **退出**。 \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/close.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/close.png new file mode 100755 index 0000000000000000000000000000000000000000..eb5704b81bca1efccd06786eb2a324c63b3edcf0 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/close.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/colortag.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/colortag.png new file mode 100755 index 0000000000000000000000000000000000000000..5b64f60d1096bbfc488196af98b4c546e64ff20d Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/colortag.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/column_mode.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/column_mode.png new file mode 100755 index 0000000000000000000000000000000000000000..52ec0e407f09e3db763f9c17b0c39a52e9ca54fd Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/column_mode.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_colortag.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_colortag.png new file mode 100755 index 0000000000000000000000000000000000000000..f7021f8e32c0237bd8cf2500545428ef5573ecd1 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_colortag.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_column_mode.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_column_mode.png new file mode 100755 index 0000000000000000000000000000000000000000..76ee58b8e34c2ffc15d3a034d0399bbb401f8a80 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_column_mode.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_read_only.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..384de02df149c88f91608b2787589a89b7dcbeb6 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_read_only02.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_read_only02.png new file mode 100755 index 0000000000000000000000000000000000000000..f3200d80ae77470ca94e77561727ac1e1119e106 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_read_only02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_toggle_case.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_toggle_case.png new file mode 100755 index 0000000000000000000000000000000000000000..05733d417f05b52435eb62310f6b7f635439e66b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/d_toggle_case.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/editer.psd b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/editer.psd new file mode 100755 index 0000000000000000000000000000000000000000..d68083edaf82a349425c63540ac895a3dfa4bb5b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/editer.psd differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/highlight.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/highlight.png new file mode 100755 index 0000000000000000000000000000000000000000..955ff0130d4ade9801a58c4821aab115a0b64b77 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/highlight.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/hotkey.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/hotkey.png new file mode 100755 index 0000000000000000000000000000000000000000..37e87eebeddeb9c6628793abbe1ef9cc4067f260 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/hotkey.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/listen.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/listen.png new file mode 100755 index 0000000000000000000000000000000000000000..d397f90eaad0909f49535c74cb5cb58d949b2f2b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/listen.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/overview.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/overview.png new file mode 100755 index 0000000000000000000000000000000000000000..56e6ef348cb76f88f29dae3c3cbaa93e706260fd Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/overview.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/printer.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/printer.png new file mode 100644 index 0000000000000000000000000000000000000000..180809cf56c67869cc00d997e25d52b9d7498627 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/printer.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/printer_setting.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/printer_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..7b0b7a5a077acf1e074da7fe969eb2b4dc7ac03f Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/printer_setting.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/read_only.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..9d26b1e1e316a68c0abee8e3ad751078bfb0a427 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/read_only_02.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/read_only_02.png new file mode 100755 index 0000000000000000000000000000000000000000..960b5a350fa3ab4dcf7917aa37101d8045b5c843 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/read_only_02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/reading.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/reading.png new file mode 100755 index 0000000000000000000000000000000000000000..7dbbeed5c8c7cb8933856dcdec4ec92e36b09ed1 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/reading.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/text_translation.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/text_translation.png new file mode 100755 index 0000000000000000000000000000000000000000..890ecd017a37cc38886ab90c129cbd834137ffa1 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/text_translation.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/togglecase.png b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/togglecase.png new file mode 100755 index 0000000000000000000000000000000000000000..63ac808ab35ececc3d630fda919d7a7b1609d896 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_CN/fig/togglecase.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/editor.md b/src/assets/loongarch64/deepin-editor/editor/zh_HK/editor.md new file mode 100755 index 0000000000000000000000000000000000000000..051eb3d4cb8abeed711382b3946cde670f696c78 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/zh_HK/editor.md @@ -0,0 +1,312 @@ +# 文本編輯器|deepin-editor| + +## 概述 + +文本編輯器是一個簡單的文本編輯工具。您可以用它書寫簡單的文本文檔,也可以使用它的高級特性,讓它成為一個代碼編輯工具,支持代碼語法高亮。 + +![overview](fig/overview.png) + +## 使用入門 + +通過以下方式運行或關閉文本編輯器,或者創建文本編輯器的快捷方式。 + +### 運行文本編輯器 + +1. 單擊任務欄上的啟動器圖標 ![deepin_launcher](../common/deepin_launcher.svg),進入啟動器界面。 +2. 上下滾動鼠標滾輪瀏覽或通過搜索,找到文本編輯器圖標![deepin_editor](../common/deepin_editor.svg),單擊運行。 +3. 右鍵單擊![deepin_editor](../common/deepin_editor.svg),您可以: + + - 單擊 **傳送到桌面**,在桌面創建快捷方式。 + - 單擊 **傳送到任務欄**,將應用程序固定到任務欄。 + - 單擊 **加至開機啟動**,將應用程序添加到開機啟動項,在電腦開機時自動運行該應用。 + +### 關閉文本編輯器 + +- 在文本編輯器界面,單擊 ![close_icon](../common/close_icon.svg),關閉文本編輯器。 +- 在文本編輯器界面,單擊主菜單 ![icon_menu](../common/icon_menu.svg) > **退出** ,關閉文本編輯器。 +- 在任務欄右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),選擇 **關閉所有** ,關閉文本編輯器。 + + +### 查看快捷鍵 + +在文本編輯器界面,使用快捷鍵 **Ctrl + Shift + ?** 打開快捷鍵預覽界面,您也可以在設置界面查看快捷鍵。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理標籤頁 + +- 新建標籤頁/窗口 + + - 單擊標籤頁上的 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **新標籤頁** 或使用快捷鍵 **Ctrl + T** 創建一個新的標籤頁。 + - 單擊![icon_menu](../common/icon_menu.svg) > **新窗口** 或使用快捷鍵 **Ctrl + N** 創建一個新的窗口。 + +- 調整標籤頁/窗口 + + - 拖拽同一窗口內的標籤頁重新排序。 + - 滾動鼠標切換同一窗口內的標籤頁。 + - 移出標籤頁創建一個新的窗口,或者從一個窗口移到另外一個窗口中。 + +- 關閉標籤頁/窗口 + + 當窗口中僅有一個標籤頁時,關閉標籤頁的同時也會關閉窗口。 + - 使用快捷鍵 **Ctrl + W** 關閉當前標籤頁。 + - 單擊標籤頁上的按鈕 ![close_icon](../common/close_icon.svg) 或者單擊鼠標中鍵,關閉當前標籤頁。 + - 右鍵單擊標籤頁,選擇 **關閉標籤頁** 、**關閉其他標籤頁** 或 **更多關閉方式** 來關閉標籤頁。 + + > ![notes](../common/notes.svg)說明:如果您的文件發生了變化而沒有保存,文本編輯器會在關閉前提示您保存更改。 + + +### 打開文件 + +您可以採用以下方式打開一個或同時打開多個文本文件,選中的文件將會在新標籤頁中打開: + +- 直接拖動文件到文本編輯器界面或其圖標上。 +- 右鍵單擊文件,選擇 **打開方式** > **文本編輯器**。選擇文本編輯器為默認打開程序後,可直接雙擊打開。 +- 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg) > **打開文件** 或使用快捷鍵 **Ctrl + O**,在彈出的窗口中選擇文件打開。 + + +### 保存文件 +- 單擊 ![icon_menu](../common/icon_menu.svg) > **保存** 或使用快捷鍵 **Ctrl + S**,保存當前文件。 +- 單擊 ![icon_menu](../common/icon_menu.svg) > **另存為** 或使用快捷鍵 **Ctrl + Shift + S**,另存當前文件。 + + +### 打印文件 + +在文本編輯器中使用打印,需要您連接並配置好打印機。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **打印**,也可以使用快捷鍵 **Ctrl + P** 打開打印預覽。 +2. 在打印預覽界面,您可以預覽文件,選擇打印機並設置打印頁面。 +3. 在打印預覽界面,單擊 **高級設置**,可配置紙張大小、打印方式等相關參數。 +4. 單擊 **打印** 即可將文件發送到打印機打印。 + + + +## 編輯文本 + +### 移動光標 + +除了使用方向鍵和鼠標單擊移動光標,您還可以使用以下快捷鍵迅速移動光標: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 保存光標位置 | Ctrl + Shift + > | +| 重置光標位置(跳轉到上次光標保存的位置) | Ctrl + Shift + < | +| 右移一個詞 (光標向右跳過一個詞) | Ctrl + 右方向鍵 | +| 左移一個詞 (光標向左跳過一個詞) | Ctrl + 左方向鍵 | +| 移動到行尾 | End | +| 移動到行頭 | Home | +| 移動到文本結尾 | Ctrl + End | +| 移動到文本開頭 | Ctrl + Home | +| 移動到行縮進 | Ctrl + M | +| 向右匹配 (光標移動到右括號的後面) | Alt + P | +| 向左匹配(光標移動到左括號的前面) | Alt + N | + +### 切換大小寫 + +切換大小寫功能可以將選中的文本全部改為大寫字母、小寫字母或者讓首字母大寫。 + +1. 選中待更改的文本內容。 +2. 單擊右鍵,選擇 **切換大小寫**。 +3. 選擇 **大寫**/**小寫**/**首字母大寫** 選項,更改會立即生效。 + +您也可以使用快捷鍵 **Alt + U/ L/ C** 迅速切換大小寫。 + +![toggle_case](fig/d_toggle_case.png) + +### 高亮文本 + +文本編輯器支持高亮不同類型的文本。 +單擊底部狀態欄最右側的三角符號, 選擇某種文本類型。若文本中有相應內容則會自動高亮。 + +![highlight](fig/highlight.png) + +### 刪除文本 +除了向左或向右逐個刪除字符外,您還可以使用以下快捷鍵迅速刪除字符: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 刪除到行尾 | Ctrl + K | +| 刪除當前行 | Ctrl + Shift + K | +| 向左刪除一個詞 | Alt + Shift + N | +| 向右刪除一個詞 | Alt + Shift + M | + +### 撤銷操作 + +如果在編輯文本時發生誤操作, 可以使用快捷鍵 **Ctrl + Z** 撤銷操作, 或者在右鍵菜單中選擇 **撤銷**。 + +### 查找文本 + +1. 單擊 ![menu](../common/icon_menu.svg) > **查找** 或使用快捷鍵 **Ctrl + F** 打開查找窗口。 +2. 在查找窗口中,輸入要搜索的文本。 +3. 單擊 **下一個**、**上一個** 逐個查找,或使用 **Enter** 鍵查找下一個匹配項。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉查找窗口。 + +> ![tips](../common/tips.svg)竅門:選中一段文本後再進行搜索,則這段文本會自動出現在查找窗口中。 + +### 替換文本 +1. 單擊 ![menu](../common/icon_menu.svg) > **替換** 或使用快捷鍵 **Ctrl + H** 打開替換窗口。 +2. 在替換窗口中,輸入要替換的文本以及新文本。 +3. 單擊 **替換** 逐個替換,單擊 **剩餘替換**、**全部替換** 一次性替換剩餘的或所有的匹配文本。單擊 **跳過** 不替換當前匹配的文本。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉搜索窗口。 + +### 跳到行 +使用該功能可以迅速跳轉到任一行。 +在右鍵菜單中選擇 **跳到行** 或者使用快捷鍵 **Ctrl + G** ,輸入行號即可跳轉到相應行。 + +### 編輯行 + +您可以使用以下快捷鍵迅速編輯行: + +| 功能 | 快捷鍵 | +| ------------ | ------------ | +| 向上插入一行(在上方插入一行) | Ctrl + Enter | +| 向下插入一行(在下方插入一行) | Ctrl + Shift + Enter | +| 複製並黏貼當前行 | Ctrl + Shift + D | +| 上移一行(與上一行交換位置) | Ctrl + Shift + Up | +| 下移一行(與下一行交換位置) | Ctrl + Shift + Down | +| 向上滾動一行 | Super + Shift + Up | +| 向下滾動一行 | Super + Shift + Down | +| 設置標記 | Alt + H | +| 取消標記 | Alt + Shift + H | +| 複製行 | Super + C | +| 剪切行 | Super + X | +| 合併行 | Ctrl + J | + +### 開啟/關閉只讀模式 + +1. 使用文本編輯器打開文檔,單擊右鍵,選擇 **開啟只讀模式**。 +2. 在只讀模式下,單擊右鍵,選擇 **關閉只讀模式**。 + +![read_only](fig/d_read_only.png) + +![read_only](fig/d_read_only02.png) + + + +### 列編輯 + +在文本編輯器界面,按住鍵盤上的 **Alt** 鍵不放,鼠標左鍵單擊多列啟動列編輯模式,為多行代碼同時編輯相同的內容,提高工作效率。 + +![mode](fig/column_mode.png) + +### 顏色標記 + +在文本編輯器界面,單擊鼠標右鍵選擇 **顏色標記**,在其下拉列表中進行選擇。 + +![color](fig/d_color_tag.png) + + - **設置標記**:對某一行或某一段文本內容添加顏色標記;有8種顏色按鈕可供選擇。 + + 將光標定在某一行,標記當前所在的行。 + + 選中一段文本內容後,標記選中的文本內容。 + - **標記所有**:將文本內容全部標記或對已選中的文本內容,在全文中標記匹配項;有8種顏色按鈕可供選擇。 + + 將光標定在任意一行,將文本內容全部標記。 + + 選中一段文本內容,在全文中標記匹配項。 + - **清除上次標記**:清除上次標記操作。 + - **清除所有標記**:清除當前所有標記。 + + + + +### 書籤管理 + +在文本編輯器設置界面,勾選 **顯示書籤圖標** 後,您可以為任意一行的文本內容添加一個書籤。將鼠標指針移至左側欄任意行號前面會顯示圖標 ![icon](../common/bookmark_normal_light.svg),添加成功後該行的書籤圖標會變為藍色填充的圖標 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加書籤 + + + 鼠標左鍵單擊 ![icon](../common/bookmark_normal_light.svg),為該行添加書籤。 + + 鼠標右鍵單擊![icon](../common/bookmark_normal_light.svg),選擇 **添加書籤**,為該行添加一個書籤。 + + 將光標定在文本中任意一行,使用快捷鍵 **Ctrl + F2** 為該行添加一個書籤。 + +- 刪除書籤 + + + 鼠標左鍵單擊已填充顏色的書籤圖標,直接刪除該行書籤。 + + 鼠標右鍵單擊已填充顏色的書籤圖標,選擇 **清除書籤**,刪除該行書籤。 + + 鼠標右鍵單擊書籤圖標,選擇 **清除所有書籤**,刪除該文本的全部書籤。 + + >![icon](../common/notes.svg)說明:鼠標移到左側行號前面才會顯示書籤圖標,移出書籤區域,書籤圖標消失。添加書籤後,該圖標一直顯示。 + + + +### 注釋管理 + +在文本編輯器界面,您可對擴展名為.cpp 、.java 、.py等代碼類型的文件進行添加注釋的操作。 +- 添加注釋 + + 選中一段文本內容,在右鍵菜單中選擇 **添加注釋**。 + + 選中一段文本內容,使用快捷鍵 **Alt + A** 添加注釋。 + +- 取消注釋 + + 選中一段已添加注釋的文本內容,在右鍵菜單中選擇 **取消注釋**。 + + 選中一段已添加注釋的文本內容,使用快捷鍵 **Alt + Z** 取消注釋。 + + >![notes](../common/notes.svg)說明:支持不同代碼語言的注釋,具體以實際為主。例如C,C#,Java注釋符號為 //,Python 注釋符號為 #。 + + + +## 主菜單 + +在主菜單中,您可以新建窗口、新建標籤頁、[查找文本](#查找文本)、[替換文本](#替換文本)、保存文件、切換窗口主題、查看幫助手冊,了解文本編輯器的更多訊息。 + +### 設置 + +您可以對基礎訊息、快捷鍵和高級訊息進行設置。 + +#### 基礎設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)> **設置**。 +2. 在基礎設置選項,您可以選擇: + - 設置字體樣式和字號大小。 + - 勾選 **自動換行**,在編輯區自動換行。 + - 勾選 **顯示代碼摺疊標誌**,在左側欄顯示![next](../common/next.svg)或者![next](../common/next_down.svg)按鈕,右鍵單擊按鈕選擇摺疊/展開當前層次或所有層次。 + - 勾選 **顯示行號**,在左側欄顯示行號。 + - 勾選 **當前行高亮**,光標所在的行高亮顯示。 + - 勾選 **顯示書籤圖標**,在左側欄顯示書籤圖標。 + - 勾選 **顯示空白制符/製表符**,顯示文本中的空白字符和製表符,您也可手動輸入或刪除空白字符和製表符。 + + > ![tips](../common/tips.svg)竅門:您還可以使用 **Ctrl + 「+」/ 「-」** 來調節文本編輯器的默認字號。使用 **Ctrl + 0** 恢復默認字號。 + + +#### 快捷鍵設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)> **設置**,在 **快捷鍵** 選項查看當前快捷鍵。 +2. 選擇一種快捷鍵映射。 +3. 單擊快捷鍵編輯框 ,可以自定義快捷鍵。 + + > ![notes](../common/notes.svg)說明: 快捷鍵映射允許您選擇某一種鍵盤快捷鍵。您可以使用標準快捷鍵,Emacs快捷鍵,或自定義快捷鍵,以符合您的使用習慣。 + + +#### 高級設置 + +1. 單擊![icon_menu](../common/icon_menu.svg)>**設置**。 +2. 在 **高級設置** 選項,您可以設置: + - 窗口狀態:正常窗口,最大化或全螢幕。 + - Tab字符寬度:Tab縮進所佔用的空間大小。 + + + +### 主題 + +窗口主題包含淺色主題、深色主題和系統主題。 + +1. 在文本編輯器界面,單擊![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題顏色。 + +### 幫助 + +查看幫助手冊,進一步了解和使用文本編輯器。 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **幫助**。 +3. 查看文本編輯器的幫助手冊。 + +### 關於 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看文本編輯器的版本和介紹。 + +### 退出 + +1. 在文本編輯器界面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **退出**。 \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/close.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/close.png new file mode 100755 index 0000000000000000000000000000000000000000..eb5704b81bca1efccd06786eb2a324c63b3edcf0 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/close.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/color_tag.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/color_tag.png new file mode 100755 index 0000000000000000000000000000000000000000..aa8b20067d4b65afa7cdb4f0ca21c1628240bfec Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/color_tag.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/column_mode.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/column_mode.png new file mode 100755 index 0000000000000000000000000000000000000000..8d55fc7aa995f012faabb4139da55a9f3771a2c3 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/column_mode.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_color_tag.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_color_tag.png new file mode 100755 index 0000000000000000000000000000000000000000..24a393283d28e2805018c16203220ba1afb82b9c Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_color_tag.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_read_only.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..e5cdf3ab18903e84ce507aa386934cbdcf7ddca8 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_read_only02.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_read_only02.png new file mode 100755 index 0000000000000000000000000000000000000000..c140b8083c385c43e57b059136137824704d77f4 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_read_only02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_toggle_case.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_toggle_case.png new file mode 100755 index 0000000000000000000000000000000000000000..bbe4afb482256cdcd5e5b761127506c57bab6b3b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/d_toggle_case.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/highlight.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/highlight.png new file mode 100755 index 0000000000000000000000000000000000000000..9ec23d428c003591fd448c0be2ce2d5c89e72089 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/highlight.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/hotkey.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/hotkey.png new file mode 100755 index 0000000000000000000000000000000000000000..84c50b0cf0b2cf8007c6e7c671fa8455292f84a6 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/hotkey.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/listen.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/listen.png new file mode 100755 index 0000000000000000000000000000000000000000..d397f90eaad0909f49535c74cb5cb58d949b2f2b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/listen.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/overview.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/overview.png new file mode 100755 index 0000000000000000000000000000000000000000..b20ade6435cee3855c8c36ad28f241c8ec71ceb0 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/overview.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/read_only.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/read_only.png new file mode 100755 index 0000000000000000000000000000000000000000..e9ecb117bce231c927a54769d8446bc9f3a56092 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/read_only02.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/read_only02.png new file mode 100755 index 0000000000000000000000000000000000000000..fe3fdee35c4d37144555001b17a2c51f14019afb Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/read_only02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/reading.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/reading.png new file mode 100755 index 0000000000000000000000000000000000000000..12ae8421d68a9b4c19d2600e111a879e3f7cbfdb Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/reading.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/toggle_case.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/toggle_case.png new file mode 100755 index 0000000000000000000000000000000000000000..e7d395f2710ebf8247a5f9d6561c4415dd2f29e5 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/toggle_case.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/translation.png b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/translation.png new file mode 100755 index 0000000000000000000000000000000000000000..b522e244afa264a01d52ccd08852cc6ca0ef826c Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_HK/fig/translation.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/editor.md b/src/assets/loongarch64/deepin-editor/editor/zh_TW/editor.md new file mode 100644 index 0000000000000000000000000000000000000000..982b23e5f38e3ba7184fc7e8ed290582428d4975 --- /dev/null +++ b/src/assets/loongarch64/deepin-editor/editor/zh_TW/editor.md @@ -0,0 +1,306 @@ +# 文字編輯器|deepin-editor| + +## 概述 + +文字編輯器是一個簡單的文字編輯工具。您可以用它書寫簡單的文字檔案,也可以使用它的進階特性,讓它成為一個程式碼編輯工具,支援程式碼語法突顯。 + +![overview](fig/overview.png) + +## 使用入門 + +### 執行文字編輯器 + +1. 單擊任務欄上的啟動器圖示 ![deepin_launcher](../common/deepin_launcher.svg),進入啟動器介面。 +2. 上下滾動滑鼠滾輪瀏覽或透過搜尋,找到文字編輯器圖示![deepin_editor](../common/deepin_editor.svg),單擊執行。 +3. 右鍵單擊![deepin_editor](../common/deepin_editor.svg),您可以: + + - 單擊 **建立桌面捷徑**,在桌面建立捷徑。 + - 單擊 **釘選到Dock**,將應用程式固定到Dock。 + - 單擊 **開機啟動**,將應用程式添加到開機啟動項,在電腦開機時自動執行該應用。 + +### 關閉文字編輯器 + +- 在文字編輯器介面,單擊 ![close_icon](../common/close_icon.svg),關閉文字編輯器。 +- 在文字編輯器介面,單擊主選單 ![icon_menu](../common/icon_menu.svg)> **離開**, 關閉文字編輯器。 +- 在Dock上右鍵單擊 ![deepin_editor](../common/deepin_editor.svg),選擇 **全部關閉**, 關閉文字編輯器。 + + +### 查看快捷鍵 + +在文字編輯器介面,使用快捷鍵 **Ctrl + Shift + ?** 打開快捷鍵預覽介面。您也可以在設定介面查看快捷鍵。熟練地使用快捷鍵,將大大提升您的操作效率。 + +![1|hotkey](fig/hotkey.png) + +## 基本操作 + +### 管理標籤頁 + +- 建立標籤頁/視窗 + + - 單擊標籤頁上的 ![plus_icon](../common/+.svg) 或 ![icon_menu](../common/icon_menu.svg) > **建立新標籤頁** 或使用快捷鍵 **Ctrl + T** 建立一個新的標籤頁。 + - 單擊![icon_menu](../common/icon_menu.svg) > **建立新視窗** 或使用快捷鍵 **Ctrl + N** 建立一個新的視窗。 + +- 調整標籤頁/視窗 + + - 拖曳同一視窗內的標籤頁重新排序。 + - 滾動滑鼠切換同一視窗內的標籤頁。 + - 移出標籤頁建立一個新的視窗,或者從一個視窗移到另外一個視窗中。 + +- 關閉標籤頁/視窗 + + 當視窗中僅有一個標籤頁時,關閉標籤頁的同時也會關閉視窗。 + + - 使用 快捷鍵**Ctrl + W** 關閉目前標籤頁。 + - 單擊標籤頁上的 ![close_icon](../common/close_icon.svg) 按鈕或者單擊滑鼠中鍵,關閉目前標籤頁。 + - 右鍵單擊標籤頁,選擇 **關閉標籤頁** 、**關閉其他標籤頁** 或 **更多關閉方式** 來關閉標籤頁。 + + > ![notes](../common/notes.svg)說明:如果您的檔案發生了變化而沒有儲存,文字編輯器會在關閉前提示您儲存更改。 + +### 開啟檔案 + +您可採用以下方式開啟一個或同時開啟多個文字檔案,選中的檔案將會在新標籤頁開啟: + +- 直接拖動檔案到文字編輯器介面或其圖示上。 +- 右鍵單擊檔案,選擇 **用其他程式開啟** > **文字編輯器**。選擇文字編輯器為預設開啟程式後,可直接雙擊檔案開啟。 +- 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)> **開啟檔案** 或使用快捷鍵 **Ctrl + O**,在彈出的視窗中選擇檔案。 + +### 儲存檔案 +- 單擊 ![icon_menu](../common/icon_menu.svg)> **儲存** 或使用快捷鍵 **Ctrl + S** ,儲存目前檔案。 +- 單擊 ![icon_menu](../common/icon_menu.svg)> **另存新檔** 或使用快捷鍵 **Ctrl + Shift + S**, 另存目前檔案。 + + +### 列印檔案 + +在文字編輯器中使用列印,需要您連接並配置好印表機。 + +1. 單擊 ![icon_menu](../common/icon_menu.svg) > **列印** 或使用快捷鍵 **Ctrl + P** 打開列印預覽。 +2. 在列印預覽介面,您可以預覽檔案,選擇印表機並設定列印頁面。 +3. 在列印預覽介面,單擊 **進階設定**,可配置紙張大小、列印方式等相關參數。 +4. 單擊 **列印** 即可將檔案發送到印表機列印。 + +![print](fig/print_setting.png) + +![print](fig/advanced_setting.png) + +## 編輯文字 + +### 移動游標 + +除了使用方向鍵和滑鼠單擊移動游標,您還可以使用以下快捷鍵迅速移動游標: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 儲存游標位置 | Ctrl + Shift + > | +| 重設游標位置(跳轉到上次游標儲存的位置) | Ctrl + Shift + < | +| 後一個字詞 (游標向右跳過一個字詞) | Ctrl + 右方向鍵 | +| 前一個字詞 (游標向左跳過一個字詞) | Ctrl + 左方向鍵 | +| 移動到行結尾 | End | +| 移動到行開頭 | Home | +| 移動到文字結尾 | Ctrl + End | +| 移動到文字開頭 | Ctrl + Home | +| 移到行縮排區塊 | Ctrl + M | +| 往後一對 (游標移動到右括號的後面) | Alt + P | +| 往前一對(游標移動到左括號的前面) | Alt + N | + +### 切換大小寫 + +切換大小寫功能可以將選中文字全部改為大寫字母、小寫字母或者首字母大寫。 + +1. 選中待更改的文字內容。 +2. 單擊右鍵,選擇 **變更大小寫**。 +3. 選擇 **大寫**/**小寫**/**首字母大寫** 選項。文字格式的更改會立即生效。 + +您也可以使用快捷鍵 **Alt + U/L/C** 迅速切換大小寫。 + +![toggle_case](fig/d_toggle_case.png) + +### 突顯文字 + +文字編輯器支援突顯不同類型的文字。單擊底部狀態欄最右側的三角符號, 選擇某種文字類型。若文字中有相應內容則會自動突顯。 + +![highlight](fig/highlight.png) + +### 刪除文字 +除了向左或向右逐個刪除字元外,您還可以使用以下快捷鍵迅速刪除字元: + +| 功能 | 快捷鍵 | +| --------------- | ------------ | +| 刪除至行結尾所有字元 | Ctrl + K | +| 刪除目前整行 | Ctrl + Shift + K | +| 刪除前一個字詞 | Alt + Shift + N | +| 刪除後一個字詞 | Alt + Shift + M | + +### 復原操作 + +如果在文字編輯時發生誤操作,您可以使用快捷鍵 **Ctrl + Z** 撤銷操作, 或者在右鍵選單中選擇 **復原**。 + +### 尋找文字 + +1. 單擊 ![menu](../common/icon_menu.svg)> **尋找** 或使用快捷鍵 **Ctrl + F** ,打開尋找視窗。 +2. 在尋找視窗中,輸入要搜尋的文字。 +3. 單擊 **上一個**、**下一個** 逐個尋找,或使用 **Enter** 鍵尋找下一個匹配項。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉尋找視窗。 + +> ![tips](../common/tips.svg)竅門:選中一段文字,再選擇尋找,則這段文字會自動出現在尋找視窗中。 + +### 取代文字 +1. 單擊 ![menu](../common/icon_menu.svg)> **取代** 或使用快捷鍵 **Ctrl + H**,打開取代視窗。 +2. 在取代為視窗中,輸入要取代的文字以及新文字。 +3. 單擊 **取代** 逐個取代,單擊 **取代剩餘部份**、**全部取代** 一次性取代剩餘的或所有的匹配文字。單擊 **跳過** 不取代目前匹配的文字。 +4. 按下 **Esc** 鍵或單擊關閉按鈕,關閉取代視窗。 + +### 前往該行 +使用該功能可以迅速前往到任一行。在右鍵選單中選擇 **前往該行** 或者使用快捷键 **Ctrl + G**,輸入行號即可前往到相應行。 + +### 編輯行 + +您可以使用以下快捷鍵迅速編輯行: + +| 功能 | 快捷鍵 | +| ------------ | ------------ | +| 於上方換行(在上方插入一行) | Ctrl + Enter | +| 於下方換行(在下方插入一行) | Ctrl + Shift + Enter | +| 複製一行 | Ctrl + Shift + D | +| 切到上一行(與上一行交換位置) | Ctrl + Shift + Up | +| 切到下一行(與下一行交換位置) | Ctrl + Shift + Down | +| 捲到上一行 | Super + Shift + Up | +| 捲到下一行 | Super + Shift + Down | +| 標記 | Alt + H | +| 取消標記 | Alt + Shift + H | +| 複製一行 | Super + C | +| 剪下一行 | Super + X | +| 合併一行 | Ctrl + J | + +### 開啟/關閉唯讀模式 + +1. 使用文字編輯器打開檔案,單擊右鍵,選擇 **開啟唯讀模式**。 +2. 在唯讀模式下,單擊右鍵,選擇 **關閉唯讀模式**。 + +![read_only](fig/d_read_only.png) + +![read_only](fig/d_read_only_02.png) + + +### 列编辑 +在文字編輯器介面,按住鍵盤上的 **Alt** 鍵不放,滑鼠左鍵單擊多列啟動列編輯模式,為多行程式碼同時編輯相同的內容,提高工作效率。 + +![column mode](fig/column mode.png) + +### 顏色標記 + +在文字編輯器介面,單擊滑鼠右鍵選擇 **顏色標記**,在其下拉選單中進行選擇。 + +![color](fig/d_color_tag.png) + + - **標記**:對某一行或某一段文字內容添加顏色標記;有8種顏色按鈕可供選擇。 + + 將游標定在某一行,標記目前所在的行。 + + 選中一段文字內容後,標記選中的文字內容。 + - **標記所有**:將文字內容全部標記或對已選中的文字內容,在全文中標記匹配項;有8種顏色按鈕可供選擇。 + + 將游標定在任意一行,將文字內容全部標記。 + + 選中一段文字內容,在全文中標記匹配項。 + - **清除上次標記**:清除上次標記操作。 + - **清除所有標記**:清除目前所有標記。 + + + +### 書籤管理 + +在文字編輯器設定介面,勾選 **顯示書籤圖標** 後,您可以為任意一行的文字內容添加書籤,將滑鼠遊標移至左側欄任意一行處會顯示 ![icon](../common/bookmark_normal_light.svg),添加成功後該行的書籤圖示會變為藍色填充的圖示 ![bookmarkbig](../common/bookmarkbig_checked_light.svg)。 + +- 添加書籤 + + + 滑鼠左鍵單擊 ![icon](../common/bookmark_normal_light.svg),為該行添加書籤。 + + 滑鼠右鍵單擊 ![icon](../common/bookmark_normal_light.svg),選擇 **添加書籤**,為該行添加書籤。 + + 將游標定在文字中任意一行,使用快捷鍵 **Ctrl + F2** 為該行添加書籤。 + +- 刪除書籤 + + + 滑鼠左鍵單擊已填充顏色的書籤圖示,直接刪除該行書籤。 + + 滑鼠右鍵單擊已填充顏色的書籤圖示,選擇 **清除書籤**,刪除該行書籤。 + + 滑鼠右鍵單擊書籤圖示,選擇 **清除所有書籤**,刪除該文字的全部書籤。 + + >![icon](../common/notes.svg)說明:滑鼠移到左側行號前面才會顯示書籤圖示,移出書籤區域,書籤圖示消失。添加書籤後,該圖示一直顯示。 + + + +### 注釋管理 + +在文字編輯器介面,您可以對副檔名為cpp 、java 、py等程式碼類型的檔案進行添加注釋的操作。 + +- 添加注釋 + + 選中一段文字內容,單擊右鍵並選擇 **添加注釋**。 + + 選中一段文字內容,使用快捷鍵 **Alt + A** 添加注釋。 + +- 取消注釋 + + 選中一段已添加注釋的文字內容,單擊右鍵並選擇 **取消注釋**。 + + 選中一段已添加注釋的文字內容,使用快捷鍵 **Alt + Z** 取消注釋。 + + >![notes](../common/notes.svg)說明:支援不同程式碼語言的注釋,具體以實際為主。例如C,C#,Java注釋符號為 //,Python 注釋符號為 #。 + + + +## 主選單 + +在主選單中,您可以 建立新視窗、建立新標籤頁、[尋找文字](#尋找文字)、[取代文字](#取代文字)、儲存檔案、切換視窗主題、查看說明手冊,了解文字編輯器的更多訊息。 + +### 設定 +您可以對基本訊息、快捷鍵和進階訊息進行設定。 + +#### 基本設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**。 +2. 在基本設定選項,您可以選擇: + - 設定字體樣式,選擇字體和字體大小。 + - 勾選 **文字換行**,在編輯區自動換行。 + - 勾選 **顯示代碼摺疊標誌**,在左側欄顯示![next](../common/next.svg)或者![next](../common/next_down.svg)按鈕,右鍵單擊按鈕選擇摺疊/展開目前層次或所有層次。 + - 勾選 **顯示行號**,在左側欄顯示行號。 + - 勾選**當前行高亮**,游標所在的行突顯顯示。 + - 勾選 **顯示書籤圖示**,在左側欄顯示書籤圖示。 + - 勾選 **顯示空白制符/制表符**,顯示文字中的空白字符和制表符,您也可以手動輸入或刪除空白字符和制表符。 + > ![tips](../common/tips.svg)竅門:您還可以使用 **Ctrl + 「+」/ 「-」** 來調節文字編輯器的預設字號。使用 **Ctrl + 0** 復原預設字號。 + + + +#### 快捷鍵設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**,在 **快捷鍵** 選項查看目前快捷鍵。 +2. 選擇一種按鍵映射。 +3. 單擊並重新輸入快捷鍵,可以自訂快捷鍵。 + + > ![notes](../common/notes.svg)說明: 按鍵映射允許您選擇某一種鍵盤快捷鍵。您可以使用標準快捷鍵、Emacs快捷鍵、或自訂快捷鍵,以符合您的使用習慣。 + + +#### 進階設定 + +1. 單擊 ![icon_menu](../common/icon_menu.svg)> **設定**。 +2. 在 **進階設定** 選項,您可以設定: + - 視窗大小:一般、最大或全螢幕。 + - Tab寬度:Tab縮排所占用的空間大小。 + + + +### 主題 + +視窗主題包含亮色主題、暗色主題和系統主題。 + +1. 在文字編輯器介面,單擊![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **主題**,選擇一個主題顏色。 + +### 說明 + +查看說明手冊,進一步了解和使用文字編輯器。 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **說明**。 +3. 查看文字編輯器的說明手冊。 + +### 關於 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **關於**。 +3. 查看文字編輯器的版本和介紹。 + +### 離開 + +1. 在文字編輯器介面,單擊 ![icon_menu](../common/icon_menu.svg)。 +2. 單擊 **離開**。 \ No newline at end of file diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/advanced_setting.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/advanced_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..7ecf14a7f1162b7c2ad15102f66f03ed97d62263 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/advanced_setting.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/close.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/close.png new file mode 100644 index 0000000000000000000000000000000000000000..eb5704b81bca1efccd06786eb2a324c63b3edcf0 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/close.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/color_tag.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/color_tag.png new file mode 100644 index 0000000000000000000000000000000000000000..31ebc41567d152199195fbc33b07d52a60b55df5 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/color_tag.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/column mode.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/column mode.png new file mode 100644 index 0000000000000000000000000000000000000000..efeb5f854f7f16c90b298e3473dd4a9724c4a1cd Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/column mode.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_color_tag.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_color_tag.png new file mode 100644 index 0000000000000000000000000000000000000000..a5923c736852e1e1e59160a5b733a6d579c0c247 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_color_tag.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read-only_02.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read-only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..db0fa12522ccc61290002dae7a524cd5a0727d19 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read-only_02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read_only.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read_only.png new file mode 100644 index 0000000000000000000000000000000000000000..af2fcf4fa489ca5e4b178973601efe48467c4f95 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read_only_02.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read_only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..022dba9fb5956aef8851d907e6270673c3736413 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_read_only_02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_toggle_case.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_toggle_case.png new file mode 100644 index 0000000000000000000000000000000000000000..be9bdc902c80095e57d5c4dc0b50eb94a6bd8159 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/d_toggle_case.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/editer.psd b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/editer.psd new file mode 100644 index 0000000000000000000000000000000000000000..d68083edaf82a349425c63540ac895a3dfa4bb5b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/editer.psd differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/highlight.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..f16308bd678e8650e3701ed9a994a8e7202c9072 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/highlight.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/hotkey.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/hotkey.png new file mode 100644 index 0000000000000000000000000000000000000000..e3225d97e31be3827dc2b4bb222b097e61493c94 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/hotkey.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/listen.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/listen.png new file mode 100644 index 0000000000000000000000000000000000000000..d397f90eaad0909f49535c74cb5cb58d949b2f2b Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/listen.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/overview.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..764cf82fcfce532c908bb8f38df53f6013bdab41 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/overview.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/print_setting.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/print_setting.png new file mode 100644 index 0000000000000000000000000000000000000000..9d08dc8e9097beb003a7f5b9d5d13cb2e54c103a Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/print_setting.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/read_only.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/read_only.png new file mode 100644 index 0000000000000000000000000000000000000000..96658be2ad45d728b8780d9ec4658b72bd56dd86 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/read_only.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/read_only_02.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/read_only_02.png new file mode 100644 index 0000000000000000000000000000000000000000..a5f735b475e7c695f9c56c426a82616eb25c0525 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/read_only_02.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/reading.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/reading.png new file mode 100644 index 0000000000000000000000000000000000000000..7fe6846cd99c737fe62a3b29e48e76576f170b4e Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/reading.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/text translation.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/text translation.png new file mode 100644 index 0000000000000000000000000000000000000000..f76230034be4aecffeed0ee1c6129efd60590c47 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/text translation.png differ diff --git a/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/toggle_case.png b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/toggle_case.png new file mode 100644 index 0000000000000000000000000000000000000000..32351990a6966c71870ccfadedfcca381f573b75 Binary files /dev/null and b/src/assets/loongarch64/deepin-editor/editor/zh_TW/fig/toggle_case.png differ diff --git "a/src/assets/loongarch64/deepin-editor/editor/\344\277\256\350\256\242\350\256\260\345\275\225.txt" "b/src/assets/loongarch64/deepin-editor/editor/\344\277\256\350\256\242\350\256\260\345\275\225.txt" new file mode 100755 index 0000000000000000000000000000000000000000..9596082445064dcb344d14cd043c02800233b3e5 --- /dev/null +++ "b/src/assets/loongarch64/deepin-editor/editor/\344\277\256\350\256\242\350\256\260\345\275\225.txt" @@ -0,0 +1,3 @@ +龙芯3A5000 文本编辑器修订记录 +版本 5.9.16 +此版本镜像无语音助手,所以不支持语音朗读、语音听写、文本翻译这三个功能 \ No newline at end of file diff --git a/src/common/CSyntaxHighlighter.cpp b/src/common/CSyntaxHighlighter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2e62ce86bd8fb13bac68f9055a96d3f8fa9d5e3 --- /dev/null +++ b/src/common/CSyntaxHighlighter.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "CSyntaxHighlighter.h" +#include + +CSyntaxHighlighter::CSyntaxHighlighter(QObject *parent): + SyntaxHighlighter (parent), + m_bHighlight(false) +{ + +} + +CSyntaxHighlighter::CSyntaxHighlighter(QTextDocument *pDocument): + SyntaxHighlighter (pDocument),m_bHighlight(false) +{ + +} + +void CSyntaxHighlighter::setEnableHighlight(bool isEnable) +{ + m_bHighlight = isEnable; +} + +void CSyntaxHighlighter::highlightBlock(const QString &text) +{ + if (!m_bHighlight) { + return; + } + + KSyntaxHighlighting::SyntaxHighlighter::highlightBlock(text); +} diff --git a/src/common/CSyntaxHighlighter.h b/src/common/CSyntaxHighlighter.h new file mode 100644 index 0000000000000000000000000000000000000000..4ff05468aa335b6e59f236a4e8a7be1b073b357e --- /dev/null +++ b/src/common/CSyntaxHighlighter.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once +#include +#include +#include + +using namespace KSyntaxHighlighting; +class CSyntaxHighlighter : public SyntaxHighlighter +{ + Q_OBJECT +public: + explicit CSyntaxHighlighter(QObject *parent = nullptr); + explicit CSyntaxHighlighter(QTextDocument *pDocument); + void setEnableHighlight(bool isEnable); + +protected: + virtual void highlightBlock(const QString & text) override; + +private: + bool m_bHighlight = false; +}; diff --git a/src/common/comment_global.h b/src/common/comment_global.h new file mode 100644 index 0000000000000000000000000000000000000000..60a60559f05dbed5cc466cb848f9a3554d2f549d --- /dev/null +++ b/src/common/comment_global.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +#if defined(UTILS_LIBRARY) +# define COMMENT_EXPORT Q_DECL_EXPORT +#elif defined(UTILS_STATIC_LIB) +# define COMMENT_EXPORT +#else +# define COMMENT_EXPORT Q_DECL_IMPORT +#endif diff --git a/src/common/common.h b/src/common/common.h new file mode 100644 index 0000000000000000000000000000000000000000..3413304541d7cc592b7138598953f4a33adc6749 --- /dev/null +++ b/src/common/common.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef COMMON_H +#define COMMON_H + +#include "../controls/findbar.h" +#include "../controls/fontitemdelegate.h" +#include "../controls/jumplinebar.h" +#include "../controls/linebar.h" +#include "../controls/replacebar.h" +#include "../controls/tabbar.h" +#include "../controls/toast.h" +#include "../controls/toolbar.h" +#include "../controls/warningnotices.h" + + +#include "../common/comment_global.h" +#include "../common/dbusinterface.h" +#include "../common/encoding.h" +#include "../common/fileloadthread.h" +#include "../common/performancemonitor.h" +#include "../common/settings.h" +#include "../common/urlinfo.h" +#include "../common/utils.h" + + +#include "../encodes/detectcode.h" + + +#include "../widgets/bottombar.h" +#include "../widgets/ColorSelectWdg.h" +#include "../widgets/ddropdownmenu.h" +#include "../widgets/window.h" + + +#include "../thememodule/themeitemdelegate.h" +#include "../thememodule/themelistmodel.h" +#include "../thememodule/themelistview.h" +#include "../thememodule/themepanel.h" + + +#include "../editor/bookmarkwidget.h" +#include "../editor/codeflodarea.h" +#include "../editor/editwrapper.h" +#include "../editor/leftareaoftextedit.h" +#include "../editor/linenumberarea.h" +#include "../editor/showflodcodewidget.h" +#include "../editor/uncommentselection.h" +#endif // COMMON_H diff --git a/src/common/config.cpp b/src/common/config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1aafb1bef53036a97e1bc5fca7e676e8fa5e36c --- /dev/null +++ b/src/common/config.cpp @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "config.h" + +#include + +#ifdef DTKCORE_CLASS_DConfigFile +#include + +const QString g_keyDisableImproveGB18030 = "disableImproveGB18030"; +#endif + +/** + @class Config + @brief 获取DConfig配置 + @details 取得DConfig配置,目前主要用于配置是否提高GB18030识别率。 + 配置文件路径为 /usr/share/dsg/configs/org.deepin.editor/org.deepin.editor.json + */ + +Config::Config(QObject *parent) + : QObject(parent) +{ +#ifdef DTKCORE_CLASS_DConfigFile + dconfig = DConfig::create("org.deepin.editor", "org.deepin.editor"); + if (dconfig->isValid()) { + // 默认提高GB18030识别率 + improveGB18030 = !dconfig->value(g_keyDisableImproveGB18030).toBool(); + qInfo() << "DConfig::ImproveGB18030:" << improveGB18030; + + connect(dconfig, &DConfig::valueChanged, this, [this](const QString &key) { + if (key == g_keyDisableImproveGB18030) { + this->improveGB18030 = !this->dconfig->value(g_keyDisableImproveGB18030).toBool(); + qInfo() << "DConfig::ImproveGB18030 Changed:" << improveGB18030; + } + }); + } else { + qWarning() << "org.deepin.editor DConfig not valid!"; + } +#else + qWarning() << "DConfig is not supported by DTK!"; +#endif +} + +Config::~Config() +{ +#ifdef DTKCORE_CLASS_DConfigFile + if (dconfig) { + delete dconfig; + } +#endif +} + +Config *Config::instance() +{ + static Config config; + return &config; +} + +bool Config::enableImproveGB18030() const +{ + return improveGB18030; +} diff --git a/src/common/config.h b/src/common/config.h new file mode 100644 index 0000000000000000000000000000000000000000..a772bb0631b5e72fce29fdfaea5ab0c743291e00 --- /dev/null +++ b/src/common/config.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CONFIG_H +#define CONFIG_H + +#include + +#include +#ifdef DTKCORE_CLASS_DConfigFile +#include +DCORE_USE_NAMESPACE +#endif + +class Config : public QObject +{ + Q_OBJECT + explicit Config(QObject *parent = nullptr); + ~Config() override; + +public: + static Config *instance(); + bool enableImproveGB18030() const; + +private: +#ifdef DTKCORE_CLASS_DConfigFile + DConfig *dconfig = nullptr; +#endif + bool improveGB18030 = true; ///< 默认提高GB18030编码识别率 +}; + +#endif // CONFIG_H diff --git a/src/common/dbusinterface.cpp b/src/common/dbusinterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..764e52c8f4bab9255e8a8dae2e9df233edc43205 --- /dev/null +++ b/src/common/dbusinterface.cpp @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "dbusinterface.h" + +SaveFileInterface::SaveFileInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +SaveFileInterface::~SaveFileInterface() +{ +} diff --git a/src/common/dbusinterface.h b/src/common/dbusinterface.h new file mode 100644 index 0000000000000000000000000000000000000000..a7b1c20772d51167b0546567c925a34f71a3fa35 --- /dev/null +++ b/src/common/dbusinterface.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef DBUS_INTERFACE_H +#define DBUS_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class SaveFileInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() { + return "com.deepin.editor.daemon"; + } + +public: + SaveFileInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); + ~SaveFileInterface(); + +public Q_SLOTS: // METHODS +// inline QDBusPendingReply saveFile(const QByteArray &filepath, const QByteArray &text, const QByteArray &encoding) { +// QList argumentList; +// argumentList << QVariant::fromValue(filepath) << QVariant::fromValue(text) << QVariant::fromValue(encoding); +// return asyncCallWithArgumentList(QStringLiteral("saveFile"), argumentList); +// } + +Q_SIGNALS: // SIGNALS +}; + +namespace DBusDaemon { + typedef ::SaveFileInterface dbus; +} +#endif diff --git a/src/common/encoding.cpp b/src/common/encoding.cpp new file mode 100644 index 0000000000000000000000000000000000000000..40cd023f51d48f1e55170b358e53cd75ab59b7c4 --- /dev/null +++ b/src/common/encoding.cpp @@ -0,0 +1,684 @@ +/* + * Copyright (C) Pedram Pourang (aka Tsu Jan) 2014-2020 + * + * FeatherPad 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 2 of the License, or + * (at your option) any later version. + * + * FeatherPad 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 . + * + * @license GPL-2.0+ + */ + +/* This file was adapted from + * Leafpad - GTK+ based simple text editor + * File: src/encoding.c + * Copyright: 2004-2005 Tarot Osuji + * License: GPL-2.0+ + * Homepage: http://tarot.freeshell.org/leafpad/ + */ + +#include +#include // getenv (not used but, maybe, for *BSD) +#include // CODESET, nl_langinfo +#include // uint8_t, uint32_t +//#include // needed by FreeBSD for setlocale +#include "encoding.h" + +#define MAX_COUNTRY_NUM 10 +enum +{ + IANA = 0, + OPENI18N, + CODEPAGE, + ENCODING_MAX_ITEM_NUM +}; +/*------------------------*/ +/* encoding numbers */ +enum +{ + LATIN1 = 0, + LATIN2, + LATIN3, + LATIN4, + LATINC, + LATINC_UA, + LATINC_TJ, + LATINA, + LATING, + LATINH, + LATIN5, + CHINESE_CN, + CHINESE_TW, + CHINESE_HK, + JAPANESE, + KOREAN, + VIETNAMESE, + THAI, + GEORGIAN, + TOTAL_NUM // 19 +}; +/*------------------------*/ +static const std::string countryTable[TOTAL_NUM][MAX_COUNTRY_NUM] = +{ + /* list of countries using each encoding set */ + /* LATIN1 */ {"" , "", "", "", "", "", "", "", "", "" }, + /* LATIN2 */ {"cs", "hr", "hu", "pl", "ro", "sk", "sl", "sq", "sr", "uz"}, + /* LATIN3 */ {"eo", "mt", "", "", "", "", "", "", "", "" }, + /* LATIN4 */ {"et", "lt", "lv", "mi", "", "", "", "", "", "" }, + /* LATINC */ {"be", "bg", "ky", "mk", "mn", "ru", "tt", "", "", "" }, + /* LATINC_UA */ {"uk", "", "", "", "", "", "", "", "", "" }, + /* LATINC_TJ */ {"tg", "", "", "", "", "", "", "", "", "" }, + /* LATINA */ {"ar", "fa", "ur", "", "", "", "", "", "", "" }, + /* LATING */ {"el", "", "", "", "", "", "", "", "", "" }, + /* LATINH */ {"he", "yi", "", "", "", "", "", "", "", "" }, + /* LATIN5 */ {"az", "tr", "", "", "", "", "", "", "", "" }, + /* CHINESE_CN */ {"zh_CN", "", "", "", "", "", "", "", "", "" }, + /* CHINESE_TW */ {"zh_TW", "", "", "", "", "", "", "", "", "" }, + /* CHINESE_HK */ {"zh_HK", "", "", "", "", "", "", "", "", "" }, + /* JAPANESE */ {"ja", "", "", "", "", "", "", "", "", "" }, + /* KOREAN */ {"ko", "", "", "", "", "", "", "", "", "" }, + /* VIETNAMESE */ {"vi", "", "", "", "", "", "", "", "", "" }, + /* THAI */ {"th", "", "", "", "", "", "", "", "", "" }, + /* GEORGIAN */ {"ka", "", "", "", "", "", "", "", "", "" } +}; +/*------------------------*/ +static const std::string encodingTable[TOTAL_NUM][ENCODING_MAX_ITEM_NUM] = +{ + /* IANA OpenI18N CODEPAGE */ + /* LATIN1 */ { "ISO-8859-1", "ISO-8859-15", "CP1252" }, + /* LATIN2 */ { "ISO-8859-2", "ISO-8859-16", "CP1250" }, + /* LATIN3 */ { "ISO-8859-3", "", "" }, + /* LATIN4 */ { "ISO-8859-4", "ISO-8859-13", "CP1257" }, + /* LATINC */ { "ISO-8859-5", "KOI8-R", "CP1251" }, + /* LATINC_UA */ { "ISO-8859-5", "KOI8-U", "CP1251" }, + /* LATINC_TJ */ { "ISO-8859-5", "KOI8-T", "CP1251" }, + /* LATINA */ { "ISO-8859-6", "", "CP1256" }, + /* LATING */ { "ISO-8859-7", "", "CP1253" }, + /* LATINH */ { "ISO-8859-8", "", "CP1255" }, + /* LATIN5 */ { "ISO-8859-9", "", "CP1254" }, + /* CHINESE_CN */ { "GB2312", "GB18030", "CP936" }, + /* CHINESE_TW */ { "BIG5", "EUC-TW", "CP950" }, + /* CHINESE_HK */ { "BIG5", "BIG5-HKSCS", "CP950" }, + /* JAPANESE */ { "ISO-2022-JP", "EUC-JP", "CP932" }, + /* KOREAN */ { "ISO-2022-KR", "EUC-KR", "CP949" }, + /* VIETNAMESE */ { "", "VISCII", "CP1258" }, + /* THAI */ { "", "TIS-620", "CP874" }, + /* GEORGIAN */ { "", "GEORGIAN-PS", "" } +}; +/*************************/ +static unsigned int getLocaleNum() +{ + static unsigned int code = 0; // for me + QStringList langs (QLocale::system().uiLanguages()); + if (!langs.isEmpty()) + { + QString lang = langs.first().replace ('-', '_'); + if (lang.length() >= 2) + { + std::string env = lang.toStdString(); + if (!env.empty() && env.length() >= 2) + { + int j = 1; + while (code == 0 && j < TOTAL_NUM) + { + for (int i = 0; i < MAX_COUNTRY_NUM; i++) + { + if (countryTable[j][i].empty()) + break; + if (env.compare (0, countryTable[j][i].length(), countryTable[j][i]) == 0) + { + code = j; + break; + } + } + j++; + } + } + } + } + return code; +} +/*************************/ +static unsigned int localeNum = getLocaleNum(); +static const std::string encodingItem[ENCODING_MAX_ITEM_NUM] = {encodingTable[localeNum][0], + encodingTable[localeNum][1], + encodingTable[localeNum][2]}; +/*************************/ +static const std::string detectCharsetLatin (const char *text) +{ + uint8_t c = *text; + bool noniso = false; + bool noniso15 = false; + uint32_t xl = 0, xa = 0, xac = 0, xcC = 0, xcC1 = 0, xcS = 0, xcna = 0; + /* the OpenI18N for the locale ("ISO-8859-15" for me) */ + std::string charset = encodingItem[OPENI18N]; + + while (c != '\0') + { + if (c >= 0x41 && c <= 0x7A) + { + /* ordinary Latin letters */ + xl ++; + } + else if (c >= 0x80 && c <= 0x9F) + { + noniso = true; + } + else if (c >= 0xC0) + { + /* Arabic or Cyrillic letters */ + xac ++; + if (c >= 0xC0 && c <= 0xCF) + { + /* Cyrillic capital letters */ + xcC++; + } + else if (c >= 0xD0 && c <= 0xDF) + { + /* Cyrillic capital letters again */ + xcC1++; + if (c == 0xDE || c == 0xDF) + { + /* not used in ISO-8859-15 (Icelandic or German) */ + noniso15 = true; + } + } + else if (c >= 0xE0) + { + /* Cyrillic small letters */ + xcS++; + /* Cyrillic but not Arabic letters */ + if (c == 0xE0 || c == 0xE2 || (c >= 0xE7 && c <= 0xEB) + || c == 0xEE || c == 0xEF || c == 0xF4 || c == 0xF9 + || c == 0xFB || c == 0xFC) + { + xcna ++; + } + /* Arabic LAM to HEH */ + else if (c == 0xE1 || c == 0xE3 || c == 0xE4 + || c == 0xE5 || c == 0xE6) + { + xa++; + } + } + } + c = *text++; + } + + /* when there is a difference fom ISO-8859-1 and ISO-8859-15, + and ordinary Latin letters are more than Arabic ones, + and the text isn't Cyrillic KOI8-U */ + if (noniso && xl >= xac && (xcC1 + xcS >= xcC || xcna == 0)) + charset = "CP1252"; // Windows-1252 + else // if (xl < xac) + { + if (!noniso && xcC + xcS < xcC1) + charset = "ISO-8859-15"; // FIXME: ISO-8859-5 ? + /* this is very tricky and I added it later */ + else if (!noniso && xcC + xcC1 + xa >= xcS - xa && !(xcC1 + xcS < xcC && xcna > 0)) + charset = "ISO-8859-1"; + else if (xcC + xcC1 < xcS && xcna > 0) + { + if (noniso || noniso15) // FIXME: this is very inefficient + charset = "CP1251"; // Cyrillic-1251 + else + charset = "ISO-8859-15"; + } + else if (xcC1 + xcS < xcC && xcna > 0) + charset = "KOI8-U"; // Cyrillic-KOI + /* this should cover most cases */ + else if (noniso || xcC + xcC1 + xa >= xcS - xa) + charset = "CP1256"; // MS Windows Arabic + } + + return charset; +} +/*************************/ +static const std::string detectCharsetCyrillic (const char *text) +{ + uint8_t c = *text; + bool noniso = false; + uint32_t xl = 0, xa = 0, xac = 0, xcC = 0, xcC1 = 0, xcS = 0, xcna = 0; + std::string charset = encodingItem[OPENI18N]; + + while (c != '\0') + { + if (c >= 0x41 && c <= 0x7A) + xl ++; + if (c >= 0x80 && c <= 0x9F) + noniso = true; + else if (c >= 0xC0) + { + xac ++; + if (c >= 0xC0 && c <= 0xCF) + xcC++; + else if (c >= 0xD0 && c <= 0xDF) + xcC1++; + else if (c >= 0xE0) + { + xcS++; + if (c == 0xE0 || c == 0xE2 || (c >= 0xE7 && c <= 0xEB) + || c == 0xEE || c == 0xEF || c == 0xF4 || c == 0xF9 + || c == 0xFB || c == 0xFC) + { + xcna ++; + } + else if (c == 0xE1 || c == 0xE3 || c == 0xE4 + || c == 0xE5 || c == 0xE6) + { + xa++; + } + } + } + c = *text++; + } + + if (xl < xac) + { + if (!noniso && (xcC + xcS < xcC1)) + charset = "ISO-8859-5"; + else if (xcC + xcC1 < xcS && xcna > 0) + charset = "CP1251"; + else if (xcC1 + xcS < xcC && xcna > 0) + charset = "KOI8-U"; + else if (noniso || xcC + xcC1 + xa >= xcS - xa) + charset = "CP1256"; + } + + return charset; +} +/*************************/ +static const std::string detectCharsetWinArabic (const char *text) +{ + uint8_t c = *text; + uint32_t xl = 0, xa = 0; + std::string charset = encodingItem[IANA]; + + while (c != '\0') + { + if (c >= 0x41 && c <= 0x7A) + xl ++; + else if (c >= 0xC0) + xa ++; + c = *text++; + } + + if (xl < xa) + charset = "CP1256"; + + return charset; +} +/*************************/ +static const std::string detectCharsetChinese (const char *text) +{ + uint8_t c = *text; + std::string charset = encodingItem[IANA]; + + while ((c = *text++) != '\0') + { + if (c >= 0x81 && c <= 0x87) + { + charset = "GB18030"; + break; + } + else if (c >= 0x88 && c <= 0xA0) + { + c = *text++; + if ((c >= 0x30 && c <= 0x39) || (c >= 0x80 && c <= 0xA0)) + { + charset = "GB18030"; + break; + } //else GBK/Big5-HKSCS cannot determine + } + else if ((c >= 0xA1 && c <= 0xC6) || (c >= 0xC9 && c <= 0xF9)) + { + c = *text++; + if (c >= 0x40 && c <= 0x7E) + charset = "BIG5"; + else if ((c >= 0x30 && c <= 0x39) || (c >= 0x80 && c <= 0xA0)) + { + charset = "GB18030"; + break; + } + } + else if (c >= 0xC7) + { + c = *text++; + if ((c >= 0x30 && c <= 0x39) || (c >= 0x80 && c <= 0xA0)) + { + charset = "GB18030"; + break; + } + } + } + + return charset; +} +/*************************/ +static const std::string detectCharsetJapanese (const char *text) +{ + uint8_t c = *text; + std::string charset = ""; + + while (charset.empty() && (c = *text++) != '\0') + { + if (c >= 0x81 && c <= 0x9F) + { + if (c == 0x8E) /* SS2 */ + { + c = *text++; + if ((c >= 0x40 && c <= 0xA0) || (c >= 0xE0 && c <= 0xFC)) + charset = "CP932"; + } + else if (c == 0x8F) /* SS3 */ + { + c = *text++; + if (c >= 0x40 && c <= 0xA0) + charset = "CP932"; + else if (c >= 0xFD) + break; + } + else + charset = "CP932"; + } + else if (c >= 0xA1 && c <= 0xDF) + { + c = *text++; + if (c <= 0x9F) + charset = "CP932"; + else if (c >= 0xFD) + break; + } + else if (c >= 0xE0 && c <= 0xEF) + { + c = *text++; + if (c >= 0x40 && c <= 0xA0) + charset = "CP932"; + else if (c >= 0xFD) + break; + } + else if (c >= 0xF0) + break; + } + + if (charset.empty()) + charset = "EUC-JP"; + + return charset; +} +/*************************/ +static const std::string detectCharsetKorean (const char *text) +{ + uint8_t c = *text; + bool noneuc = false; + bool nonjohab = false; + std::string charset = ""; + + while (charset.empty() && (c = *text++) != '\0') + { + if (c >= 0x81 && c < 0x84) + { + charset = "CP949"; + } + else if (c >= 0x84 && c < 0xA1) + { + noneuc = true; + c = *text++; + if ((c > 0x5A && c < 0x61) || (c > 0x7A && c < 0x81)) + charset = "CP1361"; + else if (c == 0x52 || c == 0x72 || c == 0x92 || (c > 0x9D && c < 0xA1) + || c == 0xB2 || (c > 0xBD && c < 0xC1) || c == 0xD2 + || (c > 0xDD && c < 0xE1) || c == 0xF2 || c == 0xFE) + { + charset = "CP949"; + } + } + else if (c >= 0xA1 && c <= 0xC6) + { + c = *text++; + if (c < 0xA1) + { + noneuc = true; + if ((c > 0x5A && c < 0x61) || (c > 0x7A && c < 0x81)) + charset = "CP1361"; + else if (c == 0x52 || c == 0x72 || c == 0x92 || (c > 0x9D && c < 0xA1)) + charset = "CP949"; + else if (c == 0xB2 || (c > 0xBD && c < 0xC1) || c == 0xD2 + || (c > 0xDD && c < 0xE1) || c == 0xF2 || c == 0xFE) + { + nonjohab = true; + } + } + } + else if (c > 0xC6 && c <= 0xD3) + { + c = *text++; + if (c < 0xA1) + charset = "CP1361"; + } + else if (c > 0xD3 && c < 0xD8) + { + nonjohab = true; + c = *text++; + } + else if (c >= 0xD8) + { + c = *text++; + if (c < 0xA1) + charset = "CP1361"; + } + if (noneuc && nonjohab) + charset = "CP949"; + } + + if (charset.empty()) + { + if (noneuc) + charset = "CP949"; + else + charset = "EUC-KR"; + } + + return charset; + +} +/*************************/ +// The character set of the locale +// ("UTF-8" for me) +static const std::string getDefaultCharset() +{ + if (setlocale (LC_ALL, "") == NULL) + return "UTF-8"; // something's wrong; fall back to UTF-8 + const std::string charset = nl_langinfo (CODESET); + return charset; +} +/*************************/ +static bool detect_noniso (const char *text) +{ + uint8_t c = *text; + + while ((c = *text++) != '\0') + { + if (c >= 0x80 && c <= 0x9F) + return true; + } + return false; +} +/*************************/ +/* In the GTK+ version, I used g_utf8_validate() + but this function validates UTF-8 directly + and seems faster than using QTextCodec::ConverterState + with QTextCodec::toUnicode(), which may give incorrect results. */ +bool validateUTF8 (const QByteArray byteArray) +{ + const char *string = byteArray.constData(); + if (!string) return true; + + const unsigned char *bytes = (const unsigned char*)string; + unsigned int cp; // code point + int bn; // bytes number + + while (*bytes != 0x00) + { + /* assuming that UTF-8 maps a sequence of 1-4 bytes, + we find the code point and the number of bytes */ + if ((*bytes & 0x80) == 0x00) + { // 0xxxxxxx, all ASCII characters (0-127) + cp = (*bytes & 0x7F); + bn = 1; + } + else if ((*bytes & 0xE0) == 0xC0) + { // 110xxxxx 10xxxxxx + cp = (*bytes & 0x1F); + bn = 2; + } + else if ((*bytes & 0xF0) == 0xE0) + { // 1110xxxx 10xxxxxx 10xxxxxx + cp = (*bytes & 0x0F); + bn = 3; + } + else if ((*bytes & 0xF8) == 0xF0) + { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + cp = (*bytes & 0x07); + bn = 4; + } + else + return false; + + bytes += 1; + for (int i = 1; i < bn; ++i) + { + /* all the other bytes should be of the form 10xxxxxx */ + if ((*bytes & 0xC0) != 0x80) + return false; + cp = (cp << 6) | (*bytes & 0x3F); + bytes += 1; + } + + if (cp > 0x10FFFF // max code point by definition + /* the range from 0xd800 to 0xdfff is reserved + for use with UTF-16 and excluded from UTF-8 */ + || (cp >= 0xD800 && cp <= 0xDFFF) + /* logically impossible situations */ + || (cp <= 0x007F && bn != 1) + || (cp >= 0x0080 && cp <= 0x07FF && bn != 2) + || (cp >= 0x0800 && cp <= 0xFFFF && bn != 3) + || (cp >= 0x10000 && cp <= 0x1FFFFF && bn != 4)) + { + return false; + } + } + + return true; +} +/*************************/ +const QString detectCharset (const QByteArray& byteArray) +{ + const char* text = byteArray.constData(); + uint8_t c = *text; + std::string charset; + + if (validateUTF8 (byteArray)) + { + while ((c = *text++) != '\0') + { + if (c > 0x7F) + { + charset = "UTF-8"; + break; + } + if (c == 0x1B) /* ESC */ + { + c = *text++; + if (c == '$') + { + c = *text++; + switch (c) + { + case 'B': // JIS X 0208-1983 + case '@': // JIS X 0208-1978 + charset = "ISO-2022-JP"; + continue; + case 'A': // GB2312-1980 + charset = "ISO-2022-JP-2"; + break; + case '(': + c = *text++; + switch (c) + { + case 'C': // KSC5601-1987 + case 'D': // JIS X 0212-1990 + charset = "ISO-2022-JP-2"; + } + break; + case ')': + c = *text++; + if (c == 'C') + charset = "ISO-2022-KR"; // KSC5601-1987 + } + break; + } + } + } + if (charset.empty()) + charset = getDefaultCharset(); + } + + if (charset.empty()) + { + switch (localeNum) + { + case LATIN1: + /* Windows-1252 */ + charset = detectCharsetLatin (text); + break; + case LATINC: + case LATINC_UA: + case LATINC_TJ: + /* Cyrillic */ + charset = detectCharsetCyrillic (text); + break; + case LATINA: + /* MS Windows Arabic */ + charset = detectCharsetWinArabic (text); + break; + case CHINESE_CN: + case CHINESE_TW: + case CHINESE_HK: + charset = detectCharsetChinese (text); + break; + case JAPANESE: + charset = detectCharsetJapanese (text); + break; + case KOREAN: + charset = detectCharsetKorean (text); + break; + case VIETNAMESE: + case THAI: + case GEORGIAN: + charset = encodingItem[OPENI18N]; + break; + default: + if (getDefaultCharset() != "UTF-8") + charset = getDefaultCharset(); + else if (detect_noniso (text)) + charset = encodingItem[CODEPAGE]; + else + charset = encodingItem[OPENI18N]; + if (charset.empty()) + charset = encodingItem[IANA]; + } + } + + return QString::fromStdString (charset); +} + + diff --git a/src/common/encoding.h b/src/common/encoding.h new file mode 100644 index 0000000000000000000000000000000000000000..921a942454488400e0f8612c5ebdc9a4f4de5ffa --- /dev/null +++ b/src/common/encoding.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) Pedram Pourang (aka Tsu Jan) 2014-2020 + * + * FeatherPad 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 2 of the License, or + * (at your option) any later version. + * + * FeatherPad 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 . + * + * @license GPL-2.0+ + */ + +#ifndef ENCODING_H +#define ENCODING_H + +#include + +const QString detectCharset (const QByteArray& byteArray); + +#endif // ENCODING_H diff --git a/src/common/eventlogutils.cpp b/src/common/eventlogutils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8caa26fd31e0abf5f0f17129dca7f84f9474d91 --- /dev/null +++ b/src/common/eventlogutils.cpp @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "eventlogutils.h" +#include +#include +#include +#include + +Eventlogutils *Eventlogutils::m_pInstance = nullptr; +Eventlogutils *Eventlogutils::GetInstance() +{ + if (m_pInstance == nullptr) { + m_pInstance = new Eventlogutils(); + } + return m_pInstance; +} + +void Eventlogutils::writeLogs(QJsonObject &data) +{ + if (!writeEventLogFunc) + return; + + writeEventLogFunc(QJsonDocument(data).toJson(QJsonDocument::Compact).toStdString()); +} + +Eventlogutils::Eventlogutils() +{ + QLibrary library("libdeepin-event-log.so"); + initFunc = reinterpret_cast(library.resolve("Initialize")); + writeEventLogFunc = reinterpret_cast(library.resolve("WriteEventLog")); + + if (!initFunc) + return; + + initFunc("deepin-editor", true); +} diff --git a/src/common/eventlogutils.h b/src/common/eventlogutils.h new file mode 100644 index 0000000000000000000000000000000000000000..27c55fe26a330b6fa552cfe27703571b296d6692 --- /dev/null +++ b/src/common/eventlogutils.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef EVENTLOGUTILS_H +#define EVENTLOGUTILS_H +#include +#include + +class Eventlogutils +{ +public: + enum EventTID { + OpenTime = 1000000000, + CloseTime = 1000000001, + StartUp = 1000000003, + Quit = 1000000004, + }; + + static Eventlogutils *GetInstance(); + void writeLogs(QJsonObject &data); +private : + static Eventlogutils *m_pInstance; + Eventlogutils(); + + bool (*initFunc)(const std::string &packagename, bool enable_sig) = nullptr; + void (*writeEventLogFunc)(const std::string &eventdata) = nullptr; +}; + +#endif // EVENTLOGUTILS_H diff --git a/src/common/fileloadthread.cpp b/src/common/fileloadthread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed0b1902dd818228be095416d98851063b66c9e3 --- /dev/null +++ b/src/common/fileloadthread.cpp @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "fileloadthread.h" +#include "utils.h" +#include "../encodes/detectcode.h" +#include +#include + +FileLoadThread::FileLoadThread(const QString &filepath, QObject *parent) + : QThread(parent), + m_strFilePath(filepath) +{ + +} + +FileLoadThread::~FileLoadThread() +{ +} + +void FileLoadThread::run() +{ + QFile file(m_strFilePath); + + if (file.open(QIODevice::ReadOnly)) { + QByteArray encode; + QByteArray indata; + + // 判断文件大小是否超过40MB, 超过40MB的文件过大,需要调整读取策略,优先加载头部文件 + static const int s_maxDirectReadLen = 40 * DATA_SIZE_1024 * DATA_SIZE_1024; + if (file.size() > s_maxDirectReadLen) { + // 先读取1MB数据 + indata = file.read(DATA_SIZE_1024 * DATA_SIZE_1024); + encode = DetectCode::GetFileEncodingFormat(m_strFilePath, indata); + + // 发送文件头信息,用于预先加载数据 + QString textEncode = QString::fromLocal8Bit(encode); + if (textEncode.contains("ASCII", Qt::CaseInsensitive) || textEncode.contains("UTF-8", Qt::CaseInsensitive)) { + emit sigPreProcess(encode, indata); + } else { + QByteArray outHeadData; + DetectCode::ChangeFileEncodingFormat(indata, outHeadData, textEncode, QString("UTF-8")); + emit sigPreProcess(encode, outHeadData); + } + } + + // 读取申请开辟内存空间时,捕获可能出现的 std::bad_alloc() 异常,防止闪退。 + try { + // reads all remaining data from the file. + indata += file.read(file.size()); + file.close(); + } catch (const std::exception &e) { + qWarning() << Q_FUNC_INFO << "Read file data error, " << QString(e.what()); + + file.close(); + emit sigLoadFinished(encode, indata, true); + return; + } + + if (encode.isEmpty()) { + //编码识别,如果文件数据大于1M,则只裁剪出1M文件数据去做编码探测 + QByteArray dateUsedForCodeIdentify; + if (indata.length() > DATA_SIZE_1024 * DATA_SIZE_1024) { + dateUsedForCodeIdentify = indata.mid(0, DATA_SIZE_1024 * DATA_SIZE_1024); + } else { + dateUsedForCodeIdentify = indata; + } + encode = DetectCode::GetFileEncodingFormat(m_strFilePath, dateUsedForCodeIdentify); + } + + QString textEncode = QString::fromLocal8Bit(encode); + if (textEncode.contains("ASCII", Qt::CaseInsensitive) || textEncode.contains("UTF-8", Qt::CaseInsensitive)) { + emit sigLoadFinished(encode, indata, false); + } else { + QByteArray outData; + DetectCode::ChangeFileEncodingFormat(indata, outData, textEncode, QString("UTF-8")); + emit sigLoadFinished(encode, outData, false); + } + } + + this->quit(); + this->deleteLater(); +} diff --git a/src/common/fileloadthread.h b/src/common/fileloadthread.h new file mode 100644 index 0000000000000000000000000000000000000000..f6a0996ae283e7bf690ab085a75b0befa60d52d5 --- /dev/null +++ b/src/common/fileloadthread.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef FILELOADTHREAD_H +#define FILELOADTHREAD_H + +#include + +class FileLoadThread : public QThread +{ + Q_OBJECT +public: + FileLoadThread(const QString &filepath, QObject *QObject = nullptr); + ~FileLoadThread(); + + void run(); + +signals: + // 预处理信号,优先处理文件头,防止出现加载时间过长的情况 + void sigPreProcess(const QByteArray &encode, const QByteArray &content); + void sigLoadFinished(const QByteArray &encode, const QByteArray &content, bool error = false); + +private: + QString m_strFilePath; +}; + +#endif diff --git a/src/common/iflytekaiassistantthread.cpp b/src/common/iflytekaiassistantthread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9739386f1d75a4cc4108a472bfc3d20cb325920 --- /dev/null +++ b/src/common/iflytekaiassistantthread.cpp @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "iflytekaiassistantthread.h" + +IflytekAiassistantThread::IflytekAiassistantThread(QObject *parent) + : QThread (parent) +{} + +IflytekAiassistantThread::~IflytekAiassistantThread() +{} + +void IflytekAiassistantThread::run() +{ + bool bIsRegistIflytekAiassistant = false; + QDBusConnection connection = QDBusConnection::sessionBus(); + QDBusConnectionInterface *bus = connection.interface(); + bool isVailid = bus->isServiceRegistered("com.iflytek.aiassistant"); + if (isVailid) { + bIsRegistIflytekAiassistant = true; + } else { + qInfo() << "com.iflytek.aiassistant service no registered!"; + } + + emit sigIsRegisteredIflytekAiassistant(bIsRegistIflytekAiassistant); +} diff --git a/src/common/iflytekaiassistantthread.h b/src/common/iflytekaiassistantthread.h new file mode 100644 index 0000000000000000000000000000000000000000..9fc676bc7a705f86c3cba6598e519d68fce76842 --- /dev/null +++ b/src/common/iflytekaiassistantthread.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef IFLYTEKAIASSISTANTTHREAD_H +#define IFLYTEKAIASSISTANTTHREAD_H + +#include +#include +#include +#include + +class IflytekAiassistantThread : public QThread +{ + Q_OBJECT +public: + IflytekAiassistantThread(QObject *object = nullptr); + ~IflytekAiassistantThread(); + +private: + void run(); + +signals: + void sigIsRegisteredIflytekAiassistant(const bool bIsRegistIflytekAiassistant); +}; + +#endif // IFLYTEKAIASSISTANTTHREAD_H diff --git a/src/common/performancemonitor.cpp b/src/common/performancemonitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f5fffbdec6246ef0c3a0587aede13244f1c198f4 --- /dev/null +++ b/src/common/performancemonitor.cpp @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "performancemonitor.h" + +const QString LOG_FLAG = "[PerformanceMonitor]"; + +const QString GRAB_POINT_INIT_APP_TIME = "[GRABPOINT] POINT-01"; +const QString GRAB_POINT_CLOSE_APP_TIME = "[GRABPOINT] POINT-02"; +const QString GRAB_POINT_OPEN_FILE_TIME = "[GRABPOINT] POINT-04"; + +qint64 PerformanceMonitor::initializeAppStartMs = 0; +qint64 PerformanceMonitor::inittalizeApoFinishMs = 0; +qint64 PerformanceMonitor::closeAppStartMs = 0; +qint64 PerformanceMonitor::closeAppFinishMs = 0; +qint64 PerformanceMonitor::openFileStartMs = 0; +qint64 PerformanceMonitor::openFileFinishMs = 0; + +PerformanceMonitor::PerformanceMonitor() +{ + +} + +void PerformanceMonitor::initializeAppStart() +{ + QDateTime current = QDateTime::currentDateTime(); + qDebug() << qPrintable(LOG_FLAG) + << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + << "start to initialize app"; + initializeAppStartMs = current.toMSecsSinceEpoch(); +} + +void PerformanceMonitor::initializAppFinish() +{ + QDateTime current = QDateTime::currentDateTime(); + qDebug() << qPrintable(LOG_FLAG) + << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + << " finish to initialize app"; + + inittalizeApoFinishMs = current.toMSecsSinceEpoch(); + qint64 time = inittalizeApoFinishMs - initializeAppStartMs; + qInfo() << qPrintable(QString("%1 startduration=%2ms #(Init app time)").arg(GRAB_POINT_INIT_APP_TIME).arg(time)); +} + +void PerformanceMonitor::closeAppStart() +{ + QDateTime current = QDateTime::currentDateTime(); + closeAppStartMs = current.toMSecsSinceEpoch(); +} + +void PerformanceMonitor::closeAPPFinish() +{ + QDateTime current = QDateTime::currentDateTime(); + qDebug() << qPrintable(LOG_FLAG) + << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + << " finish to close app"; + + closeAppFinishMs = current.toMSecsSinceEpoch(); + qint64 time = closeAppFinishMs - closeAppStartMs; + qInfo() << qPrintable(QString("%1 closeduration=%2ms #(Close app time)").arg(GRAB_POINT_CLOSE_APP_TIME).arg(time)); +} + +void PerformanceMonitor::openFileStart() +{ + QDateTime current = QDateTime::currentDateTime(); + qDebug() << qPrintable(LOG_FLAG) + << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + << "start to open file"; + openFileStartMs = current.toMSecsSinceEpoch(); +} + +void PerformanceMonitor::openFileFinish(const QString &strFileName, qint64 iFileSize) +{ + QDateTime current = QDateTime::currentDateTime(); + qDebug() << qPrintable(LOG_FLAG) + << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) + << " finish to open file"; + + openFileFinishMs = current.toMSecsSinceEpoch(); + qint64 time = openFileFinishMs - openFileStartMs; + float fFilesize = iFileSize; + qInfo() << qPrintable(QString("%1 filename=%2 filezise=%3M opentime=%4ms #(Open file time)").arg(GRAB_POINT_OPEN_FILE_TIME).arg(strFileName).arg(QString::number(fFilesize/(1024*1024), 'f', 6)).arg(time)); +} diff --git a/src/common/performancemonitor.h b/src/common/performancemonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..3b23b3538a7302d76429abffbd2cdffa079bd201 --- /dev/null +++ b/src/common/performancemonitor.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef PERFORMANCEMONITOR_H +#define PERFORMANCEMONITOR_H + + +#include +#include +#include + +class PerformanceMonitor +{ + +public: + explicit PerformanceMonitor(); + + static void initializeAppStart(); + static void initializAppFinish(); + static void closeAppStart(); + static void closeAPPFinish(); + static void openFileStart(); + static void openFileFinish(const QString &strFileName, qint64 iFileSize); + +private: + Q_DISABLE_COPY(PerformanceMonitor) + + static qint64 initializeAppStartMs; + static qint64 inittalizeApoFinishMs; + static qint64 closeAppStartMs; + static qint64 closeAppFinishMs; + static qint64 openFileStartMs; + static qint64 openFileFinishMs; +}; + +#endif // PERFORMANCEMONITOR_H diff --git a/src/common/settings.cpp b/src/common/settings.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46133ea840f87a07e2ab631aac92df1ddd2a64d7 --- /dev/null +++ b/src/common/settings.cpp @@ -0,0 +1,726 @@ +// SPDX-FileCopyrightText: 2011-2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "utils.h" +#include "settings.h" + +#include "dthememanager.h" +#include "../controls/fontitemdelegate.h" +#include "../widgets/pathsettintwgt.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Settings *Settings::s_pSetting = nullptr; + +CustemBackend::CustemBackend(const QString &filepath, QObject *parent) + : DSettingsBackend (parent), + m_settings (new QSettings(filepath, QSettings::IniFormat)) +{ + +} + +void CustemBackend::doSync() +{ + m_settings->sync(); +} + +void CustemBackend::doSetOption(const QString &key, const QVariant &value) +{ + /* + * 将配置值写入config配置文件 + * 为了规避数据写入重复或者错乱,配置写入之前上锁,写入结束后开锁 + */ + m_writeLock.lock(); + m_settings->setValue(key, value); + m_settings->sync(); + m_writeLock.unlock(); +} + +QStringList CustemBackend::keys() const +{ + QStringList keyList = m_settings->allKeys(); + + return keyList; +} + +QVariant CustemBackend::getOption(const QString &key) const +{ + return m_settings->value(key); +} + +CustemBackend::~CustemBackend() +{} + +Settings::Settings(QWidget *parent) + : QObject(parent) +{ + QString strConfigPath = QString("%1/%2/%3/config.conf") + .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) + .arg(qApp->organizationName()) + .arg(qApp->applicationName()); + + removeLockFiles(); + m_backend = new QSettingBackend(strConfigPath); + + settings = DSettings::fromJsonFile(":/resources/settings.json"); + settings->setBackend(m_backend); + + auto fontFamliy = settings->option("base.font.family"); + connect(fontFamliy, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigAdjustFont); + + auto fontSize = settings->option("base.font.size"); + connect(fontSize, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigAdjustFontSize); + + auto wordWrap = settings->option("base.font.wordwrap"); + connect(wordWrap, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigAdjustWordWrap); + + auto showLineNumber = settings->option("base.font.showlinenumber"); + connect(showLineNumber, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigSetLineNumberShow); + + auto bookmark = settings->option("base.font.showbookmark"); + connect(bookmark, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigAdjustBookmark); + + auto codeFlod = settings->option("base.font.codeflod"); + connect(codeFlod, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigShowCodeFlodFlag); + + //添加显示空白符 梁卫东 + auto blankCharacter = settings->option("base.font.showblankcharacter"); + connect(blankCharacter, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigShowBlankCharacter); + + //hightlightcurrentline + auto hightlightCurrentLine = settings->option("base.font.hightlightcurrentline"); + connect(hightlightCurrentLine, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigHightLightCurrentLine); + + /* 设置页面主题变更信息监听,当前暂时无用,暂且做屏蔽处理 + auto theme = settings->option("advance.editor.theme"); + connect(theme, &Dtk::Core::DSettingsOption::valueChanged, this, [ = ](QVariant value) { + //emit themeChanged(value.toString()); + }); */ + + auto tabSpaceNumber = settings->option("advance.editor.tabspacenumber"); + connect(tabSpaceNumber, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotsigAdjustTabSpaceNumber); + + auto keymap = settings->option("shortcuts.keymap.keymap"); + QMap keymapMap; + keymapMap.insert("keys", QStringList() << "standard" << "emacs" << "customize"); + keymapMap.insert("values", QStringList() << tr("Standard") << "Emacs" << tr("Customize")); + keymap->setData("items", keymapMap); + connect(keymap, &Dtk::Core::DSettingsOption::valueChanged, this, &Settings::slotupdateAllKeysWithKeymap); + + //only used by new window + auto windowState = settings->option("advance.window.windowstate"); + #if 0 + connect(windowState, &Dtk::Core::DSettingsOption::valueChanged, this, [=] (QVariant value) { + emit sigChangeWindowSize(value.toString()); + }); + #endif + QMap windowStateMap; + windowStateMap.insert("keys", QStringList() << "window_normal" << "window_maximum" << "fullscreen"); + windowStateMap.insert("values", QStringList() << tr("Normal") << tr("Maximum") << tr("Fullscreen")); + windowState->setData("items", windowStateMap); + + connect(settings, &Dtk::Core::DSettings::valueChanged, this, &Settings::slotCustomshortcut); +} + +void Settings::setSavePath(int id,const QString& path) +{ + switch (id) { + case PathSettingWgt::LastOptBox:{ + auto opt = settings->option("advance.open_save_setting.open_save_lastopt_path"); + opt->setValue(path); + break; + } + case PathSettingWgt::CurFileBox:{ + auto opt = settings->option("advance.open_save_setting.open_save_curfile_path"); + opt->setValue(path); + break; + } + case PathSettingWgt::CustomBox:{ + auto opt = settings->option("advance.open_save_setting.open_save_custom_path"); + opt->setValue(path); + break; + } + default: + break; + } +} + + +QString Settings::getSavePath(int id) +{ + QString path; + switch (id) { + case PathSettingWgt::LastOptBox:{ + path = settings->option("advance.open_save_setting.open_save_lastopt_path")->value().toString(); + break; + } + case PathSettingWgt::CurFileBox:{ + path = settings->option("advance.open_save_setting.open_save_curfile_path")->value().toString(); + break; + } + case PathSettingWgt::CustomBox:{ + path = settings->option("advance.open_save_setting.open_save_custom_path")->value().toString(); + break; + } + default: + break; + } + + return path; +} + +void Settings::setSavePathId(int id) +{ + auto opt = settings->option("advance.open_save_setting.savingpathwgt"); + opt->setValue(QString::number(id)); +} +int Settings::getSavePathId() +{ + return settings->option("advance.open_save_setting.savingpathwgt")->value().toInt(); + +} +Settings::~Settings() +{ + if (m_backend != nullptr) { + delete m_backend; + m_backend = nullptr; + } +} + +void Settings::setSettingDialog(DSettingsDialog *settingsDialog) +{ + m_pSettingsDialog = settingsDialog; +} + +// This function is workaround, it will remove after DTK fixed SettingDialog theme bug. +void Settings::dtkThemeWorkaround(QWidget *parent, const QString &theme) +{ + parent->setStyle(QStyleFactory::create(theme)); + + for (auto obj : parent->children()) { + auto w = qobject_cast(obj); + if (!w) { + continue; + } + + dtkThemeWorkaround(w, theme); + } +} + +//QWidget *Settings::createFontComBoBoxHandle(QObject *obj) +QPair Settings::createFontComBoBoxHandle(QObject *obj) +{ + auto option = qobject_cast(obj); + + QComboBox *comboBox = new QComboBox; + //QWidget *optionWidget = DSettingsWidgetFactory::createTwoColumWidget(option, comboBox); + QPair optionWidget = DSettingsWidgetFactory::createStandardItem(QByteArray(), option, comboBox); + + QFontDatabase fontDatabase; + comboBox->addItems(fontDatabase.families()); + //comboBox->setItemDelegate(new FontItemDelegate); + //comboBox->setFixedSize(240, 36); + + if (option->value().toString().isEmpty()) { + option->setValue(QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); + } + + // init. + comboBox->setCurrentText(option->value().toString()); + + connect(option, &DSettingsOption::valueChanged, comboBox, [ = ](QVariant var) { + comboBox->setCurrentText(var.toString()); + }); + + option->connect(comboBox, &QComboBox::currentTextChanged, option, [ = ](const QString & text) { + option->setValue(text); + }); + + return optionWidget; +} + +QWidget* Settings::createSavingPathWgt(QObject* obj) +{ + auto option = qobject_cast(obj); + QString name = option->name(); + PathSettingWgt* pathwgt = new PathSettingWgt; + QPair optionWidget = DSettingsWidgetFactory::createStandardItem(QByteArray(), option, pathwgt); + + connect(option, &DSettingsOption::valueChanged, pathwgt, [ = ](QVariant var) { + int id = var.toInt(); + pathwgt->onSaveIdChanged(id); + }); + + auto custompath = s_pSetting->settings->option("advance.open_save_setting.open_save_custom_path"); + connect(custompath, &Dtk::Core::DSettingsOption::valueChanged, [=](QVariant var){ + //pathwgt->setEditText(var.toString()); + }); + + + return optionWidget.second; +} + +QPair Settings::createKeySequenceEditHandle(QObject *obj) +{ + auto option = qobject_cast(obj); + KeySequenceEdit *shortCutLineEdit = new KeySequenceEdit(option); + + shortCutLineEdit->ShortcutDirection(Qt::AlignLeft); + shortCutLineEdit->setFocusPolicy(Qt::StrongFocus); + + // init. + shortCutLineEdit->setKeySequence(QKeySequence(option->value().toString())); + QPair optionWidget = DSettingsWidgetFactory::createStandardItem(QByteArray(), option, shortCutLineEdit); + + option->connect(shortCutLineEdit, &DKeySequenceEdit::editingFinished, [ = ](const QKeySequence & sequence) { + QString checkName = option->key(); + QString reason; + bool bIsConflicts = false; + auto keymap = instance()->settings->option("shortcuts.keymap.keymap"); + QStringList keySplitList = option->key().split("."); + keySplitList[1] = QString("%1_keymap_%2").arg(keySplitList[1]).arg(keymap->value().toString()); + + // 获取默认设置的组合键序列 + QString defaultKey; + auto defaultOption = instance()->settings->option(keySplitList.join(".")); + if (defaultOption) { + defaultKey = defaultOption->defaultValue().toString(); + } + + // 判断新设置的组合键序列是否允许 + if (!instance()->checkShortcutValid(checkName, sequence.toString(), reason, bIsConflicts, defaultKey)) { + instance()->m_pDialog = instance()->createDialog(reason, "", bIsConflicts); + instance()->m_pDialog->exec(); + // 恢复组合键序列 + shortCutLineEdit->setKeySequence(instance()->settings->value(keySplitList.join(".")).toString()); + keymap->setValue("emacs"); + keymap->setValue("customize"); + return; + } + + bool bIsCustomize = false; + QString conflictsKeys; + QString originalKeys; + + if (keymap->value().toString() != "customize") { + instance()->m_bUserChangeKey = true; + + for (auto loopOption : instance()->settings->group("shortcuts.window_keymap_customize")->options()) { + QStringList loopKeySplitList = loopOption->key().split("."); + loopKeySplitList[1] = QString("window_keymap_%1").arg(keymap->value().toString()); + + if (loopOption->value().toString() == sequence.toString()) { + + if (checkName.contains(loopKeySplitList.last())) { + keymap->setValue("customize"); + //return; + } else { + bIsConflicts = true; + loopKeySplitList[1] = QString("window_keymap_%1").arg("customize"); + conflictsKeys = loopKeySplitList.join("."); + } + } + } + + for (auto loopOption : instance()->settings->group("shortcuts.editor_keymap_customize")->options()) { + QStringList loopKeySplitList = loopOption->key().split("."); + loopKeySplitList[1] = QString("editor_keymap_%1").arg(keymap->value().toString()); + + if (loopOption->value().toString() == sequence.toString()) { + + if (checkName.contains(loopKeySplitList.last())) { + keymap->setValue("customize"); + //return; + } else { + bIsConflicts = true; + loopKeySplitList[1] = QString("editor_keymap_%1").arg("customize"); + conflictsKeys = loopKeySplitList.join("."); + } + } + } + + instance()->m_bUserChangeKey = false; + } else { + bIsCustomize = true; + instance()->m_bUserChangeKey = true; + for (auto loopOption : instance()->settings->group("shortcuts.window_keymap_customize")->options()) { + QStringList loopKeySplitList = loopOption->key().split("."); + loopKeySplitList[1] = QString("window_keymap_%1").arg(keymap->value().toString()); + + if (loopOption->value().toString() == sequence.toString()) { + + if (checkName.contains(loopKeySplitList.last())) { + //return; + } else { + bIsConflicts = true; + conflictsKeys = loopKeySplitList.join("."); + } + } + } + + for (auto loopOption : instance()->settings->group("shortcuts.editor_keymap_customize")->options()) { + QStringList loopKeySplitList = loopOption->key().split("."); + loopKeySplitList[1] = QString("editor_keymap_%1").arg(keymap->value().toString()); + + if (loopOption->value().toString() == sequence.toString()) { + + if (checkName.contains(loopKeySplitList.last())) { + //return; + } else { + bIsConflicts = true; + conflictsKeys = loopKeySplitList.join("."); + } + } + } + instance()->m_bUserChangeKey = false; + } + + keySplitList = option->key().split("."); + keySplitList[1] = QString("%1_keymap_%2").arg(keySplitList[1]).arg(keymap->value().toString()); + QString qstrSequence = sequence.toString(); + + if (sequence.toString().contains("<")) { + qstrSequence.replace(qstrSequence.indexOf("<"), 1, "<"); + } + + if (sequence.toString().contains("Return")) { + qstrSequence.replace(qstrSequence.indexOf("Return"), 6, "Enter"); + } + + QString style = QString("[%1]").arg(qstrSequence); + + if (bIsConflicts || sequence.toString() == "Alt+M") { + if (sequence.toString() == "Alt+M") { + instance()->m_pDialog = instance()->createDialog(tr("This shortcut conflicts with system shortcut %1").arg(style), "", bIsConflicts); + } else { + instance()->m_pDialog = instance()->createDialog(tr("This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately").arg(style), "", bIsConflicts); + } + + int mode = instance()->m_pDialog->exec(); + + // click cancel button. + if (mode == -1 || mode == 0) { + shortCutLineEdit->setKeySequence(QKeySequence(instance()->settings->value(keySplitList.join(".")).toString())); + keymap->setValue("emacs"); + keymap->setValue("customize"); + return; + } else { + keySplitList = option->key().split("."); + keySplitList[1] = QString("%1_keymap_customize").arg(keySplitList[1]); + + if (!bIsCustomize) { + instance()->settings->option(keySplitList.join("."))->setValue(sequence.toString()); + instance()->settings->option(conflictsKeys)->setValue(""); + shortCutLineEdit->setKeySequence(QKeySequence(instance()->settings->value(checkName).toString())); + } else { + instance()->settings->option(keySplitList.join("."))->setValue(sequence.toString()); + instance()->settings->option(conflictsKeys)->setValue(""); + } + keymap->setValue("emacs"); + keymap->setValue("customize"); + return; + } + } + + if (!bIsCustomize) { + keySplitList = option->key().split("."); + keySplitList[1] = QString("%1_keymap_customize").arg(keySplitList[1]); + instance()->settings->option(keySplitList.join("."))->setValue(sequence.toString()); + } else { + instance()->settings->option(keySplitList.join("."))->setValue(sequence.toString()); + } + keymap->setValue("emacs"); + keymap->setValue("customize"); + }); + + // 配置修改 + option->connect(option, &DTK_CORE_NAMESPACE::DSettingsOption::valueChanged, shortCutLineEdit, &KeySequenceEdit::slotDSettingsOptionvalueChanged); + return optionWidget; +} + +void KeySequenceEdit::slotDSettingsOptionvalueChanged(const QVariant & value) +{ + QString keyseq = value.toString(); + + if (keyseq.isEmpty()) { + this->clear(); + return; + } + this->setKeySequence(QKeySequence(keyseq)); +} + +bool KeySequenceEdit::eventFilter(QObject *object, QEvent *event) +{ + //设置界面 回车键和空格键 切换输入 梁卫东 2020-08-21 16:28:31 + if (object == this) { + if (event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); + + //判断是否包含组合键 梁卫东 2020-09-02 15:03:56 + Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); + bool bHasModifier = (modifiers & Qt::ShiftModifier || modifiers & Qt::ControlModifier || + modifiers & Qt::AltModifier); + + if (!bHasModifier && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Space)) { + QRect rect = this->rect(); + QList childern = findChildren(); + + for (int i =0; i < childern.size(); i++) { + QPoint pos(25,rect.height()/2); + + QMouseEvent event0(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + DApplication::sendEvent(childern[i], &event0); + } + + return true; + } + } + } + + return DKeySequenceEdit::eventFilter(object, event); +} +Settings *Settings::instance() +{ + if (s_pSetting == nullptr) { + s_pSetting = new Settings; + } + return s_pSetting; +} + +void Settings::updateAllKeysWithKeymap(QString keymap) +{ + m_bUserChangeKey = true; + + for (auto option : settings->group("shortcuts.window")->options()) { + QStringList keySplitList = option->key().split("."); + keySplitList[1] = QString("%1_keymap_%2").arg(keySplitList[1]).arg(keymap); + auto opt = settings->option(keySplitList.join(".")); + if (opt) { + option->setValue(opt->value().toString()); + } else { + qWarning() << "Unknown shortcut key:" << keySplitList.join("."); + } + } + + for (auto option : settings->group("shortcuts.editor")->options()) { + QStringList keySplitList = option->key().split("."); + keySplitList[1] = QString("%1_keymap_%2").arg(keySplitList[1]).arg(keymap); + auto opt = settings->option(keySplitList.join(".")); + if (opt) { + option->setValue(opt->value().toString()); + } else { + qWarning() << "Unknown shortcut key:" << keySplitList.join("."); + } + } + + m_bUserChangeKey = false; +} + +void Settings::copyCustomizeKeysFromKeymap(QString keymap) +{ + m_bUserChangeKey = true; + + for (auto option : settings->group("shortcuts.window_keymap_customize")->options()) { + QStringList keySplitList = option->key().split("."); + keySplitList[1] = QString("window_keymap_%1").arg(keymap); + option->setValue(settings->option(keySplitList.join("."))->value().toString()); + } + + for (auto option : settings->group("shortcuts.editor_keymap_customize")->options()) { + QStringList keySplitList = option->key().split("."); + keySplitList[1] = QString("editor_keymap_%1").arg(keymap); + option->setValue(settings->option(keySplitList.join("."))->value().toString()); + } + + m_bUserChangeKey = false; +} + +bool Settings::checkShortcutValid(const QString &Name, QString Key, QString &Reason, bool &bIsConflicts, QString defaultValue) +{ + Q_UNUSED(Name); + + if (Key.contains("<")) { + Key.replace(Key.indexOf("<"), 1, "<"); + } + + QString style = QString("[%1]").arg(Key); + // 单键 + if (Key.count("+") == 0) { + //F1-F12是允许的,这个正则不够精确,但是没关系。 + QRegExp regexp("^F[0-9]{1,2}$"); + if (!Key.contains(regexp)) { + Reason = tr("The shortcut %1 is invalid, please set another one.").arg(style); + bIsConflicts = false; + return false; + } + } + // 小键盘单键都不允许 + QRegExp regexpNum("^Num+.*"); + if (Key.contains(regexpNum)) { + Reason = tr("The shortcut %1 is invalid, please set another one.").arg(style); + bIsConflicts = false; + return false; + } + + // 屏蔽Shift组合键处理,但允许恢复为默认组合键序列 + if (Key.contains("Shift") + && Key != defaultValue) { + Reason = tr("The shortcut %1 is invalid, please set another one.").arg(style); + bIsConflicts = false; + return false; + } + + return true; +} + +bool Settings::isShortcutConflict(const QString &Name, const QString &Key) +{ + for (QString tmpKey : settings->keys()) { + if (settings->value(tmpKey).toString() == Key/* && tmpKey.contains("customize")*/) { + if (Name != tmpKey) { + return true; + } + } + } + return false; +} + +DDialog *Settings::createDialog(const QString &title, const QString &content, const bool &bIsConflicts) +{ + DDialog *dialog = new DDialog(title, content, m_pSettingsDialog); + dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnBottomHint); + dialog->setIcon(QIcon::fromTheme("deepin-editor")); + + if (bIsConflicts) { + dialog->addButton(QString(tr("Cancel")), true, DDialog::ButtonNormal); + dialog->addButton(QString(tr("Replace")), false, DDialog::ButtonRecommend); + } else { + dialog->addButton(QString(tr("OK")), true, DDialog::ButtonRecommend); + } + + return dialog; +} + +//删除config.conf配置文件目录下的.lock文件和.rmlock文件 +void Settings::removeLockFiles() +{ + QString configPath = QString("%1/%2/%3") + .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) + .arg(qApp->organizationName()) + .arg(qApp->applicationName()); + + QDir dir(configPath); + if (!dir.exists()) { + return; + } + + dir.setFilter(QDir::Files); + QStringList nameList = dir.entryList(); + for (auto name: nameList) { + if (name.contains(".lock") || name.contains(".rmlock")) { + QFile file(name); + file.remove(); + } + } +} + +void Settings::slotCustomshortcut(const QString &key, const QVariant &value) +{ + auto keymap = settings->option("shortcuts.keymap.keymap"); + if (!m_bUserChangeKey && key.startsWith("shortcuts.") && key != "shortcuts.keymap.keymap" && !key.contains("_keymap_")) { + m_bUserChangeKey = true; + + QString currentKeymap = settings->option("shortcuts.keymap.keymap")->value().toString(); + + QStringList keySplitList = key.split("."); + keySplitList[1] = QString("%1_keymap_customize").arg(keySplitList[1]); + QString customizeKey = keySplitList.join("."); + + // Just update customize key user input, don't change keymap. + if (currentKeymap == "customize") { + settings->option(customizeKey)->setValue(value); + } + // If current kemap is not "customize". + // Copy all customize keys from current keymap, and then update customize key just user input. + // Then change keymap name. + else { + copyCustomizeKeysFromKeymap(currentKeymap); + settings->option(customizeKey)->setValue(value); + keymap->setValue("customize"); + } + m_bUserChangeKey = false; + } +} + + +void Settings::slotsigAdjustFont(QVariant value) +{ + emit sigAdjustFont(value.toString()); +} + +void Settings::slotsigAdjustFontSize(QVariant value) +{ + emit sigAdjustFontSize(value.toReal()); +} + +void Settings::slotsigAdjustWordWrap(QVariant value) +{ + emit sigAdjustWordWrap(value.toBool()); +} + +void Settings::slotsigSetLineNumberShow(QVariant value) +{ + emit sigSetLineNumberShow(value.toBool()); +} + +void Settings::slotsigAdjustBookmark(QVariant value) +{ + emit sigAdjustBookmark(value.toBool()); +} + +void Settings::slotsigShowCodeFlodFlag(QVariant value) +{ + emit sigShowCodeFlodFlag(value.toBool()); +} + +void Settings::slotsigShowBlankCharacter(QVariant value) +{ + emit sigShowBlankCharacter(value.toBool()); +} + +void Settings::slotsigHightLightCurrentLine(QVariant value) +{ + emit sigHightLightCurrentLine(value.toBool()); +} + +void Settings::slotsigAdjustTabSpaceNumber(QVariant value) +{ + emit sigAdjustTabSpaceNumber(value.toInt()); +} + +void Settings::slotupdateAllKeysWithKeymap(QVariant value) +{ + updateAllKeysWithKeymap(value.toString()); +} + +KeySequenceEdit::KeySequenceEdit(DTK_CORE_NAMESPACE::DSettingsOption *opt, QWidget *parent) + : DKeySequenceEdit(parent) +{ + m_pOption = opt; + this->installEventFilter(this); +} + +DSettingsOption *KeySequenceEdit::option() +{ + return m_pOption; +} diff --git a/src/common/settings.h b/src/common/settings.h new file mode 100644 index 0000000000000000000000000000000000000000..b3c9fb35091b61bdf2150d879e1e900863e63c69 --- /dev/null +++ b/src/common/settings.h @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SETTINGS_H +#define SETTINGS_H + +#include "dsettingsdialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE +DCORE_USE_NAMESPACE +DTK_USE_NAMESPACE + +class CustemBackend : public DSettingsBackend +{ + Q_OBJECT +public: + explicit CustemBackend(const QString &filepath, QObject *parent = nullptr); + ~CustemBackend(); + + //获取参数所有的key值 + QStringList keys() const override; + //根据key获取内容 + QVariant getOption(const QString &key) const; + //同步数据 + void doSync() override; + //根据key值设置内容 + void doSetOption(const QString &key, const QVariant &value) override; + + QSettings *m_settings {nullptr}; + QMutex m_writeLock; +}; + +class Settings : public QObject +{ + Q_OBJECT +public: + explicit Settings(QWidget *parent = 0); + ~Settings(); + + void dtkThemeWorkaround(QWidget *parent, const QString &theme); + //static QWidget *createFontComBoBoxHandle(QObject *obj); + static QPair createFontComBoBoxHandle(QObject *obj); + static QPair createKeySequenceEditHandle(QObject *obj); + static QWidget* createSavingPathWgt(QObject* objg); + static Settings* instance(); + void setSettingDialog(DSettingsDialog *settingsDialog); + + int m_iDefaultFontSize = 12; + int m_iMaxFontSize = 50; + int m_iMinFontSize = 8; + DSettings *settings {nullptr}; + + void setSavePath(int id,const QString& path); + QString getSavePath(int id); + void setSavePathId(int id); + int getSavePathId(); + +signals: + void sigAdjustFont(QString name); + void sigAdjustFontSize(qreal fontSize); + void sigAdjustTabSpaceNumber(int number); + void sigAdjustWordWrap(bool enable); + void sigAdjustBookmark(bool enable); + void sigShowCodeFlodFlag(bool enable); + void sigShowBlankCharacter(bool enable); + void sigHightLightCurrentLine(bool enable); + void sigThemeChanged(const QString &theme); + void sigSetLineNumberShow(bool bIsShow); + void sigChangeWindowSize(QString mode); + +public slots: + //自定义快捷键 ut002764 2021.6.28 + void slotCustomshortcut(const QString &key, const QVariant &value); + + //添加信号槽 ut002764-07-05 + void slotsigAdjustFont(QVariant value); + void slotsigAdjustFontSize(QVariant value); + void slotsigAdjustWordWrap(QVariant value); + void slotsigSetLineNumberShow(QVariant value); + void slotsigAdjustBookmark(QVariant value); + void slotsigShowCodeFlodFlag(QVariant value); + void slotsigShowBlankCharacter(QVariant value); + void slotsigHightLightCurrentLine(QVariant value); + void slotsigAdjustTabSpaceNumber(QVariant value); + void slotupdateAllKeysWithKeymap(QVariant value); + +private: + void updateAllKeysWithKeymap(QString keymap); + void copyCustomizeKeysFromKeymap(QString keymap); + bool checkShortcutValid(const QString &Name, QString Key, QString &Reason, bool &bIsConflicts, QString defaultValue = QString::null); + bool isShortcutConflict(const QString &Name, const QString &Key); + DDialog *createDialog(const QString &title, const QString &content, const bool &bIsConflicts); + void removeLockFiles(); + +private: + Dtk::Core::QSettingBackend *m_backend {nullptr}; + + bool m_bUserChangeKey = false; + DSettingsDialog *m_pSettingsDialog; + static Settings* s_pSetting; + DDialog *m_pDialog; +}; + +class KeySequenceEdit : public DKeySequenceEdit +{ +public: + explicit KeySequenceEdit(DTK_CORE_NAMESPACE::DSettingsOption *opt, QWidget *parent = nullptr); + /** + * @brief option 获取设置页面操作句柄 + */ + DTK_CORE_NAMESPACE::DSettingsOption *option(); + /** + * @brief slotDSettingsOptionvalueChanged 设置页面配置修改 + */ + void slotDSettingsOptionvalueChanged(const QVariant &value); + +protected: + /** + * @brief eventFilter 设置页面快捷键类的事件过滤器 + */ + bool eventFilter(QObject *object, QEvent *event); + +private: + DTK_CORE_NAMESPACE::DSettingsOption *m_pOption = nullptr; +}; + +#endif // SETTINGS_H diff --git a/src/common/urlinfo.h b/src/common/urlinfo.h new file mode 100644 index 0000000000000000000000000000000000000000..eba32e543818f533647d605acb40104573ff51d9 --- /dev/null +++ b/src/common/urlinfo.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef URLINFO_H +#define URLINFO_H + +#include +#include +#include +#include +#include + +class UrlInfo +{ +public: + UrlInfo(QString path) + { + // Just check if the path is an existing file. + if (QFile::exists(path)) { + url = QUrl::fromLocalFile(QDir::current().absoluteFilePath(path)); + return; + } + + const auto match = QRegularExpression(QStringLiteral(":(\\d+)(?::(\\d+))?:?$")).match(path); + + if (match.isValid()) { + // cut away line/column specification from the path. + path.chop(match.capturedLength()); + } + + // make relative paths absolute using the current working directory + // prefer local file, if in doubt! + url = QUrl::fromUserInput(path, QDir::currentPath(), QUrl::AssumeLocalFile); + + // in some cases, this will fail, e.g. + // assume a local file and just convert it to an url. + if (!url.isValid()) { + // create absolute file path, we will e.g. pass this over dbus to other processes + url = QUrl::fromLocalFile(QDir::current().absoluteFilePath(path)); + } + } + + QUrl url; +}; + +#endif // URLINFO_H diff --git a/src/common/utils.cpp b/src/common/utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e225b5b50cddb65c61da201d1e14d7f696e2613e --- /dev/null +++ b/src/common/utils.cpp @@ -0,0 +1,1003 @@ +// SPDX-FileCopyrightText: 2011-2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "utils.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qprocess.h" + +DCORE_USE_NAMESPACE + +QT_BEGIN_NAMESPACE +extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); +QT_END_NAMESPACE + +QString Utils::m_systemLanguage; + +QString Utils::getQrcPath(const QString &imageName) +{ + return QString(":/images/%1").arg(imageName); +} + +QString Utils::getQssPath(const QString &qssName) +{ + return QString(":/qss/%1").arg(qssName); +} + +QSize Utils::getRenderSize(int fontSize, const QString &string) +{ + QFont font; + font.setPointSize(fontSize); + QFontMetrics fm(font); + + int width = 0; + int height = 0; + + for (const QString &line : string.split("\n")) { + int lineWidth = fm.width(line); + int lineHeight = fm.height(); + + if (lineWidth > width) { + width = lineWidth; + } + + height += lineHeight; + } + + return QSize(width, height); +} + +void Utils::setFontSize(QPainter &painter, int textSize) +{ + QFont font = painter.font() ; + font.setPointSize(textSize); + painter.setFont(font); +} + +void Utils::applyQss(QWidget *widget, const QString &qssName) +{ + QFile file(Utils::getQssPath(qssName)); + file.open(QFile::ReadOnly); + QTextStream filetext(&file); + QString stylesheet = filetext.readAll(); + widget->setStyleSheet(stylesheet); + file.close(); +} + +float Utils::codecConfidenceForData(const QTextCodec *codec, const QByteArray &data, const QLocale::Country &country) +{ + qreal hep_count = 0; + int non_base_latin_count = 0; + qreal unidentification_count = 0; + int replacement_count = 0; + + QTextDecoder decoder(codec); + const QString &unicode_data = decoder.toUnicode(data); + + for (int i = 0; i < unicode_data.size(); ++i) { + const QChar &ch = unicode_data.at(i); + + if (ch.unicode() > 0x7f) + ++non_base_latin_count; + + switch (ch.script()) { + case QChar::Script_Hiragana: + case QChar::Script_Katakana: + hep_count += (country == QLocale::Japan) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::Japan) ? 0 : 0.3; + break; + case QChar::Script_Han: + hep_count += (country == QLocale::China) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::China) ? 0 : 0.3; + break; + case QChar::Script_Hangul: + hep_count += (country == QLocale::NorthKorea) || (country == QLocale::SouthKorea) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::NorthKorea) || (country == QLocale::SouthKorea) ? 0 : 0.3; + break; + case QChar::Script_Cyrillic: + hep_count += (country == QLocale::Russia) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::Russia) ? 0 : 0.3; + break; + case QChar::Script_Devanagari: + hep_count += (country == QLocale::Nepal || country == QLocale::India) ? 1.2 : 0.5; + unidentification_count += (country == QLocale::Nepal || country == QLocale::India) ? 0 : 0.3; + break; + default: + // full-width character, emoji, 常用标点, 拉丁文补充1,天城文补充,CJK符号和标点符号(如:【】) + if ((ch.unicode() >= 0xff00 && ch <= 0xffef) + || (ch.unicode() >= 0x2600 && ch.unicode() <= 0x27ff) + || (ch.unicode() >= 0x2000 && ch.unicode() <= 0x206f) + || (ch.unicode() >= 0x80 && ch.unicode() <= 0xff) + || (ch.unicode() >= 0xa8e0 && ch.unicode() <= 0xa8ff) + || (ch.unicode() >= 0x0900 && ch.unicode() <= 0x097f) + || (ch.unicode() >= 0x3000 && ch.unicode() <= 0x303f)) { + ++hep_count; + } else if (ch.isSurrogate() && ch.isHighSurrogate()) { + ++i; + + if (i < unicode_data.size()) { + const QChar &next_ch = unicode_data.at(i); + + if (!next_ch.isLowSurrogate()) { + --i; + break; + } + + uint unicode = QChar::surrogateToUcs4(ch, next_ch); + + // emoji + if (unicode >= 0x1f000 && unicode <= 0x1f6ff) { + hep_count += 2; + } + } + } else if (ch.unicode() == QChar::ReplacementCharacter) { + ++replacement_count; + } else if (ch.unicode() > 0x7f) { + // 因为UTF-8编码的容错性很低,所以未识别的编码只需要判断是否为 QChar::ReplacementCharacter 就能排除 + if (codec->name() != "UTF-8") + ++unidentification_count; + } + break; + } + } + + float c = qreal(hep_count) / non_base_latin_count / 1.2; + + c -= qreal(replacement_count) / non_base_latin_count; + c -= qreal(unidentification_count) / non_base_latin_count; + + return qMax(0.0f, c); +} + +QByteArray Utils::detectEncode(const QByteArray &data, const QString &fileName) +{ + // Return local encoding if nothing in file. + if (data.isEmpty()) { + return QTextCodec::codecForLocale()->name(); + } + + if (QTextCodec *c = QTextCodec::codecForUtfText(data, nullptr)) { + return c->name(); + } + + QMimeDatabase mime_database; + const QMimeType &mime_type = fileName.isEmpty() ? mime_database.mimeTypeForData(data) : mime_database.mimeTypeForFileNameAndData(fileName, data); + const QString &mimetype_name = mime_type.name(); + KEncodingProber::ProberType proberType = KEncodingProber::Universal; + + if (mimetype_name == QStringLiteral("application/xml") + || mimetype_name == QStringLiteral("text/html") + || mimetype_name == QStringLiteral("application/xhtml+xml")) { + const QString &_data = QString::fromLatin1(data); + QRegularExpression pattern("<\\bmeta.+\\bcharset=(?'charset'\\S+?)\\s*['\"/>]"); + + pattern.setPatternOptions(QRegularExpression::DontCaptureOption | QRegularExpression::CaseInsensitiveOption); + const QString &charset = pattern.match(_data, 0, QRegularExpression::PartialPreferFirstMatch, + QRegularExpression::DontCheckSubjectStringMatchOption).captured("charset"); + + if (!charset.isEmpty()) { + return charset.toLatin1(); + } + + pattern.setPattern("<\\bmeta\\s+http-equiv=\"Content-Language\"\\s+content=\"(?'language'[a-zA-Z-]+)\""); + + const QString &language = pattern.match(_data, 0, QRegularExpression::PartialPreferFirstMatch, + QRegularExpression::DontCheckSubjectStringMatchOption).captured("language"); + + if (0 != language.size()) { + QLocale l(language); + + switch (l.script()) { + case QLocale::ArabicScript: + proberType = KEncodingProber::Arabic; + break; + case QLocale::SimplifiedChineseScript: + proberType = KEncodingProber::ChineseSimplified; + break; + case QLocale::TraditionalChineseScript: + proberType = KEncodingProber::ChineseTraditional; + break; + case QLocale::CyrillicScript: + proberType = KEncodingProber::Cyrillic; + break; + case QLocale::GreekScript: + proberType = KEncodingProber::Greek; + break; + case QLocale::HebrewScript: + proberType = KEncodingProber::Hebrew; + break; + case QLocale::JapaneseScript: + proberType = KEncodingProber::Japanese; + break; + case QLocale::KoreanScript: + proberType = KEncodingProber::Korean; + break; + case QLocale::ThaiScript: + proberType = KEncodingProber::Thai; + break; + default: + break; + } + } + } else if (mimetype_name == "text/x-python") { + QRegularExpression pattern("^#coding\\s*:\\s*(?'coding'\\S+)$"); + QTextStream stream(data); + + pattern.setPatternOptions(QRegularExpression::DontCaptureOption | QRegularExpression::CaseInsensitiveOption); + stream.setCodec("latin1"); + + while (!stream.atEnd()) { + const QString &_data = stream.readLine(); + const QString &coding = pattern.match(_data, 0).captured("coding"); + + if (!coding.isEmpty()) { + return coding.toLatin1(); + } + } + } + + // for CJK + const QList> fallback_list { + {KEncodingProber::ChineseSimplified, QLocale::China}, + {KEncodingProber::ChineseTraditional, QLocale::China}, + {KEncodingProber::Japanese, QLocale::Japan}, + {KEncodingProber::Korean, QLocale::NorthKorea}, + //{KEncodingProber::Cyrillic, QLocale::Russia}, + //{KEncodingProber::Greek, QLocale::Greece}, + //{proberType, QLocale::system().country()} + }; + + KEncodingProber prober(proberType); + prober.feed(data); + float pre_confidence = prober.confidence(); + QByteArray pre_encoding = prober.encoding(); + + QTextCodec *def_codec = QTextCodec::codecForLocale(); + QByteArray encoding; + float confidence = 0; + + for (auto i : fallback_list) { + prober.setProberType(i.first); + prober.feed(data); + + float prober_confidence = prober.confidence(); + QByteArray prober_encoding = prober.encoding(); + + if (i.first != proberType && qFuzzyIsNull(prober_confidence)) { + prober_confidence = pre_confidence; + prober_encoding = pre_encoding; + } + + confidence: + if (QTextCodec *codec = QTextCodec::codecForName(prober_encoding)) { + if (def_codec == codec) + def_codec = nullptr; + + float c = Utils::codecConfidenceForData(codec, data, i.second); + + if (prober_confidence > 0.5) { + c = c / 2 + prober_confidence / 2; + } else { + c = c / 3 * 2 + prober_confidence / 3; + } + + if (c > confidence) { + confidence = c; + encoding = prober_encoding; + } + + if (i.first == KEncodingProber::ChineseTraditional && c < 0.5) { + // test Big5 + c = Utils::codecConfidenceForData(QTextCodec::codecForName("Big5"), data, i.second); + + if (c > 0.5 && c > confidence) { + confidence = c; + encoding = "Big5"; + } + } + } + + if (i.first != proberType) { + // 使用 proberType 类型探测出的结果结合此国家再次做编码检查 + i.first = proberType; + prober_confidence = pre_confidence; + prober_encoding = pre_encoding; + goto confidence; + } + } + + if (def_codec && Utils::codecConfidenceForData(def_codec, data, QLocale::system().country()) > confidence) { + return def_codec->name(); + } + + return encoding; +} + +QByteArray Utils::getEncode(const QByteArray &data) +{ + // try to get HTML header encoding. + if (QTextCodec *codecForHtml = QTextCodec::codecForHtml(data, nullptr)) { + return codecForHtml->name(); + } + + QTextCodec *codec = nullptr; + KEncodingProber prober(KEncodingProber::Universal); + prober.feed(data.constData(), data.size()); + + // we found codec with some confidence ? + if (prober.confidence() > 0.5) { + codec = QTextCodec::codecForName(prober.encoding()); + } + + if (!codec) { + return QByteArray(); + } + + return codec->name(); +} + +bool Utils::fileExists(const QString &path) +{ + QFileInfo check_file(path); + + return check_file.exists() && check_file.isFile(); +} + +bool Utils::fileIsWritable(const QString &path) +{ + QFileDevice::Permissions permissions = QFile(path).permissions(); + + return permissions & QFileDevice::WriteUser; +} + +bool Utils::fileIsHome(const QString &path) +{ + return path.startsWith(QDir::homePath()); +} + +QString Utils::getKeyshortcut(QKeyEvent *keyEvent) +{ + QStringList keys; + Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); + if (modifiers != Qt::NoModifier) { + if (modifiers.testFlag(Qt::MetaModifier)) { + keys.append("Meta"); + } + + if (modifiers.testFlag(Qt::ControlModifier)) { + keys.append("Ctrl"); + } + + if (modifiers.testFlag(Qt::AltModifier)) { + keys.append("Alt"); + } + + if (modifiers.testFlag(Qt::ShiftModifier)) { + keys.append("Shift"); + } + + // 添加小键盘处理,若为小键盘按键按下,组合键需添加 Num ,例如 Ctrl+Num+6 / Ctrl+Num+Up + if (modifiers.testFlag(Qt::KeypadModifier)) { + keys.append("Num"); + } + } + + if (keyEvent->key() != 0 && keyEvent->key() != Qt::Key_unknown) { + keys.append(QKeySequence(keyEvent->key()).toString()); + } + + for (int i = 0; i < keys.count(); i++) { + if (keys.value(i).contains("Return")) { + keys.replace(i, "Enter"); + } + } + + return keys.join("+"); +} + +QString Utils::getKeyshortcutFromKeymap(Settings *settings, const QString &keyCategory, const QString &keyName) +{ + return settings->settings->option(QString("shortcuts.%1.%2").arg(keyCategory).arg(keyName))->value().toString(); +} + +QPixmap Utils::dropShadow(const QPixmap &source, qreal radius, const QColor &color, const QPoint &offset) +{ + QImage shadow = dropShadow(source, radius, color); + shadow.setDevicePixelRatio(source.devicePixelRatio()); + + QPainter pa(&shadow); + pa.setCompositionMode(QPainter::CompositionMode_SourceOver); + pa.drawPixmap(radius - offset.x(), radius - offset.y(), source); + pa.end(); + + return QPixmap::fromImage(shadow); +} + +QImage Utils::dropShadow(const QPixmap &px, qreal radius, const QColor &color) +{ + if (px.isNull()) { + return QImage(); + } + + QImage tmp(px.size() * px.devicePixelRatio() + QSize(radius * 2, radius * 2), QImage::Format_ARGB32_Premultiplied); + tmp.setDevicePixelRatio(px.devicePixelRatio()); + tmp.fill(0); + QPainter tmpPainter(&tmp); + tmpPainter.setCompositionMode(QPainter::CompositionMode_Source); + tmpPainter.drawPixmap(QPoint(radius, radius), px); + tmpPainter.end(); + + // Blur the alpha channel. + QImage blurred(tmp.size() * px.devicePixelRatio(), QImage::Format_ARGB32_Premultiplied); + blurred.setDevicePixelRatio(px.devicePixelRatio()); + blurred.fill(0); + QPainter blurPainter(&blurred); + qt_blurImage(&blurPainter, tmp, radius, false, true); + blurPainter.end(); + if (color == QColor(Qt::black)) { + return blurred; + } + tmp = blurred; + + // Blacken the image... + tmpPainter.begin(&tmp); + tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); + tmpPainter.fillRect(tmp.rect(), color); + tmpPainter.end(); + + return tmp; +} + +qreal Utils::easeInOut(qreal x) +{ + return (1 - qCos(M_PI * x)) / 2; +} + +qreal Utils::easeInQuad(qreal x) +{ + return qPow(x, 2); +} + +qreal Utils::easeOutQuad(qreal x) +{ + return -1 * qPow(x - 1, 2) + 1; +} + +qreal Utils::easeInQuint(qreal x) +{ + return qPow(x, 5); +} + +qreal Utils::easeOutQuint(qreal x) +{ + return qPow(x - 1, 5) + 1; +} + +QVariantMap Utils::getThemeMapFromPath(const QString &filepath) +{ + QFile file(filepath); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Failed to open " << filepath; + return QVariantMap(); + } + + QTextStream in(&file); + const QString jsonStr = in.readAll(); + file.close(); + + QByteArray jsonBytes = jsonStr.toLocal8Bit(); + QJsonDocument document = QJsonDocument::fromJson(jsonBytes); + QJsonObject object = document.object(); + + return object.toVariantMap(); +} + +bool Utils::isMimeTypeSupport(const QString &filepath) +{ + QString mimeType = QMimeDatabase().mimeTypeForFile(filepath).name(); + + if (mimeType.startsWith("text/")) { + return true; + } + + if (filepath.endsWith("pub")) { + return true; + } + // Please check full mime type list from: https://www.freeformatter.com/mime-types-list.html + QStringList textMimeTypes; + textMimeTypes << "application/cmd" + << "application/javascript" + << "application/json" + << "application/pkix-cert" + << "application/octet-stream" + << "application/sql" + << "application/vnd.apple.mpegurl" + << "application/vnd.nokia.qt.qmakeprofile" + << "application/vnd.nokia.xml.qt.resource" + << "application/x-desktop" + << "application/x-designer" + << "application/x-empty" + << "application/x-msdos-program" + << "application/x-pearl" + << "application/x-php" + << "application/x-shellscript" + << "application/x-sh" + << "application/x-theme" + << "application/x-cue" + << "application/x-csh" + << "application/x-asp" + << "application/x-subrip" + << "application/x-text" + << "application/x-trash" + << "application/x-xbel" + << "application/x-yaml" + << "application/x-pem-key" + << "application/xml" + << "application/yaml" + << "application/x-zerosize" + << "image/svg+xml" + << "application/x-perl" + << "application/x-ruby" + << "application/x-mpegURL" + << "application/x-wine-extension-ini" + << "model/vrml" + << "application/pkix-cert+pem" + << "application/x-pak" + << "application/x-code-workspace"; + + if (textMimeTypes.contains(mimeType)) { + return true; + } + + return false; +} + +bool Utils::isDraftFile(const QString &filepath) +{ + QString draftDir = QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()) + .filePath("blank-files"); + draftDir = QDir::cleanPath(draftDir); + QString dir = QFileInfo(filepath).dir().absolutePath(); + return dir == draftDir; +} + +/** + * @param filepath 文件路径 + * @return 返回传入文件路径 \a filepath 是否在备份文件夹 backup-files 中 + */ +bool Utils::isBackupFile(const QString &filepath) +{ + QString backupDir = QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()) + .filePath("backup-files"); + QString dir = QFileInfo(filepath).dir().absolutePath(); + return dir == backupDir; +} + +QStringList Utils::cleanPath(const QStringList &filePaths) +{ + QStringList paths; + for (QString path : filePaths) { + paths.push_back(QDir::cleanPath(path)); + } + + return paths; +} + +/** + * @return 返回程序使用的默认数据(存放临时、备份文件)存放位置,不同环境下路径不同 + * [debian] /home/user/.local/share/deepin/deepin-editor/ + * [linglong] /home/user/.linglong/org.deepin.editor/share/deepin/deepin-editor/ + */ +QString Utils::localDataPath() +{ + auto dataPaths = Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)); + return dataPaths.isEmpty() ? QDir::homePath() + "/.local/share/deepin/deepin-editor/" + : dataPaths.first(); +} + +const QStringList Utils::getEncodeList() +{ + QStringList encodeList; + + for (int mib : QTextCodec::availableMibs()) { + QTextCodec *codec = QTextCodec::codecForMib(mib); + QString encodeName = QString(codec->name()).toUpper(); + + if (encodeName != "UTF-8" && !encodeList.contains(encodeName)) { + encodeList.append(encodeName); + } + } + + encodeList.sort(); + encodeList.prepend("UTF-8"); + + return encodeList; +} + +QPixmap Utils::renderSVG(const QString &filePath, const QSize &size, bool bIsScale) +{ + int scaled = 1; + + if (qApp->devicePixelRatio() == 1.25 && bIsScale) { + scaled = 2; + } + + QPixmap pixmap(size * scaled); + pixmap.fill(Qt::transparent); + QImageReader reader; + + reader.setFileName(filePath); + + if (reader.canRead()) { + reader.setScaledSize(size * scaled); + pixmap = QPixmap::fromImage(reader.read()); + pixmap.setDevicePixelRatio(scaled); + } else { + pixmap.load(filePath); + } + + return pixmap; +} + +QList Utils::getHiglightColorList() +{ + QList listColor; + listColor.append(QColor("#FFA503")); + listColor.append(QColor("#FF1C49")); + listColor.append(QColor("#9023FC")); + listColor.append(QColor("#3468FF")); + listColor.append(QColor("#00C7E1")); + listColor.append(QColor("#05EA6B")); + listColor.append(QColor("#FEF144")); + listColor.append(QColor("#D5D5D1")); + return listColor; +} + +void Utils::clearChildrenFocus(QObject *objParent) +{ + // 可以获取焦点的控件名称列表 + QStringList foucswidgetlist; + //foucswidgetlist << "QLineEdit" << TERM_WIDGET_NAME; + + //qDebug() << "checkChildrenFocus start" << objParent->children().size(); + for (QObject *obj : objParent->children()) { + if (!obj->isWidgetType()) { + continue; + } + QWidget *widget = static_cast(obj); + if (Qt::NoFocus != widget->focusPolicy()) { + //qDebug() << widget << widget->focusPolicy() << widget->metaObject()->className(); + if (!foucswidgetlist.contains(widget->metaObject()->className())) { + widget->setFocusPolicy(Qt::NoFocus); + } + } + clearChildrenFocus(obj); + } + + //qDebug() << "checkChildrenFocus over" << objParent->children().size(); +} + +void Utils::clearChildrenFoucusEx(QWidget *pWidget) +{ + pWidget->clearFocus(); + + QObjectList childern = pWidget->children(); + + if (childern.size() <= 0) return; + + foreach (QObject *child, childern) { + if (!child->isWidgetType()) { + continue; + } + + QWidget *obj = static_cast(child); + clearChildrenFoucusEx(obj); + } +} + +void Utils::setChildrenFocus(QWidget *pWidget, Qt::FocusPolicy policy) +{ + pWidget->setFocusPolicy(policy); + + QObjectList childern = pWidget->children(); + + if (childern.size() <= 0) return; + + foreach (QObject *child, childern) { + if (!child->isWidgetType()) { + continue; + } + + QWidget *obj = static_cast(child); + setChildrenFocus(obj, policy); + } +} + +int Utils::getProcessCountByName(const char *pstrName) +{ + FILE *fp = NULL; + int count = -1; + char command[1024]; + + if (NULL == pstrName || strlen(pstrName) == 0) { + return count; + } + + memset(command, 0, sizeof(command)); + sprintf(command, "ps -ef | grep %s | grep -v grep | wc -l", pstrName); + + if ((fp = popen(command, "r")) != NULL) { + char buf[1024]; + memset(buf, 0, sizeof(buf)); + if ((fgets(buf, sizeof(buf) - 1, fp)) != NULL) { + count = atoi(buf); + } + pclose(fp); + } else { + qDebug() << ">>> popen error"; + } + + return count; +} + +void Utils::killProcessByName(const char *pstrName) +{ + if (pstrName != NULL && strlen(pstrName) > 0) { + char command[1024]; + memset(command, 0, sizeof(command)); + sprintf(command, "killall %s", pstrName); + system(command); + } +} + +QString Utils::getStringMD5Hash(const QString &input) +{ + QByteArray byteArray; + byteArray.append(input); + QByteArray md5Path = QCryptographicHash::hash(byteArray, QCryptographicHash::Md5); + + return md5Path.toHex(); +} + +bool Utils::activeWindowFromDock(quintptr winId) +{ + bool bRet = true; + // 优先采用V23接口 + QDBusInterface dockDbusInterfaceV23("org.deepin.dde.daemon.Dock1", + "/org/deepin/dde/daemon/Dock1", + "org.deepin.dde.daemon.Dock1"); + if (dockDbusInterfaceV23.isValid()) { + QDBusReply reply = dockDbusInterfaceV23.call("ActivateWindow", winId); + if (!reply.isValid()) { + qDebug() << "call v23 org.deepin.dde.daemon.Dock1 failed" << reply.error(); + bRet = false; + } else { + return bRet; + } + } + + QDBusInterface dockDbusInterfaceV20("com.deepin.dde.daemon.Dock", + "/com/deepin/dde/daemon/Dock", + "com.deepin.dde.daemon.Dock"); + if (dockDbusInterfaceV20.isValid() && !bRet) { + QDBusReply reply = dockDbusInterfaceV20.call("ActivateWindow", winId); + if (!reply.isValid()) { + qDebug() << "call v20 com.deepin.dde.daemon.Dock failed" << reply.error(); + bRet = false; + } + } + + return bRet; +} + +bool Utils::isShareDirAndReadOnly(const QString &filePath) +{ + bool ret = false; + + const QString sharePath = "/var/lib/samba/usershares"; + QDir shareDir(sharePath); + if (shareDir.exists()) { + QFileInfo fileInfo(filePath); + auto name = fileInfo.dir().dirName(); + if (shareDir.exists(name)) { + QFile file(sharePath + "/" + name); + if (file.open(QIODevice::ReadOnly)) { + QString fileContent = file.readAll(); + if (fileContent.contains(":R")) + ret = true; + file.close(); + } + } + } + + return ret; + +} + +QString Utils::getSystemLan() +{ + if (!m_systemLanguage.isEmpty()) { + return m_systemLanguage; + } else { + switch (getSystemVersion()) { + case V23: + m_systemLanguage = QLocale::system().name(); + break; + default: { + QDBusInterface ie("com.deepin.daemon.LangSelector", + "/com/deepin/daemon/LangSelector", + "com.deepin.daemon.LangSelector", + QDBusConnection::sessionBus()); + m_systemLanguage = ie.property("CurrentLocale").toString(); + break; + } + } + + qWarning() << "getSystemLan is" << m_systemLanguage; + return m_systemLanguage; + } +} + +/** + * @return 获取当前系统版本并返回 + */ +Utils::SystemVersion Utils::getSystemVersion() +{ + QString version = DSysInfo::majorVersion(); + if ("23" == version) { + return V23; + } + + // 其它版本默认V20 + return V20; +} + + +//judge whether the protocol is wayland +bool Utils::isWayland() +{ + static QString protocol; + if (protocol.isEmpty()) { + protocol = QProcessEnvironment::systemEnvironment().value("XDG_SESSION_TYPE"); + } + + return protocol.contains("wayland"); + +} + +QString Utils::lineFeed(const QString &text, int nWidth, const QFont &font, int nElidedRow) +{ + if (nElidedRow < 0) + nElidedRow = 2; + + QString strText = text; + QStringList strListLine; + QFontMetrics fm(font); + // 一行就直接中间截断显示 + if (1 == nElidedRow) + return fm.elidedText(text, Qt::ElideMiddle, nWidth); + + if (!strText.isEmpty()) { + for (int i = 1; i <= strText.size(); i++) { + if (fm.width(strText.left(i)) >= nWidth) { + if (strListLine.size() + 1 == nElidedRow) + break; + + strListLine.append(strText.left(i - 1)); + strText = strText.right(strText.size() - i + 1); + i = 0; + } + } + } + + // 多行时,对最后一行字符左侧省略 + if (!strListLine.isEmpty()) { + strText = fm.elidedText(strText, Qt::ElideLeft, nWidth); + strListLine.append(strText); + strText = strListLine.join('\n'); + } + + return strText; +} + +/** + * @brief 判断 [ \a x1, \a y1] 和 [ \a x2, \a y2] 区间是否存在交集 + * @param x1 固定区间左边界 + * @param y1 固定区间右边界 + * @param x2 移动区间左边界 + * @param y2 移动区间右边界 + * @return RegionType 返回重叠区间类型 + */ +Utils::RegionIntersectType Utils::checkRegionIntersect(int x1, int y1, int x2, int y2) +{ + if (y1 < x2) { + return ERight; + } else if (x1 > y2) { + return ELeft; + } else { + // 区间存在交集,判断交集类型 + // 活动区间左边界超过固定区间左边界 + bool outLeftBound = x1 > x2; + // 活动区间右边界超过固定区间右边界 + bool outRightBound = y1 < y2; + + if (outLeftBound && outRightBound) { + return EIntersectOutter; + } else if (outLeftBound) { + return EIntersectLeft; + } else if (outRightBound) { + return EIntersectRight; + } else { + return EIntersectInner; + } + } +} + +/** + * @return 取得当前文本编辑器支持的编码格式,按区域划分,从文件 :/encodes/encodes.ini 中读取 + * @note 非多线程安全,仅在 gui 线程调用 + */ +QVector > Utils::getSupportEncoding() +{ + static QVector > s_groupEncodeVec; + if (s_groupEncodeVec.isEmpty()) { + QVector > tmpEncodeVec; + + QFile file(":/encodes/encodes.ini"); + QString data; + if (file.open(QIODevice::ReadOnly)) { + data = QString::fromUtf8(file.readAll()); + file.close(); + } + + QTextStream readStream(&data,QIODevice::ReadOnly); + while (!readStream.atEnd()) { + QString group = readStream.readLine(); + QString key = group.mid(1,group.length()-2); + QString encodes = readStream.readLine(); + QString value = encodes.mid(8,encodes.length()-2); + tmpEncodeVec.append(QPair(key, value.split(","))); + } + + s_groupEncodeVec = tmpEncodeVec; + } + + return s_groupEncodeVec; +} + +/** + * @return 取得当前文本编辑器支持的编码格式列表 + */ +QStringList Utils::getSupportEncodingList() +{ + QStringList encodingList; + auto supportEncoding = getSupportEncoding(); + for (auto encodingData : supportEncoding) { + encodingList.append(encodingData.second); + } + std::sort(encodingList.begin(), encodingList.end()); + + return encodingList; +} diff --git a/src/common/utils.h b/src/common/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..f2691e0cfc753f6165b04be28f70ddc9c4a2f4dc --- /dev/null +++ b/src/common/utils.h @@ -0,0 +1,132 @@ +// SPDX-FileCopyrightText: 2011-2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once +#include "settings.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef SAFE_DELETE +#define SAFE_DELETE(p) if((p)) { delete (p); (p) = nullptr;} +#endif + +#ifndef LINGLONG_PREFIX +#define LINGLONG_PREFIX "/usr/" +#endif + +#define DEEPIN_THEME QString("%1share/deepin-editor/themes/deepin.theme").arg(LINGLONG_PREFIX) +#define DEEPIN_DARK_THEME QString("%1share/deepin-editor/themes/deepin_dark.theme").arg(LINGLONG_PREFIX) +#define DATA_SIZE_1024 1024 +#define TEXT_EIDT_MARK_ALL "MARK_ALL" +#define PROC_MEMINFO_PATH "/proc/meminfo" +#define COPY_CONSUME_MEMORY_MULTIPLE 9 //复制文本时内存占用系数 +#define PASTE_CONSUME_MEMORY_MULTIPLE 7 //粘贴文本时内存占用系数 + +class Utils +{ +public: + /** + * @brief 区间交叉类型 + */ + enum RegionIntersectType { + ELeft, ///< 活动区间在固定区间左侧 例如 [0, 9] 和 [-5, -1] + ERight, ///< 活动区间在固定区间右侧 例如 [0, 9] 和 [10, 15] + + EIntersectLeft, ///< 活动区间在固定区间左侧存在范围重叠 例如 [0, 9] 和 [-5, 5] + EIntersectRight, ///< 活动区间在固定区间右侧存在范围重叠 例如 [0, 9] 和 [5, 15] + EIntersectOutter, ///< 活动区间包含固定区间 例如 [0, 9] 和 [-10, 10] + EIntersectInner, ///< 活动区间处于固定区间内部 例如 [0, 9] 和 [5, 6] + }; + + /** + * @brief 当前运行时系统环境 + */ + enum SystemVersion { + V20, + V23, + }; + + static QString getQrcPath(const QString &imageName); + static QString getQssPath(const QString &qssName); + static QSize getRenderSize(int fontSize, const QString &string); + static void setFontSize(QPainter &painter, int textSize); + static void applyQss(QWidget *widget, const QString &qssName); + static QString getKeyshortcut(QKeyEvent *keyEvent); + static QString getKeyshortcutFromKeymap(Settings *settings, const QString &keyCategory, const QString &keyName); + static bool fileExists(const QString &path); + static bool fileIsWritable(const QString &path); + static bool fileIsHome(const QString &path); + static void passInputEvent(int wid); + static QPixmap dropShadow(const QPixmap &source, qreal radius, const QColor &color, const QPoint &offset); + static QImage dropShadow(const QPixmap &px, qreal radius, const QColor &color); + static QByteArray detectEncode(const QByteArray &data, const QString &fileName = QString()); + static QByteArray getEncode(const QByteArray &data); + static qreal easeInOut(qreal x); + static qreal easeInQuad(qreal x); + static qreal easeInQuint(qreal x); + static qreal easeOutQuad(qreal x); + static qreal easeOutQuint(qreal x); + static QVariantMap getThemeMapFromPath(const QString &filepath); + static bool isMimeTypeSupport(const QString &filepath); + static bool isDraftFile(const QString &filepath); + // 返回文件是否为备份文件 + static bool isBackupFile(const QString &filepath); + static QStringList cleanPath(const QStringList &filePaths); + // 返回程序使用的本地数据路径(存放临时、备份文件) + static QString localDataPath(); + static const QStringList getEncodeList(); + static QPixmap renderSVG(const QString &filePath, const QSize &size, bool bIsScale = true); + static QList getHiglightColorList(); + /******************************************************************************* + 1. @函数: clearChildrenFocus + 2. @作者: n014361 王培利 + 3. @日期: 2020-05-08 + 4. @说明: 清空控件内部所有子控件的焦点获取 + 安全考虑,不要全局使用.仅在个别控件中使用 + *******************************************************************************/ + static void clearChildrenFocus(QObject *objParent); + //清除 控件及子控件所以焦点 梁卫东 2020-09-14 10:34:19 + static void clearChildrenFoucusEx(QWidget *pWidget); + //设置所有控件焦点 梁卫东 2020-09-15 17:55:18 + static void setChildrenFocus(QWidget *pWidget, Qt::FocusPolicy policy = Qt::StrongFocus); + //根据指定名称获取进程数量 秦浩玲 2021-01-26 + static int getProcessCountByName(const char *pstrName); + //批量结束指定名称的进程 秦浩玲 2021-01-26 + static void killProcessByName(const char *pstrName); + //计算字符串MD5哈希值 秦浩玲 2021-01-28 + static QString getStringMD5Hash(const QString &input); + //通过dbus接口从任务栏激活窗口 add by guoshaoyu 2021-04-07 + static bool activeWindowFromDock(quintptr winId); + + //判断是否共享文件夹且只读 + static bool isShareDirAndReadOnly(const QString &filePath); + + static float codecConfidenceForData(const QTextCodec *codec, const QByteArray &data, const QLocale::Country &country); + + //return system language + static QString getSystemLan(); + // 取得系统版本是否为 V23 + static SystemVersion getSystemVersion(); + + static bool isWayland(); + + // 计算换行内容 text: 原始文本内容, nWidth: 一行最大宽度, font:字体大小, nElideRow: 最大显示行数,超出最大行时,中间内容加···省略号显示 + static QString lineFeed(const QString &text, int nWidth, const QFont &font, int nElidedRow = 2); + + // 判断 [x1, y1] 和 [x2, y2] 区间是否存在交集,返回交集类型 + static RegionIntersectType checkRegionIntersect(int x1, int y1, int x2, int y2); + // 取得当前文本编辑器支持的编码格式,从文件 :/encodes/encodes.ini 中读取 + static QVector> getSupportEncoding(); + static QStringList getSupportEncodingList(); + +private: + static QString m_systemLanguage; +}; diff --git a/src/controls/findbar.cpp b/src/controls/findbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f67ec49515d80c0de30cb9c1517691e463916245 --- /dev/null +++ b/src/controls/findbar.cpp @@ -0,0 +1,175 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "findbar.h" +#include "../common/utils.h" + +#include + +FindBar::FindBar(QWidget *parent) + : DFloatingWidget(parent) +{ + // Init. + //setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); + hide(); + setFixedHeight(60); + + // Init layout and widgets. + + m_layout = new QHBoxLayout(); + m_layout->setSpacing(10); + m_findLabel = new QLabel(tr("Find")); + m_findLabel->setMinimumHeight(36); + m_editLine = new LineBar(); + m_editLine->lineEdit()->setMinimumHeight(36); + m_findPrevButton = new QPushButton(tr("Previous")); + //m_findPrevButton->setFixedSize(80, 36); + m_findNextButton = new QPushButton(tr("Next")); + //m_findNextButton->setFixedSize(80, 36); + m_closeButton = new DIconButton(DStyle::SP_CloseButton); + m_closeButton->setIconSize(QSize(30, 30)); + m_closeButton->setFixedSize(30, 30); + m_closeButton->setEnabledCircle(true); + m_closeButton->setFlat(true); + m_layout->setContentsMargins(16, 6, 10, 6); + + m_layout->addWidget(m_findLabel); + m_layout->addWidget(m_editLine); + m_layout->addWidget(m_findPrevButton); + m_layout->addWidget(m_findNextButton); + m_layout->addWidget(m_closeButton); + this->setLayout(m_layout); + + // Make button don't grab keyboard focus after click it. + // m_findNextButton->setFocusPolicy(Qt::NoFocus); + // m_findPrevButton->setFocusPolicy(Qt::NoFocus); + // m_closeButton->setFocusPolicy(Qt::NoFocus); + + connect(this, &FindBar::pressEsc, this, &FindBar::findCancel, Qt::QueuedConnection); + // connect(m_editLine, &LineBar::pressEnter, this, &FindBar::findNext, Qt::QueuedConnection); //Shielded by Hengbo ,for new demand. 20200220 + //connect(m_editLine, &LineBar::pressCtrlEnter, this, &FindBar::findPrev, Qt::QueuedConnection); + connect(m_editLine, &LineBar::returnPressed, this, &FindBar::handleContentChanged, Qt::QueuedConnection); + connect(m_editLine, &LineBar::signal_sentText, this, &FindBar::receiveText, Qt::QueuedConnection); + //connect(m_editLine, &LineBar::contentChanged, this, &FindBar::slot_ifClearSearchWord, Qt::QueuedConnection); + + connect(m_findNextButton, &QPushButton::clicked, this, &FindBar::handleFindNext, Qt::QueuedConnection); + connect(m_findPrevButton, &QPushButton::clicked, this, &FindBar::handleFindPrev, Qt::QueuedConnection); + //connect(m_findPrevButton, &QPushButton::clicked, this, &FindBar::findPrev, Qt::QueuedConnection); + + connect(m_closeButton, &DIconButton::clicked, this, &FindBar::findCancel, Qt::QueuedConnection); +} + +bool FindBar::isFocus() +{ + return m_editLine->lineEdit()->hasFocus(); +} + +void FindBar::focus() +{ + m_editLine->lineEdit()->setFocus(); + m_editLine->lineEdit()->selectAll(); +} + +void FindBar::activeInput(QString text, QString file, int row, int column, int scrollOffset) +{ + // Try fill keyword with select text. + m_editLine->lineEdit()->clear(); + m_editLine->lineEdit()->insert(text); + m_editLine->lineEdit()->selectAll(); + + // Show. + QWidget::show(); + + // Save file info for back to position. + m_findFile = file; + m_findFileRow = row; + m_findFileColumn = column; + m_findFileSrollOffset = scrollOffset; + + // Focus. + focus(); +} + +void FindBar::findCancel() +{ + QWidget::hide(); + emit sigFindbarClose(); +} + +void FindBar::handleContentChanged() +{ + updateSearchKeyword(m_findFile, m_editLine->lineEdit()->text()); +} + +void FindBar::handleFindPrev() +{ + findPrev(m_editLine->lineEdit()->text()); +} + +void FindBar::handleFindNext() +{ + findNext(m_editLine->lineEdit()->text()); +} + +void FindBar::hideEvent(QHideEvent *) +{ + //保留查询标记 + //removeSearchKeyword(); +} + +bool FindBar::focusNextPrevChild(bool next) +{ + return false; +} + +void FindBar::keyPressEvent(QKeyEvent *e) +{ + const QString &key = Utils::getKeyshortcut(e); + if (key == "Esc") { + QWidget::hide(); + emit sigFindbarClose(); + } + if (m_closeButton->hasFocus() && key == "Tab") { + m_editLine->lineEdit()->setFocus(); + } else { + DFloatingWidget::keyPressEvent(e); + } + if (key == "Enter") { + if (m_findPrevButton->hasFocus()) { + m_findPrevButton->click(); + } + if (m_findNextButton->hasFocus()) { + m_findNextButton->click(); + } + } +} + +void FindBar::setMismatchAlert(bool isAlert) +{ + m_editLine->setAlert(isAlert); +} + +void FindBar::receiveText(QString t) +{ + searched = false; + if (t != "") { + m_receivedText = t; + } +} + +void FindBar::setSearched(bool _) +{ + searched = _; +} + +void FindBar::findPreClicked() +{ + if (!searched) { + updateSearchKeyword(m_findFile, m_editLine->lineEdit()->text()); + emit findPrev(m_editLine->lineEdit()->text()); + searched = true; + } else { + emit findPrev(m_editLine->lineEdit()->text()); + } +} diff --git a/src/controls/findbar.h b/src/controls/findbar.h new file mode 100644 index 0000000000000000000000000000000000000000..d971a7b02a66d76649c8e065c0625b05489975e3 --- /dev/null +++ b/src/controls/findbar.h @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef FINDBAR_H +#define FINDBAR_H + +#include "linebar.h" + +#include +#include +#include +#include +#include +#include "dimagebutton.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +DWIDGET_USE_NAMESPACE + +class FindBar : public DFloatingWidget +{ + Q_OBJECT + +public: + explicit FindBar(QWidget *parent = 0); + + bool isFocus(); + void focus(); + + void activeInput(QString text, QString file, int row, int column, int scrollOffset); + void setMismatchAlert(bool isAlert); + void receiveText(QString t); + void setSearched(bool _); + void findPreClicked(); + +signals: + void pressEsc(); + void findNext(const QString &keyword); + void findPrev(const QString &keyword); + + void removeSearchKeyword(); + void updateSearchKeyword(QString file, QString keyword); + + //add guoshao + void sigFindbarClose(); + +public slots: + void findCancel(); + void handleContentChanged(); + void handleFindNext(); + void handleFindPrev(); + +protected: + void hideEvent(QHideEvent *event) override; + bool focusNextPrevChild(bool next) override; + void keyPressEvent(QKeyEvent *e) override; + +private: + QPushButton *m_findNextButton; + QPushButton *m_findPrevButton; + DIconButton *m_closeButton; + LineBar *m_editLine; + QHBoxLayout *m_layout; + QLabel *m_findLabel; + QString m_findFile; + int m_findFileColumn; + int m_findFileRow; + int m_findFileSrollOffset; + QColor m_backgroundColor; + QString m_receivedText = " "; + bool searched = false; + + QPoint last; +}; + +#endif diff --git a/src/controls/fontitemdelegate.cpp b/src/controls/fontitemdelegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07235e8e89aa71041c72bd7aea3d6f074a2a8355 --- /dev/null +++ b/src/controls/fontitemdelegate.cpp @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "fontitemdelegate.h" +#include + +FontItemDelegate::FontItemDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ + +} + +FontItemDelegate::~FontItemDelegate() +{ +} + +void FontItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + const QString text = index.data(Qt::DisplayRole).toString(); + bool isSelected = option.state & QStyle::State_Selected; + + painter->setPen(Qt::black); + + if (isSelected) { + painter->setPen(Qt::NoPen); + painter->setBrush(QColor("#2CA7F8")); + painter->drawRect(option.rect); + painter->setPen(Qt::white); + } + + QFont font(painter->font()); + font.setFamily(text); + painter->setFont(font); + + QRect textRect = option.rect; + painter->drawText(QRect(textRect.x() + 10, + textRect.y(), + textRect.width() - 10, + textRect.height()), Qt::AlignVCenter | Qt::AlignLeft, text); +} + +QSize FontItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(-1, 30); +} diff --git a/src/controls/fontitemdelegate.h b/src/controls/fontitemdelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..50e9ebcf45e04206e65077b2da74a5c3db5d961c --- /dev/null +++ b/src/controls/fontitemdelegate.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef FONTITEMDELEGATE_H +#define FONTITEMDELEGATE_H + +#include + +class FontItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit FontItemDelegate(QObject *parent = nullptr); + ~FontItemDelegate(); + +protected: + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +#endif diff --git a/src/controls/jumplinebar.cpp b/src/controls/jumplinebar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ce32b49dacf89a21b9e3a7db9cc5c49b7c70386 --- /dev/null +++ b/src/controls/jumplinebar.cpp @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "jumplinebar.h" + +#include + +#include + +// 各项组件的默认大小 +const int nJumpLineBarWidth = 212; +const int nJumpLineBarHeight = 60; +const int s_nJumpLineBarSpinBoxWidth = 124; +const int s_nJumpLineBarSPinBoxHeight = 36; +// 水平方向与边界间距 +const int s_nJumpLineBarHorizenMargin = 10; + +JumpLineBar::JumpLineBar(DFloatingWidget *parent) + : DFloatingWidget(parent) +{ + // Init layout and widgets. + m_layout = new QHBoxLayout(); + m_layout->setContentsMargins(10, 6, 10, 6); + m_layout->setSpacing(5); + + m_closeButton = new DIconButton(DStyle::SP_CloseButton); + m_closeButton->setIconSize(QSize(30, 30)); + m_closeButton->setFixedSize(30, 30); + m_closeButton->setEnabledCircle(true); + m_closeButton->setFlat(true); + + m_label = new QLabel(); + m_label->setText(tr("Go to Line: ")); + // 按文本长度计算显示宽度,不同语言下翻译文本长度不一,需完整显示 + m_label->setFixedWidth(fontMetrics().width(m_label->text())); + m_pSpinBoxInput = new DSpinBox; + m_pSpinBoxInput->setFixedSize(s_nJumpLineBarSpinBoxWidth, s_nJumpLineBarSPinBoxHeight); + m_pSpinBoxInput->lineEdit()->clear(); + m_pSpinBoxInput->setButtonSymbols(QAbstractSpinBox::NoButtons); + m_pSpinBoxInput->installEventFilter(this); + + m_layout->addWidget(m_label); + m_layout->addWidget(m_pSpinBoxInput); + m_layout->addWidget(m_closeButton); + this->setLayout(m_layout); + + // 初始化浮动条宽度,根据文本长度计算 + setFixedHeight(nJumpLineBarHeight); + setFixedWidth(m_layout->sizeHint().width() + s_nJumpLineBarHorizenMargin); + + connect(this, &JumpLineBar::pressEsc, this, &JumpLineBar::jumpCancel, Qt::QueuedConnection); + connect(m_pSpinBoxInput->lineEdit(), &QLineEdit::returnPressed, this, &JumpLineBar::jumpConfirm, Qt::QueuedConnection); + connect(m_pSpinBoxInput->lineEdit(), &QLineEdit::textChanged, this, &JumpLineBar::handleLineChanged, Qt::QueuedConnection); + connect(m_closeButton, &DIconButton::clicked, this, &JumpLineBar::close, Qt::QueuedConnection); +} + +JumpLineBar::~JumpLineBar() +{} + +void JumpLineBar::focus() +{ + m_pSpinBoxInput->lineEdit()->setFocus(); +} + +bool JumpLineBar::isFocus() +{ + return m_pSpinBoxInput->lineEdit()->hasFocus(); +} + +void JumpLineBar::activeInput(QString file, int row, int column, int lineCount, int scrollOffset) +{ + // Save file info for back to line. + m_jumpFile = file; + m_rowBeforeJump = row; + m_columnBeforeJump = column; + m_jumpFileScrollOffset = scrollOffset; + m_lineCount = lineCount; + // 调整为 0~lineCount ,0已被处理不允许首位输入,不影响仅单行的情况 + // 设置 range 后会自动调整输入范围,不使用 clear() 防止在读取文件时已输入的行号被清空 + m_pSpinBoxInput->setRange(0, lineCount); + int lineWidth = QString::number(lineCount).size() * fontMetrics().width('9'); + if (m_pSpinBoxInput->minimumWidth() < lineWidth) { + m_pSpinBoxInput->setFixedWidth(lineWidth); + } else { + m_pSpinBoxInput->setFixedWidth(s_nJumpLineBarSpinBoxWidth); + } + setFixedWidth(m_layout->sizeHint().width() + s_nJumpLineBarHorizenMargin); + + // Clear line number. + if (m_pSpinBoxInput->lineEdit()->text().toInt() > lineCount) + m_pSpinBoxInput->lineEdit()->setText(""); +} + +void JumpLineBar::handleFocusOut() +{ + //hide(); + lostFocusExit(); +} + +void JumpLineBar::handleLineChanged() +{ + QString content = m_pSpinBoxInput->lineEdit()->text(); + if (content != "") { + if (content.toInt() == 0) { + m_pSpinBoxInput->clear(); + return; + } + jumpToLine(m_jumpFile, content.toInt(), false); + } +} + +void JumpLineBar::jumpCancel() +{ + hide(); + // esc键不跳转 返回当前 + // backToPosition(m_jumpFile, m_rowBeforeJump, m_columnBeforeJump, m_jumpFileScrollOffset); +} + +void JumpLineBar::jumpConfirm() +{ + QString content = m_pSpinBoxInput->lineEdit()->text(); + if (content != "") { + jumpToLine(m_jumpFile, content.toInt(), true); + } +} + +void JumpLineBar::slotFocusChanged(bool bFocus) +{ + if (bFocus == false) { + lostFocusExit(); + } +} + +// Hide 跳转到行窗口时,需要清空编辑框中的内容 +void JumpLineBar::hide() +{ + m_pSpinBoxInput->clear(); + DFloatingWidget::hide(); +} + +int JumpLineBar::getLineCount() +{ + return m_lineCount; +} + +bool JumpLineBar::eventFilter(QObject *pObject, QEvent *pEvent) +{ + if (pObject == m_pSpinBoxInput) { + if (pEvent->type() == QEvent::FocusOut) { + handleFocusOut(); + /** + * 规避当DSpinBox输入框里为空且失去focus焦点时会显示上一次输入的数值内容的问题 + */ + if (m_pSpinBoxInput->lineEdit()->text() == "") { + m_pSpinBoxInput->lineEdit()->clear(); + } + } + } + + return DFloatingWidget::eventFilter(pObject, pEvent); +} + diff --git a/src/controls/jumplinebar.h b/src/controls/jumplinebar.h new file mode 100644 index 0000000000000000000000000000000000000000..f6431cd1db630db769552df5a629dcc843836a81 --- /dev/null +++ b/src/controls/jumplinebar.h @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef JUMPLINEBAR_H +#define JUMPLINEBAR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class JumpLineBar : public DFloatingWidget +{ + Q_OBJECT +public: + explicit JumpLineBar(DFloatingWidget *parent = 0); + ~JumpLineBar(); + +public slots: + void focus(); + bool isFocus(); + void activeInput(QString file, int row, int column, int lineCount, int scrollOffset); + void handleFocusOut(); + void handleLineChanged(); + void jumpCancel(); + void jumpConfirm(); + void slotFocusChanged(bool bFocus); + void hide(); + int getLineCount(); + +signals: + void backToPosition(QString file, int row, int column, int scrollOffset); + void jumpToLine(QString file, int line, bool focusEditor); + void lostFocusExit(); + void pressEsc(); + +protected: + bool eventFilter(QObject *pObject, QEvent *pEvent); + +private: + DSpinBox *m_pSpinBoxInput {nullptr}; + QHBoxLayout *m_layout {nullptr}; + QLabel *m_label {nullptr}; + QString m_jumpFile; + int m_jumpFileScrollOffset; + int m_rowBeforeJump; + int m_columnBeforeJump; + int m_lineCount; + QColor m_backgroundColor; + DIconButton *m_closeButton=nullptr; +}; + +#endif diff --git a/src/controls/linebar.cpp b/src/controls/linebar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9df662a02e723c494ca9440439c4a64fb9f18e8 --- /dev/null +++ b/src/controls/linebar.cpp @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "linebar.h" +#include "../common/utils.h" + +#include + +LineBar::LineBar(DLineEdit *parent) + : DLineEdit(parent) +{ + // Init. + setClearButtonEnabled(true); + + m_autoSaveInternal = 50; + m_autoSaveTimer = new QTimer(this); + m_autoSaveTimer->setSingleShot(true); + + connect(m_autoSaveTimer, &QTimer::timeout, this, &LineBar::handleTextChangeTimer); + connect(this, &DLineEdit::textEdited, this, &LineBar::sendText, Qt::QueuedConnection); + connect(this, &DLineEdit::textChanged, this, &LineBar::handleTextChanged, Qt::QueuedConnection); +} + +void LineBar::handleTextChangeTimer() +{ + // Emit contentChanged signal. + contentChanged(); +} + +void LineBar::handleTextChanged(const QString &str) +{ + // Stop timer if new character is typed, avoid unused timer run. + if (m_autoSaveTimer->isActive()) { + m_autoSaveTimer->stop(); + } + if(str.isEmpty()) { + setAlert(false); + } + // Start new timer. + m_autoSaveTimer->start(m_autoSaveInternal); +} + +void LineBar::sendText(QString t) +{ + emit signal_sentText(t); +} + +void LineBar::focusOutEvent(QFocusEvent *e) +{ + // Emit focus out signal. + focusOut(); + + // Throw event out avoid DLineEdit can't hide cursor after lost focus. + DLineEdit::focusOutEvent(e); +} + +void LineBar::keyPressEvent(QKeyEvent *e) +{ + QString key = Utils::getKeyshortcut(e); + Qt::KeyboardModifiers modifiers = e->modifiers(); + + if(modifiers == Qt::ControlModifier && e->text() == "\r"){ + pressCtrlEnter(); + }else if(modifiers == Qt::AltModifier && e->text() == "\r"){ + pressAltEnter(); + }else if(modifiers == Qt::MetaModifier && e->text() == "\r"){ + pressMetaEnter(); + }else if(modifiers == Qt::NoModifier && e->text() == "\r"){ + pressEnter(); + }else { + // Pass event to DLineEdit continue, otherwise you can't type anything after here. ;) + DLineEdit::keyPressEvent(e); + } +} diff --git a/src/controls/linebar.h b/src/controls/linebar.h new file mode 100644 index 0000000000000000000000000000000000000000..875348e052c062136a14d7a17c9d3ec00a81556f --- /dev/null +++ b/src/controls/linebar.h @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef LINEBAR_H +#define LINEBAR_H + +#include "dlineedit.h" + +#include + +DWIDGET_USE_NAMESPACE + +class LineBar : public DLineEdit +{ + Q_OBJECT + +public: + explicit LineBar(DLineEdit *parent = 0); + +public slots: + void handleTextChangeTimer(); + void handleTextChanged(const QString &str=""); + void sendText(QString t); + +signals: + void contentChanged(); + void focusOut(); + void pressAltEnter(); + void pressCtrlEnter(); + void pressEnter(); + void pressMetaEnter(); + void signal_sentText(QString t); + +protected: + virtual void focusOutEvent(QFocusEvent *e); + virtual void keyPressEvent(QKeyEvent *e); + +private: + QTimer *m_autoSaveTimer; + int m_autoSaveInternal; +}; + +#endif diff --git a/src/controls/replacebar.cpp b/src/controls/replacebar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c5c282456a8bc2d0efaf6339cccb7c287534536 --- /dev/null +++ b/src/controls/replacebar.cpp @@ -0,0 +1,221 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "replacebar.h" +#include "../common/utils.h" + +#include + +ReplaceBar::ReplaceBar(QWidget *parent) + : DFloatingWidget(parent) +{ + // Init. + hide(); + setFixedHeight(60); + + // Init layout and widgets. + m_layout = new QHBoxLayout(); + m_layout->setSpacing(10); + m_layout->setContentsMargins(16, 6, 10, 6); + m_replaceLabel = new QLabel(tr("Find")); + //m_replaceLabel->setMinimumHeight(36); + m_replaceLine = new LineBar(); + //m_replaceLine->lineEdit()->setMinimumHeight(36); + m_withLabel = new QLabel(tr("Replace With")); + //m_withLabel->setMinimumHeight(36); + m_withLine = new LineBar(); + //m_withLine->lineEdit()->setMinimumHeight(36); + m_replaceButton = new QPushButton(tr("Replace")); + //m_replaceButton->setMinimumWidth(66); + //m_replaceButton->setMinimumHeight(36); + m_replaceSkipButton = new QPushButton(tr("Skip")); + //m_replaceSkipButton->setMinimumWidth(66); + //m_replaceSkipButton->setMinimumHeight(36); + m_replaceRestButton = new QPushButton(tr("Replace Rest")); + //m_replaceRestButton->setMinimumWidth(80); + //m_replaceRestButton->setMinimumHeight(36); + m_replaceAllButton = new QPushButton(tr("Replace All")); + //m_replaceAllButton->setMinimumWidth(80); + //m_replaceAllButton->setMinimumHeight(36); + m_closeButton = new DIconButton(DStyle::SP_CloseButton); + m_closeButton->setFlat(true); + m_closeButton->setFixedSize(30, 30); + m_closeButton->setEnabledCircle(true); + m_closeButton->setIconSize(QSize(30, 30)); + + m_layout->addWidget(m_replaceLabel); + m_layout->addWidget(m_replaceLine); + m_layout->addWidget(m_withLabel); + m_layout->addWidget(m_withLine); + m_layout->addWidget(m_replaceButton); + m_layout->addWidget(m_replaceSkipButton); + m_layout->addWidget(m_replaceRestButton); + m_layout->addWidget(m_replaceAllButton); + m_layout->addWidget(m_closeButton); + this->setLayout(m_layout); + + // Make button don't grab keyboard focus after click it. + #if 0 + m_replaceButton->setFocusPolicy(Qt::NoFocus); + m_replaceSkipButton->setFocusPolicy(Qt::NoFocus); + m_replaceRestButton->setFocusPolicy(Qt::NoFocus); + m_replaceAllButton->setFocusPolicy(Qt::NoFocus); + m_closeButton->setFocusPolicy(Qt::NoFocus); + #endif + connect(m_replaceLine, &LineBar::signal_sentText, this, &ReplaceBar::change, Qt::QueuedConnection); + + connect(this, &ReplaceBar::pressEsc, this, &ReplaceBar::replaceClose, Qt::QueuedConnection); + + //connect(m_replaceLine, &LineBar::pressEnter, this, &ReplaceBar::handleReplaceNext, Qt::QueuedConnection); //Shielded by Hengbo for new demand. + connect(m_withLine, &LineBar::returnPressed, this, &ReplaceBar::handleReplaceNext, Qt::QueuedConnection); + connect(m_replaceLine, &LineBar::pressCtrlEnter, this, &ReplaceBar::handleSkip,Qt::QueuedConnection); + connect(m_withLine, &LineBar::pressCtrlEnter, this, &ReplaceBar::handleSkip,Qt::QueuedConnection); + connect(m_replaceLine, &LineBar::pressAltEnter, this, &ReplaceBar::handleReplaceRest, Qt::QueuedConnection); + connect(m_withLine, &LineBar::pressAltEnter, this, &ReplaceBar::handleReplaceRest, Qt::QueuedConnection); + connect(m_replaceLine, &LineBar::pressMetaEnter, this, &ReplaceBar::handleReplaceAll, Qt::QueuedConnection); + connect(m_withLine, &LineBar::pressMetaEnter, this, &ReplaceBar::handleReplaceAll, Qt::QueuedConnection); + connect(m_replaceLine, &LineBar::returnPressed, this, &ReplaceBar::handleContentChanged, Qt::QueuedConnection); + connect(m_replaceButton, &QPushButton::clicked, this, &ReplaceBar::handleReplaceNext, Qt::QueuedConnection); + connect(m_replaceSkipButton, &QPushButton::clicked, this, &ReplaceBar::handleSkip,Qt::QueuedConnection); + connect(m_replaceRestButton, &QPushButton::clicked, this, &ReplaceBar::handleReplaceRest, Qt::QueuedConnection); + connect(m_replaceAllButton, &QPushButton::clicked, this, &ReplaceBar::handleReplaceAll, Qt::QueuedConnection); + + connect(m_closeButton, &DIconButton::clicked, this, &ReplaceBar::replaceClose, Qt::QueuedConnection); +} + +bool ReplaceBar::isFocus() +{ + return m_replaceLine->hasFocus(); +} + +void ReplaceBar::focus() +{ + m_replaceLine->lineEdit()->setFocus(); +} + +void ReplaceBar::activeInput(QString text, QString file, int row, int column, int scrollOffset) +{ + // Try fill keyword with select text. + m_withLine->lineEdit()->clear(); + m_replaceLine->lineEdit()->clear(); + m_replaceLine->lineEdit()->insert(text); + m_replaceLine->lineEdit()->selectAll(); + + // Show. + show(); + + // Save file info for back to position. + m_replaceFile = file; + m_replaceFileRow = row; + m_replaceFileColumn = column; + m_replaceFileSrollOffset = scrollOffset; + + // Focus. + focus(); +} + +void ReplaceBar::handleSkip() +{ + emit replaceSkip(m_replaceFile, m_replaceLine->lineEdit()->text()); +} + +void ReplaceBar::replaceClose() +{ + searched = false; + hide(); + emit sigReplacebarClose(); +} + +void ReplaceBar::handleContentChanged() +{ + updateSearchKeyword(m_replaceFile, m_replaceLine->lineEdit()->text()); +} + +void ReplaceBar::handleReplaceNext() +{ + if (!searched) { + emit removeSearchKeyword(); + emit beforeReplace(m_replaceLine->lineEdit()->text()); + } + replaceNext(m_replaceFile, m_replaceLine->lineEdit()->text(), m_withLine->lineEdit()->text()); + searched = true; +} + +void ReplaceBar::handleReplaceRest() +{ + replaceRest(m_replaceLine->lineEdit()->text(), m_withLine->lineEdit()->text()); +} + +void ReplaceBar::handleReplaceAll() +{ + replaceAll(m_replaceLine->lineEdit()->text(), m_withLine->lineEdit()->text()); +} + +void ReplaceBar::hideEvent(QHideEvent *) +{ + searched = false; + removeSearchKeyword(); +} + +bool ReplaceBar::focusNextPrevChild(bool) +{ + // Make keyword jump between two EditLine widgets. + auto *editWidget = qobject_cast(focusWidget()); + if (editWidget != nullptr) { + if (editWidget == m_replaceLine) { + m_withLine->lineEdit()->setFocus(); + + return true; + } else if (editWidget == m_withLine) { + m_replaceLine->lineEdit()->setFocus(); + + return true; + } + } + + return false; +} + +void ReplaceBar::keyPressEvent(QKeyEvent *e) +{ + const QString &key = Utils::getKeyshortcut(e); + if (key == "Esc") { + QWidget::hide(); + emit sigReplacebarClose(); + } + if (m_closeButton->hasFocus() && key == "Tab") { + m_replaceLine->lineEdit()->setFocus(); + } else { + DFloatingWidget::keyPressEvent(e); + } + if (key == "Enter") { + if (m_replaceAllButton->hasFocus()) { + m_replaceAllButton->click(); + } + if (m_replaceButton->hasFocus()) { + m_replaceButton->click(); + } + if (m_replaceRestButton->hasFocus()) { + m_replaceRestButton->click(); + } + if (m_replaceSkipButton->hasFocus()) { + m_replaceSkipButton->click(); + } + } +} + +void ReplaceBar::setMismatchAlert(bool isAlert) +{ + m_replaceLine->setAlert(isAlert); +} + +void ReplaceBar::setsearched(bool _) +{ + searched = _; +} + +void ReplaceBar::change() +{ + searched = false; +} diff --git a/src/controls/replacebar.h b/src/controls/replacebar.h new file mode 100644 index 0000000000000000000000000000000000000000..bc8d17838271880e7d4dd56bdc7f32f9ab9abb16 --- /dev/null +++ b/src/controls/replacebar.h @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef REPLACEBAR_H +#define REPLACEBAR_H + +#include +#include "linebar.h" +#include +#include +#include +#include +#include "dimagebutton.h" +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class ReplaceBar : public DFloatingWidget +{ + Q_OBJECT + +public: + explicit ReplaceBar(QWidget *parent = 0); + + bool isFocus(); + void focus(); + + void activeInput(QString text, QString file, int row, int column, int scrollOffset); + void setMismatchAlert(bool isAlert); + void setsearched(bool _); + +signals: + void pressEsc(); + void replaceNext(QString file, QString replaceText, QString withText); + void replaceSkip(QString file, QString keyword); + void replaceRest(QString replaceText, QString withText); + void replaceAll(QString replaceText, QString withText); + void beforeReplace(QString _); + + void backToPosition(QString file, int row, int column, int scrollOffset); + + void removeSearchKeyword(); + void updateSearchKeyword(QString file, QString keyword); + + void sigReplacebarClose(); + +public slots: + void change(); + void replaceClose(); + void handleContentChanged(); + void handleReplaceAll(); + void handleReplaceNext(); + void handleReplaceRest(); + void handleSkip(); + +protected: + void hideEvent(QHideEvent *event); + bool focusNextPrevChild(bool next); + void keyPressEvent(QKeyEvent *e); + +private: + QPushButton *m_replaceAllButton; + QPushButton *m_replaceButton; + QPushButton *m_replaceRestButton; + QPushButton *m_replaceSkipButton; + DIconButton *m_closeButton; + LineBar *m_replaceLine; + LineBar *m_withLine; + QHBoxLayout *m_layout; + QLabel *m_replaceLabel; + QLabel *m_withLabel; + QString m_replaceFile; + int m_replaceFileColumn; + int m_replaceFileRow; + int m_replaceFileSrollOffset; + QColor m_backgroundColor; + bool searched = false; + + QPoint last; +}; + +#endif diff --git a/src/controls/settingsdialog.cpp b/src/controls/settingsdialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a7f246d595dfbb36cfcae85b584bf50dd43b647 --- /dev/null +++ b/src/controls/settingsdialog.cpp @@ -0,0 +1,130 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +void GenerateSettingTranslate() +{ + auto group_baseName = QObject::tr("Basic"); + auto base_fontName = QObject::tr("Font Style"); + auto base_font_familyName = QObject::tr("Font"); + auto base_font_sizeName = QObject::tr("Font Size"); + auto group_shortcutsName = QObject::tr("Shortcuts"); + auto shortcuts_keymapName = QObject::tr("Keymap"); + auto shortcurs_keymap_keymap = QObject::tr("Keymap"); + auto shortcuts_windowName = QObject::tr("Window"); + auto shortcuts_window_addblanktabName = QObject::tr("New tab"); + auto shortcuts_window_newwindowName = QObject::tr("New window"); + auto shortcuts_window_savefileName = QObject::tr("Save"); + auto shortcuts_window_saveasfileName = QObject::tr("Save as"); + auto shortcuts_window_selectnexttabName = QObject::tr("Next tab"); + auto shortcuts_window_selectprevtabName = QObject::tr("Previous tab"); + auto shortcuts_window_closetabName = QObject::tr("Close tab"); + auto shortcuts_window_closeothertabsName = QObject::tr("Close other tabs"); + auto shortcuts_window_restoretabName = QObject::tr("Restore tab"); + auto shortcuts_window_openfileName = QObject::tr("Open file"); + auto shortcuts_window_incrementfontsizeName = QObject::tr("Increment font size"); + auto shortcuts_window_decrementfontsizeName = QObject::tr("Decrement font size"); + auto shortcuts_window_resetfontsizeName = QObject::tr("Reset font size"); + auto shortcuts_window_help = QObject::tr("Help"); + auto shortcuts_window_togglefullscreenName = QObject::tr("Toggle fullscreen"); + auto shortcuts_window_findName = QObject::tr("Find"); + Q_UNUSED(QObject::tr("Find Next")); + Q_UNUSED(QObject::tr("Find Previous")); + auto shortcuts_window_replaceName = QObject::tr("Replace"); + auto shortcuts_window_jumptolineName = QObject::tr("Go to line"); + auto shortcuts_window_savepositionName = QObject::tr("Save cursor position"); + auto shortcuts_window_restorepositionName = QObject::tr("Reset cursor position"); + auto shortcuts_window_escapeName = QObject::tr("Exit"); + auto shortcuts_window_displayshortcutsName = QObject::tr("Display shortcuts"); + auto shortcuts_window_printName = QObject::tr("Print"); + auto group_editorName = QObject::tr("Editor"); + auto shortcuts_editor_indentlineName = QObject::tr("Increase indent"); + auto shortcuts_editor_backindentlineName = QObject::tr("Decrease indent"); + auto shortcuts_editor_forwardcharName = QObject::tr("Forward character"); + auto shortcuts_editor_backwardcharName = QObject::tr("Backward character"); + auto shortcuts_editor_forwardwordName = QObject::tr("Forward word"); + auto shortcuts_editor_backwarwordName = QObject::tr("Backward word"); + auto shortcuts_editor_nextlineName = QObject::tr("Next line"); + auto shortcuts_editor_prevlineName = QObject::tr("Previous line"); + auto shortcuts_editor_newlineName = QObject::tr("New line"); + auto shortcuts_editor_opennewlineaboveName = QObject::tr("New line above"); + auto shortcuts_editor_opennewlinebelowName = QObject::tr("New line below"); + auto shortcuts_editor_duplicatelineName = QObject::tr("Duplicate line"); + auto shortcuts_editor_killlineName = QObject::tr("Delete to end of line"); + auto shortcuts_editor_killcurrentlineName = QObject::tr("Delete current line"); + auto shortcuts_editor_swaplineupName = QObject::tr("Swap line up"); + auto shortcuts_editor_swaplinedownName = QObject::tr("Swap line down"); + auto shortcuts_editor_scrolllineupName = QObject::tr("Scroll up one line"); + auto shortcuts_editor_scrolllinedownName = QObject::tr("Scroll down one line"); + auto shortcuts_editor_scrollupName = QObject::tr("Page up"); + auto shortcuts_editor_scrolldownName = QObject::tr("Page down"); + auto shortcuts_editor_movetoendoflineName = QObject::tr("Move to end of line"); + auto shortcuts_editor_movetostartoflineName = QObject::tr("Move to start of line"); + auto shortcuts_editor_movetoendName = QObject::tr("Move to end of text"); + auto shortcuts_editor_movetostartName = QObject::tr("Move to start of text"); + auto shortcuts_editor_movetolineindentationName = QObject::tr("Move to line indentation"); + auto shortcuts_editor_upcasewordName = QObject::tr("Upper case"); + auto shortcuts_editor_downcasewordName = QObject::tr("Lower case"); + auto shortcuts_editor_capitalizewordName = QObject::tr("Capitalize"); + auto shortcuts_editor_killbackwardwordName = QObject::tr("Delete backward word"); + auto shortcuts_editor_killforwardwordName = QObject::tr("Delete forward word"); + auto shortcuts_editor_forwardpairName = QObject::tr("Forward over a pair"); + auto shortcuts_editor_backwardpairName = QObject::tr("Backward over a pair"); + auto shortcuts_editor_selectallName = QObject::tr("Select all"); + auto shortcuts_editor_copyName = QObject::tr("Copy"); + auto shortcuts_editor_cutName = QObject::tr("Cut"); + auto shortcuts_editor_pasteName = QObject::tr("Paste"); + auto shortcuts_editor_transposecharName = QObject::tr("Transpose character"); + auto shortcuts_editor_setmarkName = QObject::tr("Mark"); + auto shortcuts_editor_exchangemarkName = QObject::tr("Unmark"); + auto shortcuts_editor_copylinesName = QObject::tr("Copy line"); + auto shortcuts_editor_cutlinesName = QObject::tr("Cut line"); + auto shortcuts_editor_joinlinesName = QObject::tr("Merge lines"); + auto shortcuts_editor_togglereadonlymodeName = QObject::tr("Read-Only mode"); + auto shortcuts_editor_togglecommentName = QObject::tr("Add comment"); + auto shortcuts_editor_removecommentName = QObject::tr("Remove comment"); + auto shortcuts_editor_undoName = QObject::tr("Undo"); + auto shortcuts_editor_redoName = QObject::tr("Redo"); + auto shortcuts_editor_switchbookmarkName = QObject::tr("Add/Remove bookmark"); + auto shortcuts_editor_movetoprebookmarkName = QObject::tr("Move to previous bookmark"); + auto shortcuts_editor_movetonextbookmarkName = QObject::tr("Move to next bookmark"); + auto group_advanceName = QObject::tr("Advanced"); + auto advance_windowName = QObject::tr("Window"); + auto advance_window_windowstateName = QObject::tr("Window size"); + auto advance_editor_tabspacenumberName = QObject::tr("Tab width"); + auto allow_midbutton_paste_name = QObject::tr("Paste by pressing a middle mouse button"); + + auto advance_startup_name = QObject::tr("Startup"); + auto advance_startup_saveTabBeforeCloseName = QObject::tr("Reopen last closed tabs"); + + auto advance_open_save_setting_name = QObject::tr("Open/Save Settings"); + + auto base_font_wordwrapText = QObject::tr("Word wrap"); + auto base_font_codeflod = QObject::tr("Code folding flag"); + auto base_font_showLineNumber = QObject::tr("Show line numbers"); + auto base_font_showBookmark = QObject::tr("Show bookmarks icon"); + auto showblankcharacter = QObject::tr("Show whitespaces and tabs"); + auto base_font_highlightCurrentLine = QObject::tr("Highlight current line"); + auto shortcuts_editor_markName = QObject::tr("Color mark"); + + //编码翻译 + auto Unicode = QObject::tr("Unicode"); + auto WesternEuropean = QObject::tr("WesternEuropean"); + auto CentralEuropean = QObject::tr("CentralEuropean"); + auto Baltic = QObject::tr("Baltic"); + auto Cyrillic = QObject::tr("Cyrillic"); + auto Arabic = QObject::tr("Arabic"); + auto Greek = QObject::tr("Greek"); + auto Hebrew = QObject::tr("Hebrew"); + auto Turkish = QObject::tr("Turkish"); + auto Thai = QObject::tr("Thai"); + auto Celtic = QObject::tr("Celtic"); + auto SouthEasternEuropean = QObject::tr("SouthEasternEuropean"); + auto Simplified = QObject::tr("ChineseSimplified"); + auto Traditional = QObject::tr("ChineseTraditional"); + auto Japanese = QObject::tr("Japanese"); + auto Korean = QObject::tr("Korean"); + auto Vietnamese = QObject::tr("Vietnamese"); +} diff --git a/src/controls/tabbar.cpp b/src/controls/tabbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17b4ab25035de4570fba16270f8a5bed3dff4744 --- /dev/null +++ b/src/controls/tabbar.cpp @@ -0,0 +1,805 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "tabbar.h" +#include "../widgets/window.h" +#include "../common/utils.h" +#include "../editor/editwrapper.h" +#include "../startmanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QPixmap *Tabbar::sm_pDragPixmap = nullptr; + +/** + * @brief ‘&’在Qt中被标记为助记符,替换 \a str 中的‘&’字符为“&&”,以正确显示文件名中的‘&’符号 + * painter 绘制 CE_ToolButtonLabel 时设置了 Qt::TextShowMnemonic + * @note 在插入、新建标签页时,内部已使用替换,部分外部更新标签页名称,需手动处理 + * @sa Tabbar::addTabWithIndex(), Tabbar::insertFromMimeData(), Tabbar::setTabText() + */ +QString replaceMnemonic(const QString &str) +{ + QString tmp = str; + tmp.replace(QChar('&'), QString("&&")); + return tmp; +} + +/** + * @brief ‘&’在Qt中被标记为助记符,替换 \a str 中的"&&字符为'&',以正确取得文件名中的‘&’符号 + */ +QString restoreMnemonic(const QString &str) +{ + QString tmp = str; + tmp.replace(QString("&&"), QChar('&')); + return tmp; +} + +Tabbar::Tabbar(QWidget *parent) + : DTabBar(parent) +{ + m_rightClickTab = -1; + + installEventFilter(this); + + setMovable(true); + setTabsClosable(true); + setVisibleAddButton(true); + setDragable(true); + // setStartDragDistance(40); + setElideMode(Qt::ElideMiddle); + setTabPalette(palette().buttonText().color().name(), palette().highlightedText().color().name()); + setFocusPolicy(Qt::NoFocus); + + connect(this, &DTabBar::dragStarted, this, &Tabbar::onTabDrapStart); + connect(this, &DTabBar::tabMoved, this, &Tabbar::handleTabMoved); + connect(this, &DTabBar::tabDroped, this, &Tabbar::handleTabDroped); + connect(this, &DTabBar::tabIsRemoved, this, &Tabbar::handleTabIsRemoved); + connect(this, &DTabBar::tabReleaseRequested, this, &Tabbar::handleTabReleased); + connect(this, &DTabBar::dragActionChanged, this, &Tabbar::handleDragActionChanged); +} + +Tabbar::~Tabbar() +{ + if (m_moreWaysCloseMenu != nullptr) { + delete m_moreWaysCloseMenu; + m_moreWaysCloseMenu = nullptr; + } + if (m_rightMenu != nullptr) { + delete m_rightMenu; + m_rightMenu = nullptr; + } +} + +void Tabbar::addTab(const QString &filePath, const QString &tabName, const QString &tipPath) +{ + addTabWithIndex(currentIndex() + 1, filePath, tabName, tipPath); +} + +void Tabbar::addTabWithIndex(int index, const QString &filePath, const QString &tabName, const QString &tipPath) +{ + // FIXME(rekols): do not insert duplicate values. + if (m_tabPaths.contains(filePath)) { + return; + } + m_tabPaths.insert(index, filePath); + m_tabTruePaths.insert(index, tipPath); + // } + + // 除去空白符 梁卫东 2020-08-26 14:49:15 ;适配助记符 + QString trimmedName = replaceMnemonic(tabName.simplified()); + DTabBar::insertTab(index, trimmedName); + DTabBar::setCurrentIndex(index); + if (filePath.contains(Utils::localDataPath())) { + if (Utils::isBackupFile(filePath) && !tipPath.isNull() && tipPath.length() > 0) { + setTabToolTip(index, tipPath); + } else { + setTabToolTip(index, tabName); + } + } else { + QString path = filePath; + QFontMetrics fontMetrics(font()); + int nFontWidth = fontMetrics.width(path) * (qApp->devicePixelRatio() == 1.25 ? 2 : 1); + + Window *pWindow = static_cast(this->window()); + int w = pWindow->width() - 200; + if (w < 800) w = 800; + + if (nFontWidth >= w) { + int mod = nFontWidth % w; + + int step = nFontWidth / w + (mod > 0 ? 1 : 0); + + for (int i = 1; i < step; i++) { + path.insert(i * (path.length() / step), '\n'); + } + } + + setTabToolTip(index, path); + } +} + +void Tabbar::resizeEvent(QResizeEvent *event) +{ + int cnt = count(); + + for (int i = 0; i < cnt ; i++) { + QString path = tabToolTip(i); + path = path.replace("\n", ""); + QFontMetrics fontMetrics(font()); + int nFontWidth = fontMetrics.width(path) * (qApp->devicePixelRatio() == 1.25 ? 2 : 1); + + Window *pWindow = static_cast(this->window()); + int w = pWindow->width() - 200; + if (w < 800) w = 800; + + if (nFontWidth >= w) { + int mod = nFontWidth % w; + + int step = nFontWidth / w + (mod > 0 ? 1 : 0); + + for (int j = 1; j < step; j++) { + path.insert(j * (path.length() / step), '\n'); + } + } + + setTabToolTip(i, path); + } + + // 临时修改方案:通过调用setIconSize(),更新内部的layoutDirty标识,强制重新刷新标签页布局, BUG链接:https://pms.uniontech.com/bug-view-137607.html + // TODO: 需要dtk暴露接口重新布局 + setIconSize(iconSize()); + + DTabBar::resizeEvent(event); +} + +void Tabbar::closeTab(int index) +{ + if (index < 0) { + return; + } + emit requestHistorySaved(fileAt(index)); + DTabBar::removeTab(index); +} + +void Tabbar::closeCurrentTab() +{ + closeTab(currentIndex()); +} + +void Tabbar::closeCurrentTab(const QString &strFilePath) +{ + closeTab(this->indexOf(strFilePath)); +} + +void Tabbar::closeOtherTabs() +{ + closeOtherTabsExceptFile(currentPath()); +} + +void Tabbar::closeOtherTabsExceptFile(const QString &filePath) +{ + QStringList closePathList; + + for (const QString &path : m_tabPaths) { + if (filePath != path) { + closePathList << path; + } + } + + emit closeTabs(closePathList); +} + +void Tabbar::closeLeftTabs(const QString &filePath) +{ + QStringList closePathList; + + for (const QString &path : m_tabPaths) { + if (filePath == path) { + break; + } + closePathList << path; + } + emit closeTabs(closePathList); + +} + +void Tabbar::closeRightTabs(const QString &filePath) +{ + + QStringList closePathlist; + + + for (int i = m_tabPaths.count() - 1; i >= 0; i--) { + m_tabPaths.value(i); + + if (filePath == m_tabPaths.value(i)) { + break; + } + closePathlist << m_tabPaths.value(i); + } + + emit closeTabs(closePathlist); +} + +void Tabbar::updateTab(int index, const QString &filePath, const QString &tabName) +{ + // 适配助记符 '&' 后设置文本 + setTabText(index, tabName); + m_tabPaths[index] = filePath; + m_tabTruePaths[index] = filePath; + + //show file path at tab,blank file only show it's name. + if (filePath.contains(Utils::localDataPath())) { + setTabToolTip(index, tabName); + } else { + QString path = filePath; + QFontMetrics fontMetrics(font()); + int nFontWidth = fontMetrics.width(path) * (qApp->devicePixelRatio() == 1.25 ? 2 : 1); + + Window *pWindow = static_cast(this->window()); + int w = pWindow->width() - 200; + if (w < 800) w = 800; + + if (nFontWidth >= w) { + int mod = nFontWidth % w; + + int step = nFontWidth / w + (mod > 0 ? 1 : 0); + + for (int i = 1; i < step; i++) { + path.insert(i * (path.length() / step), '\n'); + } + } + + setTabToolTip(index, path); + } +} + +void Tabbar::previousTab() +{ + int currentIndex = DTabBar::currentIndex(); + + if (currentIndex <= 0) { + DTabBar::setCurrentIndex(DTabBar::count() - 1); + } else { + DTabBar::setCurrentIndex(currentIndex - 1); + } +} + +void Tabbar::nextTab() +{ + int currentIndex = DTabBar::currentIndex(); + + if (currentIndex >= DTabBar::count() - 1) { + DTabBar::setCurrentIndex(0); + } else { + DTabBar::setCurrentIndex(currentIndex + 1); + } +} + +int Tabbar::indexOf(const QString &filePath) +{ + return m_tabPaths.indexOf(filePath); +} + +QString Tabbar::currentName() const +{ + return textAt(currentIndex()); +} + +QString Tabbar::currentPath() const +{ + return m_tabPaths.value(currentIndex()); +} + +QString Tabbar::truePathAt(int index) const +{ + return m_tabTruePaths.value(index); +} + +QString Tabbar::fileAt(int index) const +{ + return m_tabPaths.value(index); +} + +QString Tabbar::textAt(int index) const +{ + // 获取显示文本时恢复设置的助记符 '&' + return restoreMnemonic(DTabBar::tabText(index)); +} + +/** + * @brief 设置索引 \a index 指向标签页显示文本为 \a text + */ +void Tabbar::setTabText(int index, const QString &text) +{ + // 替换助记符 + QString tmp = replaceMnemonic(text); + DTabBar::setTabText(index, tmp); +} + +void Tabbar::setTabPalette(const QString &activeColor, const QString &highlightColor) +{ + QPalette pa = this->palette(); + pa.setColor(QPalette::Inactive, QPalette::HighlightedText, QColor(highlightColor)); + pa.setColor(QPalette::Inactive, QPalette::WindowText, QColor(activeColor)); + pa.setColor(QPalette::Active, QPalette::WindowText, QColor(activeColor)); + setPalette(pa); +} + +void Tabbar::setBackground(const QString &startColor, const QString &endColor) +{ + m_backgroundStartColor = startColor; + m_backgroundEndColor = endColor; +} + +void Tabbar::setDNDColor(const QString &startColor, const QString &endColor) +{ + m_dndStartColor = startColor; + m_dndEndColor = endColor; +} + +QPixmap Tabbar::createDragPixmapFromTab(int index, const QStyleOptionTab &option, QPoint *hotspot) const +{ + const qreal ratio = qApp->devicePixelRatio(); + + Window *window = static_cast(this->window()); + EditWrapper *wrapper = window->wrapper(fileAt(index)); + //加载大文本不允许拖拽 + //if(wrapper && wrapper->getFileLoading()) return QPixmap(); + + TextEdit *textEdit = wrapper->textEditor(); + + int width = textEdit->width() * ratio; + int height = textEdit->height() * ratio; + QImage screenshotImage(width, height, QImage::Format_ARGB32_Premultiplied); + screenshotImage.setDevicePixelRatio(ratio); + textEdit->render(&screenshotImage, QPoint(), QRegion(0, 0, width, height)); + + // scaled image to smaller. + int scaledWidth = width * ratio / 5; + int scaledHeight = height * ratio / 5; + auto scaledImage = screenshotImage.scaled(scaledWidth, scaledHeight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + QImage backgroundImage(scaledWidth + 10, scaledHeight + 10, QImage::Format_ARGB32_Premultiplied); + backgroundImage.fill(QColor(palette().color(QPalette::Base))); + // clip screenshot image with window radius. + QPainter painter(&backgroundImage); + painter.drawImage(5, 5, scaledImage); + painter.setRenderHint(QPainter::Antialiasing, true); + + if (!Utils::isWayland() && count() == 1) { + this->window()->showMinimized(); + } + + // adjust offset. + hotspot->setX(scaledWidth / 2); + hotspot->setY(scaledHeight / 2); + + QPainterPath rectPath; + + if (DWindowManagerHelper::instance()->hasComposite()) { + QPainterPath roundedRectPath; + + rectPath.addRect(0, 0, scaledWidth + 10, scaledHeight + 10); + roundedRectPath.addRoundedRect(QRect(0, 0, scaledWidth / ratio + 10, scaledHeight / ratio + 10), 6, 6); + + rectPath -= roundedRectPath; + + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillPath(rectPath, Qt::transparent); + + QColor shadowColor = QColor(palette().color(QPalette::BrightText)); + shadowColor.setAlpha(80); + + painter.end(); + if (sm_pDragPixmap) delete sm_pDragPixmap; + sm_pDragPixmap = new QPixmap(Utils::dropShadow(QPixmap::fromImage(backgroundImage), 5, shadowColor, QPoint(0, 0))); + return Utils::dropShadow(QPixmap::fromImage(backgroundImage), 5, shadowColor, QPoint(0, 0)); + } else { + painter.end(); + if (sm_pDragPixmap) delete sm_pDragPixmap; + sm_pDragPixmap = new QPixmap(QPixmap::fromImage(backgroundImage)); + return QPixmap::fromImage(backgroundImage); + } + +#if 0 + QPixmap backgroundImage = DTabBar::createDragPixmapFromTab(index, option, hotspot); + if (sm_pDragPixmap) delete sm_pDragPixmap; + sm_pDragPixmap = new QPixmap(backgroundImage); + return backgroundImage; +#endif +} + +QMimeData *Tabbar::createMimeDataFromTab(int index, const QStyleOptionTab &option) const +{ + const QString tabName = textAt(index); + + Window *window = static_cast(this->window()); + EditWrapper *wrapper = window->wrapper(fileAt(index)); + + if (wrapper && wrapper->getFileLoading()) return nullptr; + + QMimeData *mimeData = new QMimeData; + mimeData->setParent(window); + + if (!wrapper) { + //m_tabbar->closeCurrentTab(); + return nullptr; + } + + mimeData->setProperty("wrapper", QVariant::fromValue(static_cast(wrapper))); + mimeData->setProperty("isModified", wrapper->isModified()); + mimeData->setData("dedit/tabbar", tabName.toUtf8()); + mimeData->removeFormat("text/plain"); + + return mimeData; +} + +void Tabbar::insertFromMimeDataOnDragEnter(int index, const QMimeData *source) +{ + if (source == nullptr) { + return; + } + + const QString tabName = QString::fromUtf8(source->data("dedit/tabbar")); + QVariant pVar = source->property("wrapper"); + EditWrapper *wrapper = static_cast(pVar.value()); + + //大文本加载不允许拖拽 + if (wrapper && (wrapper && wrapper->getFileLoading())) return; + + Window *window = static_cast(this->window()); + + if (!wrapper) { + return; + } + + window->addTabWithWrapper(wrapper, wrapper->textEditor()->getFilePath(), wrapper->textEditor()->getTruePath(), tabName, index); + //window->currentWrapper()->textEditor()->setModified(source->property("isModified").toBool()); + wrapper->updateModifyStatus(source->property("isModified").toBool()); + wrapper->OnUpdateHighlighter(); + window->focusActiveEditor(); +} + +void Tabbar::insertFromMimeData(int index, const QMimeData *source) +{ + if (source == nullptr) { + return; + } + + const QString tabName = QString::fromUtf8(source->data("dedit/tabbar")); + QVariant pVar = source->property("wrapper"); + EditWrapper *wrapper = static_cast(pVar.value()); + Window *window = static_cast(this->window()); + + if (!wrapper) { + return; + } + + //qDebug() << "insertFromMimeData"; + window->addTabWithWrapper(wrapper, wrapper->textEditor()->getFilePath(), wrapper->textEditor()->getTruePath(), tabName, index); + //window->currentWrapper()->textEditor()->setModified(source->property("isModified").toBool()); + wrapper->updateModifyStatus(source->property("isModified").toBool()); + wrapper->OnUpdateHighlighter(); + window->focusActiveEditor(); +} + +bool Tabbar::canInsertFromMimeData(int index, const QMimeData *source) const +{ + return source->hasFormat("dedit/tabbar"); +} + +void Tabbar::handleDragActionChanged(Qt::DropAction action) +{ + // Reset cursor to Qt::ArrowCursor if drag tab to TextEditor widget. + if (action == Qt::IgnoreAction) { + if (dragIconWindow()) { + QGuiApplication::changeOverrideCursor(Qt::ArrowCursor); + DPlatformWindowHandle::setDisableWindowOverrideCursor(dragIconWindow(), true); + } + } else if (dragIconWindow()) { + DPlatformWindowHandle::setDisableWindowOverrideCursor(dragIconWindow(), false); + if (QGuiApplication::overrideCursor()) + QGuiApplication::changeOverrideCursor(QGuiApplication::overrideCursor()->shape()); + } +} + +bool Tabbar::eventFilter(QObject *, QEvent *event) +{ + + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + + if (mouseEvent->button() == Qt::RightButton) { + QPoint position = mouseEvent->pos(); + m_rightClickTab = this->tabAt(position); + int indexCount = this->count(); + +// m_rightClickTab = -1; + +// for (int i = 0; i < count(); i++) { +// if (tabRect(i).contains(position)) { +// m_rightClickTab = i; +// break; +// } +// } + + // popup right menu on tab. + if (m_rightClickTab >= 0) { + m_rightMenu = new DMenu; + //m_rightMenu->setStyle(QStyleFactory::create("dlight")); + + m_closeTabAction = new QAction(tr("Close tab"), this); + m_closeOtherTabAction = new QAction(tr("Close other tabs"), this); + m_moreWaysCloseMenu = new DMenu(tr("More options"), this); + m_closeLeftTabAction = new QAction(tr("Close tabs to the left"), this); + m_closeRightTabAction = new QAction(tr("Close tabs to the right"), this); + m_closeAllunModifiedTabAction = new QAction(tr("Close unmodified tabs"), this); + + m_moreWaysCloseMenu->addAction(m_closeLeftTabAction); + m_moreWaysCloseMenu->addAction(m_closeRightTabAction); + m_moreWaysCloseMenu->addAction(m_closeAllunModifiedTabAction); + + if (m_tabPaths.length() < 2) { + m_closeOtherTabAction->setEnabled(false); + m_closeLeftTabAction->setEnabled(false); + m_closeRightTabAction->setEnabled(false); + } + + //优化tab菜单显示 梁卫东 + if (m_rightClickTab == 0 && indexCount == 1) { + m_closeLeftTabAction->setEnabled(false); + m_closeRightTabAction->setEnabled(false); + } else if (m_rightClickTab == 0 && indexCount > 1) { + m_closeLeftTabAction->setEnabled(false); + m_closeRightTabAction->setEnabled(true); + } else if (m_rightClickTab == indexCount - 1 && indexCount == 1) { + m_closeLeftTabAction->setEnabled(false); + m_closeRightTabAction->setEnabled(false); + } else if (m_rightClickTab == indexCount - 1 && indexCount > 1) { + m_closeLeftTabAction->setEnabled(true); + m_closeRightTabAction->setEnabled(false); + } else { + m_closeLeftTabAction->setEnabled(true); + m_closeRightTabAction->setEnabled(true); + } + + //showTabs(); + + connect(m_closeTabAction, &QAction::triggered, this, [ = ] { + Q_EMIT tabCloseRequested(m_rightClickTab); + }); + + connect(m_closeOtherTabAction, &QAction::triggered, this, [ = ] { + closeOtherTabsExceptFile(fileAt(m_rightClickTab)); + }); + + connect(m_closeLeftTabAction, &QAction::triggered, this, [ = ] { + closeLeftTabs(fileAt(m_rightClickTab)); +// int currentIndex = DTabBar::currentIndex(); +// if(currentIndex>=0) { +// for (int i=0;i=0){ +// for (int i=count;i>currentIndex;i--) { +// closeTab(currentIndex+1); +// } +// } + }); + + connect(m_closeAllunModifiedTabAction, &QAction::triggered, this, [ = ] { + Window *window = static_cast(this->window());//确定在哪个窗口关闭 +// for (int i=0;iwrapper(m_tabPaths.value(i)); +// if (!wrapper->textEditor()->document()->isModified()){ +// closeTab(this->indexOf(m_tabPaths.value(i))); +// } +// } + for (auto path : m_tabPaths) + { + EditWrapper *wrapper = window->wrapper(path);//路径获取文件 + if (!wrapper->isModified()) { + window->removeWrapper(path, true); + closeTab(this->indexOf(path)); + } + } + + }); + + m_rightMenu->addAction(m_closeTabAction); + m_rightMenu->addAction(m_closeOtherTabAction); + m_rightMenu->addMenu(m_moreWaysCloseMenu); + //yanyuhan 只有一个标签页时不显示更多方式关闭 + if (m_tabPaths.size() > 1) { + m_moreWaysCloseMenu->setEnabled(true); + } else { + m_moreWaysCloseMenu->setEnabled(false); + } + + m_rightMenu->exec(mapToGlobal(position)); + + return true; + } + } + + } else if (event->type() == QEvent::DragEnter) { + +// if ((!e->source() || e->source()->parent() != this) && +// mimeData->hasFormat("dedit/tabbar")) { +// static_cast(this->window())->changeTitlebarBackground(m_dndStartColor, m_dndEndColor); +// } + } else if (event->type() == QEvent::DragLeave) { + } else if (event->type() == QEvent::Drop) { + } else if (event->type() == QEvent::DragMove) { + event->accept(); + } + + return false; +} + +void Tabbar::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::MidButton) { + emit tabCloseRequested(tabAt(QPoint(e->x(), e->y()))); + } + + DTabBar::mousePressEvent(e); +} + +void Tabbar::dropEvent(QDropEvent *e) +{ + if (e->dropAction() == Qt::CopyAction && e->mimeData()->hasFormat("dedit/tabbar")) { + if (sm_pDragPixmap) { + QPoint cursorPos = QCursor::pos() - QPoint(sm_pDragPixmap->width() / 2, 20); + DLabel *pLabel = new DLabel(); + pLabel->setWindowFlags(Qt::FramelessWindowHint); + pLabel->move(cursorPos); + pLabel->setPixmap(*sm_pDragPixmap); + pLabel->setMaximumSize(sm_pDragPixmap->size()); + pLabel->show(); + + QRect startRect = QRect(cursorPos, sm_pDragPixmap->size()); + QRect endRect = QRect(QCursor::pos(), QSize(0, 0)); + QPropertyAnimation *geometry = new QPropertyAnimation(pLabel, "geometry"); + connect(geometry, &QPropertyAnimation::finished, pLabel, &DLabel::deleteLater); + connect(geometry, &QPropertyAnimation::finished, geometry, &QPropertyAnimation::deleteLater); + geometry->setDuration(100); + geometry->setStartValue(startRect); + geometry->setEndValue(endRect); + geometry->setEasingCurve(QEasingCurve::InCubic); + geometry->start(); + } + } + + DTabBar::dropEvent(e); +} + +QSize Tabbar::tabSizeHint(int index) const +{ + + if (index >= 0) { + int total = this->width(); + + //计算每个tab平均宽度 返回 100到160 + int aveargeWidth = 160; + aveargeWidth = total / DTabBar::count(); + + if (aveargeWidth >= 160) { + aveargeWidth = 160; + } else if (aveargeWidth <= 110) { + aveargeWidth = 110; + } + + return QSize(aveargeWidth, 40); + } + + return DTabBar::tabSizeHint(index); +} + +QSize Tabbar::minimumTabSizeHint(int index) const +{ + Q_UNUSED(index) + return QSize(110, 40); +} + +QSize Tabbar::maximumTabSizeHint(int index) const +{ + Q_UNUSED(index) + return QSize(160, 40); +} + +void Tabbar::handleTabMoved(int fromIndex, int toIndex) +{ + //qDebug () << "handleTabMoved"; + if (m_tabPaths.count() > fromIndex && m_tabPaths.count() > toIndex && fromIndex >= 0 && toIndex >= 0) { + m_tabPaths.swap(fromIndex, toIndex); + m_tabTruePaths.swap(fromIndex, toIndex); + } +} + +void Tabbar::showTabs() +{ + int currentIndex = DTabBar::currentIndex(); + if (currentIndex <= 0) { + m_closeLeftTabAction->setEnabled(false); + } + if (currentIndex >= DTabBar::count() - 1) { + m_closeRightTabAction->setEnabled(false); + } +} + +void Tabbar::handleTabReleased(int index) +{ + if (index == -1) index = 0; + QString path = m_listOldTabPath.value(index); + if (path.isEmpty()) { + return; + } + + int newIndex = m_tabPaths.indexOf(path); + const QString tabPath = fileAt(newIndex); + const QString tabName = textAt(newIndex); + + Window *window = static_cast(this->window()); + EditWrapper *wrapper = window->wrapper(tabPath); + if (!wrapper) { + return; + } + + StartManager::instance()->createWindowFromWrapper(tabName, tabPath, wrapper->textEditor()->getTruePath(), wrapper, wrapper->isModified()); + + closeTab(newIndex); + // remove wrapper from window, not delete. + window->removeWrapper(tabPath, false); +} + +void Tabbar::handleTabIsRemoved(int index) +{ + //qDebug() << "handleTabIsRemoved" << index; + const QString filePath = m_tabPaths.at(index); + Window *window = static_cast(this->window()); + m_tabPaths.removeAt(index); + m_tabTruePaths.removeAt(index); + window->removeWrapper(filePath, false); +} + +void Tabbar::handleTabDroped(int index, Qt::DropAction action, QObject *target) +{ + Tabbar *tabbar = qobject_cast(target); + if (tabbar == nullptr) { + // tab页拖动到外部应用如网页电子表格或wps电子表格时, + // DTabBar::dragActionChanged 信号收到的DropType为MoveAction, + // 这种情况下DTabBar内容不能发出DTabBar::tabReleaseRequested来重新构建编辑窗口 + // 因此只能再次添加判断,若目标文本编辑窗口的TabBar未创建,则重新重建文本编辑窗口 + handleTabReleased(index); + } else { +// QString path = m_listOldTabPath.value(index); +// int newIndex = m_tabPaths.indexOf(path); + + closeTab(index); +// StartManager::instance()->setDragEnter(false); + } +} + +void Tabbar::onTabDrapStart() +{ + Window *window = static_cast(this->window()); + window->setChildrenFocus(false); + m_listOldTabPath = m_tabPaths; +} diff --git a/src/controls/tabbar.h b/src/controls/tabbar.h new file mode 100644 index 0000000000000000000000000000000000000000..0df7423ca0f967b235b1064d7f569aa3a012eecf --- /dev/null +++ b/src/controls/tabbar.h @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TABBAR_H +#define TABBAR_H + +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class EditWrapper; +class Tabbar : public DTabBar +{ + Q_OBJECT + +public: + explicit Tabbar(QWidget *parent = nullptr); + ~Tabbar(); + + void addTab(const QString &filePath, const QString &tabName, const QString &tipPath = QString::null); + void addTabWithIndex(int index, const QString &filePath, const QString &tabName, const QString &tipPath = QString::null); + void closeTab(int index); + void closeCurrentTab(); + /** + * @brief closeCurrentTab 移除指定文件对应的tab标签项 + * @param strFilePath 指定的文件(路径加文件名) + */ + void closeCurrentTab(const QString &strFilePath); + void closeOtherTabs(); + + void closeLeftTabs(const QString &filePath); + void closeRightTabs(const QString &filePath); + + void closeOtherTabsExceptFile(const QString &filePath); + void updateTab(int index, const QString &filePath, const QString &tabName); + void previousTab(); + void nextTab(); + + int indexOf(const QString &filePath); + + QString currentName() const; + QString currentPath() const; + QString truePathAt(int index) const; + QString fileAt(int index) const; + QString textAt(int index) const; + + // 设置索引为index的标签页显示文本为text + void setTabText(int index, const QString &text); + + void setTabPalette(const QString &activeColor, const QString &inactiveColor); + void setBackground(const QString &startColor, const QString &endColor); + void setDNDColor(const QString &startColor, const QString &endColor); + void showTabs(); + +signals: + void requestHistorySaved(const QString &filePath); + void closeTabs(const QStringList pathList); + +protected: + QPixmap createDragPixmapFromTab(int index, const QStyleOptionTab &option, QPoint *hotspot) const; + QMimeData *createMimeDataFromTab(int index, const QStyleOptionTab &option) const; + void insertFromMimeDataOnDragEnter(int index, const QMimeData *source); + void insertFromMimeData(int index, const QMimeData *source); + bool canInsertFromMimeData(int index, const QMimeData *source) const; + bool eventFilter(QObject *, QEvent *event); + + QSize tabSizeHint(int index) const; + QSize minimumTabSizeHint(int index) const; + QSize maximumTabSizeHint(int index) const; + void mousePressEvent(QMouseEvent *e); + void dropEvent(QDropEvent *e); + void resizeEvent(QResizeEvent *event); + +private: + void handleTabMoved(int fromIndex, int toIndex); + void handleTabReleased(int index); + void handleTabIsRemoved(int index); + void handleTabDroped(int index, Qt::DropAction, QObject *target); + void handleDragActionChanged(Qt::DropAction action); + void onTabDrapStart(); + +private: + QStringList m_tabPaths; + QStringList m_tabTruePaths; + QStringList m_listOldTabPath; + QString m_backgroundStartColor; + QString m_backgroundEndColor; + QString m_dndStartColor; + QString m_dndEndColor; + + QAction *m_closeOtherTabAction; + QAction *m_closeTabAction; + QAction *m_closeLeftTabAction; + QAction *m_closeRightTabAction; + QAction *m_closeAllunModifiedTabAction; + DMenu *m_rightMenu {nullptr}; + DMenu *m_moreWaysCloseMenu {nullptr}; + int m_rightClickTab; + int m_nDragIndex; + QString m_qstrDragName; + QString m_qstrDragPath; + EditWrapper *m_pWrapper = nullptr; + + bool m_bLayoutDirty = false; + +public: + static QPixmap *sm_pDragPixmap; +}; + +#endif diff --git a/src/controls/toolbar.cpp b/src/controls/toolbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f2f4c1f2e7c20dfa0988362ed10dd8013671fa93 --- /dev/null +++ b/src/controls/toolbar.cpp @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "toolbar.h" +#include +#include + +DWIDGET_USE_NAMESPACE + +ToolBar::ToolBar(QWidget *parent) + : QWidget(parent), + m_layout(new QHBoxLayout(this)) +{ + m_layout->setContentsMargins(0, 0, 0, 0); +} + +ToolBar::~ToolBar() +{ +} + +void ToolBar::setTabbar(QWidget *w) +{ + m_layout->addWidget(w, 0); + m_layout->addSpacing(70); +} diff --git a/src/controls/toolbar.h b/src/controls/toolbar.h new file mode 100644 index 0000000000000000000000000000000000000000..8424e52a7c3830c6fd4441bcf297a86091b0be4d --- /dev/null +++ b/src/controls/toolbar.h @@ -0,0 +1,24 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TOOLBAR_H +#define TOOLBAR_H + +#include +#include + +class ToolBar : public QWidget +{ + +public: + explicit ToolBar(QWidget *parent = nullptr); + ~ToolBar(); + + void setTabbar(QWidget *w); + +private: + QHBoxLayout *m_layout {nullptr}; +}; + +#endif diff --git a/src/controls/warningnotices.cpp b/src/controls/warningnotices.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f7e9555d692071f1faf3512934e6e62314b09db --- /dev/null +++ b/src/controls/warningnotices.cpp @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "warningnotices.h" +#include + +WarningNotices::WarningNotices(MessageType notifyType, QWidget *parent) + : DFloatingMessage(notifyType,parent) +{ + QFont font; + font.setPixelSize(14); + font.setFamily("SourceHanSansSC-Medium"); + this->setFont(font); + + this->setContentsMargins(7, 7, 7, 7); + + setIcon(QIcon(":/images/warning.svg")); + m_reloadBtn = new QPushButton(tr("Reload"),this); + //m_reloadBtn->setFixedSize(80, 36); + m_saveAsBtn = new QPushButton(qApp->translate("Window", "Save as"),this); + + //m_saveAsBtn->setFixedSize(80, 36); + m_reloadBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_saveAsBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + connect(m_reloadBtn, &QPushButton::clicked, this, &WarningNotices::slotreloadBtnClicked); + connect(m_saveAsBtn, &QPushButton::clicked, this, &WarningNotices::slotsaveAsBtnClicked); +} + +WarningNotices::~WarningNotices() +{ + +} + +void WarningNotices::setReloadBtn() +{ + if (!m_reloadBtn->isVisible()) { + m_reloadBtn->setVisible(true); + } + m_reloadBtn->setVisible(true); + m_saveAsBtn->setVisible(false); + setWidget(m_reloadBtn); +} + +void WarningNotices::setSaveAsBtn() +{ + if (!m_saveAsBtn->isVisible()) { + m_saveAsBtn->setVisible(true); + } + m_saveAsBtn->setVisible(true); + m_reloadBtn->setVisible(false); + setWidget(m_saveAsBtn); +} + +void WarningNotices::clearBtn() +{ + m_saveAsBtn->setVisible(false); + m_reloadBtn->setVisible(false); +} + +void WarningNotices::slotreloadBtnClicked() +{ + this->hide(); + emit reloadBtnClicked(); +} + +void WarningNotices::slotsaveAsBtnClicked() +{ + this->hide(); + emit saveAsBtnClicked(); +} diff --git a/src/controls/warningnotices.h b/src/controls/warningnotices.h new file mode 100644 index 0000000000000000000000000000000000000000..3ef6db0f55a1d84471d807de6c6326750eaf5019 --- /dev/null +++ b/src/controls/warningnotices.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef WARNINGNOTICES_H +#define WARNINGNOTICES_H + +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class WarningNotices : public DFloatingMessage +{ + Q_OBJECT +public: + explicit WarningNotices(MessageType notifyType = MessageType::ResidentType ,QWidget *parent = nullptr); + ~WarningNotices(); + + void setReloadBtn(); + void setSaveAsBtn(); + void clearBtn(); + +signals: + void reloadBtnClicked(); + void saveAsBtnClicked(); + void closeBtnClicked(); + +public slots: + void slotreloadBtnClicked(); + void slotsaveAsBtnClicked(); + +private: + QPushButton *m_reloadBtn; + QPushButton *m_saveAsBtn; + QHBoxLayout *m_pLayout; +}; + +#endif // WARNINGNOTICES_H diff --git a/src/deepin-editor.pro b/src/deepin-editor.pro new file mode 100644 index 0000000000000000000000000000000000000000..8c40232b173655d9577807a26eacc2a07b859ae7 --- /dev/null +++ b/src/deepin-editor.pro @@ -0,0 +1,145 @@ +###################################################################### +# Automatically generated by qmake (3.0) ?? 2? 4 17:49:37 2017 +###################################################################### + +QT += KSyntaxHighlighting +QT += core +QT += dbus +QT += gui +QT += network +QT += printsupport +QT += svg +QT += widgets +QT += x11extras +QT += KCodecs +QT += xml + +TEMPLATE = app +TARGET = deepin-editor + +CONFIG += link_pkgconfig +CONFIG += c++11 +PKGCONFIG += xcb xcb-util dtkwidget dtkwm dtkgui dframeworkdbus +RESOURCES += deepin-editor.qrc + +INCLUDEPATH += common controls editor encodes thememodule widgets +INCLUDEPATH += ../3rdparty/lib/include/uchardet +INCLUDEPATH += ../3rdparty/lib/include + +HEADERS += editor/bookmarkwidget.h \ + editor/codeflodarea.h \ + editor/dtextedit.h \ + editor/editwrapper.h \ + editor/leftareaoftextedit.h \ + editor/linenumberarea.h \ + editor/showflodcodewidget.h \ + editor/uncommentselection.h \ + encodes/detectcode.h \ + common/comment_global.h \ + common/common.h \ + common/encoding.h \ + common/dbusinterface.h \ + common/fileloadthread.h \ + common/performancemonitor.h \ + common/settings.h \ + common/urlinfo.h \ + common/utils.h \ + controls/findbar.h \ + controls/fontitemdelegate.h \ + controls/jumplinebar.h \ + controls/linebar.h \ + controls/replacebar.h \ + controls/tabbar.h \ + controls/toast.h \ + controls/toolbar.h \ + controls/warningnotices.h \ + thememodule/themeitemdelegate.h \ + thememodule/themelistmodel.h \ + thememodule/themelistview.h \ + thememodule/themepanel.h \ + widgets/bottombar.h \ + widgets/ColorSelectWdg.h \ + widgets/ddropdownmenu.h \ + widgets/window.h \ + editorapplication.h \ + environments.h \ + startmanager.h + +SOURCES += editor/bookmarkwidget.cpp \ + editor/codeflodarea.cpp \ + editor/dtextedit.cpp \ + editor/editwrapper.cpp \ + editor/leftareaoftextedit.cpp \ + editor/linenumberarea.cpp \ + editor/showflodcodewidget.cpp \ + editor/uncommentselection.cpp \ + encodes/detectcode.cpp \ + common/encoding.cpp \ + common/dbusinterface.cpp \ + common/fileloadthread.cpp \ + common/performancemonitor.cpp \ + common/settings.cpp \ + common/utils.cpp \ + controls/findbar.cpp \ + controls/fontitemdelegate.cpp \ + controls/jumplinebar.cpp \ + controls/linebar.cpp \ + controls/replacebar.cpp \ + controls/tabbar.cpp \ + controls/toast.cpp \ + controls/toolbar.cpp \ + controls/warningnotices.cpp \ + controls/settingsdialog.cpp \ + thememodule/themeitemdelegate.cpp \ + thememodule/themelistmodel.cpp \ + thememodule/themelistview.cpp \ + thememodule/themepanel.cpp \ + widgets/bottombar.cpp \ + widgets/ColorSelectWdg.cpp \ + widgets/ddropdownmenu.cpp \ + widgets/window.cpp \ + editorapplication.cpp \ + startmanager.cpp \ + main.cpp + + +QMAKE_CXXFLAGS += -g +QMAKE_CFLAGS += -fPIC +LIBS += -lX11 -lXext -lXtst + +isEmpty(BINDIR):BINDIR=/usr/bin +isEmpty(APPDIR):APPDIR=/usr/share/applications +isEmpty(DSRDIR):DSRDIR=/usr/share/deepin-editor + +target.path = $$INSTROOT$$BINDIR +desktop.path = $$INSTROOT$$APPDIR +desktop.files = $$PWD/../deepin-editor.desktop + +themes.path = $$DSRDIR/themes +themes.files += themes/deepin.theme +themes.files += themes/breeze_dark.theme +themes.files += themes/solarized_dark.theme +themes.files += themes/solarized_light.theme +themes.files += themes/atom_dark.theme + +INSTALLS += target desktop themes +DISTFILES += \ + themes/deepin_dark.theme \ + images/warning.svg +TRANSLATIONS += ../translations/deepin-editor_zh_CN.ts\ + ../translations/deepin-editor_zh_HK.ts\ + ../translations/deepin-editor_zh_TW.ts\ + ../translations/deepin-editor.ts + + +LIBS += -L$$PWD/../3rdparty/lib/lib/ -lenca -lm +PRE_TARGETDEPS += $$PWD/../3rdparty/lib/lib/libenca.a + +LIBS += -L$$PWD/../3rdparty/lib/lib/ -luchardet +PRE_TARGETDEPS += $$PWD/../3rdparty/lib/lib/libuchardet.a + +LIBS += -L$$PWD/../3rdparty/lib/lib/ -liconv +PRE_TARGETDEPS += $$PWD/../3rdparty/lib/lib/libiconv.a + +LIBS += -L$$PWD/../3rdparty/lib/lib/ -lcharset +PRE_TARGETDEPS += $$PWD/../3rdparty/lib/lib/libcharset.a diff --git a/src/deepin-editor.qrc b/src/deepin-editor.qrc new file mode 100644 index 0000000000000000000000000000000000000000..99a2fc821c9f1af1820f9eff93e9649acaf1db71 --- /dev/null +++ b/src/deepin-editor.qrc @@ -0,0 +1,36 @@ + + + images/bar_close_normal_light.svg + images/bar_close_hover_light.svg + images/bar_close_press_light.svg + images/bar_close_normal_dark.svg + images/bar_close_hover_dark.svg + images/bar_close_press_dark.svg + images/dropdown_arrow_light.svg + images/dropdown_arrow_dark.svg + images/close_normal_light.svg + images/close_hover_light.svg + images/close_press_light.svg + images/close_normal_dark.svg + images/close_hover_dark.svg + images/close_press_dark.svg + images/logo_96.svg + images/logo_48.svg + images/logo_24.svg + images/warning.svg + images/ok.svg + qss/main.qss + resources/settings.json + images/bookmark.svg + images/u-d.svg + images/u-l.svg + images/d-d.svg + images/d-l.svg + images/like_hover_light.svg + images/like_hover_dark.svg + encodes/encodes.ini + encodes/encodes1.ini + images/arrow_dark.svg + images/arrow_light.svg + + diff --git a/src/editor/FlashTween.cpp b/src/editor/FlashTween.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a349ddcf96f2c786190d98c8fc789cfbb2b0020c --- /dev/null +++ b/src/editor/FlashTween.cpp @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "FlashTween.h" + +FlashTween::FlashTween() +{ + m_timerX = new QTimer(); + QObject::connect(m_timerX, &QTimer::timeout, this ,&FlashTween::__runX); + + m_timerY = new QTimer(); + QObject::connect(m_timerY, &QTimer::timeout, this ,&FlashTween::__runY); +} + +FlashTween::~FlashTween() +{ + if (m_timerX != nullptr) { + delete m_timerX; + m_timerX = nullptr; + } + + if (m_timerY != nullptr) { + delete m_timerY; + m_timerY = nullptr; + } +} + +void FlashTween::startY(qreal t,qreal b,qreal c,qreal d, FunSlideInertial f) +{ + if(c==0.0 || d==0.0) return; + m_currentTimeY = t; + m_beginValueY = b; + m_changeValueY = c; + m_durationTimeY = d; + + m_lastValueY = 0; + m_fSlideGestureY = f; + m_directionY = m_changeValueY<0?1:-1; + + if (m_timerY != nullptr) { + m_timerY->stop(); + m_timerY->start(CELL_TIME); + } +} + +void FlashTween::startX(qreal t,qreal b,qreal c,qreal d, FunSlideInertial f) +{ + if(c==0.0 || d==0.0) return; + m_currentTimeX = t; + m_beginValueX = b; + m_changeValueX = c; + m_durationTimeX = d; + + m_lastValueX = 0; + m_fSlideGestureX = f; + m_directionX = m_changeValueX<0?1:-1; + + m_timerX->stop(); + m_timerX->start(CELL_TIME); +} + +void FlashTween::__runY() +{ + qreal tempValue = m_lastValueY; + m_lastValueY = FlashTween::sinusoidalEaseOut(m_currentTimeY, m_beginValueY, abs(m_changeValueY), m_durationTimeY); + m_fSlideGestureY(m_directionY*(m_lastValueY-tempValue)); + //qDebug()<<"###############################"<stop(); + } + } +} + +void FlashTween::__runX() +{ + qreal tempValue = m_lastValueX; + m_lastValueX = FlashTween::sinusoidalEaseOut(m_currentTimeX, m_beginValueX, abs(m_changeValueX), m_durationTimeX); + m_fSlideGestureX(m_directionX*(m_lastValueX - tempValue)); + //qDebug()<<"###############################"<stop(); + } +} + diff --git a/src/editor/FlashTween.h b/src/editor/FlashTween.h new file mode 100644 index 0000000000000000000000000000000000000000..15e685b6dc4590c7116543cccb180cfb6d666a8c --- /dev/null +++ b/src/editor/FlashTween.h @@ -0,0 +1,122 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once +#include +#include +#include +#include +#define CELL_TIME 15 +#define TAP_MOVE_DELAY 300 + + +// Tween算法(模拟惯性) +typedef std::function FunSlideInertial; + +class FlashTween :public QObject +{ + Q_OBJECT +public: + FlashTween(); + ~FlashTween(); + +public: + QTimer* m_timerY = nullptr; + QTimer* m_timerX = nullptr; + + void startX(qreal t,qreal b,qreal c,qreal d, FunSlideInertial fSlideGesture); + void startY(qreal t,qreal b,qreal c,qreal d, FunSlideInertial fSlideGesture); + void stopX(){m_timerX->stop();} + void stopY(){m_timerY->stop();} + bool activeX(){return m_timerX->isActive();} + bool activeY(){return m_timerY->isActive();} + +private slots: + void __runY(); + void __runX(); + +private: + FunSlideInertial m_fSlideGestureX = nullptr; + FunSlideInertial m_fSlideGestureY = nullptr; + + //纵向单指惯性滑动 + qreal m_currentTimeY = 0; + qreal m_beginValueY = 0; + qreal m_changeValueY = 0; + qreal m_durationTimeY = 0; + qreal m_directionY = 1; + qreal m_lastValueY = 0; + + qreal m_currentTimeX = 0; + qreal m_beginValueX = 0; + qreal m_changeValueX = 0; + qreal m_durationTimeX = 0; + qreal m_directionX = 1; + qreal m_lastValueX = 0; + +private: + /** + 链接:https://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html + 效果说明 + Linear:无缓动效果; + Quadratic:二次方的缓动(t^2); + Cubic:三次方的缓动(t^3); + Quartic:四次方的缓动(t^4); + Quintic:五次方的缓动(t^5); + Sinusoidal:正弦曲线的缓动(sin(t)); + Exponential:指数曲线的缓动(2^t); + Circular:圆形曲线的缓动(sqrt(1-t^2)); + Elastic:指数衰减的正弦曲线缓动; + Back:超过范围的三次方缓动((s+1)*t^3 - s*t^2); + Bounce:指数衰减的反弹缓动。 + 每个效果都分三个缓动方式(方法),分别是: + easeIn:从0开始加速的缓动; + easeOut:减速到0的缓动; + easeInOut:前半段从0开始加速,后半段减速到0的缓动。 + 其中Linear是无缓动效果,没有以上效果。 + 四个参数分别是: + t: current time(当前时间); + b: beginning value(初始值); + c: change in value(变化量); + d: duration(持续时间)。 + */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsequence-point" + static qreal quadraticEaseOut(qreal t,qreal b,qreal c,qreal d){ + return -c *(t/=d)*(t-2) + b; + } + + static qreal cubicEaseOut(qreal t,qreal b,qreal c,qreal d){ + return c*((t=t/d-1)*t*t + 1) + b; + } + + static qreal quarticEaseOut(qreal t,qreal b,qreal c,qreal d){ + return -c * ((t=t/d-1)*t*t*t - 1) + b; + } + + static qreal quinticEaseOut(qreal t,qreal b,qreal c,qreal d){ + return c*((t=t/d-1)*t*t*t*t + 1) + b; + } + + static qreal sinusoidalEaseOut(qreal t,qreal b,qreal c,qreal d){ + return c * sin(t/d * (3.14/2)) + b; + } + + static qreal circularEaseOut(qreal t,qreal b,qreal c,qreal d){ + return c * sqrt(1 - (t=t/d-1)*t) + b; + } + + static qreal bounceEaseOut(qreal t,qreal b,qreal c,qreal d){ + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } + } + #pragma GCC diagnostic pop +}; diff --git a/src/editor/bookmarkwidget.cpp b/src/editor/bookmarkwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2e65ef7a2a654c6dfdef7ecfc270602291cdccb --- /dev/null +++ b/src/editor/bookmarkwidget.cpp @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "bookmarkwidget.h" +#include "leftareaoftextedit.h" +#include + +BookMarkWidget::BookMarkWidget(LeftAreaTextEdit *leftAreaWidget) +{ + m_leftAreaWidget = leftAreaWidget; +} + +BookMarkWidget::~BookMarkWidget() +{ + +} + +void BookMarkWidget::paintEvent(QPaintEvent *event) +{ + m_leftAreaWidget->bookMarkAreaPaintEvent(event); +} diff --git a/src/editor/bookmarkwidget.h b/src/editor/bookmarkwidget.h new file mode 100644 index 0000000000000000000000000000000000000000..8ee92eb84e90bfc08a431e8fb556e57d7e08c6c2 --- /dev/null +++ b/src/editor/bookmarkwidget.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef BOOKMARKWIDGET_H +#define BOOKMARKWIDGET_H + +#include + +class LeftAreaTextEdit; +class BookMarkWidget : public QWidget +{ + Q_OBJECT +public: + explicit BookMarkWidget(LeftAreaTextEdit *leftAreaWidget); + ~BookMarkWidget() override; + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + LeftAreaTextEdit *m_leftAreaWidget; +}; + +#endif // BOOKMARKWIDGET_H diff --git a/src/editor/changemarkcommand.cpp b/src/editor/changemarkcommand.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc655a28693a1d129d2eb49281438c7cc4b5ae79 --- /dev/null +++ b/src/editor/changemarkcommand.cpp @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: 2020 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "changemarkcommand.h" + +ChangeMarkCommand::ChangeMarkCommand(QPointer editPtr, const QList &oldMark, const QList &newMark, QUndoCommand *parent) + : QUndoCommand(parent) + , m_EditPtr(editPtr) + , m_oldMarkReplace(oldMark) + , m_newMarkReplace(newMark) +{ + +} + +ChangeMarkCommand::~ChangeMarkCommand() +{ + +} + +void ChangeMarkCommand::undo() +{ + // 优先执行子撤销项,保证在文本操作后执行 + QUndoCommand::undo(); + + // 插入文本后,恢复旧的颜色标记状态 + if (m_EditPtr && !m_oldMarkReplace.isEmpty()) { + auto oldMark = TextEdit::convertReplaceToMark(m_oldMarkReplace); + m_EditPtr->manualUpdateAllMark(oldMark); + } +} + +void ChangeMarkCommand::redo() +{ + // 优先执行子撤销项,保证在文本操作后执行 + QUndoCommand::redo(); + + // 插入文本后,更新颜色标记状态 + if (m_EditPtr && !m_newMarkReplace.isEmpty()) { + auto newMark = TextEdit::convertReplaceToMark(m_newMarkReplace); + m_EditPtr->manualUpdateAllMark(newMark); + } +} diff --git a/src/editor/changemarkcommand.h b/src/editor/changemarkcommand.h new file mode 100644 index 0000000000000000000000000000000000000000..8159c14d671442a000e3a7e32da76cbf1c369b97 --- /dev/null +++ b/src/editor/changemarkcommand.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2020 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CHANGEMARKCOMMAND_H +#define CHANGEMARKCOMMAND_H + +#include +#include "dtextedit.h" + +// 用于进行颜色标记前后变更撤销恢复 +class ChangeMarkCommand : public QUndoCommand +{ +public: + ChangeMarkCommand(QPointer editPtr, + const QList &oldMark, + const QList &newMark, + QUndoCommand *parent = nullptr); + virtual ~ChangeMarkCommand(); + + virtual void undo(); + virtual void redo(); + +private: + QPointer m_EditPtr; // 操作的文本编辑器对象指针 + QList m_oldMarkReplace; // 缓存的标识操作记录 + QList m_newMarkReplace; // 新的标识操作记录 +}; + +#endif // CHANGEMARKCOMMAND_H diff --git a/src/editor/codeflodarea.cpp b/src/editor/codeflodarea.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa39488d0201bb8a6ad22d9dee91d4f1b427c665 --- /dev/null +++ b/src/editor/codeflodarea.cpp @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "codeflodarea.h" +#include "leftareaoftextedit.h" + + +CodeFlodArea::CodeFlodArea(LeftAreaTextEdit *leftAreaWidget) +{ + m_pLeftAreaWidget = leftAreaWidget; +} + +CodeFlodArea::~CodeFlodArea() +{ + +} + +void CodeFlodArea::paintEvent(QPaintEvent *e) +{ + m_pLeftAreaWidget->codeFlodAreaPaintEvent(e); +} + diff --git a/src/editor/codeflodarea.h b/src/editor/codeflodarea.h new file mode 100644 index 0000000000000000000000000000000000000000..46f9fb35d0ef4ca2e5b225ea388ad15389fa6344 --- /dev/null +++ b/src/editor/codeflodarea.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CODEFLODAREA_H +#define CODEFLODAREA_H +#include +class LeftAreaTextEdit; + + +class CodeFlodArea: public QWidget +{ + Q_OBJECT +public: + explicit CodeFlodArea(LeftAreaTextEdit *leftAreaWidget); + ~CodeFlodArea() override; + void paintEvent(QPaintEvent *e) override; + +private: + LeftAreaTextEdit* m_pLeftAreaWidget = nullptr; +}; + +#endif // CODEFLODAREA_H diff --git a/src/editor/deletebackcommond.cpp b/src/editor/deletebackcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84d905834c9b65579e5e57cd334da6b6bb9f46d0 --- /dev/null +++ b/src/editor/deletebackcommond.cpp @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: 2022 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "deletebackcommond.h" +#include + +DeleteBackCommand::DeleteBackCommand(QTextCursor cursor, QPlainTextEdit *edit): + m_cursor(cursor), + m_edit(edit) +{ + m_delText = m_cursor.selectedText(); + m_delPos = std::min(m_cursor.position(), m_cursor.anchor()); + m_insertPos = m_delPos; +} + +DeleteBackCommand::~DeleteBackCommand() +{ + +} + +void DeleteBackCommand::undo() +{ + m_cursor.setPosition(m_insertPos); + m_cursor.insertText(m_delText); + + m_cursor.setPosition(m_delPos); + m_edit->setTextCursor(m_cursor); +} + +void DeleteBackCommand::redo() +{ + m_cursor.setPosition(m_delPos); + m_cursor.setPosition(m_delPos+m_delText.size(), QTextCursor::KeepAnchor); + m_cursor.deleteChar(); + + // 撤销恢复时光标移回要撤销的位置 + m_edit->setTextCursor(m_cursor); +} + +DeleteBackAltCommand::DeleteBackAltCommand(QList &selections,QPlainTextEdit* edit): + m_ColumnEditSelections(selections), + m_edit(edit) +{ + int size = m_ColumnEditSelections.size(); + int sum=0; + for(int i=0;isetTextCursor(cursor); + } + +} + +void DeleteBackAltCommand::redo() +{ + int size = m_deletions.size(); + + for(int i=0;i +#include +#include +#include +//向后删除单一文字或选中文字的撤销重做 +class DeleteBackCommand:public QUndoCommand +{ +public: + DeleteBackCommand(QTextCursor cursor,QPlainTextEdit* edit); + virtual ~DeleteBackCommand(); + virtual void undo(); + virtual void redo(); + +private: + QTextCursor m_cursor; + QString m_delText {QString()}; + int m_delPos {0}; + int m_insertPos {0}; + + QPlainTextEdit* m_edit; + +}; + +//列模式下向后删除的撤销重做 +class DeleteBackAltCommand:public QUndoCommand +{ +public: + DeleteBackAltCommand(QList &selections,QPlainTextEdit* edit); + virtual ~DeleteBackAltCommand(); + virtual void undo(); + virtual void redo(); + +public: + struct DelNode + { + QString m_delText; + int m_delPos; + int m_insertPos; + int m_id_in_Column; + QTextCursor m_cursor; + }; + +private: + QList& m_ColumnEditSelections; + QList m_deletions; + QPlainTextEdit* m_edit; +}; + +#endif // DELETEBACKCOMMOND_H diff --git a/src/editor/deletetextundocommand.cpp b/src/editor/deletetextundocommand.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74516ff2011d1c9b283ea8073af0bcced347f148 --- /dev/null +++ b/src/editor/deletetextundocommand.cpp @@ -0,0 +1,193 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "deletetextundocommand.h" +#include "editwrapper.h" +#include +#include + +DeleteTextUndoCommand::DeleteTextUndoCommand(QTextCursor textcursor, QPlainTextEdit *edit, QUndoCommand *parent) + : QUndoCommand(parent) + , m_edit(edit) + , m_textCursor(textcursor) + , m_beginPos(m_textCursor.selectionStart()) +{ + if (m_textCursor.hasSelection()) { + m_sInsertText = m_textCursor.selectedText(); + } else { + int pos = m_textCursor.positionInBlock() - 1; + if (pos >= 0) { + m_sInsertText = m_textCursor.block().text().at(pos); + } else { + //上一行lastQChar + m_sInsertText = "\n"; + } + } +} + +DeleteTextUndoCommand::DeleteTextUndoCommand(QList &selections, + QPlainTextEdit *edit, + QUndoCommand *parent) + : QUndoCommand(parent) + , m_edit(edit) + , m_ColumnEditSelections(selections) + , m_beginPos(m_textCursor.selectionStart()) +{ + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + QTextCursor textCursor = m_ColumnEditSelections[i].cursor; + if (textCursor.hasSelection()) { + m_selectTextList.append(textCursor.selectedText()); + } else { + int pos = textCursor.positionInBlock() - 1; + if (pos >= 0) { + m_selectTextList.append(textCursor.block().text().at(pos)); + } else { + //上一行lastQChar + m_selectTextList.append("\n"); + } + } + } +} + +void DeleteTextUndoCommand::undo() +{ + if (m_ColumnEditSelections.isEmpty()) { + // 插入前将光标恢复到删除前位置 + m_textCursor.setPosition(m_beginPos); + m_textCursor.insertText(m_sInsertText); + m_textCursor.setPosition(m_textCursor.position() - m_sInsertText.length(), QTextCursor::KeepAnchor); + + // 进行撤销/恢复时将光标移动到撤销位置 + if (m_edit) { + m_edit->setTextCursor(m_textCursor); + } + } else { + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + m_ColumnEditSelections[i].cursor.insertText(m_selectTextList[i]); + m_ColumnEditSelections[i].cursor.setPosition( + m_ColumnEditSelections[i].cursor.position() - m_selectTextList[i].length(), QTextCursor::KeepAnchor); + } + + if (m_edit && !m_ColumnEditSelections.isEmpty()) { + m_edit->setTextCursor(m_ColumnEditSelections.last().cursor); + } + } +} + +void DeleteTextUndoCommand::redo() +{ + if (m_ColumnEditSelections.isEmpty()) { + m_textCursor.deletePreviousChar(); + + // 进行撤销/恢复时将光标移动到撤销位置 + if (m_edit) { + m_edit->setTextCursor(m_textCursor); + } + } else { + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + m_ColumnEditSelections[i].cursor.deletePreviousChar(); + } + + if (m_edit && !m_ColumnEditSelections.isEmpty()) { + m_edit->setTextCursor(m_ColumnEditSelections.last().cursor); + } + } +} + +DeleteTextUndoCommand2::DeleteTextUndoCommand2(QTextCursor textcursor, QString text, QPlainTextEdit *edit, bool currLine) + : m_textCursor(textcursor) + , m_sInsertText(text) + , m_edit(edit) + , m_iscurrLine(currLine) +{ + m_sInsertText.replace("\r\n", "\n"); +} + +DeleteTextUndoCommand2::DeleteTextUndoCommand2(QList &selections, + QString text, + QPlainTextEdit *edit, + bool currLine) + : m_sInsertText(text) + , m_ColumnEditSelections(selections) + , m_edit(edit) + , m_iscurrLine(currLine) +{ + m_sInsertText.replace("\r\n", "\n"); + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + QTextCursor textCursor = m_ColumnEditSelections[i].cursor; + if (textCursor.hasSelection()) { + m_selectTextList.append(textCursor.selectedText()); + } else { + int pos = textCursor.positionInBlock() - 1; + if (pos >= 0) { + m_selectTextList.append(textCursor.block().text().at(pos)); + } else { + //上一行lastQChar + m_selectTextList.append("\n"); + } + } + } +} + +void DeleteTextUndoCommand2::undo() +{ + if (m_ColumnEditSelections.isEmpty()) { + m_textCursor.setPosition(m_beginPostion); + m_textCursor.insertText(m_sInsertText); + m_textCursor.setPosition(m_beginPostion); + m_edit->setTextCursor(m_textCursor); + } else { + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + m_ColumnEditSelections[i].cursor.setPosition(m_beginPostion); + m_ColumnEditSelections[i].cursor.insertText(m_selectTextList[i]); + m_ColumnEditSelections[i].cursor.setPosition(m_beginPostion); + m_edit->setTextCursor(m_ColumnEditSelections[i].cursor); + } + } +} + +void DeleteTextUndoCommand2::redo() +{ + if (m_ColumnEditSelections.isEmpty()) { + bool isEmptyLine = (m_sInsertText.size() == 0); + bool isBlankLine = (m_sInsertText.trimmed().size() == 0); + + if (!m_iscurrLine) { + //删除到行尾 + if (isEmptyLine || m_textCursor.atBlockEnd()) { + m_textCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + } else if (isBlankLine && m_textCursor.atBlockStart()) { + m_textCursor.movePosition(QTextCursor::StartOfBlock); + m_textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } else { + m_textCursor.movePosition(QTextCursor::NoMove, QTextCursor::MoveAnchor); + m_textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } + } else { + //删除整行 + m_textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + m_textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + m_textCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + } + + m_sInsertText = m_textCursor.selectedText(); + m_beginPostion = m_textCursor.selectionStart(); + m_textCursor.deletePreviousChar(); + + // 进行撤销/恢复时将光标移动到撤销位置 + m_edit->setTextCursor(m_textCursor); + } else { + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + m_beginPostion = m_ColumnEditSelections[i].cursor.selectionStart(); + m_ColumnEditSelections[i].cursor.deletePreviousChar(); + m_edit->setTextCursor(m_ColumnEditSelections[i].cursor); + } + } +} diff --git a/src/editor/deletetextundocommand.h b/src/editor/deletetextundocommand.h new file mode 100644 index 0000000000000000000000000000000000000000..efd69cb131168b83bd8e355d0036da365b1bceb3 --- /dev/null +++ b/src/editor/deletetextundocommand.h @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef DELETETEXTUNDOCOMMAND_H +#define DELETETEXTUNDOCOMMAND_H + +#include +#include +#include +#include +#include + +class DeleteTextUndoCommand : public QUndoCommand +{ +public: + explicit DeleteTextUndoCommand(QTextCursor textcursor, QPlainTextEdit* edit, QUndoCommand *parent = nullptr); + explicit DeleteTextUndoCommand(QList &selections, QPlainTextEdit* edit, QUndoCommand *parent = nullptr); + virtual void undo(); + virtual void redo(); + +private: + QPlainTextEdit* m_edit; + QTextCursor m_textCursor; + QString m_sInsertText; + QList m_selectTextList; + QList m_ColumnEditSelections; + int m_beginPos; // 记录光标删除前位置 +}; + +//重写ctrl + k 和Ctrl +shift +K 逻辑的删除和撤销功能 ut002764 +class DeleteTextUndoCommand2 : public QUndoCommand +{ +public: + explicit DeleteTextUndoCommand2(QTextCursor textcursor,QString text,QPlainTextEdit* edit,bool currLine); + explicit DeleteTextUndoCommand2(QList &selections,QString text,QPlainTextEdit* edit,bool m_iscurrLine); + virtual void undo(); + virtual void redo(); + +private: + QTextCursor m_textCursor; + QString m_sInsertText; + QList m_selectTextList; + QList m_ColumnEditSelections; + QPlainTextEdit* m_edit; + int m_beginPostion {0}; + bool m_iscurrLine {false}; +}; + +#endif // INSERTTEXTUNDOCOMMAND_H diff --git a/src/editor/dtextedit.cpp b/src/editor/dtextedit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..44c481733acb9865fe48e6d65bf6d716a8d346c3 --- /dev/null +++ b/src/editor/dtextedit.cpp @@ -0,0 +1,7982 @@ +// SPDX-FileCopyrightText: 2011-2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + + +#include "../common/utils.h" +#include "../widgets/window.h" +#include "../widgets/bottombar.h" +#include "dtextedit.h" +#include "leftareaoftextedit.h" +#include "editwrapper.h" +#include "showflodcodewidget.h" +#include "deletebackcommond.h" +#include "replaceallcommond.h" +#include "insertblockbytextcommond.h" +#include "indenttextcommond.h" +#include "undolist.h" +#include "changemarkcommand.h" +#include "endlineformatcommond.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +TextEdit::TextEdit(QWidget *parent) + : DPlainTextEdit(parent), + m_wrapper(nullptr) +{ + setUndoRedoEnabled(false); + //撤销重做栈 + m_pUndoStack = new QUndoStack(); + + m_nLines = 0; + m_nBookMarkHoverLine = -1; + m_bIsFileOpen = false; + m_qstrCommitString = ""; + m_bIsShortCut = false; + m_bIsInputMethod = false; + m_isSelectAll = false; + m_touchTapDistance = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::TouchDoubleTapDistance).toInt(); + m_fontLineNumberArea.setFamily("SourceHanSansSC-Normal"); + + m_pLeftAreaWidget = new LeftAreaTextEdit(this); + m_pLeftAreaWidget->m_pFlodArea->setAttribute(Qt::WA_Hover, true); //开启悬停事件 + m_pLeftAreaWidget->m_pBookMarkArea->setAttribute(Qt::WA_Hover, true); + m_pLeftAreaWidget->m_pFlodArea->installEventFilter(this); + m_pLeftAreaWidget->m_pBookMarkArea->installEventFilter(this); + m_foldCodeShow = new ShowFlodCodeWidget(this); + m_foldCodeShow->setVisible(false); + + viewport()->installEventFilter(this); + viewport()->setCursor(Qt::IBeamCursor); + + // Don't draw frame around editor widget. + setFrameShape(QFrame::NoFrame); + setFocusPolicy(Qt::StrongFocus); + setMouseTracking(true); + setContentsMargins(0, 0, 0, 0); + setEditPalette(palette().foreground().color().name(), palette().foreground().color().name()); + + grabGesture(Qt::TapGesture); + grabGesture(Qt::TapAndHoldGesture); + grabGesture(Qt::SwipeGesture); + grabGesture(Qt::PanGesture); + grabGesture(Qt::PinchGesture); + + // Init widgets. + //左边栏控件 滑动条滚动跟新行号 折叠标记 + connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this, &TextEdit::slotValueChanged); + connect(this, &QPlainTextEdit::textChanged, this, &TextEdit::updateLeftAreaWidget); + connect(this, &QPlainTextEdit::textChanged, this, [this]() { + this->m_wrapper->UpdateBottomBarWordCnt(this->characterCount()); + }); + + connect(this, &QPlainTextEdit::cursorPositionChanged, this, &TextEdit::cursorPositionChanged); + connect(this, &QPlainTextEdit::selectionChanged, this, &TextEdit::onSelectionArea); + + connect(document(), &QTextDocument::contentsChange, this, &TextEdit::updateMark); + connect(document(), &QTextDocument::contentsChange, this, &TextEdit::checkBookmarkLineMove); + connect(document(), &QTextDocument::contentsChange, this, &TextEdit::onTextContentChanged); + + connect(m_pUndoStack, &QUndoStack::canRedoChanged, this, &TextEdit::slotCanRedoChanged); + connect(m_pUndoStack, &QUndoStack::canUndoChanged, this, &TextEdit::slotCanUndoChanged); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + switch (Utils::getSystemVersion()) { + case Utils::V23: + dbus.systemBus().connect("org.deepin.dde.Gesture1", + "/org/deepin/dde/Gesture1", "org.deepin.dde.Gesture1", + "Event", + this, SLOT(fingerZoom(QString, QString, int))); + break; + default: + dbus.systemBus().connect("com.deepin.daemon.Gesture", + "/com/deepin/daemon/Gesture", "com.deepin.daemon.Gesture", + "Event", + this, SLOT(fingerZoom(QString, QString, int))); + break; + } + + //初始化右键菜单 + initRightClickedMenu(); + + // Init scroll animation. + m_scrollAnimation = new QPropertyAnimation(verticalScrollBar(), "value"); + m_scrollAnimation->setEasingCurve(QEasingCurve::InOutExpo); + m_scrollAnimation->setDuration(300); + + m_cursorMode = Insert; + + connect(m_scrollAnimation, &QPropertyAnimation::finished, this, &TextEdit::handleScrollFinish, Qt::QueuedConnection); + + // Monitor cursor mark status to update in line number area. + connect(this, &TextEdit::cursorMarkChanged, this, &TextEdit::handleCursorMarkChanged); + + // configure content area + setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &TextEdit::adjustScrollbarMargins, Qt::QueuedConnection); + // Don't blink the cursor when selecting text + // Recover blink when not selecting text. + connect(this, &TextEdit::selectionChanged, this, &TextEdit::slotSelectionChanged, Qt::QueuedConnection); +} + +TextEdit::~TextEdit() +{ + if (m_scrollAnimation != nullptr) { + if (m_scrollAnimation->state() != QAbstractAnimation::Stopped) { + m_scrollAnimation->stop(); + } + delete m_scrollAnimation; + m_scrollAnimation = nullptr; + } + if (m_colorMarkMenu != nullptr) { + delete m_colorMarkMenu; + m_colorMarkMenu = nullptr; + } + if (m_convertCaseMenu != nullptr) { + delete m_convertCaseMenu; + m_convertCaseMenu = nullptr; + } + if (m_rightMenu != nullptr) { + delete m_rightMenu; + m_rightMenu = nullptr; + } + + if (m_pUndoStack != nullptr) { + m_pUndoStack->deleteLater(); + } +} + +void TextEdit::insertTextEx(QTextCursor cursor, QString text) +{ + QUndoCommand *pInsertStack = new InsertTextUndoCommand(cursor, text, this); + m_pUndoStack->push(pInsertStack); + ensureCursorVisible(); +} + +/** + * @brief 将多组插入信息 \a multiText 压入单个撤销栈,便于撤销栈管理。 + * @param multiText 多组插入信息,每组含插入光标位置和插入文本。 + */ +void TextEdit::insertMultiTextEx(const QList > &multiText) +{ + if (multiText.isEmpty()) { + return; + } + + QUndoCommand *pMultiCommand = new QUndoCommand; + // 将所有的插入信息添加到单个撤销项中,便于单次处理 + for (auto pairText : multiText) { + // pMultiCommand 析构时会自动析构子撤销项 + (void)new InsertTextUndoCommand(pairText.first, pairText.second, this, pMultiCommand); + } + m_pUndoStack->push(pMultiCommand); + ensureCursorVisible(); +} + +void TextEdit::deleteSelectTextEx(QTextCursor cursor) +{ + if (cursor.hasSelection()) { + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(cursor, this); + m_pUndoStack->push(pDeleteStack); + } +} + +void TextEdit::deleteSelectTextEx(QTextCursor cursor, QString text, bool currLine) +{ + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand2(cursor, text, this, currLine); + m_pUndoStack->push(pDeleteStack); +} + +void TextEdit::deleteTextEx(QTextCursor cursor) +{ + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(cursor, this); + m_pUndoStack->push(pDeleteStack); +} + +/** + * @brief 将多组删除信息 \a multiText 压入单个撤销栈,便于撤销栈管理。 + * @param multiText 多组删除信息,每组含删除光标信息(删除位置和选取区域)。 + */ +void TextEdit::deleteMultiTextEx(const QList &multiText) +{ + if (multiText.isEmpty()) { + return; + } + + QUndoCommand *pMultiCommand = new QUndoCommand; + // 将所有的插入信息添加到单个撤销项中,便于单次处理 + for (auto textCursor : multiText) { + // pMultiCommand 析构时会自动析构子撤销项 + (void)new DeleteTextUndoCommand(textCursor, this, pMultiCommand); + } + m_pUndoStack->push(pMultiCommand); +} + +void TextEdit::insertSelectTextEx(QTextCursor cursor, QString text) +{ + QUndoCommand *pInsertStack = new InsertTextUndoCommand(cursor, text, this); + m_pUndoStack->push(pInsertStack); + ensureCursorVisible(); +} + +void TextEdit::insertColumnEditTextEx(QString text) +{ + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + for (int i = 0; i < m_altModSelections.size(); i++) { + if (m_altModSelections[i].cursor.hasSelection()) deleteTextEx(m_altModSelections[i].cursor); + } + QUndoCommand *pInsertStack = new InsertTextUndoCommand(m_altModSelections, text, this); + m_pUndoStack->push(pInsertStack); + ensureCursorVisible(); +} + +void TextEdit::initRightClickedMenu() +{ + // Init menu. + m_rightMenu = new DMenu(); + m_undoAction = new QAction(tr("Undo"), this); + m_redoAction = new QAction(tr("Redo"), this); + m_cutAction = new QAction(tr("Cut"), this); + m_copyAction = new QAction(tr("Copy"), this); + m_pasteAction = new QAction(tr("Paste"), this); + m_deleteAction = new QAction(tr("Delete"), this); + m_selectAllAction = new QAction(tr("Select All"), this); + m_findAction = new QAction(tr("Find"), this); + m_replaceAction = new QAction(tr("Replace"), this); + m_jumpLineAction = new QAction(tr("Go to Line"), this); + m_enableReadOnlyModeAction = new QAction(tr("Turn on Read-Only mode"), this); + m_disableReadOnlyModeAction = new QAction(tr("Turn off Read-Only mode"), this); + m_fullscreenAction = new QAction(tr("Fullscreen"), this); + m_exitFullscreenAction = new QAction(tr("Exit fullscreen"), this); + m_openInFileManagerAction = new QAction(tr("Display in file manager"), this); + m_toggleCommentAction = new QAction(tr("Add Comment"), this); + m_voiceReadingAction = new QAction(tr("Text to Speech"), this); + m_stopReadingAction = new QAction(tr("Stop reading"), this); + m_dictationAction = new QAction(tr("Speech to Text"), this); + m_translateAction = new QAction(tr("Translate"), this); + m_columnEditAction = new QAction(tr("Column Mode"), this); + m_addBookMarkAction = new QAction(tr("Add bookmark"), this); + m_cancelBookMarkAction = new QAction(tr("Remove Bookmark"), this); + m_preBookMarkAction = new QAction(tr("Previous bookmark"), this); + m_nextBookMarkAction = new QAction(tr("Next bookmark"), this); + m_clearBookMarkAction = new QAction(tr("Remove All Bookmarks"), this); + m_flodAllLevel = new QAction(tr("Fold All"), this); + m_flodCurrentLevel = new QAction(tr("Fold Current Level"), this); + m_unflodAllLevel = new QAction(tr("Unfold All"), this); + m_unflodCurrentLevel = new QAction(tr("Unfold Current Level"), this); + + //yanyuhan + //颜色标记、折叠/展开、书签、列编辑、设置注释、取消注释; + //点击颜色标记菜单,显示二级菜单,包括:标记、清除上次标记、清除标记、标记所有; + m_colorMarkMenu = new DMenu(tr("Color Mark")); + + // 为颜色标记Menu,增加事件过滤 + m_colorMarkMenu->installEventFilter(this); + m_cancleMarkAllLine = new QAction(tr("Clear All Marks"), this); + m_cancleLastMark = new QAction(tr("Clear Last Mark"), this); + + //添加当前颜色选择控件 梁卫东 + ColorSelectWdg *pColorsSelectWdg = new ColorSelectWdg(QString(), this); + connect(pColorsSelectWdg, &ColorSelectWdg::sigColorSelected, this, &TextEdit::slotSigColorSelected); + + m_actionColorStyles = new QWidgetAction(this); + m_actionColorStyles->setDefaultWidget(pColorsSelectWdg); + + m_markCurrentAct = new QAction(tr("Mark"), this); + connect(m_markCurrentAct, &QAction::triggered, this, [this, pColorsSelectWdg]() { + isMarkCurrentLine(true, pColorsSelectWdg->getDefaultColor().name()); + renderAllSelections(); + }); + + //添加全部颜色选择控件 梁卫东 + ColorSelectWdg *pColorsAllSelectWdg = new ColorSelectWdg(QString(), this); + connect(pColorsAllSelectWdg, &ColorSelectWdg::sigColorSelected, this, &TextEdit::slotSigColorAllSelected); + m_actionAllColorStyles = new QWidgetAction(this); + m_actionAllColorStyles->setDefaultWidget(pColorsAllSelectWdg); + + m_markAllAct = new QAction(tr("Mark All"), this); + connect(m_markAllAct, &QAction::triggered, this, [this, pColorsAllSelectWdg]() { + m_strMarkAllLineColorName = pColorsAllSelectWdg->getDefaultColor().name(); + isMarkAllLine(true, pColorsAllSelectWdg->getDefaultColor().name()); + renderAllSelections(); + }); + + m_addComment = new QAction(tr("Add Comment"), this); + m_cancelComment = new QAction(tr("Remove Comment"), this); + + connect(m_rightMenu, &DMenu::aboutToHide, this, &TextEdit::removeHighlightWordUnderCursor); + connect(m_undoAction, &QAction::triggered, this, [ = ]() { + this->undo_(); + }); + connect(m_redoAction, &QAction::triggered, this, [ = ]() { + this->redo_(); + }); + connect(m_cutAction, &QAction::triggered, this, &TextEdit::slotCutAction); + connect(m_copyAction, &QAction::triggered, this, &TextEdit::slotCopyAction); + connect(m_pasteAction, &QAction::triggered, this, &TextEdit::slotPasteAction); + connect(m_deleteAction, &QAction::triggered, this, &TextEdit::slotDeleteAction); + connect(m_selectAllAction, &QAction::triggered, this, &TextEdit::slotSelectAllAction); + connect(m_findAction, &QAction::triggered, this, &TextEdit::clickFindAction); + connect(m_replaceAction, &QAction::triggered, this, &TextEdit::clickReplaceAction); + connect(m_jumpLineAction, &QAction::triggered, this, &TextEdit::clickJumpLineAction); + connect(m_fullscreenAction, &QAction::triggered, this, &TextEdit::clickFullscreenAction); + connect(m_exitFullscreenAction, &QAction::triggered, this, &TextEdit::clickFullscreenAction); + connect(m_enableReadOnlyModeAction, &QAction::triggered, this, &TextEdit::toggleReadOnlyMode); + connect(m_disableReadOnlyModeAction, &QAction::triggered, this, &TextEdit::toggleReadOnlyMode); + connect(m_openInFileManagerAction, &QAction::triggered, this, &TextEdit::slotOpenInFileManagerAction); + connect(m_addComment, &QAction::triggered, this, &TextEdit::slotAddComment); + connect(m_cancelComment, &QAction::triggered, this, &TextEdit::slotCancelComment); + connect(m_voiceReadingAction, &QAction::triggered, this, &TextEdit::slotVoiceReadingAction); + connect(m_stopReadingAction, &QAction::triggered, this, &TextEdit::slotStopReadingAction); + connect(m_dictationAction, &QAction::triggered, this, &TextEdit::slotdictationAction); + connect(m_translateAction, &QAction::triggered, this, &TextEdit::slot_translate); + connect(m_columnEditAction, &QAction::triggered, this, &TextEdit::slotColumnEditAction); + connect(m_addBookMarkAction, &QAction::triggered, this, &TextEdit::addOrDeleteBookMark); + connect(m_cancelBookMarkAction, &QAction::triggered, this, &TextEdit::addOrDeleteBookMark); + connect(m_preBookMarkAction, &QAction::triggered, this, &TextEdit::slotPreBookMarkAction); + connect(m_nextBookMarkAction, &QAction::triggered, this, &TextEdit::slotNextBookMarkAction); + connect(m_clearBookMarkAction, &QAction::triggered, this, &TextEdit::slotClearBookMarkAction); + connect(m_flodAllLevel, &QAction::triggered, this, &TextEdit::slotFlodAllLevel); + connect(m_unflodAllLevel, &QAction::triggered, this, &TextEdit::slotUnflodAllLevel); + connect(m_flodCurrentLevel, &QAction::triggered, this, &TextEdit::slotFlodCurrentLevel); + connect(m_unflodCurrentLevel, &QAction::triggered, this, &TextEdit::slotUnflodCurrentLevel); + connect(m_cancleMarkAllLine, &QAction::triggered, this, &TextEdit::slotCancleMarkAllLine); + connect(m_cancleLastMark, &QAction::triggered, this, &TextEdit::slotCancleLastMark); + + // Init convert case sub menu. + m_haveWordUnderCursor = false; + m_convertCaseMenu = new DMenu(tr("Change Case")); + m_upcaseAction = new QAction(tr("Upper Case"), this); + m_downcaseAction = new QAction(tr("Lower Case"), this); + m_capitalizeAction = new QAction(tr("Capitalize"), this); + m_convertCaseMenu->addAction(m_upcaseAction); + m_convertCaseMenu->addAction(m_downcaseAction); + m_convertCaseMenu->addAction(m_capitalizeAction); + + connect(m_upcaseAction, &QAction::triggered, this, &TextEdit::upcaseWord); + connect(m_downcaseAction, &QAction::triggered, this, &TextEdit::downcaseWord); + connect(m_capitalizeAction, &QAction::triggered, this, &TextEdit::capitalizeWord); + + m_canUndo = false; + m_canRedo = false; + + connect(this, &TextEdit::undoAvailable, this, &TextEdit::slotUndoAvailable); + connect(this, &TextEdit::redoAvailable, this, &TextEdit::slotRedoAvailable); +} + +void TextEdit::popRightMenu(QPoint pos) +{ + //清除菜单分割线残影 + if (m_rightMenu != nullptr) { + delete m_rightMenu; + m_rightMenu = nullptr; + } + m_rightMenu = new DMenu; + + m_rightMenu->clear(); + QTextCursor selectionCursor = textCursor(); + selectionCursor.movePosition(QTextCursor::StartOfBlock); + selectionCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + QString text = selectionCursor.selectedText(); + + // init base. + bool isBlankLine = text.trimmed().isEmpty(); + + bool isAddUndoRedo = false; + if (m_pUndoStack->canUndo() && m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_undoAction); + isAddUndoRedo = true; + } + + if (m_pUndoStack->canRedo() && m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_redoAction); + isAddUndoRedo = true; + } + + if (isAddUndoRedo) { + m_rightMenu->addSeparator(); + } + + if (textCursor().hasSelection() || m_hasColumnSelection) { + if (m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_cutAction); + } + m_rightMenu->addAction(m_copyAction); + } + + if (canPaste()) { + if (m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_pasteAction); + } + } + + if (textCursor().hasSelection() || m_hasColumnSelection) { + if (m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_deleteAction); + } + + } + + if (!document()->isEmpty()) { + m_rightMenu->addAction(m_selectAllAction); + } + + m_rightMenu->addSeparator(); + + if (!document()->isEmpty()) { + m_rightMenu->addAction(m_findAction); + if (m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_replaceAction); + } + m_rightMenu->addAction(m_jumpLineAction); + m_rightMenu->addSeparator(); + } + + if (textCursor().hasSelection()) { + if (m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addMenu(m_convertCaseMenu); + } + } else { + m_convertCaseMenu->hide(); + } + + // intelligent judge whether to support comments. + const auto def = m_repository.definitionForFileName(QFileInfo(m_sFilePath).fileName()); + if (characterCount() && + (textCursor().hasSelection() || !isBlankLine) && + !def.filePath().isEmpty()) { + + /* + * 不支持注释的文件类型,右键菜单不显示“添加注释/取消注释” + * 不支持注释的文件类型:Markdown(.d)/vCard(.vcf)/JSON(.json) + */ + if (def.name() != "Markdown" + && !def.name().contains(QString("vCard")) + && !def.name().contains(QString("JSON"))) { + m_rightMenu->addAction(m_addComment); + m_rightMenu->addAction(m_cancelComment); + } + } + + if (m_bReadOnlyPermission || m_readOnlyMode) { + m_addComment->setEnabled(false); + m_cancelComment->setEnabled(false); + } else { + m_addComment->setEnabled(true); + m_cancelComment->setEnabled(true); + } + + m_rightMenu->addSeparator(); + if (m_bReadOnlyPermission == false) { + if (m_readOnlyMode) { + m_rightMenu->addAction(m_disableReadOnlyModeAction); + } else { + m_rightMenu->addAction(m_enableReadOnlyModeAction); + } + } + + m_rightMenu->addAction(m_openInFileManagerAction); + m_rightMenu->addSeparator(); + if (static_cast(this->window())->isFullScreen()) { + m_rightMenu->addAction(m_exitFullscreenAction); + } else { + m_rightMenu->addAction(m_fullscreenAction); + } + + /* 专业版/家庭版/教育版鼠标右键菜单支持语音读写 */ + /* 更换成只要发现有com.iflytek.aiassistant服务已经注册开启,则开启支持语音读写功能 */ + /*if ((DSysInfo::uosEditionType() == DSysInfo::UosEdition::UosProfessional) || + (DSysInfo::uosEditionType() == DSysInfo::UosEdition::UosHome) || + (DSysInfo::uosEditionType() == DSysInfo::UosEdition::UosEducation)) {*/ + + if (m_wrapper->window()->getIsRegistIflytekAiassistant()) { + bool stopReadingState = false; + QDBusMessage stopReadingMsg = QDBusMessage::createMethodCall("com.iflytek.aiassistant", + "/aiassistant/tts", + "com.iflytek.aiassistant.tts", + "isTTSInWorking"); + + QDBusReply stopReadingStateRet = QDBusConnection::sessionBus().asyncCall(stopReadingMsg, 100); + if (stopReadingStateRet.isValid()) { + stopReadingState = stopReadingStateRet.value(); + } + if (!stopReadingState) { + m_rightMenu->addAction(m_voiceReadingAction); + m_voiceReadingAction->setEnabled(false); + } else { + m_rightMenu->removeAction(m_voiceReadingAction); + m_rightMenu->addAction(m_stopReadingAction); + } + bool voiceReadingState = false; + QDBusMessage voiceReadingMsg = QDBusMessage::createMethodCall("com.iflytek.aiassistant", + "/aiassistant/tts", + "com.iflytek.aiassistant.tts", + "getTTSEnable"); + + QDBusReply voiceReadingStateRet = QDBusConnection::sessionBus().asyncCall(voiceReadingMsg, 100); + //没有收到返回就加载配置文件数据 + if (voiceReadingStateRet.isValid()) { + voiceReadingState = voiceReadingStateRet.value(); + } else { + voiceReadingState = m_wrapper->window()->getIflytekaiassistantConfig("aiassistant-tts"); + } + if ((textCursor().hasSelection() && voiceReadingState) || m_hasColumnSelection) { + m_voiceReadingAction->setEnabled(true); + } + + m_rightMenu->addAction(m_dictationAction); + bool dictationState = false; + QDBusMessage dictationMsg = QDBusMessage::createMethodCall("com.iflytek.aiassistant", + "/aiassistant/iat", + "com.iflytek.aiassistant.iat", + "getIatEnable"); + + QDBusReply dictationStateRet = QDBusConnection::sessionBus().asyncCall(dictationMsg, 100); + //没有收到返回就加载配置文件数据 + if (dictationStateRet.isValid()) { + dictationState = dictationStateRet.value(); + } else { + dictationState = m_wrapper->window()->getIflytekaiassistantConfig("aiassistant-iat"); + } + m_dictationAction->setEnabled(dictationState); + if (m_bReadOnlyPermission || m_readOnlyMode) { + m_dictationAction->setEnabled(false); + } + + m_rightMenu->addAction(m_translateAction); + m_translateAction->setEnabled(false); + bool translateState = false; + QDBusMessage translateReadingMsg = QDBusMessage::createMethodCall("com.iflytek.aiassistant", + "/aiassistant/trans", + "com.iflytek.aiassistant.trans", + "getTransEnable"); + + QDBusReply translateStateRet = QDBusConnection::sessionBus().asyncCall(translateReadingMsg, 100); + //没有收到返回就加载配置文件数据 + if (translateStateRet.isValid()) { + translateState = translateStateRet.value(); + } else { + translateState = m_wrapper->window()->getIflytekaiassistantConfig("aiassistant-trans"); + } + if ((textCursor().hasSelection() && translateState) || m_hasColumnSelection) { + m_translateAction->setEnabled(translateState); + } + } + + + if (!this->document()->isEmpty()) { + + m_colorMarkMenu->clear(); + // 清空 tab order list + m_MarkColorMenuTabOrder.clear(); + + // 增加 Mark Color Menu Item + m_colorMarkMenu->addAction(m_markCurrentAct); + m_colorMarkMenu->addAction(m_actionColorStyles); + // 将对应 Mark Color Menu Item 加入 Tab Order + // QPair , bool决定tab过程中是否可以获取focus + m_MarkColorMenuTabOrder.append(QPair(m_markCurrentAct, true)); + m_MarkColorMenuTabOrder.append(QPair(m_actionColorStyles, false)); + + // 增加 Mark Color Menu Item + m_colorMarkMenu->addSeparator(); + m_colorMarkMenu->addAction(m_markAllAct); + m_colorMarkMenu->addAction(m_actionAllColorStyles); + m_colorMarkMenu->addSeparator(); + // 将对应 Mark Color Menu Item 加入 Tab Order + m_MarkColorMenuTabOrder.append(QPair(m_markAllAct, true)); + m_MarkColorMenuTabOrder.append(QPair(m_actionAllColorStyles, false)); + + if (m_markOperations.size() > 0) { + // 增加 Mark Color Menu Item + m_colorMarkMenu->addAction(m_cancleLastMark); + m_colorMarkMenu->addSeparator(); + m_colorMarkMenu->addAction(m_cancleMarkAllLine); + // 将对应 Mark Color Menu Item 加入 Tab Order + m_MarkColorMenuTabOrder.append(QPair(m_cancleLastMark, true)); + m_MarkColorMenuTabOrder.append(QPair(m_cancleMarkAllLine, true)); + } + + m_rightMenu->addSeparator(); + if (m_bReadOnlyPermission == false && m_readOnlyMode == false) { + m_rightMenu->addAction(m_columnEditAction); + } + m_rightMenu->addMenu(m_colorMarkMenu); + } + + QPoint pos1 = cursorRect().bottomRight(); + //当全选大文本 坐标超出屏幕外显示不了 梁卫东 2020-08-19 10:23:29 + if (pos1.y() > this->rect().height()) { + pos1.setY((this->rect().height()) / 2); + pos1.setX((this->rect().width()) / 2); + } + if (pos.isNull()) { + m_rightMenu->exec(mapToGlobal(pos1)); + } else { + m_rightMenu->exec(pos); + } +} + +void TextEdit::setWrapper(EditWrapper *w) +{ + m_wrapper = w; +} + +EditWrapper *TextEdit::getWrapper() +{ + return m_wrapper; +} + +bool TextEdit::isUndoRedoOpt() +{ + return (m_pUndoStack->canRedo() || m_pUndoStack->canUndo()); +} + +bool TextEdit::getModified() +{ + return (document()->isModified() && (m_pUndoStack->canUndo() || m_pUndoStack->index() != m_lastSaveIndex)); +} + + +int TextEdit::getCurrentLine() +{ + return textCursor().blockNumber() + 1; +} + +int TextEdit::getCurrentColumn() +{ + return textCursor().columnNumber(); +} + +int TextEdit::getPosition() +{ + return textCursor().position(); +} + +int TextEdit::getScrollOffset() +{ + return verticalScrollBar()->value(); +} + +void TextEdit::forwardChar() +{ + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::NextCharacter); + } +} + +void TextEdit::backwardChar() +{ + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::PreviousCharacter); + } +} + +void TextEdit::forwardWord() +{ + QTextCursor cursor = textCursor(); + + if (m_cursorMark) { + cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); + } else { + cursor.movePosition(QTextCursor::NextWord, QTextCursor::MoveAnchor); + } + + setTextCursor(cursor); +} + +void TextEdit::backwardWord() +{ + QTextCursor cursor = textCursor(); + + if (m_cursorMark) { + // cursor.setPosition(getPrevWordPosition(cursor, QTextCursor::KeepAnchor), QTextCursor::KeepAnchor); + cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + } else { + // cursor.setPosition(getPrevWordPosition(cursor, QTextCursor::MoveAnchor), QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); + } + + setTextCursor(cursor); +} + +void TextEdit::forwardPair() +{ + // Record cursor and seleciton position before move cursor. + int actionStartPos = textCursor().position(); + int selectionStartPos = textCursor().selectionStart(); + int selectionEndPos = textCursor().selectionEnd(); + + // Because find always search start from selection end position. + // So we need clear selection to make search start from cursor. + QTextCursor removeSelectionCursor = textCursor(); + removeSelectionCursor.clearSelection(); + setTextCursor(removeSelectionCursor); + + // Start search. + if (find(QRegExp("[\"'>)}]"))) { + int findPos = textCursor().position(); + + QTextCursor cursor = textCursor(); + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + + if (actionStartPos == selectionStartPos) { + cursor.setPosition(selectionEndPos, QTextCursor::MoveAnchor); + cursor.setPosition(findPos, moveMode); + } else { + cursor.setPosition(selectionStartPos, QTextCursor::MoveAnchor); + cursor.setPosition(findPos, moveMode); + } + + setTextCursor(cursor); + } +} + +void TextEdit::backwardPair() +{ + // Record cursor and seleciton position before move cursor. + int actionStartPos = textCursor().position(); + int selectionStartPos = textCursor().selectionStart(); + int selectionEndPos = textCursor().selectionEnd(); + + // Because find always search start from selection end position. + // So we need clear selection to make search start from cursor. + QTextCursor removeSelectionCursor = textCursor(); + removeSelectionCursor.clearSelection(); + setTextCursor(removeSelectionCursor); + + QTextDocument::FindFlags options; + options |= QTextDocument::FindBackward; + + if (find(QRegExp("[\"'<({]"), options)) { + QTextCursor cursor = textCursor(); + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + + cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor); + + int findPos = cursor.position(); + + if (actionStartPos == selectionStartPos) { + cursor.setPosition(selectionEndPos, QTextCursor::MoveAnchor); + cursor.setPosition(findPos, moveMode); + setTextCursor(cursor); + } else { + cursor.setPosition(selectionStartPos, QTextCursor::MoveAnchor); + cursor.setPosition(findPos, moveMode); + setTextCursor(cursor); + } + } +} + +int TextEdit::blockCount() const +{ + return document()->blockCount(); +} + +int TextEdit::characterCount() const +{ + return document()->characterCount(); +} + +QTextBlock TextEdit::firstVisibleBlock() +{ + return document()->findBlockByLineNumber(getFirstVisibleBlockId()); +} + +void TextEdit::moveToStart() +{ + verticalScrollBar()->setValue(0); + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::Start); + } + + // 移动展示区域,手动高亮文本 + m_wrapper->OnUpdateHighlighter(); +} + +void TextEdit::moveToEnd() +{ + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::End); + } + + // 移动展示区域,手动高亮文本 + m_wrapper->OnUpdateHighlighter(); +} + +void TextEdit::moveToStartOfLine() +{ + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::StartOfBlock); + } +} + +void TextEdit::moveToEndOfLine() +{ + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::EndOfBlock); + } +} + +void TextEdit::moveToLineIndentation() +{ + // Init cursor and move type. + QTextCursor cursor = textCursor(); + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + + // Get line start position. + cursor.movePosition(QTextCursor::StartOfBlock, moveMode); + int startColumn = cursor.columnNumber(); + + // Get line end position. + cursor.movePosition(QTextCursor::EndOfBlock, moveMode); + int endColumn = cursor.columnNumber(); + + // Move to line start first. + cursor.movePosition(QTextCursor::StartOfBlock, moveMode); + int nStartPos = cursor.position(); + + if (nStartPos - 1 < 0) { + nStartPos = 0; + //cursor.setPosition(nStartPos, QTextCursor::MoveAnchor); + cursor.setPosition(nStartPos + 1, moveMode); + } else { + cursor.setPosition(nStartPos - 1, moveMode); + cursor.setPosition(nStartPos, QTextCursor::KeepAnchor); + } + + //cursor.movePosition(QTextCursor::PreviousCharacter,QTextCursor::KeepAnchor); + // Move to first non-blank char of line. + int column = startColumn; + while (column < endColumn) { + QChar currentChar = *cursor.selection().toPlainText().data(); + //QChar currentChar = toPlainText().at(std::max(cursor.position() - 1, 0)); + + if (!currentChar.isSpace()) { + //cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor); + cursor.setPosition(cursor.position() - 1, moveMode); + break; + } else { + //cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor); + cursor.setPosition(cursor.position() + 1, moveMode); + } + + column++; + } + + cursor.clearSelection(); + setTextCursor(cursor); +} + +void TextEdit::nextLine() +{ + m_isSelectAll = false; + if (!characterCount()) + return; + + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::Down); + } + + if (m_wrapper != nullptr) { + m_wrapper->OnUpdateHighlighter(); + if ((m_wrapper->window()->findBarIsVisiable() || m_wrapper->window()->replaceBarIsVisiable()) && + (QString::compare(m_wrapper->window()->getKeywordForSearchAll(), m_wrapper->window()->getKeywordForSearch(), Qt::CaseInsensitive) == 0)) { + highlightKeywordInView(m_wrapper->window()->getKeywordForSearchAll()); + } + + markAllKeywordInView(); + } +} + +void TextEdit::prevLine() +{ + m_isSelectAll = false; + if (!characterCount()) + return; + + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor); + setTextCursor(cursor); + } else { + moveCursorNoBlink(QTextCursor::Up); + } + + if (m_wrapper != nullptr) { + m_wrapper->OnUpdateHighlighter(); + if ((m_wrapper->window()->findBarIsVisiable() || m_wrapper->window()->replaceBarIsVisiable()) && + (QString::compare(m_wrapper->window()->getKeywordForSearchAll(), m_wrapper->window()->getKeywordForSearch(), Qt::CaseInsensitive) == 0)) { + highlightKeywordInView(m_wrapper->window()->getKeywordForSearchAll()); + } + + markAllKeywordInView(); + } +} + +void TextEdit::moveCursorNoBlink(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode) +{ + // Function moveCursorNoBlink will blink cursor when move cursor. + // But function movePosition won't, so we use movePosition to avoid that cursor link when moving cursor. + QTextCursor cursor = textCursor(); + cursor.movePosition(operation, mode); + setTextCursor(cursor); +} + +void TextEdit::jumpToLine(int line, bool keepLineAtCenter) +{ + QTextCursor cursor(document()->findBlockByNumber(line - 1)); // line - 1 because line number starts from 0 + //verticalScrollBar()->setValue(fontMetrics().height() * line - height()); + // Update cursor. + setTextCursor(cursor); + + if (keepLineAtCenter) { + keepCurrentLineAtCenter(); + } + m_pLeftAreaWidget->m_pLineNumberArea->update(); +} + +void TextEdit::newline() +{ + // Stop mark if mark is set. + tryUnsetMark(); + + QTextCursor cursor = textCursor(); + auto com = new InsertTextUndoCommand(cursor, "\n", this); + m_pUndoStack->push(com); + setTextCursor(cursor); +} + +void TextEdit::openNewlineAbove() +{ + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + InsertTextUndoCommand *com = new InsertTextUndoCommand(cursor, "\n", this); + m_pUndoStack->push(com); + cursor.movePosition(QTextCursor::Up, QTextCursor::MoveAnchor); + setTextCursor(cursor); +} + +void TextEdit::openNewlineBelow() +{ + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); + InsertTextUndoCommand *com = new InsertTextUndoCommand(cursor, "\n", this); + m_pUndoStack->push(com); + + //make the vertical scroll bar change together. + this->setTextCursor(cursor); +} + +/* + * swap tow lines. + * firstly,combine the contents of the current line with the contents of the previous or next line. + * then,insert the combined content. + * */ +void TextEdit::moveLineDownUp(bool up) +{ + if (up) { + QTextCursor cursor = this->textCursor(); + //current line isn't the first line of this document + if (0 != cursor.blockNumber()) { + int startpos = 0; + int endpos = 0; + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + endpos = cursor.position(); + QString curtext = cursor.selectedText(); + + cursor.movePosition(QTextCursor::PreviousBlock); + startpos = cursor.position(); + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + QString uptext = cursor.selectedText(); + + cursor.setPosition(startpos); + cursor.setPosition(endpos, QTextCursor::KeepAnchor); + InsertTextUndoCommand *com = new InsertTextUndoCommand(cursor, curtext + "\n" + uptext, this); + m_pUndoStack->push(com); + + //ensure that this operation can be performed multiple times in succession. + //and make the vertical scroll bar change together at the same time. + cursor.setPosition(startpos); + this->setTextCursor(cursor); + } + } else { + QTextCursor cursor = this->textCursor(); + //current line isn't the last line of this document + if (cursor.blockNumber() + 1 != this->document()->blockCount()) { + int startpos = 0; + int endpos = 0; + cursor.movePosition(QTextCursor::StartOfLine); + startpos = cursor.position(); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + QString curtext = cursor.selectedText(); + + cursor.movePosition(QTextCursor::NextBlock); + cursor.movePosition(QTextCursor::StartOfLine); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + endpos = cursor.position(); + QString downtext = cursor.selectedText(); + + cursor.setPosition(startpos); + cursor.setPosition(endpos, QTextCursor::KeepAnchor); + InsertTextUndoCommand *com = new InsertTextUndoCommand(cursor, downtext + "\n" + curtext, this); + m_pUndoStack->push(com); + + //make the vertical scroll bar change together. + cursor.setPosition(endpos); + this->setTextCursor(cursor); + } + } + + +} + +void TextEdit::scrollLineUp() +{ + QScrollBar *scrollbar = verticalScrollBar(); + + scrollbar->setValue(scrollbar->value() - 1); + + if (cursorRect().y() > rect().height() - fontMetrics().height()) { + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Up, moveMode); + setTextCursor(cursor); + } +} + +void TextEdit::scrollLineDown() +{ + QScrollBar *scrollbar = verticalScrollBar(); + + scrollbar->setValue(scrollbar->value() + 1); + + if (cursorRect().y() < 0) { + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Down, moveMode); + setTextCursor(cursor); + } +} + +void TextEdit::scrollUp() +{ + QScrollBar *scrollbar = verticalScrollBar(); + scrollbar->triggerAction(QAbstractSlider::SliderPageStepSub); + + m_pLeftAreaWidget->m_pLineNumberArea->update(); + //m_pLeftAreaWidget->m_pFlodArea->update(); + //m_pLeftAreaWidget->m_pBookMarkArea->update(); + + if (verticalScrollBar()->maximum() > 0) { + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + QPoint startPoint = QPointF(0, fontMetrics().height()).toPoint(); + QTextCursor cur = cursorForPosition(startPoint); + QTextCursor cursor = textCursor(); + cursor.setPosition(cur.position(), moveMode); + setTextCursor(cursor); + } + + if (m_wrapper != nullptr) { + m_wrapper->OnUpdateHighlighter(); + if ((m_wrapper->window()->findBarIsVisiable() || m_wrapper->window()->replaceBarIsVisiable()) && + (QString::compare(m_wrapper->window()->getKeywordForSearchAll(), m_wrapper->window()->getKeywordForSearch(), Qt::CaseInsensitive) == 0)) { + highlightKeywordInView(m_wrapper->window()->getKeywordForSearchAll()); + } + + markAllKeywordInView(); + } +} + +void TextEdit::scrollDown() +{ + QScrollBar *scrollbar = verticalScrollBar(); + scrollbar->triggerAction(QAbstractSlider::SliderPageStepAdd); + + m_pLeftAreaWidget->m_pLineNumberArea->update(); + //m_pLeftAreaWidget->m_pFlodArea->update(); + //m_pLeftAreaWidget->m_pBookMarkArea->update(); + + if (verticalScrollBar()->maximum() > 0) { + auto moveMode = m_cursorMark ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor; + QPoint endPoint = QPointF(0, height() - fontMetrics().height()).toPoint(); + QTextCursor cur = cursorForPosition(endPoint); + QTextCursor cursor = textCursor(); + cursor.setPosition(cur.position(), moveMode); + setTextCursor(cursor); + } + + if (m_wrapper != nullptr) { + m_wrapper->OnUpdateHighlighter(); + if ((m_wrapper->window()->findBarIsVisiable() || m_wrapper->window()->replaceBarIsVisiable()) && + (QString::compare(m_wrapper->window()->getKeywordForSearchAll(), m_wrapper->window()->getKeywordForSearch(), Qt::CaseInsensitive) == 0)) { + highlightKeywordInView(m_wrapper->window()->getKeywordForSearchAll()); + } + + markAllKeywordInView(); + } +} + +/* + * copy the current line + * firstly,get the text of current line. + * then,insert the text with '\n' at the end of current line. + * */ +void TextEdit::duplicateLine() +{ + auto cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + auto text = cursor.selectedText(); + + text = "\n" + text; + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); + auto com = new InsertTextUndoCommand(cursor, text, this); + m_pUndoStack->push(com); + + //make the vertical scroll bar change together. + this->setTextCursor(cursor); +} + +void TextEdit::copyLines() +{ + // Record current cursor and build copy cursor. + QTextCursor currentCursor = textCursor(); + QTextCursor copyCursor = textCursor(); + + if (textCursor().hasSelection()) { + // Sort selection bound cursors. + int startPos = textCursor().anchor(); + int endPos = textCursor().position(); + + if (startPos > endPos) { + std::swap(startPos, endPos); + } + + // Selectoin multi-lines. + QTextCursor startCursor = textCursor(); + startCursor.setPosition(startPos, QTextCursor::MoveAnchor); + startCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + + QTextCursor endCursor = textCursor(); + endCursor.setPosition(endPos, QTextCursor::MoveAnchor); + endCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); + + copyCursor.setPosition(startCursor.position(), QTextCursor::MoveAnchor); + copyCursor.setPosition(endCursor.position(), QTextCursor::KeepAnchor); + + popupNotify(tr("Selected line(s) copied")); + } else { + // Selection current line. + copyCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + copyCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + + popupNotify(tr("Current line copied")); + } + + // Copy lines to system clipboard. + setTextCursor(copyCursor); + copySelectedText(); + + // Reset cursor before copy lines. + copyCursor.setPosition(currentCursor.position(), QTextCursor::MoveAnchor); + setTextCursor(copyCursor); +} + +void TextEdit::cutlines() +{ + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (textCursor().hasSelection() || m_bIsAltMod) { + this->cut(); + popupNotify(tr("Selected line(s) clipped")); + } else { + auto cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + if (cursor.hasSelection()) { + QString data = cursor.selectedText(); + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(cursor, this); + m_pUndoStack->push(pDeleteStack); + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + popupNotify(tr("Current line clipped")); + } + } +} + +void TextEdit::joinLines() +{ + QTextCursor cursor = this->textCursor(); + //the current line isn't the last line of text. + if (cursor.blockNumber() + 1 != this->document()->blockCount()) { + int startpos = 0; + int endpos = 0; + cursor.movePosition(QTextCursor::EndOfBlock); + startpos = cursor.position(); + cursor.movePosition(QTextCursor::NextBlock); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + endpos = cursor.position(); + QString t = cursor.selectedText(); + + cursor.setPosition(startpos); + cursor.setPosition(endpos, QTextCursor::KeepAnchor); + auto com = new InsertTextUndoCommand(cursor, t, this); + m_pUndoStack->push(com); + + cursor.setPosition(startpos); + this->setTextCursor(cursor); + } +} + +void TextEdit::killLine() +{ + if (tryUnsetMark()) { + return; + } + + // Remove selection content if has selection. + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (textCursor().hasSelection()) { + //textCursor().removeSelectedText(); + //deleteSelectTextEx(textCursor()); + deleteSelectTextEx(textCursor(), textCursor().selectedText(), false); + } else { + auto cursor = this->textCursor(); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + + //the right of current line has no text but it is not the end line of this document + if (cursor.selectedText().isEmpty() && cursor.blockNumber() + 1 != this->document()->blockCount()) { + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor); + } + + if (!cursor.selectedText().isEmpty()) { + DeleteBackCommand *com = new DeleteBackCommand(cursor, this); + m_pUndoStack->push(com); + } + } +} + +void TextEdit::killCurrentLine() +{ + if (tryUnsetMark()) { + return; + } + + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + auto cursor = this->textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + if (cursor.blockNumber() + 1 != this->document()->blockCount()) { + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor); + } else { + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } + if (!cursor.selectedText().isEmpty()) { + DeleteBackCommand *com = new DeleteBackCommand(cursor, this); + m_pUndoStack->push(com); + } +} + +void TextEdit::killBackwardWord() +{ + tryUnsetMark(); + + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (textCursor().hasSelection()) { + //textCursor().removeSelectedText(); + } else { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + deleteSelectTextEx(cursor); + } +} + +void TextEdit::killForwardWord() +{ + tryUnsetMark(); + + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (textCursor().hasSelection()) { + //textCursor().removeSelectedText(); + } else { + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); + deleteSelectTextEx(cursor); + } +} + +void TextEdit::indentText() +{ + auto cursor = this->textCursor(); + if (cursor.hasSelection()) { + //calculate the start postion and the end postion of current selection. + int pos1 = cursor.position(); + int pos2 = cursor.anchor(); + if (pos1 > pos2) + std::swap(pos1, pos2); + + //calculate the start line and end line of current selection. + cursor.setPosition(pos1); + int line1 = cursor.blockNumber(); + cursor.setPosition(pos2); + int line2 = cursor.blockNumber(); + + //do the indent operation + auto com = new IndentTextCommand(this, pos1, pos2, line1, line2); + m_pUndoStack->push(com); + } +} + +void TextEdit::unindentText() +{ + QTextCursor cursor = this->textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock); + int pos = cursor.position(); + cursor.setPosition(cursor.position() + 1, QTextCursor::KeepAnchor); + + //the text in front of current line is '\t'. + if ("\t" == cursor.selectedText()) { + DeleteBackCommand *com = new DeleteBackCommand(cursor, this); + m_pUndoStack->push(com); + } + //the text in front of current line is ' '. + else if (" " == cursor.selectedText()) { + int startpos = pos; + int cnt = 0; + // calculate the number of ' '. + while (document()->characterAt(pos) == ' ' && cnt < m_tabSpaceNumber) { + pos++; + cnt++; + } + cursor.setPosition(startpos); + cursor.setPosition(pos, QTextCursor::KeepAnchor); + DeleteBackCommand *com = new DeleteBackCommand(cursor, this); + m_pUndoStack->push(com); + + } + +} + +void TextEdit::setTabSpaceNumber(int number) +{ + m_tabSpaceNumber = number; + updateFont(); + //updateLineNumber(); + updateLeftAreaWidget(); +} + +void TextEdit::upcaseWord() +{ + tryUnsetMark(); + convertWordCase(UPPER); +} + +void TextEdit::downcaseWord() +{ + tryUnsetMark(); + convertWordCase(LOWER); +} + +void TextEdit::capitalizeWord() +{ + tryUnsetMark(); + + convertWordCase(CAPITALIZE); +} + +void TextEdit::transposeChar() +{ + QTextCursor cursor = this->textCursor(); + int pos = cursor.position(); + cursor.setPosition(pos + 1, QTextCursor::KeepAnchor); + QString r = cursor.selectedText(); + cursor.setPosition(pos - 1); + cursor.setPosition(pos, QTextCursor::KeepAnchor); + QString l = cursor.selectedText(); + + if (!l.isEmpty() && !r.isEmpty()) { + cursor.setPosition(pos - 1); + cursor.setPosition(pos + 1, QTextCursor::KeepAnchor); + auto com = new InsertTextUndoCommand(cursor, r + l, this); + m_pUndoStack->push(com); + ensureCursorVisible(); + } +} + +void TextEdit::handleCursorMarkChanged(bool mark, QTextCursor cursor) +{ + if (mark) { + m_markStartLine = cursor.blockNumber() + 1; + } else { + m_markStartLine = -1; + } + + m_pLeftAreaWidget->m_pLineNumberArea->update(); + m_pLeftAreaWidget->m_pBookMarkArea->update(); +} + +void TextEdit::slotValueChanged(int iValue) +{ + Q_UNUSED(iValue); + if (m_isSelectAll) { + this->selectTextInView(); + } + + this->updateLeftAreaWidget(); +} + +void TextEdit::convertWordCase(ConvertCase convertCase) +{ +#if 0 + if (textCursor().hasSelection()) { + QString text = textCursor().selectedText(); + + if (convertCase == UPPER) { + textCursor().insertText(text.toUpper()); + } else if (convertCase == LOWER) { + textCursor().insertText(text.toLower()); + } else { + textCursor().insertText(capitalizeText(text)); + } + } else { + QTextCursor cursor; + + // Move cursor to mouse position first. if have word under mouse pointer. + if (m_haveWordUnderCursor) { + setTextCursor(m_wordUnderPointerCursor); + } + + cursor = textCursor(); + cursor.movePosition(QTextCursor::NoMove, QTextCursor::MoveAnchor); + cursor.setPosition(getNextWordPosition(cursor, QTextCursor::KeepAnchor), QTextCursor::KeepAnchor); + + QString text = cursor.selectedText(); + if (convertCase == UPPER) { + cursor.insertText(text.toUpper()); + } else if (convertCase == LOWER) { + cursor.insertText(text.toLower()); + } else { + cursor.insertText(capitalizeText(text)); + } + + setTextCursor(cursor); + + m_haveWordUnderCursor = false; + } +#endif + + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (textCursor().hasSelection()) { + QString text = textCursor().selectedText(); + if (convertCase == UPPER) { + text = text.toUpper(); + } else if (convertCase == LOWER) { + text = text.toLower(); + } else { + text = capitalizeText(text); + } + + // 如果没有实际文本更改效果,不进行文本替换操作 + if (text != textCursor().selectedText()) { + InsertTextUndoCommand *insertCommand = new InsertTextUndoCommand(textCursor(), text, this); + m_pUndoStack->push(insertCommand); + } + } else { + QTextCursor cursor; + + // Move cursor to mouse position first. if have word under mouse pointer. + if (m_haveWordUnderCursor) { + setTextCursor(m_wordUnderPointerCursor); + } + + cursor = textCursor(); + cursor.movePosition(QTextCursor::NoMove, QTextCursor::MoveAnchor); + cursor.setPosition(getNextWordPosition(cursor, QTextCursor::KeepAnchor), QTextCursor::KeepAnchor); + + QString text = cursor.selectedText(); + if (!text.isEmpty()) { + if (convertCase == UPPER) { + text = text.toUpper(); + } else if (convertCase == LOWER) { + text = text.toLower(); + } else { + text = capitalizeText(text); + } + + InsertTextUndoCommand *insertCommand = new InsertTextUndoCommand(cursor, text, this); + m_pUndoStack->push(insertCommand); + + setTextCursor(cursor); + + m_haveWordUnderCursor = false; + } + } +} + +QString TextEdit::capitalizeText(QString text) +{ + QString newText = text.toLower(); + QChar currentChar; + QChar nextChar; + if (!newText.at(0).isSpace()) { + newText.replace(0, 1, newText.at(0).toUpper()); + } + + for (int i = 0; i < newText.size(); i++) { + currentChar = newText.at(i); + if (i + 1 < newText.size()) + nextChar = newText.at(i + 1); + if (currentChar.isSpace() && !nextChar.isSpace()) { + newText.replace(i + 1, 1, nextChar.toUpper()); + } + } + + return newText; +} + +void TextEdit::keepCurrentLineAtCenter() +{ + QScrollBar *scrollbar = verticalScrollBar(); + + int currentLine = cursorRect().top() / cursorRect().height(); + int halfEditorLines = rect().height() / 2 / cursorRect().height(); + scrollbar->setValue(scrollbar->value() + currentLine - halfEditorLines); +} + +void TextEdit::scrollToLine(int scrollOffset, int row, int column) +{ + // Save cursor postion. + m_restoreRow = row; + m_restoreColumn = column; + + // Start scroll animation. + m_scrollAnimation->setStartValue(verticalScrollBar()->value()); + m_scrollAnimation->setEndValue(scrollOffset); + m_scrollAnimation->start(); +} + +void TextEdit::setLineWrapMode(bool enable) +{ + QTextCursor cursor = textCursor(); + int nJumpLine = textCursor().blockNumber() + 1; + this->setWordWrapMode(QTextOption::WrapAnywhere); + QPlainTextEdit::setLineWrapMode(enable ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap); + m_pLeftAreaWidget->m_pLineNumberArea->update(); + m_pLeftAreaWidget->m_pFlodArea->update(); + m_pLeftAreaWidget->m_pBookMarkArea->update(); + + jumpToLine(nJumpLine, false); + setTextCursor(cursor); +} + +void TextEdit::setFontFamily(QString name) +{ + // Update font. + m_fontName = name; + updateFont(); + updateLeftAreaWidget(); +} + +void TextEdit::setFontSize(qreal size) +{ + // Update font. + m_fontSize = size; + updateFont(); + + // Update line number after adjust font size. + updateLeftAreaWidget(); +} + +void TextEdit::updateFont() +{ + QFont font = document()->defaultFont(); + font.setFixedPitch(true); + font.setPointSizeF(m_fontSize); + font.setFamily(m_fontName); + setFont(font); + setTabStopWidth(m_tabSpaceNumber * QFontMetrics(font).width(QChar(0x2192))); + + if (m_isSelectAll) { + selectTextInView(); + } +} + +void TextEdit::replaceAll(const QString &replaceText, const QString &withText) +{ + if (m_readOnlyMode || m_bReadOnlyPermission) { + return; + } + + if (replaceText.isEmpty()) { + return; + } + + // 替换文本相同,返回 + if (replaceText == withText) { + return; + } + + QTextDocument::FindFlags flags; + flags &= QTextDocument::FindCaseSensitively; + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Start); + QTextCursor startCursor = textCursor(); + + QString oldText = this->toPlainText(); + + // 保存旧的标记索引光标记录信息,只需要更新其坐标偏移信息即可 + QList backupMarkList = convertMarkToReplace(m_markOperations); + auto replaceList = backupMarkList; + // 计算替换颜色标记信息 + calcMarkReplaceList(replaceList, oldText, replaceText, withText); + + QString newText = oldText; + newText.replace(replaceText, withText); + + if (oldText != newText) { + ChangeMarkCommand *pChangeMark = new ChangeMarkCommand(this, backupMarkList, replaceList); + // 设置替换撤销项为颜色标记变更撤销项的子项 + new ReplaceAllCommand(oldText, newText, cursor, pChangeMark); + m_pUndoStack->push(pChangeMark); + } +} + +void TextEdit::replaceNext(const QString &replaceText, const QString &withText) +{ + if (m_readOnlyMode || m_bReadOnlyPermission) { + return; + } + + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (replaceText.isEmpty() || !m_findHighlightSelection.cursor.hasSelection()) { + //无限替换的根源 + return; + } + + QTextCursor cursor = textCursor(); + + if (m_cursorStart != -1) { + cursor.setPosition(m_cursorStart); + m_cursorStart = -1; + } else { + cursor.setPosition(m_findHighlightSelection.cursor.selectionStart()); + } + cursor.movePosition(QTextCursor::NoMove, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, replaceText.size()); + + // 文本替换长度变更调整量 + int adjustlen = withText.size() - replaceText.size(); + // 保存旧的标记索引光标记录信息,只需要更新其坐标偏移信息即可 + QList backupMarkList = convertMarkToReplace(m_markOperations); + auto replaceList = backupMarkList; + for (auto &info : replaceList) { + if (MarkAll == info.opt.type + || MarkAllMatch == info.opt.type) { + continue; + } + + // 获取替换文本区域和颜色标记区域的交叉关系 + Utils::RegionIntersectType type = Utils::checkRegionIntersect( + cursor.selectionStart(), cursor.selectionStart() + replaceText.size(), info.start, info.end); + // 仅进行单次处理 + switch (type) { + case Utils::ELeft: + // 当前无交集,颜色标记在替换文本左侧,表示当前颜色标记已经经过 + break; + case Utils::ERight: { + // 颜色标记位于右侧 + info.start += adjustlen; + info.end += adjustlen; + break; + } + case Utils::EIntersectLeft: { + // 交集在替换文本左侧,拓展颜色标记右侧到替换文本右侧 + info.end = cursor.selectionStart() + withText.size(); + break; + } + case Utils::EIntersectRight: { + // 交集在替换文本右侧,拓展颜色标记左侧到替换文本左侧 + info.start = cursor.selectionStart(); + info.end += adjustlen; + break; + } + case Utils::EIntersectOutter: { + // 标记内容包含替换文本 + info.end += adjustlen; + break; + } + case Utils::EIntersectInner: { + // 替换文本内容包含标记信息, 取消当前文本标记(无论单个文本还是单行文本,均移除) + // 在 manualUpdateAllMark() 函数处理会移除此标记 + info.start = 0; + info.end = 0; + break; + } + default: + break; + } + } + + QString strSelection(cursor.selectedText()); + if (!strSelection.compare(replaceText) || replaceText.contains("\n")) { + ChangeMarkCommand *pChangeMark = new ChangeMarkCommand(this, backupMarkList, replaceList); + // 设置插入撤销项为颜色标记变更撤销项的子项 + new InsertTextUndoCommand(cursor, withText, this, pChangeMark); + m_pUndoStack->push(pChangeMark); + ensureCursorVisible(); + } + + // Update cursor. + setTextCursor(cursor); + highlightKeyword(replaceText, getPosition()); +} + +void TextEdit::replaceRest(const QString &replaceText, const QString &withText) +{ + if (m_readOnlyMode || m_bReadOnlyPermission) { + return; + } + + // If replace text is nothing, don't do replace action. + if (replaceText.isEmpty()) { + return; + } + + // 替换文本相同,返回 + if (replaceText == withText) { + return; + } + + QTextDocument::FindFlags flags; + flags &= QTextDocument::FindCaseSensitively; + + QTextCursor cursor = textCursor(); + QTextCursor startCursor = textCursor(); + startCursor.beginEditBlock(); + + int pos = cursor.position(); + QString oldText = this->toPlainText(); + QString newText = oldText.left(pos); + QString right = oldText.right(oldText.size() - pos); + + // 保存旧的标记索引光标记录信息,只需要更新其坐标偏移信息即可 + QList backupMarkList = convertMarkToReplace(m_markOperations); + auto replaceList = backupMarkList; + // 计算替换颜色标记信息 + calcMarkReplaceList(replaceList, right, replaceText, withText, pos); + + right.replace(replaceText, withText); + newText += right; + + if (oldText != newText) { + ChangeMarkCommand *pChangeMark = new ChangeMarkCommand(this, backupMarkList, replaceList); + // 设置替换撤销项为颜色标记变更撤销项的子项 + new ReplaceAllCommand(oldText, newText, cursor, pChangeMark); + m_pUndoStack->push(pChangeMark); + } + + startCursor.endEditBlock(); + setTextCursor(startCursor); +} + +void TextEdit::beforeReplace(const QString &strReplaceText) +{ + if (strReplaceText.isEmpty() || !m_findHighlightSelection.cursor.hasSelection()) { + highlightKeyword(strReplaceText, getPosition()); + } +} + +bool TextEdit::findKeywordForward(const QString &keyword) +{ + if (textCursor().hasSelection()) { + // Get selection bound. + int startPos = textCursor().anchor(); + int endPos = textCursor().position(); + + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + //setTextCursor(cursor); + + QTextDocument::FindFlags options; + options &= QTextDocument::FindCaseSensitively; + + bool foundOne = find(keyword, options); + + cursor.setPosition(endPos, QTextCursor::MoveAnchor); + cursor.setPosition(startPos, QTextCursor::KeepAnchor); + //setTextCursor(cursor); + + return foundOne; + } else { + QTextCursor recordCursor = textCursor(); + + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + //setTextCursor(cursor); + + QTextDocument::FindFlags options; + options &= QTextDocument::FindCaseSensitively; + + bool foundOne = find(keyword, options); + + //setTextCursor(recordCursor); + + return foundOne; + } +} + +void TextEdit::removeKeywords() +{ + m_findHighlightSelection.cursor = textCursor(); + m_findHighlightSelection.cursor.clearSelection(); + + m_findMatchSelections.clear(); + + updateHighlightLineSelection(); + + renderAllSelections(); + + //setFocus(); +} + +bool TextEdit::highlightKeyword(QString keyword, int position) +{ + Q_UNUSED(position) + m_findMatchSelections.clear(); + updateHighlightLineSelection(); + updateCursorKeywordSelection(keyword, true); + bool bRet = updateKeywordSelectionsInView(keyword, m_findMatchFormat, &m_findMatchSelections); + renderAllSelections(); + + return bRet; +} + +bool TextEdit::highlightKeywordInView(QString keyword) +{ + m_findMatchSelections.clear(); + bool bRet = updateKeywordSelectionsInView(keyword, m_findMatchFormat, &m_findMatchSelections); + // 直接设置 setExtraSelections 会导致无法显示颜色标记,调用 renderAllSelections 进行显示更新 + // setExtraSelections(m_findMatchSelections); + renderAllSelections(); + + return bRet; +} + +void TextEdit::clearFindMatchSelections() +{ + m_findMatchSelections.clear(); +} + +void TextEdit::updateCursorKeywordSelection(QString keyword, bool findNext) +{ + bool findOne = searchKeywordSeletion(keyword, textCursor(), findNext); + + if (!findOne) { + QTextCursor cursor = textCursor(); + cursor.movePosition(findNext ? QTextCursor::Start : QTextCursor::End, QTextCursor::MoveAnchor); + if (!searchKeywordSeletion(keyword, cursor, findNext)) { + m_findHighlightSelection.cursor = textCursor(); + m_findMatchSelections.clear(); + renderAllSelections(); + } + } +} + +void TextEdit::updateHighlightLineSelection() +{ + if (m_gestureAction == GA_slide) { + QTextCursor textCursor = QPlainTextEdit::textCursor(); + return; + } + + QTextEdit::ExtraSelection selection; + + selection.format.setBackground(m_currentLineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + m_currentLineSelection = selection; +} + +bool TextEdit::updateKeywordSelections(QString keyword, QTextCharFormat charFormat, QList &listSelection) +{ + // Clear keyword selections first. + listSelection.clear(); + + // Update selections with keyword. + if (!keyword.isEmpty()) { + QTextCursor cursor(document()); + QTextDocument::FindFlags flags; + //flags &= QTextDocument::FindCaseSensitively; + QTextEdit::ExtraSelection extra; + extra.format = charFormat; + cursor = document()->find(keyword, cursor, flags); + + if (cursor.isNull()) { + return false; + } + + while (!cursor.isNull()) { + extra.cursor = cursor; + listSelection.append(extra); + cursor = document()->find(keyword, cursor, flags); + } + + return true; + } + + return false; +} + +bool TextEdit::updateKeywordSelectionsInView(QString keyword, QTextCharFormat charFormat, QList *listSelection) +{ + // Clear keyword selections first. + listSelection->clear(); + + // Update selections with keyword. + if (!keyword.isEmpty()) { + QTextCursor cursor(document()); + QTextEdit::ExtraSelection extra; + extra.format = charFormat; + + QScrollBar *pScrollBar = verticalScrollBar(); + QPoint startPoint = QPointF(0, 0).toPoint(); + QTextBlock beginBlock = cursorForPosition(startPoint).block(); + int beginPos = beginBlock.position(); + QTextBlock endBlock; + + if (pScrollBar->maximum() > 0) { + QPoint endPoint = QPointF(0, 1.5 * height()).toPoint(); + endBlock = cursorForPosition(endPoint).block(); + } else { + endBlock = document()->lastBlock(); + } + int endPos = endBlock.position() + endBlock.length() - 1; + + // 内部计算时,均视为 \n 结尾 + QLatin1Char endLine('\n'); + QString multiLineText; + if (keyword.contains(endLine)) { + auto temp = this->textCursor(); + temp.setPosition(beginPos); + while (temp.position() < endPos) { + temp.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + multiLineText += temp.selectedText(); + multiLineText += endLine; + temp.setPosition(temp.position() + 1); + } + cursor = findCursor(keyword, multiLineText, 0, false, beginPos); + } else { + cursor = document()->find(keyword, beginPos); + } + + if (cursor.isNull()) { + return false; + } + + while (!cursor.isNull()) { + extra.cursor = cursor; + /* 查找字符时,查找到完全相等的时候才高亮,如查找小写f时,大写的F不高亮 */ + if (!extra.cursor.selectedText().compare(keyword) || keyword.contains(endLine)) { + listSelection->append(extra); + } + + if (keyword.contains(endLine)) { + int pos = std::max(extra.cursor.position(), extra.cursor.anchor()); + cursor = findCursor(keyword, multiLineText, pos - beginPos, false, beginPos); + } else { + cursor = document()->find(keyword, cursor); + } + + if (cursor.position() > endPos) { + break; + } + } + + return true; + } + + return false; +} + +bool TextEdit::searchKeywordSeletion(QString keyword, QTextCursor cursor, bool findNext) +{ + if (keyword.isEmpty()) { + return false; + } + + bool ret = false; + int offsetLines = 3; + + if (findNext) { + QTextCursor next = document()->find(keyword, cursor, QTextDocument::FindCaseSensitively); + if (keyword.contains("\n")) { + int pos = std::max(cursor.position(), cursor.anchor()); + next = findCursor(keyword, this->toPlainText(), pos); + } + if (!next.isNull()) { + m_findHighlightSelection.cursor = next; + jumpToLine(next.blockNumber() + offsetLines, false); + setTextCursor(next); + ret = true; + } + } else { + QTextCursor prev = document()->find(keyword, cursor, QTextDocument::FindBackward | QTextDocument::FindCaseSensitively); + if (keyword.contains("\n")) { + int pos = std::min(cursor.position(), cursor.anchor()); + prev = findCursor(keyword, this->toPlainText().mid(0, pos), -1, true); + } + if (!prev.isNull()) { + m_findHighlightSelection.cursor = prev; + jumpToLine(prev.blockNumber() + offsetLines, false); + setTextCursor(prev); + ret = true; + } + } + + return ret; +} + +void TextEdit::renderAllSelections() +{ + QList finalSelections; + QList> selectionsSortList; + + // 标记当前行的浅灰色 + if (m_HightlightYes) { + finalSelections.append(m_currentLineSelection); + } + // 此处代码无作用,去除 + // else { + // selections.clear(); + // } + + // 按代码逻辑,推测m_markAllSelection 用于还原所有文本的背景颜色, 实际不需要 + // 考虑到各平台运行之间可能存在运行差异,暂不清除 + // finalSelections.append(m_markAllSelection); + + // 选中区域的颜色标记,先加入 selectionsSortList + // 通过时间戳升序排序后,加入到 finalSelections 中 + selectionsSortList.append(m_wordMarkSelections); + + // Find 和 Replace 高亮选中,移动到最后放入到 finalSelections 中 + // 保证此高亮状态,若存在,一定可以被用户看到 + // selections.append(m_findMatchSelections); + // selections.append(m_findHighlightSelection); + + // 不再使用,注释掉 + // selections.append(m_wordUnderCursorSelection); + + // 标记括号移动到处理完颜色标记后,插入到 finalSelections 中 + // selections.append(m_beginBracketSelection); + // selections.append(m_endBracketSelection); + + // 仅对代码文件有效,标记代码中的代码段,例如函数内{}所有内容 + // 移动到处理完颜色标记后,插入到 finalSelections 中,插入晚于括号 + // selections.append(m_markFoldHighLightSelections); + + // Alt选中区域的高亮, 移动到排序后面加入 + // selections.append(m_altModSelections); + + // 将颜色标记,标记所有的 selections 加入到 selectionsSortList 中, 后边将进行排序 + QMap>>::Iterator it; + for (it = m_mapKeywordMarkSelections.begin(); it != m_mapKeywordMarkSelections.end(); ++it) { + selectionsSortList.append(it.value()); + } + + // 通过时间戳重新排序颜色标记功能的 selections + qSort(selectionsSortList.begin(), selectionsSortList.end(), [](const QPair &A, const QPair &B) { + return (A.second < B.second); + }); + + // 将排序后的颜色标记 selections 加入到 finalSelections 中 + for (int i = 0; i < selectionsSortList.size(); i++) { + finalSelections.append(selectionsSortList.at(i).first); + } + + // 标记括号 + finalSelections.append(m_beginBracketSelection); + finalSelections.append(m_endBracketSelection); + + // 标记代码段 + finalSelections.append(m_markFoldHighLightSelections); + + // Alt选中区域的高亮 + finalSelections.append(m_altModSelections); + + // 查找替换的高亮需要放在最后 + // Find 高亮 + finalSelections.append(m_findMatchSelections); + // Replace 高亮 + finalSelections.append(m_findHighlightSelection); + + // 设置到 QPlainText 中进行渲染 + setExtraSelections(finalSelections); +} + +void TextEdit::updateMarkAllSelectColor() +{ + isMarkAllLine(m_bIsMarkAllLine, m_strMarkAllLineColorName); + renderAllSelections(); +} + +DMenu *TextEdit::getHighlightMenu() +{ + return m_hlGroupMenu; +} + +void TextEdit::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + QPainter painter(m_pLeftAreaWidget->m_pLineNumberArea); + QColor lineNumberAreaBackgroundColor; + + if (DApplicationHelper::instance()->themeType() == DApplicationHelper::ColorType::DarkType) { + lineNumberAreaBackgroundColor = palette().brightText().color(); + lineNumberAreaBackgroundColor.setAlphaF(0.06); + + m_lineNumbersColor.setAlphaF(0.2); + } else { + lineNumberAreaBackgroundColor = palette().brightText().color(); + lineNumberAreaBackgroundColor.setAlphaF(0.03); + m_lineNumbersColor.setAlphaF(0.3); + } + //painter.fillRect(event->rect(), lineNumberAreaBackgroundColor); + + int blockNumber = getFirstVisibleBlockId(); + QTextBlock block = document()->findBlockByNumber(blockNumber); + + int top = this->viewport()->geometry().top() + verticalScrollBar()->value(); + int bottom = top + static_cast(document()->documentLayout()->blockBoundingRect(block).height()); + + Utils::setFontSize(painter, document()->defaultFont().pointSize() - 2); + QPoint endPoint; + + if (verticalScrollBar()->maximum() > 0) { + endPoint = QPointF(0, height() + height() / verticalScrollBar()->maximum() * verticalScrollBar()->value()).toPoint(); + } + + QTextCursor cur = cursorForPosition(endPoint); + QTextBlock endBlock = cur.block(); + int nPageLine = endBlock.blockNumber(); + int nStartLine = block.blockNumber(); + + if (verticalScrollBar()->maximum() == 0) { + nPageLine = blockCount() - 1; + } + + auto currentCursor = this->textCursor(); + cur = textCursor(); + for (int i = nStartLine; i <= nPageLine; i++) { + if (i + 1 == m_markStartLine) { + painter.setPen(m_regionMarkerColor); + } else { + painter.setPen(m_lineNumbersColor); + } + + m_fontLineNumberArea.setPointSize(font().pointSize() - 1); + painter.setFont(m_fontLineNumberArea); + + cur.setPosition(block.position(), QTextCursor::MoveAnchor); + + if (block.isVisible()) { + int w = this->m_fontSize <= 15 ? 15 : m_fontSize; + updateLeftWidgetWidth(w); + int offset = 0; + //the language currently set by the system is Tibetan. + if ("bo_CN" == Utils::getSystemLan()) { + offset = 2; + } + if (cur.blockNumber() == currentCursor.blockNumber()) { + painter.setPen(qApp->palette().highlight().color()); + } + painter.drawText(0, cursorRect(cur).y() + offset, + m_pLeftAreaWidget->m_pLineNumberArea->width(), cursorRect(cur).height(), + Qt::AlignVCenter | Qt::AlignHCenter, QString::number(block.blockNumber() + 1)); + } + + block = block.next(); + top = bottom/* + document()->documentMargin()*/; + bottom = top + static_cast(document()->documentLayout()->blockBoundingRect(block).height()); + } +} + +void TextEdit::codeFLodAreaPaintEvent(QPaintEvent *event) +{ + m_listFlodIconPos.clear(); + QPainter painter(m_pLeftAreaWidget->m_pFlodArea); + + QColor codeFlodAreaBackgroundColor; + if (DApplicationHelper::instance()->themeType() == DApplicationHelper::ColorType::DarkType) { + codeFlodAreaBackgroundColor = palette().brightText().color(); + codeFlodAreaBackgroundColor.setAlphaF(0.06); + + m_lineNumbersColor.setAlphaF(0.2); + } else { + codeFlodAreaBackgroundColor = palette().brightText().color(); + codeFlodAreaBackgroundColor.setAlphaF(0.03); + m_lineNumbersColor.setAlphaF(0.3); + } + + int blockNumber = getFirstVisibleBlockId(); + QTextBlock block = document()->findBlockByNumber(blockNumber); + + DGuiApplicationHelper *guiAppHelp = DGuiApplicationHelper::instance(); + QString theme = ""; + + if (guiAppHelp->themeType() == DGuiApplicationHelper::ColorType::DarkType) { //暗色主题 + theme = "d"; + } else { //浅色主题 + theme = "l"; + } + + // QString flodImagePath = QString(":/images/d-%1.svg").arg(theme); + //QString unflodImagePath = QString(":/images/u-%1.svg").arg(theme); + + QPoint endPoint; + + if (verticalScrollBar()->maximum() > 0) { + endPoint = QPointF(0, height() + height() / verticalScrollBar()->maximum() * verticalScrollBar()->value()).toPoint(); + } + + QTextCursor cur = cursorForPosition(endPoint); + QTextBlock endBlock = cur.block(); + int nPageLine = endBlock.blockNumber(); + + if (verticalScrollBar()->maximum() == 0) { + nPageLine = blockCount() - 1; + } + + cur = textCursor(); + + for (int iBlockCount = blockNumber ; iBlockCount <= nPageLine; ++iBlockCount) { + if (block.isVisible()) { + //判定是否包含注释代码左括号、是否整行是注释,isNeedShowFoldIcon该函数是为了做判定当前行是否包含成对的括号,如果包括,则不显示折叠标志 + + //获取行数文本块 出去字符串判断 梁卫东2020年09月01日17:16:17 + QString text = block.text(); + //若存在字符串行,多个字符串中间的 '{' '}' 同样被忽略 + QRegExp regExp("\".*\""); + QString curText = text.remove(regExp); + + //不同类型文件注释符号不同 梁卫东 2020-09-03 17:28:45 + bool bHasCommnent = false; + QString multiLineCommentMark; + QString singleLineCommentMark; + + if (m_commentDefinition.isValid()) { + multiLineCommentMark = m_commentDefinition.multiLineStart.trimmed(); + singleLineCommentMark = m_commentDefinition.singleLine.trimmed(); + //判断是否包含单行或多行注释 + if (!multiLineCommentMark.isEmpty()) bHasCommnent = block.text().trimmed().startsWith(multiLineCommentMark); + if (!singleLineCommentMark.isEmpty()) bHasCommnent = block.text().trimmed().startsWith(singleLineCommentMark); + } else { + bHasCommnent = false; + } + + //添加注释判断 存在不显示折叠标志 不存在显示折叠标准 梁卫东 2020年09月03日17:28:50 + if (curText.contains("{") && isNeedShowFoldIcon(block) && !bHasCommnent) { + + cur.setPosition(block.position(), QTextCursor::MoveAnchor); + + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHints(QPainter::SmoothPixmapTransform); + + int w = this->m_fontSize <= 15 ? 15 : m_fontSize; + updateLeftWidgetWidth(w); + int h = cursorRect(cur).height(); + // 绘制行纵向居中 + int offset = qMax(0, (h - w) / 2); + //the language currently set by the system is Tibetan. + if ("bo_CN" == Utils::getSystemLan()) + offset = h <= 20 ? 0 : h / 10; + + QRect rect(0, cursorRect(cur).y() + offset, w, w); + if (block.next().isVisible()) { + if (block.isVisible()) { + paintCodeFlod(&painter, rect); + } + } else { + if (block.isVisible()) { + paintCodeFlod(&painter, rect, true); + } + } + m_listFlodIconPos.append(block.blockNumber()); + } + } + + block = block.next(); + } +} + +void TextEdit::setBookmarkFlagVisable(bool isVisable, bool bIsFirstOpen) +{ + int w = this->m_fontSize <= 15 ? 15 : m_fontSize; + updateLeftWidgetWidth(w); + + m_pIsShowBookmarkArea = isVisable; + m_pLeftAreaWidget->m_pBookMarkArea->setVisible(isVisable); +} + +void TextEdit::setCodeFlodFlagVisable(bool isVisable, bool bIsFirstOpen) +{ + int w = this->m_fontSize <= 15 ? 15 : m_fontSize; + updateLeftWidgetWidth(w); + + m_pIsShowCodeFoldArea = isVisable; + m_pLeftAreaWidget->m_pFlodArea->setVisible(isVisable); +} + +void TextEdit::setHighLineCurrentLine(bool ok) +{ + m_HightlightYes = ok; + renderAllSelections(); +} + +void TextEdit::updateLeftAreaWidget() +{ +#if 0 +// not used anymore + int blockSize = QString::number(blockCount()).size(); + int leftAreaWidth = 0; + + //跟新左边框宽度 + if (m_pIsShowBookmarkArea) { + leftAreaWidth += m_pLeftAreaWidget->m_pBookMarkArea->width(); + } + if (m_pIsShowCodeFoldArea) { + leftAreaWidth += m_pLeftAreaWidget->m_pFlodArea->width(); + } + + if (bIsSetLineNumberWidth) { + leftAreaWidth += blockSize * fontMetrics().width('9') + 5; + } + // m_pLeftAreaWidget->setFixedWidth(leftAreaWidth); +#endif + m_pLeftAreaWidget->updateAll(); +} + + +void TextEdit::handleScrollFinish() +{ + // Restore cursor postion. + jumpToLine(m_restoreRow, false); + + QTextCursor cursor = textCursor(); + cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, m_restoreColumn); + + // Update cursor. + setTextCursor(cursor); +} + +void TextEdit::setSyntaxDefinition(KSyntaxHighlighting::Definition def) +{ + m_commentDefinition.setComments(def.singleLineCommentMarker(), def.multiLineCommentMarker().first, def.multiLineCommentMarker().second); +} + +bool TextEdit::setCursorKeywordSeletoin(int position, bool findNext) +{ + int offsetLines = 3; + + if (findNext) { + for (int i = 0; i < m_findMatchSelections.size(); i++) { + if (m_findMatchSelections[i].cursor.position() > position) { + m_findHighlightSelection.cursor = m_findMatchSelections[i].cursor; + + jumpToLine(m_findMatchSelections[i].cursor.blockNumber() + offsetLines, false); + + QTextCursor cursor = textCursor(); + cursor.setPosition(m_findMatchSelections[i].cursor.position()); + + // Update cursor. + setTextCursor(cursor); + + return true; + } + } + } else { + for (int i = m_findMatchSelections.size() - 1; i >= 0; i--) { + if (m_findMatchSelections[i].cursor.position() < position) { + m_findHighlightSelection.cursor = m_findMatchSelections[i].cursor; + + jumpToLine(m_findMatchSelections[i].cursor.blockNumber() + offsetLines, false); + + QTextCursor cursor = textCursor(); + cursor.setPosition(m_findMatchSelections[i].cursor.position()); + + // Update cursor. + setTextCursor(cursor); + return true; + } + } + } + + return false; +} + +void TextEdit::cursorPositionChanged() +{ + // 以赋值形式,清空 Bracket 括号的selection + // m_beginBracketSelection 和 m_endBracketSelection 将在 updateHighlightBrackets 重新设置 + m_beginBracketSelection = QTextEdit::ExtraSelection(); + m_endBracketSelection = QTextEdit::ExtraSelection(); + + updateHighlightLineSelection(); + updateHighlightBrackets('(', ')'); + updateHighlightBrackets('{', '}'); + updateHighlightBrackets('[', ']'); + renderAllSelections(); + + QTextCursor cursor = textCursor(); + if (m_wrapper) { + m_wrapper->bottomBar()->updatePosition(cursor.blockNumber() + 1, + cursor.positionInBlock() + 1); + } + + m_pLeftAreaWidget->m_pLineNumberArea->update(); + m_pLeftAreaWidget->m_pBookMarkArea->update(); + m_pLeftAreaWidget->m_pFlodArea->update(); +} + +void TextEdit::cut() +{ + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + //列编辑添加撤销重做 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QString data; + for (auto it = m_altModSelections.begin(); it != m_altModSelections.end(); it++) { + auto text = (*it).cursor.selectedText(); + data += text ; + if (it != m_altModSelections.end() - 1) + data += "\n"; + } + //删除有选择 + for (int i = 0; i < m_altModSelections.size(); i++) { + if (m_altModSelections[i].cursor.hasSelection()) { + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(m_altModSelections[i].cursor, this); + m_pUndoStack->push(pDeleteStack); + } + } + //设置到剪切板 + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + } else { + QTextCursor cursor = textCursor(); + //有选择内容才剪切 + if (cursor.hasSelection()) { + QString data = this->selectedText(true); + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(cursor, this); + m_pUndoStack->push(pDeleteStack); + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + } + } + unsetMark(); +} + +void TextEdit::copy() +{ + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QString data; + for (auto it = m_altModSelections.begin(); it != m_altModSelections.end(); it++) { + auto text = (*it).cursor.selectedText(); + data += text ; + if (it != m_altModSelections.end() - 1) + data += "\n"; + } + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + tryUnsetMark(); + } else { + if (!m_isSelectAll) { + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + if (textCursor().hasSelection()) { + //clipboard->setText(textCursor().selection().toPlainText()); + clipboard->setText(this->selectedText(true)); + tryUnsetMark(); + } else { + clipboard->setText(m_highlightWordCacheCursor.selectedText()); + } + } else { + QClipboard *clipboard = QApplication::clipboard(); + QString text = this->toPlainText(); + clipboard->setText(text); + } + } +} + +void TextEdit::paste() +{ +#if 0 + //2021-05-25:为解决大文本粘贴卡顿而注释重写 + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + const QClipboard *clipboard = QApplication::clipboard(); //获取剪切版内容 + auto text = clipboard->text(); + if (text.isEmpty()) + return; + if (!m_bIsAltMod) { + QTextCursor cursor = textCursor(); + insertSelectTextEx(cursor, text); + unsetMark(); + } else { + insertColumnEditTextEx(text); + } + +#endif + + + //大文件粘贴-采用分块插入 + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + const QClipboard *clipboard = QApplication::clipboard(); //获取剪切版内容 + auto text = clipboard->text(); + + if (text.isEmpty()) + return; + if (!m_bIsAltMod) { + int block = 1 * 1024 * 1024; + int size = text.size(); + if (size > block) { + InsertBlockByTextCommand *commond = new InsertBlockByTextCommand(text, this, m_wrapper); + m_pUndoStack->push(commond); + } else { + QTextCursor cursor = textCursor(); + insertSelectTextEx(cursor, text); + unsetMark(); + } + } else { + insertColumnEditTextEx(text); + } + + m_isSelectAll = false; +} + +void TextEdit::highlight() +{ + QTimer::singleShot(0, this, [&]() { + if (nullptr != m_wrapper) + m_wrapper->OnUpdateHighlighter(); + }); +} + +void TextEdit::selectTextInView() +{ + int startPos = cursorForPosition(QPoint(0, 0)).position(); + QPoint endPoint = QPoint(this->viewport()->width(), this->viewport()->height()); + int endPos = cursorForPosition(endPoint).position(); + + QTextCursor cursor = this->textCursor(); + cursor.setPosition(endPos); + cursor.setPosition(startPos, QTextCursor::KeepAnchor); + this->setTextCursor(cursor); + this->horizontalScrollBar()->setValue(0); +} + +void TextEdit::setSelectAll() +{ + if (m_wrapper->getFileLoading()) + return; + + m_bIsAltMod = false; + m_isSelectAll = true; + selectTextInView(); +} + +void TextEdit::slotSigColorSelected(bool bSelected, QColor color) +{ + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + isMarkCurrentLine(bSelected, color.name()); + renderAllSelections(); + m_colorMarkMenu->close(); + m_rightMenu->close(); //选择颜色关闭菜单 梁卫东 2020-08-21 09:34:53 +} + +void TextEdit::slotSigColorAllSelected(bool bSelected, QColor color) +{ + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + isMarkAllLine(bSelected, color.name()); + renderAllSelections(); + m_colorMarkMenu->close(); + m_rightMenu->close(); //选择颜色关闭菜单 梁卫东 2020-08-21 09:34:53 +} + +void TextEdit::slotCutAction(bool checked) +{ + Q_UNUSED(checked); + this->cut(); +} + +void TextEdit::slotCopyAction(bool checked) +{ + Q_UNUSED(checked); + if (isAbleOperation(OperationType::CopyOperation)) { + copy(); + } else { + DMessageManager::instance()->sendMessage(this, QIcon(":/images/warning.svg"), tr("Copy failed: not enough memory")); + } +} + +void TextEdit::slotPasteAction(bool checked) +{ + Q_UNUSED(checked); + if (isAbleOperation(OperationType::PasteOperation)) { + paste(); + } else { + DMessageManager::instance()->sendMessage(this, QIcon(":/images/warning.svg"), tr("Paste failed: not enough memory")); + } +} + +void TextEdit::slotDeleteAction(bool checked) +{ + Q_UNUSED(checked); + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + for (int i = 0; i < m_altModSelections.size(); i++) { + if (m_altModSelections[i].cursor.hasSelection()) { + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(m_altModSelections[i].cursor, this); + m_pUndoStack->push(pDeleteStack); + } + } + } else { + if (textCursor().hasSelection()) { + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(textCursor(), this); + m_pUndoStack->push(pDeleteStack); + } else { + setTextCursor(m_highlightWordCacheCursor); + } + } +} + +void TextEdit::slotSelectAllAction(bool checked) +{ + Q_UNUSED(checked); + setSelectAll(); +} + +bool TextEdit::slotOpenInFileManagerAction(bool checked) +{ + Q_UNUSED(checked); + return DDesktopServices::showFileItem(this->getTruePath()); +} + +void TextEdit::slotAddComment(bool checked) +{ + Q_UNUSED(checked); + toggleComment(true); +} + +void TextEdit::slotCancelComment(bool checked) +{ + Q_UNUSED(checked); + toggleComment(false); +} + +void TextEdit::slotVoiceReadingAction(bool checked) +{ + Q_UNUSED(checked); + QProcess::startDetached("dbus-send --print-reply --dest=com.iflytek.aiassistant /aiassistant/deepinmain com.iflytek.aiassistant.mainWindow.TextToSpeech"); + emit signal_readingPath(); +} + +bool TextEdit::slotStopReadingAction(bool checked) +{ + Q_UNUSED(checked); + return QProcess::startDetached("dbus-send --print-reply --dest=com.iflytek.aiassistant /aiassistant/tts com.iflytek.aiassistant.tts.stopTTSDirectly"); +} + +void TextEdit::slotdictationAction(bool checked) +{ + Q_UNUSED(checked); + QProcess::startDetached("dbus-send --print-reply --dest=com.iflytek.aiassistant /aiassistant/deepinmain com.iflytek.aiassistant.mainWindow.SpeechToText"); +} + +void TextEdit::slotColumnEditAction(bool checked) +{ + Q_UNUSED(checked); + DMessageManager::instance()->sendMessage(this, QIcon(":/images/ok.svg"), tr("Press ALT and click lines to edit in column mode")); +} + +void TextEdit::slotPreBookMarkAction(bool checked) +{ + Q_UNUSED(checked); + int line = getLineFromPoint(m_mouseClickPos); + int index = m_listBookmark.indexOf(line); + + if (index == 0) { + jumpToLine(m_listBookmark.last(), true); + } else { + jumpToLine(m_listBookmark.value(index - 1), true); + } +} + +void TextEdit::slotNextBookMarkAction(bool checked) +{ + Q_UNUSED(checked); + int line = getLineFromPoint(m_mouseClickPos); + int index = m_listBookmark.indexOf(line); + + if (index == -1 && !m_listBookmark.isEmpty()) { + jumpToLine(m_listBookmark.last(), false); + } + + if (index == m_listBookmark.count() - 1) { + jumpToLine(m_listBookmark.first(), false); + } else { + jumpToLine(m_listBookmark.value(index + 1), false); + } +} + +void TextEdit::slotClearBookMarkAction(bool checked) +{ + Q_UNUSED(checked); + m_listBookmark.clear(); + qDebug() << "ClearBookMark:" << m_listBookmark; + m_pLeftAreaWidget->m_pBookMarkArea->update(); +} + +void TextEdit::slotFlodAllLevel(bool checked) +{ + Q_UNUSED(checked); + flodOrUnflodAllLevel(true); +} + +void TextEdit::slotUnflodAllLevel(bool checked) +{ + Q_UNUSED(checked); + flodOrUnflodAllLevel(false); +} + +void TextEdit::slotFlodCurrentLevel(bool checked) +{ + Q_UNUSED(checked); + flodOrUnflodCurrentLevel(true); +} + +void TextEdit::slotUnflodCurrentLevel(bool checked) +{ + Q_UNUSED(checked); + flodOrUnflodCurrentLevel(false); +} + +void TextEdit::slotCancleMarkAllLine(bool checked) +{ + Q_UNUSED(checked); + isMarkAllLine(false); +} + +void TextEdit::slotCancleLastMark(bool checked) +{ + Q_UNUSED(checked); + cancelLastMark(); +} + +void TextEdit::slotUndoAvailable(bool undoIsAvailable) +{ + m_canUndo = undoIsAvailable; +} + +void TextEdit::slotRedoAvailable(bool redoIsAvailable) +{ + m_canRedo = redoIsAvailable; +} + +void TextEdit::redo_() +{ + if (!m_pUndoStack->canRedo()) { + return; + } + + m_pUndoStack->redo(); + if (m_pUndoStack->index() == m_lastSaveIndex) { + this->m_wrapper->window()->updateModifyStatus(m_sFilePath, false); + this->m_wrapper->setTemFile(false); + this->document()->setModified(false); + } + +} +void TextEdit::undo_() +{ + if (!m_pUndoStack->canUndo()) { + return; + } + + m_pUndoStack->undo(); + + // 对撤销栈清空的情况下,有两种文件仍需保留*号(重做无需如下判定) + // 1. 备份文件,上次修改之后直接关闭时备份的文件,仍需要提示保存 + // 2. 临时文件,上次修改后关闭,撤销操作后文件内容不为空 + if (m_pUndoStack->index() == m_lastSaveIndex + && !m_wrapper->isBackupFile() + && !(m_wrapper->isDraftFile() && !m_wrapper->isPlainTextEmpty())) { + this->m_wrapper->window()->updateModifyStatus(m_sFilePath, false); + this->m_wrapper->setTemFile(false); + this->document()->setModified(false); + } +} + +/*! + \brief 从索引位置 \a from 移动文本内容 \a text 到 \a to, 当仅拷贝文本时, + \a copy 置为true. + \param from 移动/拷贝文本位置 + \param to 目的文本位置 + \param text 文本内容 + \param copy 是否为拷贝文本,默认为移动 + */ +void TextEdit::moveText(int from, int to, const QString &text, bool copy) +{ + auto cursor = this->textCursor(); + auto list = new UndoList; + cursor.setPosition(from); + QUndoCommand *delCommand = nullptr; + // 拷贝模式下无需删除文本 + if (!copy) { + cursor.setPosition(from + text.size(), QTextCursor::KeepAnchor); + delCommand = new DeleteBackCommand(cursor, this); + } + + cursor.setPosition(to); + auto insertCommand = new InsertTextUndoCommand(cursor, text, this); + + //the positon of 'from' is on the left of the position of 'to', + //therefore,firstly do the insert operation. + if (from < to) { + list->appendCom(insertCommand); + if (!copy) { + list->appendCom(delCommand); + } + m_pUndoStack->push(list); + } else if (from > to) { + if (!copy) { + list->appendCom(delCommand); + } + list->appendCom(insertCommand); + m_pUndoStack->push(list); + } +} + +/** + * @brief 在text中查找substr,并返回QTextCursor + * @param substr:需要查找的串 + * text:源字符串 + * from:从text的from位置开始查找 + * backword:是否反向查找 + * cursorPos: text起始位置在全文本中的位置 + * @return + */ +QTextCursor TextEdit::findCursor(const QString &substr, const QString &text, int from, bool backward, int cursorPos) +{ + // 处理换行符为 \r\n (光标计算时被视为单个字符)的情况,移除多计算的字符数 + // text 均为 \n 结尾 + QString findSubStr = substr; + if (BottomBar::Windows == m_wrapper->bottomBar()->getEndlineFormat()) { + findSubStr.replace("\r\n", "\n"); + } + + int index = -1; + if (backward) { + index = text.lastIndexOf(findSubStr, from); + } else { + index = text.indexOf(findSubStr, from); + } + if (-1 != index) { + auto cursor = this->textCursor(); + cursor.setPosition(index + cursorPos); + cursor.setPosition(cursor.position() + findSubStr.size(), QTextCursor::KeepAnchor); + return cursor; + } else { + return QTextCursor(); + } +} + +/** + * @brief 点击行号处理:选中当前行,光标置于下一行行首 + * @param + * @return + */ +void TextEdit::onPressedLineNumber(const QPoint &point) +{ + QScrollBar *pScrollBar = verticalScrollBar(); + QPoint startPoint = QPointF(0, 0).toPoint(); + QTextBlock beginBlock = cursorForPosition(startPoint).block(); + QTextBlock endBlock; + if (pScrollBar->maximum() > 0) { + QPoint endPoint = QPointF(0, 1.5 * height()).toPoint(); + endBlock = cursorForPosition(endPoint).block(); + } else { + endBlock = document()->lastBlock(); + } + + int linenumber = -1; + auto cursor = this->textCursor(); + while (beginBlock.position() <= endBlock.position()) { + cursor.setPosition(beginBlock.position(), QTextCursor::MoveAnchor); + int offset = 0; + //the language currently set by the system is Tibetan. + if ("bo_CN" == Utils::getSystemLan()) { + offset = 2; + } + QRect rect(0, cursorRect(cursor).y() + offset, m_pLeftAreaWidget->m_pLineNumberArea->width(), cursorRect(cursor).height()); + if (rect.contains(point)) { + linenumber = beginBlock.blockNumber(); + break; + } + beginBlock = beginBlock.next(); + } + if (-1 != linenumber) { + if (this->document()->lastBlock().blockNumber() == linenumber) { + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } else { + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor); + } + this->setTextCursor(cursor); + } +} + +/** + * @return 返回当前光标选中的内容 + * @note 如果从编辑器获得的选中文本跨越换行符,则文本将包含 Unicode U+2029 段落分隔符而不是换行符 \n 字符。 + * 可使用 QString::replace() 将这些字符替换为换行符,为避免文本原有 Unicode U+2029 分割符影响, + * 手动调整换行符插入位置。 + */ +QString TextEdit::selectedText(bool checkCRLF) +{ + auto cursor = this->textCursor(); + auto temp = cursor; + int startpos = std::min(cursor.anchor(), cursor.position()); + int endpos = std::max(cursor.anchor(), cursor.position()); + int startblock = 0, endblock = 0; + cursor.setPosition(startpos); + startblock = cursor.blockNumber(); + cursor.setPosition(endpos); + endblock = cursor.blockNumber(); + // 仅单个文本块,直接提取文本数据 + if (startblock == endblock) { + return temp.selectedText(); + } + + QString text; + cursor.setPosition(startpos); + // 取得首个文本块内容 + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + text += cursor.selectedText(); + cursor.setPosition(cursor.position() + 1); + + // 不同风格使用不同换行符,默认不替换,仅在剪贴板、保存文件等时设置 + QString endLine = "\n"; + if (checkCRLF && BottomBar::Windows == m_wrapper->bottomBar()->getEndlineFormat()) { + endLine = "\r\n"; + } + + // 获取中间完整文本块内容 + while ((cursor.position() + cursor.block().length()) < endpos) { + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + text += endLine; + text += cursor.selectedText(); + cursor.setPosition(cursor.position() + 1); + } + + // 取得尾部文本块内容 + if (cursor.position() < endpos) { + // 判断是否尾部文本块达到当前文本块末尾,到达末尾需要将 U+2029 替换为 \n + bool needAdjustNewline = bool(cursor.position() + cursor.block().length() == endpos); + cursor.setPosition(endpos, QTextCursor::KeepAnchor); + text += endLine; + text += cursor.selectedText(); + + if (needAdjustNewline && text.endsWith("\u2029")) { + text.replace("\u2029", endLine); + } + } + + return text; +} + +/** + * @brief 行尾符号改变后处理函数; + * 1.这里并没有做"\n"和"\r\n"之间的替换,实际的替换动作在保存的时候才发生; + * @param + * @return + */ + +void TextEdit::onEndlineFormatChanged(BottomBar::EndlineFormat from, BottomBar::EndlineFormat to) +{ + //auto endlineCom = new EndlineFormartCommand(this,m_wrapper->bottomBar(),from,to); + //m_pUndoStack->push(endlineCom); + m_wrapper->bottomBar()->setEndlineMenuText(to); +} + +/** + * @brief 系统调色板更新时重绘部分组件,例如:列选取项 + */ +void TextEdit::onAppPaletteChanged() +{ + // 判断是否处于列选取状态 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QColor highlightBackground = DGuiApplicationHelper::instance()->applicationPalette().color(QPalette::Highlight); + for (auto &selection : m_altModSelections) { + selection.format.setBackground(highlightBackground); + } + + // 更新高亮状态 + renderAllSelections(); + } +} + +void TextEdit::updateHighlightBrackets(const QChar &openChar, const QChar &closeChar) +{ + QTextDocument *doc = document(); + QTextCursor cursor = textCursor(); + int position = cursor.position(); + + QTextCursor bracketBeginCursor; + QTextCursor bracketEndCursor; + cursor.clearSelection(); + + if (!bracketBeginCursor.isNull() || !bracketEndCursor.isNull()) { + bracketBeginCursor.setCharFormat(QTextCharFormat()); + bracketEndCursor.setCharFormat(QTextCharFormat()); + bracketBeginCursor = bracketEndCursor = QTextCursor(); + } + + QChar begin, end; + + if (doc->characterAt(position) == openChar || + doc->characterAt(position) == closeChar || + doc->characterAt(position - 1) == openChar || + doc->characterAt(position - 1) == closeChar) { + bool forward = doc->characterAt(position) == openChar || + doc->characterAt(position - 1) == openChar; + + if (forward) { + if (doc->characterAt(position) == openChar) { + position++; + } else { + cursor.setPosition(position - 1); + } + + begin = openChar; + end = closeChar; + } else { + if (doc->characterAt(position) == closeChar) { + cursor.setPosition(position + 1); + position -= 1; + } else { + position -= 2; + } + + begin = closeChar; + end = openChar; + } + + bracketBeginCursor = cursor; + bracketBeginCursor.movePosition(forward ? QTextCursor::NextCharacter : QTextCursor::PreviousCharacter, + QTextCursor::KeepAnchor); + + int braceDepth = 1; + // 判断当前是否处于字符串内,字符串内的 openChar closeChar {} () [] 等不进行统计 + bool inCodeString = false; + QChar c; + while (!(c = doc->characterAt(position)).isNull()) { + if (inCodeString) { + // 判断 " 是否存在转义字符,若不存在,则退出字符串模式 + // 注意回退(!forward)模式下,position = 0,characterAt(position - 1) 将返回空字符,同样符合判断,不会触发越界访问 + if ('"' == c + && '\\' != doc->characterAt(position - 1)) { + inCodeString = false; + } + } else { + if (c == begin) { + braceDepth++; + } else if (c == end) { + braceDepth--; + + if (!braceDepth) { + bracketEndCursor = QTextCursor(doc); + bracketEndCursor.setPosition(position); + bracketEndCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + break; + } + } else if ('"' == c) { + inCodeString = true; + } + } + + forward ? position++ : position--; + } + + // cannot find the end bracket to not need to highlight. + if (!bracketEndCursor.isNull()) { + m_beginBracketSelection.cursor = bracketBeginCursor; + m_beginBracketSelection.format = m_bracketMatchFormat; + + m_endBracketSelection.cursor = bracketEndCursor; + m_endBracketSelection.format = m_bracketMatchFormat; + } + } +} + +int TextEdit::getFirstVisibleBlockId() const +{ + QTextCursor cur = QTextCursor(this->document()); + if (cur.isNull()) { + return 0; + } + cur.movePosition(QTextCursor::Start); + + QPoint startPoint; + QTextBlock startBlock, endBlock; + + if (verticalScrollBar()->maximum() > height()) { + startPoint = QPointF(0, height() / verticalScrollBar()->maximum() * verticalScrollBar()->value()).toPoint(); + //endPoint = QPointF(0,height() + height()/verticalScrollBar()->maximum()*verticalScrollBar()->value()).toPoint(); + } else if (verticalScrollBar()->maximum() > 0 && verticalScrollBar()->maximum() <= height()) { + + startPoint = QPointF(0, verticalScrollBar()->value() / verticalScrollBar()->maximum()).toPoint(); + } + + cur = cursorForPosition(startPoint); + startBlock = document()->findBlock(cur.position()); + cur.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + if (startBlock.text() != cur.selection().toPlainText()) { + return startBlock.blockNumber() + 1; + } + + return startBlock.blockNumber(); +} + +void TextEdit::setLeftAreaUpdateState(TextEdit::UpdateOperationType statevalue) +{ + if (statevalue != m_LeftAreaUpdateState) { + m_LeftAreaUpdateState = statevalue; + + // 当文件读取完成时,手动触发更新界面 + if (TextEdit::FileOpenEnd == m_LeftAreaUpdateState) { + m_pLeftAreaWidget->updateAll(); + } + } +} + +TextEdit::UpdateOperationType TextEdit::getLeftAreaUpdateState() +{ + return m_LeftAreaUpdateState; +} +//line 开始处理的行号 isvisable是否折叠 iInitnum左括号默认开始计算的数量 isFirstLine是否是第一行,因为第一行默认不折叠 +bool TextEdit::getNeedControlLine(int line, bool isVisable) +{ + // 查询折叠区域文本块范围 + QTextBlock beginBlock, endBlock, curBlock; + bool bFoundBrace = findFoldBlock(line, beginBlock, endBlock, curBlock); + + //没有找到右括弧折叠左括弧后面所有行 + if (!bFoundBrace) { + //遍历最后右括弧文本块 设置块隐藏或显示 + while (beginBlock.isValid()) { + beginBlock.setVisible(isVisable); + viewport()->adjustSize(); + beginBlock = beginBlock.next(); + } + return true; + //没有找到匹配左右括弧 //如果左右"{" "}"在同一行不折叠 + } else if (!bFoundBrace || endBlock == curBlock) { + return false; + } else { + //遍历最后右括弧文本块 设置块隐藏或显示 + while (beginBlock != endBlock && beginBlock.isValid()) { + if (beginBlock.isValid()) { + beginBlock.setVisible(isVisable); + } + viewport()->adjustSize(); + beginBlock = beginBlock.next(); + } + + //最后一行显示或隐藏,或者下行就包含"}" + if (beginBlock.isValid() && beginBlock == endBlock && endBlock.text().simplified() == "}") { + endBlock.setVisible(isVisable); + viewport()->adjustSize(); + } + + return true; + } +} + +bool TextEdit::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::Gesture: + gestureEvent(static_cast(event)); + break; + case QEvent::PaletteChange: + // 调色板更新时更新选取高亮颜色 + onAppPaletteChanged(); + break; + default: + break; + } + + return DPlainTextEdit::event(event); +} + +bool TextEdit::gestureEvent(QGestureEvent *event) +{ + if (QGesture *tap = event->gesture(Qt::TapGesture)) + tapGestureTriggered(static_cast(tap)); + if (QGesture *tapAndHold = event->gesture(Qt::TapAndHoldGesture)) + tapAndHoldGestureTriggered(static_cast(tapAndHold)); + if (QGesture *pan = event->gesture(Qt::PanGesture)) + panTriggered(static_cast(pan)); + if (QGesture *pinch = event->gesture(Qt::PinchGesture)) + pinchTriggered(static_cast(pinch)); + if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) + swipeTriggered(static_cast(swipe)); + + return true; +} + +void TextEdit::tapGestureTriggered(QTapGesture *tap) +{ + //单指点击函数 + switch (tap->state()) { + case Qt::GestureStarted: { + m_gestureAction = GA_tap; + m_tapBeginTime = QDateTime::currentDateTime().toMSecsSinceEpoch(); + break; + } + case Qt::GestureUpdated: { + m_gestureAction = GA_slide; + break; + } + case Qt::GestureCanceled: { + //根据时间长短区分轻触滑动 + qint64 timeSpace = QDateTime::currentDateTime().toMSecsSinceEpoch() - m_tapBeginTime; + if (timeSpace < TAP_MOVE_DELAY || m_slideContinueX || m_slideContinueY) { + m_slideContinueX = false; + m_slideContinueY = false; + m_gestureAction = GA_slide; + qDebug() << "slide start" << timeSpace; + } else { + qDebug() << "null start" << timeSpace; + m_gestureAction = GA_null; + } + break; + } + case Qt::GestureFinished: { + m_gestureAction = GA_null; + break; + } + default: { + Q_ASSERT(false); + break; + } + } +} + +void TextEdit::tapAndHoldGestureTriggered(QTapAndHoldGesture *tapAndHold) +{ + //单指长按 + switch (tapAndHold->state()) { + case Qt::GestureStarted: + m_gestureAction = GA_hold; + break; + case Qt::GestureUpdated: + break; + case Qt::GestureCanceled: + break; + case Qt::GestureFinished: + m_gestureAction = GA_null; + break; + default: + break; + } +} + +void TextEdit::panTriggered(QPanGesture *pan) +{ + //两指平移 + switch (pan->state()) { + case Qt::GestureStarted: + m_gestureAction = GA_pan; + break; + case Qt::GestureUpdated: + break; + case Qt::GestureCanceled: + break; + case Qt::GestureFinished: + m_gestureAction = GA_null; + break; + default: + break; + } +} + +void TextEdit::pinchTriggered(QPinchGesture *pinch) +{ + //两指拉伸 -----缩放or放大 + switch (pinch->state()) { + case Qt::GestureStarted: { + m_gestureAction = GA_pinch; + if (static_cast(m_scaleFactor) != m_fontSize) { + m_scaleFactor = m_fontSize; + } + break; + } + case Qt::GestureUpdated: { + QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags(); + if (changeFlags & QPinchGesture::ScaleFactorChanged) { + m_currentStepScaleFactor = pinch->totalScaleFactor(); + } + break; + } + case Qt::GestureCanceled: { + break; + } + case Qt::GestureFinished: { + m_gestureAction = GA_null; + m_scaleFactor *= m_currentStepScaleFactor; + m_currentStepScaleFactor = 1; + break; + } + default: { + break; + } + }//switch + + //QFont font = getVTFont(); + int size = static_cast(m_scaleFactor * m_currentStepScaleFactor); + if (size < 8) + size = 8; + if (size > 50) + size = 50; + //根据移动距离设置字体大小 + setFontSize(size); + //同步设置界面字体栏数值 + qobject_cast(this->window())->changeSettingDialogComboxFontNumber(size); +} + +void TextEdit::swipeTriggered(QSwipeGesture *swipe) +{ + //三指滑动 +// switch (swipe->state()) { +// case Qt::GestureStarted: +// m_gestureAction = GA_swipe; +// break; +// case Qt::GestureUpdated: +// break; +// case Qt::GestureCanceled: +// m_gestureAction = GA_null; +// break; +// case Qt::GestureFinished: +// Q_ASSERT(false); +// break; +// default: +// Q_ASSERT(false); +// break; +// } + +} + +void TextEdit::slideGestureY(qreal diff) +{ + static qreal delta = 0.0; + int step = static_cast(diff + delta); + delta = diff + delta - step; + + verticalScrollBar()->setValue(verticalScrollBar()->value() + step); +} + +void TextEdit::slideGestureX(qreal diff) +{ + static qreal delta = 0.0; + int step = static_cast(diff + delta); + delta = diff + delta - step; + + horizontalScrollBar()->setValue(horizontalScrollBar()->value() + step * 30); +} + +void TextEdit::setTheme(const QString &path) +{ + QVariantMap jsonMap = Utils::getThemeMapFromPath(path); + QVariantMap textStylesMap = jsonMap["text-styles"].toMap(); + QString themeCurrentLineColor = jsonMap["editor-colors"].toMap()["current-line"].toString(); + QString textColor = textStylesMap["Normal"].toMap()["text-color"].toString(); + + m_backgroundColor = QColor(jsonMap["editor-colors"].toMap()["background-color"].toString()); + m_currentLineColor = QColor(themeCurrentLineColor); + m_currentLineNumberColor = QColor(jsonMap["editor-colors"].toMap()["current-line-number"].toString()); + m_lineNumbersColor = QColor(jsonMap["editor-colors"].toMap()["line-numbers"].toString()); + m_regionMarkerColor = QColor(textStylesMap["RegionMarker"].toMap()["selected-text-color"].toString()); + m_selectionColor = QColor(textStylesMap["Normal"].toMap()["selected-text-color"].toString()); + m_selectionBgColor = QColor(textStylesMap["Normal"].toMap()["selected-bg-color"].toString()); + m_bracketMatchFormat = currentCharFormat(); + m_bracketMatchFormat.setForeground(QColor(jsonMap["editor-colors"].toMap()["bracket-match-fg"].toString())); + m_bracketMatchFormat.setBackground(QColor(jsonMap["editor-colors"].toMap()["bracket-match-bg"].toString())); + + QString findMatchBgColor = jsonMap["editor-colors"].toMap()["find-match-background"].toString(); + QString findMatchFgColor = jsonMap["editor-colors"].toMap()["find-match-foreground"].toString(); + m_findMatchFormat = currentCharFormat(); + m_findMatchFormat.setBackground(QColor(findMatchBgColor)); + m_findMatchFormat.setForeground(QColor(findMatchFgColor)); + + QString findHighlightBgColor = jsonMap["editor-colors"].toMap()["find-highlight-background"].toString(); + QString findHighlightFgColor = jsonMap["editor-colors"].toMap()["find-highlight-foreground"].toString(); + m_findHighlightSelection.format.setProperty(QTextFormat::BackgroundBrush, QBrush(QColor(findHighlightBgColor))); + m_findHighlightSelection.format.setProperty(QTextFormat::ForegroundBrush, QBrush(QColor(findHighlightFgColor))); + + m_beginBracketSelection.format = m_bracketMatchFormat; + m_endBracketSelection.format = m_bracketMatchFormat; + + int iVerticalScrollValue = getScrollOffset(); + int iHorizontalScrollVaule = horizontalScrollBar()->value(); + getScrollOffset(); + verticalScrollBar()->setSliderPosition(iVerticalScrollValue); + horizontalScrollBar()->setSliderPosition(iHorizontalScrollVaule); + + m_pLeftAreaWidget->m_pLineNumberArea->update(); + m_pLeftAreaWidget->m_pBookMarkArea->update(); + + updateHighlightLineSelection(); + renderAllSelections(); +} + +void TextEdit::removeHighlightWordUnderCursor() +{ + //m_highlightWordCacheCursor = m_wordUnderCursorSelection.cursor; + QTextEdit::ExtraSelection selection; + //m_wordUnderCursorSelection = selection; + + renderAllSelections(); + m_nBookMarkHoverLine = -1; + m_pLeftAreaWidget->m_pBookMarkArea->update(); +} + +void TextEdit::setSettings(Settings *keySettings) +{ + m_settings = keySettings; +} + + +void TextEdit::copySelectedText() +{ + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QString data; + for (auto sel : m_altModSelections) { + data.append(sel.cursor.selectedText()); + } + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + } else { + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + if (textCursor().hasSelection()) { + clipboard->setText(textCursor().selection().toPlainText()); + tryUnsetMark(); + } else { + clipboard->setText(m_highlightWordCacheCursor.selectedText()); + } + } + tryUnsetMark(); +} + +void TextEdit::cutSelectedText() +{ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(textCursor().selection().toPlainText()); + + QTextCursor cursor = textCursor(); + cursor.removeSelectedText(); + setTextCursor(cursor); + + unsetMark(); +} + +void TextEdit::pasteText() +{ + QPlainTextEdit::paste(); + + unsetMark(); +} + +void TextEdit::setMark() +{ + bool currentMark = m_cursorMark; + bool markCursorChanged = false; + + if (m_cursorMark) { + if (textCursor().hasSelection()) { + markCursorChanged = true; + + QTextCursor cursor = textCursor(); + cursor.clearSelection(); + setTextCursor(cursor); + } else { + m_cursorMark = false; + } + } else { + m_cursorMark = true; + } + + if (m_cursorMark != currentMark || markCursorChanged) { + cursorMarkChanged(m_cursorMark, textCursor()); + } +} + +void TextEdit::unsetMark() +{ + bool currentMark = m_cursorMark; + + m_cursorMark = false; + + if (m_cursorMark != currentMark) { + cursorMarkChanged(m_cursorMark, textCursor()); + } +} + +bool TextEdit::tryUnsetMark() +{ + if (m_cursorMark) { + QTextCursor cursor = textCursor(); + cursor.clearSelection(); + setTextCursor(cursor); + + unsetMark(); + + return true; + } else { + return false; + } +} + +void TextEdit::exchangeMark() +{ + unsetMark(); + + if (textCursor().hasSelection()) { + // Record cursor and seleciton position before move cursor. + int actionStartPos = textCursor().position(); + int selectionStartPos = textCursor().selectionStart(); + int selectionEndPos = textCursor().selectionEnd(); + + QTextCursor cursor = textCursor(); + if (actionStartPos == selectionStartPos) { + cursor.setPosition(selectionStartPos, QTextCursor::MoveAnchor); + cursor.setPosition(selectionEndPos, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(selectionEndPos, QTextCursor::MoveAnchor); + cursor.setPosition(selectionStartPos, QTextCursor::KeepAnchor); + } + + setTextCursor(cursor); + } +} + +void TextEdit::saveMarkStatus() +{ + m_cursorMarkStatus = m_cursorMark; + m_cursorMarkPosition = textCursor().anchor(); +} + +void TextEdit::restoreMarkStatus() +{ + if (m_cursorMarkStatus) { + QTextCursor currentCursor = textCursor(); + + QTextCursor cursor = textCursor(); + cursor.setPosition(m_cursorMarkPosition, QTextCursor::MoveAnchor); + cursor.setPosition(currentCursor.position(), QTextCursor::KeepAnchor); + + setTextCursor(cursor); + } +} + + +void TextEdit::slot_translate() +{ + QProcess::startDetached("dbus-send --print-reply --dest=com.iflytek.aiassistant /aiassistant/deepinmain com.iflytek.aiassistant.mainWindow.TextToTranslate"); +} + +QString TextEdit::getWordAtCursor() +{ + if (!characterCount()) { + return ""; + } else { + QTextCursor cursor = textCursor(); + QChar currentChar = toPlainText().at(std::max(cursor.position() - 1, 0)); + + cursor.movePosition(QTextCursor::NoMove, QTextCursor::MoveAnchor); + while (!currentChar.isSpace() && cursor.position() != 0) { + // while (!currentChar.isSpace() && cursor.position() != 0) { + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + currentChar = toPlainText().at(std::max(cursor.position() - 1, 0)); + + if (currentChar == '-') { + break; + } + } + + return cursor.selectedText(); + } +} + +QString TextEdit::getWordAtMouse() +{ + if (!characterCount()) { + return ""; + } else { + auto pos = mapFromGlobal(QCursor::pos()); + QTextCursor cursor(cursorForPosition(pos)); + + // Get cursor rectangle. + auto rect = cursorRect(cursor); + int widthOffset = 10; + rect.setX(std::max(rect.x() - widthOffset / 2, 0)); + rect.setWidth(rect.width() + widthOffset); + + // Just highlight word under pointer when cursor rectangle contain mouse pointer coordinate. + if ((rect.x() <= pos.x()) && + (pos.x() <= rect.x() + rect.width()) && + (rect.y() <= pos.y()) && + (pos.y() <= rect.y() + rect.height())) { + cursor.select(QTextCursor::WordUnderCursor); + + return cursor.selectedText(); + } else { + return ""; + } + } +} + +void TextEdit::toggleReadOnlyMode(bool notNotify) +{ + if (m_readOnlyMode) { + if (m_cursorMode == Overwrite) { + emit cursorModeChanged(Overwrite); + } else { + emit cursorModeChanged(Insert); + } + setReadOnly(false); + m_readOnlyMode = false; + setCursorWidth(1); + updateHighlightLineSelection(); + + if (!notNotify) { + popupNotify(tr("Read-Only mode is off")); + } + } else { + m_readOnlyMode = true; + setReadOnly(true); + setCursorWidth(0); //隐藏光标 + document()->clearUndoRedoStacks(); + updateHighlightLineSelection(); + + if (!notNotify) { + popupNotify(tr("Read-Only mode is on")); + } + emit cursorModeChanged(Readonly); + } +} + +void TextEdit::toggleComment(bool bValue) +{ + const auto def = m_repository.definitionForFileName(QFileInfo(m_sFilePath).fileName()); + QTextCursor selectionCursor = textCursor(); + selectionCursor.movePosition(QTextCursor::StartOfBlock); + selectionCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + QString text = selectionCursor.selectedText(); + // init base. + bool isBlankLine = text.trimmed().isEmpty(); + if (characterCount() == 0 || isBlankLine || def.filePath().isEmpty()) { + return; + } + + if (m_readOnlyMode) { + popupNotify(tr("Read-Only mode is on")); + return; + } + + //不同类型文件注释符号不同 梁卫东 2020-09-03 17:28:45 + bool bHasCommnent = false; + if (m_commentDefinition.isValid()) { + QString multiLineCommentMark = m_commentDefinition.multiLineStart.simplified(); + QString singleLineCommentMark = m_commentDefinition.singleLine.simplified(); + if (multiLineCommentMark.isEmpty() && singleLineCommentMark.isEmpty()) { + bHasCommnent = false; + } else { + bHasCommnent = true; + } + } + if (!bHasCommnent) { + return; + } + + QString name = def.name(); + if (name == "Markdown") { + return; + } + + if (!def.filePath().isEmpty()) { + if (bValue) { + setComment(); + } else { + removeComment(); + //unCommentSelection(); + } + } else { + // do not need to prompt the user. + // popupNotify(tr("File does not support syntax comments")); + } +} + +int TextEdit::getNextWordPosition(QTextCursor &cursor, QTextCursor::MoveMode moveMode) +{ + // FIXME(rekols): if is empty text, it will crash. + if (!characterCount()) { + return 0; + } + + // Move next char first. + QTextCursor copyCursor = cursor; + copyCursor.movePosition(QTextCursor::NextCharacter, moveMode); + QString currentChar = copyCursor.selection().toPlainText(); + + // Just to next non-space char if current char is space. + if (currentChar.data()->isSpace()) { + while (copyCursor.position() < characterCount() - 1 && currentChar.data()->isSpace()) { + copyCursor.movePosition(QTextCursor::NextCharacter, moveMode); + currentChar = copyCursor.selection().toPlainText(); + } + while (copyCursor.position() < characterCount() - 1 && !atWordSeparator(copyCursor.position())) { + copyCursor.movePosition(QTextCursor::NextCharacter, moveMode); + + //cursor.movePosition(QTextCursor::NextCharacter, moveMode); + } + } + // Just to next word-separator char. + else { + while (copyCursor.position() < characterCount() - 1 && !atWordSeparator(copyCursor.position())) { + copyCursor.movePosition(QTextCursor::NextCharacter, moveMode); + } + } + + return copyCursor.position(); +} + +int TextEdit::getPrevWordPosition(QTextCursor cursor, QTextCursor::MoveMode moveMode) +{ + if (!characterCount()) { + return 0; + } + + // Move prev char first. + QTextCursor copyCursor = cursor; + copyCursor.movePosition(QTextCursor::PreviousCharacter, moveMode); + QString currentChar = copyCursor.selection().toPlainText(); + + // Just to next non-space char if current char is space. + if (currentChar.data()->isSpace()) { + while (copyCursor.position() > 0 && currentChar.data()->isSpace()) { + copyCursor.movePosition(QTextCursor::PreviousCharacter, moveMode); + currentChar = copyCursor.selection().toPlainText(); + } + } + // Just to next word-separator char. + else { + while (copyCursor.position() > 0 && !atWordSeparator(copyCursor.position())) { + copyCursor.movePosition(QTextCursor::PreviousCharacter, moveMode); + } + } + + return copyCursor.position(); +} + +bool TextEdit::atWordSeparator(int position) +{ + QTextCursor copyCursor = textCursor(); + copyCursor.setPosition(position, QTextCursor::MoveAnchor); + copyCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + QString currentChar = copyCursor.selection().toPlainText(); + return m_wordSepartors.contains(currentChar); +} + +void TextEdit::showCursorBlink() +{ + // -1 表示恢复Qt的默认值 + QApplication::setCursorFlashTime(-1); +} + +void TextEdit::hideCursorBlink() +{ + QApplication::setCursorFlashTime(0); +} + +void TextEdit::setReadOnlyPermission(bool permission) +{ + m_bReadOnlyPermission = permission; //true为不可读 + if (permission) { + m_Permission2 = true; + setReadOnly(true); + emit cursorModeChanged(Readonly); + } else { + m_Permission = false; + if (!m_readOnlyMode) { + setReadOnly(false); + //emit cursorModeChanged(Insert); + } else { + setReadOnly(true); + emit cursorModeChanged(Readonly); + } + } + SendtoggleReadOnlyMode(); +} + +void TextEdit::SendtoggleReadmessage() +{ + if (!m_bReadOnlyPermission) { + if (m_cursorMode == Overwrite) { + emit cursorModeChanged(Overwrite); + } else { + emit cursorModeChanged(Insert); + } + setReadOnly(false); + setCursorWidth(1); + updateHighlightLineSelection(); + } else { + setReadOnly(true); + setCursorWidth(0); //隐藏光标 + document()->clearUndoRedoStacks(); + updateHighlightLineSelection(); + emit cursorModeChanged(Readonly); + } +} + +bool TextEdit::isAbleOperation(int iOperationType) +{ + /* + * 读取并计算系统剩余内存大小,根据系统剩余内存大小决定本次复制/粘贴操作是否可继续执行 + * 解决的问题:复制/粘贴大文本字符内容(50MB/100MB/500MB)时会占用大量内存,系统内存不足会导致应用闪退 + */ + bool bRet = true; + qlonglong memory = 0; + qlonglong memoryAll = 0; + bool bVaule = false; + QFile file(PROC_MEMINFO_PATH); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qInfo() << "Open " << PROC_MEMINFO_PATH << " failed."; + return bRet; + } + + QTextStream stream(&file); + qlonglong buff[16] = {0}; + for (int i = 0; i <= 15; ++i) { + QString line = stream.readLine(); + QStringList list = line.split(QRegExp("\\s{1,}")); + if (list.size() >= 2) { + buff[i] = list.at(1).toLongLong(&bVaule); + } + } + + memoryAll = buff[0]; + memory = buff[0] - buff[2]; + /* 系统当前可用内存大小 */ + qlonglong iSystemAvailableMemory = memoryAll - memory; + file.close(); + + if (iOperationType == OperationType::CopyOperation) { + if (m_isSelectAll) { + if (characterCount() / DATA_SIZE_1024 * COPY_CONSUME_MEMORY_MULTIPLE > iSystemAvailableMemory) { + bRet = false; + } + } else if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QString strSelectText; + for (auto it = m_altModSelections.begin(); it != m_altModSelections.end(); it++) { + auto text = (*it).cursor.selectedText(); + strSelectText += text; + if (it != m_altModSelections.end() - 1) + strSelectText += "\n"; + } + if (strSelectText.size() / DATA_SIZE_1024 * COPY_CONSUME_MEMORY_MULTIPLE > iSystemAvailableMemory) { + bRet = false; + } + } else if (textCursor().hasSelection()) { + if (textCursor().selection().toPlainText().size() / DATA_SIZE_1024 * COPY_CONSUME_MEMORY_MULTIPLE > iSystemAvailableMemory) { + bRet = false; + } + } + } else if (iOperationType == OperationType::PasteOperation) { + const QClipboard *clipboard = QApplication::clipboard(); + QString strClipboardText = clipboard->text(); + //文本内容大于系统总内存,不允许粘贴 + if ((document()->characterCount() + strClipboardText.size()) / DATA_SIZE_1024 * PASTE_CONSUME_MEMORY_MULTIPLE > memoryAll) { + bRet = false; + } + if (strClipboardText.size() / DATA_SIZE_1024 * PASTE_CONSUME_MEMORY_MULTIPLE > iSystemAvailableMemory) { + bRet = false; + } + + /* 当文本框里的文本内容达到800MB后,再次持续粘贴,则只允许粘贴<=500KB大小的文本内容 */ + if (bRet == true) { + if (document()->characterCount() > (800 * DATA_SIZE_1024 * DATA_SIZE_1024) && strClipboardText.size() / DATA_SIZE_1024 > 500) { + bRet = false; + } + } + } + + return bRet; +} + +void TextEdit::SendtoggleReadOnlyMode() +{ + if (m_bReadOnlyPermission && !m_Permission) { + m_Permission = m_bReadOnlyPermission; + SendtoggleReadmessage(); + } else if (m_Permission2 && !m_bReadOnlyPermission) { + m_Permission2 = m_bReadOnlyPermission; + SendtoggleReadmessage(); + } +} + +bool TextEdit::getReadOnlyPermission() +{ + return m_bReadOnlyPermission; +} + +bool TextEdit::getReadOnlyMode() +{ + return m_readOnlyMode; +} + +void TextEdit::hideRightMenu() +{ + //arm平台全屏然后恢复窗口,右键菜单不会消失,所以加了这个函数 + if (m_rightMenu) { + m_rightMenu->hide(); + } +} + +void TextEdit::bookMarkAreaPaintEvent(QPaintEvent *event) +{ + BookMarkWidget *bookMarkArea = m_pLeftAreaWidget->m_pBookMarkArea; + QPainter painter(bookMarkArea); + QColor lineNumberAreaBackgroundColor; + if (DApplicationHelper::instance()->themeType() == DApplicationHelper::ColorType::DarkType) { + lineNumberAreaBackgroundColor = palette().brightText().color(); + lineNumberAreaBackgroundColor.setAlphaF(0.06); + + m_lineNumbersColor.setAlphaF(0.2); + } else { + lineNumberAreaBackgroundColor = palette().brightText().color(); + lineNumberAreaBackgroundColor.setAlphaF(0.03); + m_lineNumbersColor.setAlphaF(0.3); + } + + QTextBlock lineBlock;//第几行文本块 + QImage image; + QString pixmapPath; + QList list = m_listBookmark; + bool bIsContains = false; + + if (!m_listBookmark.contains(m_nBookMarkHoverLine) && m_nBookMarkHoverLine != -1 && m_nBookMarkHoverLine <= blockCount()) { + list << m_nBookMarkHoverLine; + } else { + bIsContains = true; + } + + foreach (auto line, list) { + lineBlock = document()->findBlockByNumber(line - 1); + QTextCursor cur = textCursor(); + cur.setPosition(lineBlock.position(), QTextCursor::MoveAnchor); + if (line == m_nBookMarkHoverLine && !bIsContains) { + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::DarkType) { + pixmapPath = ":/images/like_hover_dark.svg"; + image = QImage(":/images/like_hover_dark.svg"); + } else { + image = QImage(":/images/like_hover_light.svg"); + pixmapPath = ":/images/like_hover_light.svg"; + } + } else { + image = QImage(":/images/bookmark.svg"); + pixmapPath = ":/images/bookmark.svg"; + } + + if (line > 0) { + lineBlock = document()->findBlockByNumber(line - 1); + if (!lineBlock.isVisible()) { + continue; + } + + int w = this->m_fontSize <= 15 ? 15 : m_fontSize; + updateLeftWidgetWidth(w); + int h = cursorRect(cur).height(); + // 绘制行纵向居中 + int offset = qMax(0, (h - w) / 2); + //the language currently set by the system is Tibetan. + if ("bo_CN" == Utils::getSystemLan()) + offset = h <= 20 ? 0 : h / 10; + + QRect rect(0, cursorRect(cur).y() + offset, w, w); + QSvgRenderer render; + render.load(pixmapPath); + render.render(&painter, rect); + } + } +} + +int TextEdit::getLineFromPoint(const QPoint &point) +{ + QTextCursor cursor = cursorForPosition(point); + QTextBlock block = cursor.block(); +// qDebug() << "block.blockNumber()" << block.blockNumber(); + return block.blockNumber() + 1; +} + +void TextEdit::addOrDeleteBookMark() +{ + int line = 0; + if (m_bIsShortCut) { + line = getCurrentLine(); + m_bIsShortCut = false; + } else { + line = getLineFromPoint(m_mouseClickPos); + } + + if (line > blockCount()) { + return; + } + + if (m_listBookmark.contains(line)) { + m_listBookmark.removeOne(line); + m_nBookMarkHoverLine = -1; + qDebug() << "DeleteBookMark:" << line << m_listBookmark; + } else { + m_listBookmark.push_back(line); + qDebug() << "AddBookMark:" << line << m_listBookmark; + } + + m_pLeftAreaWidget->m_pBookMarkArea->update(); +} + +void TextEdit::moveToPreviousBookMark() +{ + int line = getCurrentLine(); + int index = m_listBookmark.indexOf(line); + + if (index == -1 && !m_listBookmark.isEmpty()) { + jumpToLine(m_listBookmark.last(), false); + return; + } + + if (index == 0) { + jumpToLine(m_listBookmark.last(), false); + } else { + jumpToLine(m_listBookmark.value(index - 1), false); + } +} + +void TextEdit::moveToNextBookMark() +{ + int line = getCurrentLine(); + int index = m_listBookmark.indexOf(line); + + if (index == -1 && !m_listBookmark.isEmpty()) { + jumpToLine(m_listBookmark.first(), false); + return; + } + + if (index == m_listBookmark.count() - 1) { + jumpToLine(m_listBookmark.first(), false); + } else { + jumpToLine(m_listBookmark.value(index + 1), false); + } +} + +void TextEdit::checkBookmarkLineMove(int from, int charsRemoved, int charsAdded) +{ + Q_UNUSED(charsRemoved); + Q_UNUSED(charsAdded); + + if (m_bIsFileOpen) { + return; + } + + if (m_nLines != blockCount()) { + QTextCursor cursor = textCursor(); + int nAddorDeleteLine = document()->findBlock(from).blockNumber() + 1; + int currLine = textCursor().blockNumber() + 1; + + if (m_nLines > blockCount()) { + foreach (const auto line, m_listBookmark) { + if (m_nSelectEndLine != -1) { + if (nAddorDeleteLine < line && line <= m_nSelectEndLine) { + m_listBookmark.removeOne(line); + } else if (line > m_nSelectEndLine) { + m_listBookmark.replace(m_listBookmark.indexOf(line), line - m_nSelectEndLine + nAddorDeleteLine); + } + } else { + if (line == currLine + 1) { + m_listBookmark.removeOne(currLine + 1); + } else if (line > currLine + 1) { + m_listBookmark.replace(m_listBookmark.indexOf(line), line - m_nLines + blockCount()); + } + } + } + } else { + foreach (const auto line, m_listBookmark) { + if (nAddorDeleteLine < line) { + m_listBookmark.replace(m_listBookmark.indexOf(line), line + blockCount() - m_nLines); + } + } + } + } + m_nLines = blockCount(); +} + +void TextEdit::flodOrUnflodAllLevel(bool isFlod) +{ + m_listMainFlodAllPos.clear(); + //折叠 + if (isFlod) { + for (int line = 0; line < document()->blockCount(); line++) { + if (blockContainStrBrackets(line) + && document()->findBlockByNumber(line).isVisible() + && !document()->findBlockByNumber(line).text().trimmed().startsWith("//")) { + if (getNeedControlLine(line, false)) { + m_listMainFlodAllPos.append(line); + } + } + } + //展开 + } else { + for (int line = 0; line < document()->blockCount(); line++) { + if (blockContainStrBrackets(line) + && !document()->findBlockByNumber(line + 1).isVisible() + && !document()->findBlockByNumber(line).text().trimmed().startsWith("//")) { + if (getNeedControlLine(line, true)) { + m_listMainFlodAllPos.append(line); + } + } + } + } + + //折叠时出现点击光标选择行变短 + QPlainTextEdit::LineWrapMode curMode = this->lineWrapMode(); + QPlainTextEdit::LineWrapMode WrapMode = curMode == QPlainTextEdit::NoWrap ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap; + this->setWordWrapMode(QTextOption::WrapAnywhere); + this->setLineWrapMode(WrapMode); + + m_pLeftAreaWidget->m_pFlodArea->update(); + m_pLeftAreaWidget->m_pLineNumberArea->update(); + m_pLeftAreaWidget->m_pBookMarkArea->update(); + + viewport()->update(); + document()->adjustSize(); + + this->setLineWrapMode(curMode); + viewport()->update(); +} + +void TextEdit::flodOrUnflodCurrentLevel(bool isFlod) +{ + int line = getLineFromPoint(m_mouseClickPos); + getNeedControlLine(line - 1, !isFlod); + m_pLeftAreaWidget->m_pFlodArea->update(); + m_pLeftAreaWidget->m_pLineNumberArea->update(); + m_pLeftAreaWidget->m_pBookMarkArea->update(); + viewport()->update(); + document()->adjustSize(); + +} + +void TextEdit::getHideRowContent(int iLine) +{ + // 预览文本块没有必要读取所有文本数据,调整为仅读取部分 + // Note:需要注意单个文本块(一般为一行数据)过长的情况 + // 最大显示的预览文本块数量,不超过1000 + static int s_MaxDisplayBlockCount = 1000; + + // 查询折叠区域文本块范围 + QTextBlock beginBlock, endBlock, curBlock; + bool bFoundBrace = findFoldBlock(iLine, beginBlock, endBlock, curBlock); + + if (QColor(m_backgroundColor).lightness() < 128) { + m_foldCodeShow->initHighLight(m_sFilePath, false); + } else { + m_foldCodeShow->initHighLight(m_sFilePath, true); + } + + m_foldCodeShow->appendText("{", width()); + //左右括弧没有匹配到 + if (!bFoundBrace) { + // 读取文本块索引 + int curIndex = 0; + //遍历最后右括弧文本块 设置块隐藏或显示,显示文本块不超过1000 + while (beginBlock.isValid() + && (curIndex++ < s_MaxDisplayBlockCount)) { + m_foldCodeShow->appendText(beginBlock.text(), width()); + beginBlock = beginBlock.next(); + } + + //如果左右"{" "}"在同一行不折叠 + } else if (endBlock == curBlock) { + return; + } else { + // 读取文本块索引 + int curIndex = 0; + //遍历最后右括弧文本块 设置块隐藏或显示,显示文本块不超过1000 + while (beginBlock != endBlock + && beginBlock.isValid() + && (curIndex++ < s_MaxDisplayBlockCount)) { + if (beginBlock.isValid()) { + m_foldCodeShow->appendText(beginBlock.text(), width()); + } + + beginBlock = beginBlock.next(); + } + + if (endBlock.text().simplified() == "}") { + m_foldCodeShow->appendText("}", width()); + } + + m_foldCodeShow->appendText("}", width()); + } +} + +bool TextEdit::isNeedShowFoldIcon(QTextBlock block) +{ + QString blockText = block.text(); + bool hasFindLeft = false; // 是否已经找到当前行第一个左括号 + int rightNum = 0, leftNum = 0;//右括号数目、左括号数目 + for (int i = 0 ; i < blockText.count(); ++i) { + if (blockText.at(i) == "}" && hasFindLeft) { + rightNum++; + } else if (blockText.at(i) == "{") { + if (!hasFindLeft) + hasFindLeft = true; + leftNum++; + } + } + + if (rightNum == leftNum) { + return false; + } else { + return true; + } +} + +int TextEdit::getHighLightRowContentLineNum(int iLine) +{ + // 查询折叠区域文本块范围 + QTextBlock beginBlock, endBlock, curBlock; + bool bFoundBrace = findFoldBlock(iLine, beginBlock, endBlock, curBlock); + + //左右括弧没有匹配到 + if (!bFoundBrace) { + //遍历最后右括弧文本块 设置块隐藏或显示 + while (beginBlock.isValid()) { + iLine++; + beginBlock = beginBlock.next(); + } + return iLine; + //如果左右"{" "}"在同一行不折叠 + } else if (!bFoundBrace || endBlock == curBlock) { + return iLine; + } else { + while (beginBlock != endBlock && beginBlock.isValid()) { + iLine++; + beginBlock = beginBlock.next(); + } + + iLine++; + return iLine; + } +} + +void TextEdit::paintCodeFlod(QPainter *painter, QRect rect, bool flod) +{ + painter->save(); + + painter->translate(rect.width() / 2.0, rect.height() / 2.0); + painter->translate(0, rect.y()); + QPainterPath path; + //QPointF p1(rect.x()+rect.width() * (1.0/3),rect.y()+rect.height()*(1.0/3)); + //QPointF p2(rect.x()+rect.width() * (2.0/3),rect.y()+rect.height()*(1.0/3)); + //QPointF p3(rect.x()+rect.width() * (1.0/2),rect.y()+rect.height()*(1.5/3)); + QPointF p1(-1 * rect.width() * (1.0 / 6), -1 * rect.height() * (1.0 / 6)); + QPointF p2(rect.width() * (1.0 / 6), -1 * rect.height() * (1.0 / 6)); + QPointF p3(0, 0); + path.moveTo(p1); + path.lineTo(p3); + path.lineTo(p2); + + if (flod) { + painter->rotate(-90); + } + + QPen pen(this->palette().foreground(), 2); + painter->setPen(pen); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->drawPath(path); + + painter->restore(); +} + +QColor TextEdit::getBackColor() +{ + return m_backgroundColor; +} + +int TextEdit::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, this->document()->blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + // 行号使用单独字体 + QFontMetrics fm(m_fontLineNumberArea); + int w = fm.horizontalAdvance(QLatin1Char('9')) * digits; + + return w > 15 ? w : 15; +} + +void TextEdit::updateLeftWidgetWidth(int width) +{ + if (m_LeftAreaUpdateState != TextEdit::FileOpenBegin) { + m_pLeftAreaWidget->m_pFlodArea->setFixedWidth(width); + m_pLeftAreaWidget->m_pLineNumberArea->setFixedWidth(lineNumberAreaWidth()); + m_pLeftAreaWidget->m_pBookMarkArea->setFixedWidth(width); + setLeftAreaUpdateState(TextEdit::Normal); + } +} + +int TextEdit::getLinePosYByLineNum(int iLine) +{ + QTextBlock block = document()->findBlockByNumber(iLine); + QTextCursor cur = textCursor(); + + while (!block.isVisible()) { + block = block.next(); + } + + cur.setPosition(block.position(), QTextCursor::MoveAnchor); + return cursorRect(cur).y(); +} + +bool TextEdit::ifHasHighlight() +{ + if (!m_findHighlightSelection.cursor.isNull()) + return m_findHighlightSelection.cursor.hasSelection(); + else { + return false; + } +} + +void TextEdit::setIsFileOpen() +{ + m_bIsFileOpen = true; +} + +void TextEdit::setTextFinished() +{ + m_bIsFileOpen = false; + m_nLines = blockCount(); + + if (!m_listBookmark.isEmpty()) { + return; + } + + QStringList bookmarkList = readHistoryRecordofBookmark(); + QStringList filePathList = readHistoryRecordofFilePath("advance.editor.browsing_history_file"); + QList linesList; + + QString qstrPath = m_sFilePath; + + if (filePathList.contains(qstrPath)) { + int index = 2; + QString qstrLines = bookmarkList.value(filePathList.indexOf(qstrPath)); + QString sign; + + for (int i = 0; i < qstrLines.count() - 1; i++) { + sign = qstrLines.at(i); + sign.append(qstrLines.at(i + 1)); + + if (sign == ",*" || sign == ")*") { + linesList << qstrLines.mid(index, i - index).toInt(); + index = i + 2; + } + } + } + + foreach (const auto line, linesList) { + if (line <= document()->blockCount()) { + if (!m_listBookmark.contains(line)) { + m_listBookmark << line; + } + } + } +// qDebug() << m_listBookmark << document()->blockCount(); +} + +QStringList TextEdit::readHistoryRecord(QString key) +{ + QString history = m_settings->settings->option(key)->value().toString(); + QStringList historyList; + int nLeftPosition = history.indexOf("*{"); + int nRightPosition = history.indexOf("}*"); + + while (nLeftPosition != -1) { + historyList << history.mid(nLeftPosition, nRightPosition + 2 - nLeftPosition); + nLeftPosition = history.indexOf("*{", nLeftPosition + 2); + nRightPosition = history.indexOf("}*", nRightPosition + 2); + } + + return historyList; +} + +QStringList TextEdit::readHistoryRecordofBookmark() +{ + QString history = m_settings->settings->option("advance.editor.browsing_history_file")->value().toString(); + QStringList bookmarkList; + int nLeftPosition = history.indexOf("*("); + int nRightPosition = history.indexOf(")*"); + + while (nLeftPosition != -1) { + bookmarkList << history.mid(nLeftPosition, nRightPosition + 2 - nLeftPosition); + nLeftPosition = history.indexOf("*(", nLeftPosition + 2); + nRightPosition = history.indexOf(")*", nRightPosition + 2); + } + + return bookmarkList; +} + +QStringList TextEdit::readHistoryRecordofFilePath(QString key) +{ + QString history = m_settings->settings->option(key)->value().toString(); + QStringList filePathList; + int nLeftPosition = history.indexOf("*["); + int nRightPosition = history.indexOf("]*"); + + while (nLeftPosition != -1) { + filePathList << history.mid(nLeftPosition + 2, nRightPosition - 2 - nLeftPosition); + nLeftPosition = history.indexOf("*[", nLeftPosition + 2); + nRightPosition = history.indexOf("]*", nRightPosition + 2); + } + + return filePathList; +} + +void TextEdit::writeEncodeHistoryRecord() +{ + QString history = m_settings->settings->option("advance.editor.browsing_encode_history")->value().toString(); + + QStringList pathList = readHistoryRecordofFilePath("advance.editor.browsing_encode_history"); + + foreach (auto path, pathList) { + QFileInfo f(path); + if (!f.isFile()) { + int nLeftPosition = history.indexOf(path); + int nRightPosition = history.indexOf("}*", nLeftPosition); + history.remove(nLeftPosition - 4, nRightPosition + 6 - nLeftPosition); + } + } + + int nLeftPosition = history.indexOf(m_sFilePath); + int nRightPosition = history.indexOf("}*", nLeftPosition); + + if (history.contains(m_sFilePath)) { + history.remove(nLeftPosition - 4, nRightPosition + 6 - nLeftPosition); + } + + QString encodeHistory = history + "*{*[" + m_sFilePath + "]*" + m_textEncode + "}*"; + m_settings->settings->option("advance.editor.browsing_encode_history")->setValue(encodeHistory); +} + +QStringList TextEdit::readEncodeHistoryRecord() +{ + QString history = m_settings->settings->option("advance.editor.browsing_encode_history")->value().toString(); + QStringList filePathList; + int nLeftPosition = history.indexOf("]*"); + int nRightPosition = history.indexOf("}*"); + + while (nLeftPosition != -1) { + filePathList << history.mid(nLeftPosition + 2, nRightPosition - 2 - nLeftPosition); + nLeftPosition = history.indexOf("]*", nLeftPosition + 2); + nRightPosition = history.indexOf("}*", nRightPosition + 2); + } + + return filePathList; +} + +void TextEdit::tellFindBarClose() +{ + m_bIsFindClose = true; +} + +void TextEdit::setEditPalette(const QString &activeColor, const QString &inactiveColor) +{ + QPalette pa = this->palette(); + pa.setColor(QPalette::Inactive, QPalette::Text, QColor(inactiveColor)); + pa.setColor(QPalette::Active, QPalette::Text, QColor(activeColor)); + setPalette(pa); +} + +void TextEdit::setCodeFoldWidgetHide(bool isHidden) +{ + if (m_foldCodeShow) { + m_foldCodeShow->setHidden(isHidden); + } +} + + +void TextEdit::setTruePath(QString qstrTruePath) +{ + m_qstrTruePath = qstrTruePath; +} + +QString TextEdit::getTruePath() +{ + if (m_qstrTruePath.isEmpty()) { + return m_sFilePath; + } + + return m_qstrTruePath; +} + +QList TextEdit::getBookmarkInfo() +{ + return m_listBookmark; +} + +void TextEdit::setBookMarkList(QList bookMarkList) +{ + m_listBookmark = bookMarkList; +} + +void TextEdit::updateSaveIndex() +{ + m_lastSaveIndex = m_pUndoStack->index(); +} + +void TextEdit::isMarkCurrentLine(bool isMark, QString strColor, qint64 timeStamp) +{ + qint64 operationTimeStamp = timeStamp; + if (operationTimeStamp < 0) { + operationTimeStamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); + } + + if (isMark) { + QTextEdit::ExtraSelection selection; + selection.cursor = textCursor(); + selection.format.setBackground(QColor(strColor)); + + TextEdit::MarkOperation markOperation; + markOperation.color = strColor; + + if (textCursor().hasSelection()) { + markOperation.type = MarkOnce; + } else { + markOperation.type = MarkLine; + int beginPos = textCursor().block().position(); + int endPos = beginPos + textCursor().block().length() - 1; + selection.cursor.setPosition(beginPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(endPos, QTextCursor::KeepAnchor); + } + //alt选中光标单独处理 + if (m_bIsAltMod) { + for (int i = 0; i < m_altModSelections.size(); ++i) { + markOperation.cursor = m_altModSelections[i].cursor; + selection.cursor = m_altModSelections[i].cursor; + m_markOperations.append(QPair(markOperation, operationTimeStamp)); + m_wordMarkSelections.append( + QPair + (selection, operationTimeStamp)); + } + } else { + markOperation.cursor = selection.cursor; + m_markOperations.append(QPair(markOperation, operationTimeStamp)); + m_wordMarkSelections.append( + QPair + (selection, operationTimeStamp)); + } + } else { + clearMarksForTextCursor(); + } +} + +void TextEdit::markAllKeywordInView() +{ + if (m_markOperations.isEmpty()) { + return; + } + + QList>::iterator it; + + for (it = m_markOperations.begin(); it != m_markOperations.end(); ++it) { + if (MarkAllMatch == it->first.type) { + // 标记当前视图根据匹配文本查找的所有文本 + markKeywordInView(it->first.matchText, it->first.color, it->second); + } else if (MarkAll == it->first.type) { + markAllInView(it->first.color, it->second); + } + } + + renderAllSelections(); +} + +bool TextEdit::markKeywordInView(QString keyword, QString color, qint64 timeStamp) +{ + qint64 operationTimeStamp = timeStamp; + if (operationTimeStamp < 0) { + operationTimeStamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); + } + + if (keyword.isEmpty()) { + return false; + } + + QList listExtraSelection; + QTextCharFormat format; + bool ret = false; + + format.setBackground(QColor(color)); + ret = updateKeywordSelectionsInView(keyword, format, &listExtraSelection); + + // 构建带有时间戳的 listExtraSelectionWithTimeStamp + QList> listExtraSelectionWithTimeStamp; + for (int i = 0; i < listExtraSelection.size(); i++) { + listExtraSelectionWithTimeStamp.append(QPair + (listExtraSelection.at(i), operationTimeStamp)); + } + + if (ret) { + m_mapKeywordMarkSelections[keyword] = listExtraSelectionWithTimeStamp; + } + + return ret; +} + +void TextEdit::markAllInView(QString color, qint64 timeStamp) +{ + // 增加时间戳 + qint64 operationTimeStamp = timeStamp; + if (operationTimeStamp < 0) { + operationTimeStamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); + } + + QTextEdit::ExtraSelection selection; + QList> listSelections; + + // 此处选中操作存在错误 + // QScrollBar *pScrollBar = verticalScrollBar(); + // QPoint startPoint = QPointF(0, 0).toPoint(); + // QTextBlock beginBlock = cursorForPosition(startPoint).block(); + // QTextBlock endBlock; + // + // if (pScrollBar->maximum() > 0) { + // QPoint endPoint = QPointF(0, 1.5 * height()).toPoint(); + // endBlock = cursorForPosition(endPoint).block(); + // } else { + // endBlock = document()->lastBlock(); + // } + + // selection.cursor = textCursor(); + // selection.cursor.setPosition(beginBlock.position(), QTextCursor::MoveAnchor); + // selection.cursor.setPosition(endBlock.position() + endBlock.length() - 1, QTextCursor::KeepAnchor); + + // 标准 QTextCursor 选中操作 + QTextCursor textCursor(document()); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + textCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + + selection.format.setBackground(QColor(color)); + selection.cursor = textCursor; + + listSelections.append(QPair + (selection, operationTimeStamp)); + + m_mapKeywordMarkSelections[TEXT_EIDT_MARK_ALL] = listSelections; +} + +void TextEdit::isMarkAllLine(bool isMark, QString strColor) +{ + // 增加时间戳 + qint64 timeStamp = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + if (isMark) { + QString selectionText = textCursor().selectedText(); + if (selectionText.length() != 0 && selectionText.length() < (document()->characterCount() - 1)) { + // 没有使用的变量,去除 + // QList wordMarkSelections = m_wordMarkSelections; + QList listExtraSelection; + // 没有使用的变量,去除 + // QList listSelections; + QTextEdit::ExtraSelection extraSelection; + QTextCharFormat format; + format.setBackground(QColor(strColor)); + extraSelection.cursor = textCursor(); + extraSelection.format = format; + + TextEdit::MarkOperation markOperation; + markOperation.type = MarkAllMatch; + markOperation.cursor = textCursor(); + markOperation.color = strColor; + markOperation.matchText = selectionText; + m_markOperations.append(QPair(markOperation, timeStamp)); + + if (updateKeywordSelectionsInView(selectionText, format, &listExtraSelection)) { + + QList> listExtraSelectionWithTimeStamp; + for (int i = 0; i < listExtraSelection.size(); i++) { + listExtraSelectionWithTimeStamp.append(QPair + (listExtraSelection.at(i), timeStamp)); + } + + m_mapKeywordMarkSelections[selectionText] = listExtraSelectionWithTimeStamp; + } else { + // 选中部分在文档中仅此一个,查找标记失败了,进行补充处理 + QTextEdit::ExtraSelection extraSelect; + listExtraSelection.append(extraSelection); + QList> listExtraSelectionWithTimeStamp; + for (int i = 0; i < listExtraSelection.size(); i++) { + listExtraSelectionWithTimeStamp.append(QPair + (listExtraSelection.at(i), timeStamp)); + } + + m_mapKeywordMarkSelections.insert(selectionText, listExtraSelectionWithTimeStamp); + } + + } else if (!textCursor().hasSelection() || selectionText.length() == (document()->characterCount() - 1)) { + TextEdit::MarkOperation markOperation; + markOperation.type = MarkAll; + markOperation.color = strColor; + m_markOperations.append(QPair(markOperation, timeStamp)); + markAllInView(strColor, timeStamp); + } + } else { + m_markOperations.clear(); + m_wordMarkSelections.clear(); + m_mapKeywordMarkSelections.clear(); + + QTextEdit::ExtraSelection selection; + selection.format.setBackground(QColor(strColor)); + selection.cursor = textCursor(); + selection.cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + selection.cursor.clearSelection(); + m_markAllSelection = selection; + } + + renderAllSelections(); +} + +void TextEdit::cancelLastMark() +{ + if (m_markOperations.isEmpty()) { + return; + } + + switch (m_markOperations.last().first.type) { + case MarkOnce: + case MarkLine: { + if (!m_wordMarkSelections.isEmpty()) { + // m_wordMarkSelections.removeLast(); + // 考虑到可能的插入操作,需要同步清理时间戳一样的selection + const qint64 operationTimeStamp = m_markOperations.last().second; + for (int i = 0; i < m_wordMarkSelections.size(); i++) { + if (operationTimeStamp == m_wordMarkSelections.at(i).second) { + m_wordMarkSelections.removeAt(i); + i--; + } + } + } + break; + } + + case MarkAllMatch: { + // QString keyword = m_markOperations.last().first.cursor.selectedText(); + QString keyword; + qint64 timeStamp = m_markOperations.last().second; + // 使用时间戳查找 keyword + QMap>>::Iterator it; + for (it = m_mapKeywordMarkSelections.begin(); it != m_mapKeywordMarkSelections.end(); ++it) { + if (it.value().size() > 0) { + qint64 itsTimeStamp = it.value().first().second; + if (itsTimeStamp == timeStamp) { + keyword = it.key(); + break; + } + } + } + + if (m_mapKeywordMarkSelections.contains(keyword)) { + m_mapKeywordMarkSelections.remove(keyword); + } + break; + } + + case MarkAll: { + if (m_mapKeywordMarkSelections.contains(TEXT_EIDT_MARK_ALL)) { + m_mapKeywordMarkSelections.remove(TEXT_EIDT_MARK_ALL); + } + break; + } + + } + + m_markOperations.removeLast(); + + // 如果在标记颜色操作后,更改文本内容,如果存在残留,补充一个清除处理 + if (m_markOperations.isEmpty() && + (m_wordMarkSelections.size() > 0 || m_mapKeywordMarkSelections.size() > 0)) { + qWarning() << __FUNCTION__ << __LINE__ << " cancle mark color operation," + << "find exist remain selections, will clear!"; + m_wordMarkSelections.clear(); + m_mapKeywordMarkSelections.clear(); + } + + renderAllSelections(); +} + +bool TextEdit::clearMarkOperationForCursor(QTextCursor cursor) +{ + bool bRet = false; + for (int i = m_markOperations.size() - 1; i >= 0; --i) { + if (m_markOperations.at(i).first.cursor == cursor) { + m_markOperations.removeAt(i); + bRet = true; + break; + } + } + + return bRet; +} + +bool TextEdit::clearMarksForTextCursor() +{ + bool bFind = false; + QTextCursor cursor; + QTextCursor textcursor = textCursor(); + + for (int i = m_wordMarkSelections.size() - 1; i >= 0; --i) { + cursor = m_wordMarkSelections.at(i).first.cursor; + if (textcursor.hasSelection()) { + if (textcursor == cursor) { + bFind = true; + clearMarkOperationForCursor(cursor); + m_wordMarkSelections.removeAt(i); + break; + } + + } else { + if (textcursor.position() >= cursor.selectionStart() && textcursor.position() <= cursor.selectionEnd()) { + bFind = true; + clearMarkOperationForCursor(cursor); + m_wordMarkSelections.removeAt(i); + } + } + } + + return bFind; +} + +void TextEdit::toggleMarkSelections() +{ + if (!clearMarksForTextCursor()) { + ColorSelectWdg *pColorSelectWdg = static_cast(m_actionColorStyles->defaultWidget()); + isMarkCurrentLine(true, pColorSelectWdg->getDefaultColor().name()); + } + + renderAllSelections(); +} + +/** + * @brief 转换标记项替换信息 \a replaceInfo 为标记项信息,标记项替换信息包含了光标的绝对位置, + * 在转换过程中,光标会更新当前选中区域为绝对位置 + * @param replaceInfo 标记替换信息 + * @return 转换后的标记操作项列表 + */ +QList > TextEdit::convertReplaceToMark(const QList &replaceInfo) +{ + QList > markList; + for (auto info : replaceInfo) { + MarkOperation markOpt = info.opt; + + // 更新当前光标选中信息 + markOpt.cursor.setPosition(info.start); + markOpt.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, info.end - info.start); + + markList.append(qMakePair(markOpt, info.time)); + } + + return markList; +} + +/** + * @brief 转换标记操作项 \a markInfo 为标记项替换信息,标记项替换信息包含了光标的绝对位置, + * 在转换过程中,会记录当前选中区域为绝对位置 + * @param markInfo 标记信息 + * @return 转换后的标记替换信息列表 + */ +QList TextEdit::convertMarkToReplace(const QList > &markInfo) +{ + QList replaceMarkList; + for (auto info : markInfo) { + MarkReplaceInfo replace; + replace.opt = info.first; + replace.time = info.second; + + // 记录当前光标位置,QTextDocument后续操作文本到QTextCursor光标范围时,会导致QTextCursor记录的光标位置失效 + replace.start = info.first.cursor.selectionStart(); + replace.end = info.first.cursor.selectionEnd(); + + replaceMarkList.append(replace); + } + + return replaceMarkList; +} + +/** + * @brief 更新所有的标记信息为 \a markInfo , 用于撤销项处理颜色标记变更 + * @param markInfo 颜色标记信息列表 + */ +void TextEdit::manualUpdateAllMark(const QList > &markInfo) +{ + m_markOperations = markInfo; + + // 全部标记更新后,修改手动标记文本部分 + m_wordMarkSelections.clear(); + // 用于将跨行的单行颜色标记拓展为多行处理 + QList> multiLineSelections; + + for (auto itr = m_markOperations.begin(); itr != m_markOperations.end();) { + if (MarkAll == (*itr).first.type + || MarkAllMatch == (*itr).first.type) { + ++itr; + continue; + } + + // 若无选中项,则过滤此颜色标记 + if (!(*itr).first.cursor.hasSelection()) { + itr = m_markOperations.erase(itr); + continue; + } + + auto &info = *itr; + if (MarkOnce == info.first.type) { + QTextEdit::ExtraSelection selection; + selection.format.setBackground(QColor(info.first.color)); + selection.cursor = info.first.cursor; + + // 更新单独文本标记 + m_wordMarkSelections.append(qMakePair(selection, info.second)); + + } else if (MarkLine == info.first.type) { + int selectStart = info.first.cursor.selectionStart(); + int selectEnd = info.first.cursor.selectionEnd(); + QTextBlock startBlock = document()->findBlock(selectStart); + QTextBlock endBlock = document()->findBlock(selectEnd); + + // 判断是否为多行颜色标记 + bool isMultiLine = startBlock < endBlock; + + while (startBlock.isValid() + && endBlock.isValid() + && !(endBlock < startBlock)) { + QTextEdit::ExtraSelection selection; + selection.format.setBackground(QColor(info.first.color)); + selection.cursor = info.first.cursor; + // 更新单行标记的索引区间, 注意标记单行颜色不包括换行符 + selection.cursor.setPosition(startBlock.position()); + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, startBlock.length() - 1); + + // 更新单行文本标记,允许使用一样的时间戳 + m_wordMarkSelections.append(qMakePair(selection, info.second)); + + // 追加拆解的多行颜色标记信息,允许使用一样的时间戳 + if (isMultiLine) { + auto copyInfo = info; + copyInfo.first.cursor = selection.cursor; + multiLineSelections.append(copyInfo); + } + + // 继续下一文本块处理 + startBlock = startBlock.next(); + } + + // 若为多行颜色标记,会将当前文本颜色标记移除,后续添加为多行颜色标记 + if (isMultiLine) { + itr = m_markOperations.erase(itr); + continue; + } + } + + // 继续下一遍历 + ++itr; + } + + // 追加多行颜色标记处理记录 + m_markOperations.append(multiLineSelections); + + // 对修改后的颜色标记进行排序 + std::sort(m_markOperations.begin(), m_markOperations.end(), + [](const QPair &a, const QPair &b) { + return a.second < b.second; + }); + std::sort(m_wordMarkSelections.begin(), m_wordMarkSelections.end(), + [](const QPair &a, const QPair &b) { + return a.second < b.second; + }); + + // 计算全文标记部分并刷新界面颜色标记 + markAllKeywordInView(); +} + +/** + * @brief 查询颜色标记范围内存在多少组替换文本的函数,对 \a markStart ~ \a markEnd 区间进行搜索, + * 判断 \a posList 中是否存在已查询到的替换文本位置索引,并将这些位置索引转换为索引区间列表返回。 + * @param posList 已查询的替换文本位置索引 + * @param markStart 颜色标记开始位置索引 + * @param markEnd 颜色标记结束位置索引 + * @param replaceText 替换的文本 + * @return 查找到和颜色标记位置有交叉的文本位置索引区间 + */ +static QPair findMatchRange(const QList &posList, int markStart, int markEnd, const QString &replaceText) +{ + // 判断颜色标记 info 范围内是否包含替换文本索引信息 + QPair foundPosRange {-1, -1}; + if (posList.isEmpty()) { + return foundPosRange; + } + + // 将颜色标记搜索范围向左延伸 replaceText.size() - 1 位置(),若此区间出现replaceText, 那么必定和 markStart ~ markEnd 相交 + int adjustMarkStart = markStart - replaceText.size(); + + // 获取最近的左侧查找文本位置索引,使用 qUpperBound, 索引必须大于 adjustMarkStart + auto leftfindItr = qUpperBound(posList.begin(), posList.end(), adjustMarkStart); + if (leftfindItr != posList.end() + && (*leftfindItr) < markEnd) { + // 设置查询的左边界 + foundPosRange.first = static_cast(std::distance(posList.begin(), leftfindItr)); + } + + // 获取最近的右侧查找文本位置索引(小于右边界 markEnd) + auto rightFindItr = qLowerBound(posList.rbegin(), posList.rend(), markEnd - 1, std::greater()); + if (rightFindItr != posList.rend() + && markStart < (*rightFindItr)) { + // 设置右边界 + foundPosRange.second = static_cast(std::distance(rightFindItr, posList.rend() - 1)); + } else if (-1 != foundPosRange.first) { + foundPosRange.second = foundPosRange.first; + } + + return foundPosRange; +} + +/** + * @brief 根据当前已查找到的替换文本偏移位置和颜色标记的交叉范围,调整颜色标记的位置 + * @param foundPosList 已查询的替换文本位置索引 + * @param info 需要计算的颜色标记 + * @param replaceText 被替换的文本 + * @param withText 替换后的文本 + */ +static void updateMarkReplaceRange(const QList &foundPosList, TextEdit::MarkReplaceInfo &info, const QString &replaceText, const QString &withText) +{ + // 文本替换长度变更调整量 + int adjustlen = withText.size() - replaceText.size(); + // 获取替换文本位置索引列表 + QPair posIndexRange = findMatchRange(foundPosList, info.start, info.end, replaceText); + + if (-1 == posIndexRange.first + && -1 == posIndexRange.second) { + // 颜色标记内不包含替换文本,和替换文本无交集 + // 根据当前查询位置判断 foundPosList[findCount - 1] 方向 + if (!foundPosList.isEmpty() + && info.end <= foundPosList.last()) { + // 处于颜色标记右侧,减去右侧替换文本的偏移量 + info.start += (foundPosList.size() - 1) * adjustlen; + info.end += (foundPosList.size() - 1) * adjustlen; + } else { + // 处于颜色标记左侧 + info.start += foundPosList.size() * adjustlen; + info.end += foundPosList.size() * adjustlen; + } + } else { + // 判断左侧是否有交集,拓展颜色标记到替换文本 + if (-1 != posIndexRange.first + && foundPosList[posIndexRange.first] <= info.start) { + // 存在交叉,调整位置到左侧替换位置起始边界 + info.start = foundPosList[posIndexRange.first] + (posIndexRange.first * adjustlen); + } else { + info.start += posIndexRange.first * adjustlen; + } + + // 判断右侧是否有交集,拓展颜色标记到替换文本 + if (-1 != posIndexRange.second + && info.end < (foundPosList[posIndexRange.second] + replaceText.size())) { + // 存在交叉,调整位置到右侧替换后文本的边界 + info.end = foundPosList[posIndexRange.second] + (posIndexRange.second * adjustlen) + withText.size(); + } else { + info.end += (posIndexRange.second + 1) * adjustlen; + } + } +} + +/** + * @brief 根据传入的颜色标记信息 \a replaceList 计算文本 \a oldText 替换后颜色标记的位置变化 + * 在文本替换过程前,记录当前标记光标位置,遍历需要替换的文本位置,记录需要修改的颜色标记位置变更。 + * @param replaceList 颜色标记替换信息 + * @param oldText 需要替换的文本内容 + * @param replaceText 被替换的文本 + * @param withText 替换后的文本 + * @param offset 非全文替换时使用,用于补充文本缺失部分偏移量 + * + * @note 文本替换颜色标记处理 + * @li MarkOnce 单个文本颜色标记 + * 1. 替换文本覆盖了颜色标记内容,移除颜色标记 + * 2. 替换文本和单个颜色标记内容存在交叉,包括替换文本处于颜色标记内,将颜色标记拓展到替换文本,替换文本的背景色显示为颜色标记背景色 + * 3. 若替换文本内包含多个颜色标记,每个颜色标记均拓展到替换文本,颜色标记显示层级按设置时间排列 + * @li MarkLine 单行文本颜色标记 + * 1. 同单个颜色标记处理 + * @li MarkAllMatch 单个文本全文查找颜色标记 + * 1. 替换前后不进行特殊处理 + * @li MarkAll 全文颜色标记 + * 1. 替换前后不进行特殊处理 + */ +void TextEdit::calcMarkReplaceList(QList &replaceList, const QString &oldText, const QString &replaceText, const QString &withText, int offset) const +{ + // 当前替换项为空或相同,退出 + if (replaceList.isEmpty() + || replaceText == withText) { + return; + } + + // 将传入的替换列表排序,按光标位置先后顺序进行排列 + std::sort(replaceList.begin(), replaceList.end(), [](const MarkReplaceInfo & a, const MarkReplaceInfo & b) { + return a.start < b.start; + }); + + // 当前标记的索引,后续使用 updateMarkRange() 初始化,设置为-1 + int currentMarkIndex = -1; + // 临时缓存的当前标记的索引范围 + QPair curMarkRange {0, 0}; + // 更新当前标记替换项索引和其对应的标记范围 + auto updateMarkIndexAndRange = [&]() { + currentMarkIndex++; + while (currentMarkIndex >= 0 && currentMarkIndex < replaceList.size()) { + auto &markInfo = replaceList.at(currentMarkIndex); + // 标记类型为标记全文或文本全文标记(使用文本查找而非光标位置),不进行替换处理 + if (MarkAllMatch == markInfo.opt.type + || MarkAll == markInfo.opt.type) { + currentMarkIndex++; + continue; + } + + curMarkRange = qMakePair(markInfo.start, markInfo.end); + break; + } + }; + updateMarkIndexAndRange(); + + // 查找统计及已查找偏移量 + int findOffset = 0; + QList foundPosList; + + // 查找替换位置,遍历查找替换文本出现位置 + int findPos = oldText.indexOf(replaceText, findOffset); + // 需要取得左侧所有的变更相对偏移,从文本左侧开始循环遍历 + while (-1 != findPos + && currentMarkIndex < replaceList.size()) { + // 转换为相对全文的偏移 + int realPos = findPos + offset; + // 记录已查询的索引位置 + foundPosList.append(realPos); + + // 获取替换文本区域和颜色标记区域的交叉关系 + Utils::RegionIntersectType type = Utils::checkRegionIntersect(realPos, realPos + replaceText.size(), + curMarkRange.first, curMarkRange.second); + + // 判断是否处于查询范围内,处于右侧区间则后续处理 + while (Utils::ERight != type) { + auto &info = replaceList[currentMarkIndex]; + + bool checkNext = false; + switch (type) { + case Utils::EIntersectInner: { + // 替换文本内容包含标记信息, 取消当前文本标记(无论单个文本还是单行文本,均移除) + // 在 manualUpdateAllMark() 函数处理会移除此标记 + info.start = 0; + info.end = 0; + checkNext = true; + break; + } + case Utils::ELeft: { + // 当前无交集,颜色标记在替换文本左侧,表示当前颜色标记已经经过 + updateMarkReplaceRange(foundPosList, info, replaceText, withText); + + checkNext = true; + break; + } + // 其它交叉类型需要等待颜色标记区间内所有替换文本均查找后处理,单个颜色标记中可能含多个替换文本 + default: + break; + } + + if (checkNext) { + // 更新当前计算的颜色标记和范围 + updateMarkIndexAndRange(); + // 判断颜色标记是否计算完成 + if (currentMarkIndex == replaceList.size()) { + break; + } + + // 继续查找下一颜色标记和当前查询位置的交叉范围 + type = Utils::checkRegionIntersect(realPos, realPos + replaceText.size(), curMarkRange.first, curMarkRange.second); + } else { + break; + } + } + + if (currentMarkIndex == replaceList.size()) { + break; + } + + // 继续查找替换文本位置 + findOffset = findPos + replaceText.size(); + findPos = oldText.indexOf(replaceText, findOffset); + } + + // 继续处理剩余颜色标记偏移 + while (currentMarkIndex != replaceList.size()) { + // 将后续未处理到的颜色标记调整偏移量 + auto &info = replaceList[currentMarkIndex]; + updateMarkReplaceRange(foundPosList, info, replaceText, withText); + + updateMarkIndexAndRange(); + } +} + +void TextEdit::markSelectWord() +{ + bool isFind = false; + for (int i = 0 ; i < m_wordMarkSelections.size(); ++i) { + QTextCursor curson = m_wordMarkSelections.at(i).first.cursor; + curson.movePosition(QTextCursor::EndOfLine); + QTextCursor currentCurson = textCursor(); + currentCurson.movePosition(QTextCursor::EndOfLine); + //if (m_wordMarkSelections.at(i).cursor == textCursor()) { + if (curson == currentCurson) { + isFind = true; + m_wordMarkSelections.removeAt(i); + renderAllSelections(); + break; + } + } + if (!isFind) { + //添加快捷键标记颜色 + ColorSelectWdg *pColorSelectWdg = static_cast(m_actionColorStyles->defaultWidget()); + isMarkCurrentLine(true, pColorSelectWdg->getDefaultColor().name()); + renderAllSelections(); + } +} + +void TextEdit::updateMark(int from, int charsRemoved, int charsAdded) +{ + //只读模式下实现禁止语音输入的效果 + if (m_readOnlyMode) { + //undo(); + return; + } + + //如果是读取文件导致的文本改变 + if (m_bIsFileOpen) { + return; + } + + //更新标记 + int nStartPos = 0,///< 标记的起始位置 + nEndPos = 0,///< 标记的结束位置 + nCurrentPos = 0;///< 当前光标位置 + QTextEdit::ExtraSelection selection;///< 指定文本格式 + QList listSelections;///< 指定文本格式列表 + QList> wordMarkSelections = m_wordMarkSelections;///< 标记列表 + QColor strColor;///< 指定文本颜色格式 + nCurrentPos = textCursor().position(); + + //如果是删除字符 + if (charsRemoved > 0) { + QList listRemoveItem;///< 要移除标记的indexs + + //寻找要移除标记的index + for (int i = 0; i < wordMarkSelections.count(); i++) { + + nEndPos = wordMarkSelections.value(i).first.cursor.selectionEnd(); + nStartPos = wordMarkSelections.value(i).first.cursor.selectionStart(); + strColor = wordMarkSelections.value(i).first.format.background().color(); + + //如果有文字被选择 + if (m_nSelectEndLine != -1) { + + //如果删除的内容,完全包含标记内容 + if (m_nSelectStart <= nStartPos && m_nSelectEnd >= nEndPos) { + listRemoveItem.append(i); + } + } else { + + //如果标记内容全部被删除 + if (wordMarkSelections.value(i).first.cursor.selection().toPlainText().isEmpty()) { + // 此时 remove m_wordMarkSelections中的元素 + // 会造成 m_wordMarkSelections 和 wordMarkSelections的长度不一致 + // m_wordMarkSelections.removeAt(i); + listRemoveItem.append(i); + } + } + } + + //从标记列表中移除标记 + for (int j = 0; j < listRemoveItem.count(); j++) { + // 不应该-j + // m_wordMarkSelections.removeAt(listRemoveItem.value(j) - j); + m_wordMarkSelections.removeAt(listRemoveItem.value(j)); + } + } + + //如果是添加字符 + if (charsAdded > 0) { + for (int i = 0; i < wordMarkSelections.count(); i++) { + nEndPos = wordMarkSelections.value(i).first.cursor.selectionEnd(); + nStartPos = wordMarkSelections.value(i).first.cursor.selectionStart(); + strColor = wordMarkSelections.value(i).first.format.background().color(); + qint64 timeStamp = wordMarkSelections.value(i).second; + + //如果字符添加在标记中 + if (nCurrentPos > nStartPos && nCurrentPos < nEndPos) { + + m_wordMarkSelections.removeAt(i); + selection.format.setBackground(strColor); + selection.cursor = textCursor(); + + QTextEdit::ExtraSelection preSelection; + + //如果是输入法输入 + if (m_bIsInputMethod) { + + //添加第一段标记 + selection.cursor.setPosition(nStartPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nCurrentPos - m_qstrCommitString.count(), QTextCursor::KeepAnchor); + m_wordMarkSelections.insert(i, QPair + (selection, timeStamp)); + + preSelection.cursor = selection.cursor; + preSelection.format = selection.format; + + //添加第二段标记 + selection.cursor.setPosition(nCurrentPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nEndPos, QTextCursor::KeepAnchor); + m_wordMarkSelections.insert(i + 1, QPair + (selection, timeStamp)); + + m_bIsInputMethod = false; + } else { + + //添加第一段标记 + selection.cursor.setPosition(nStartPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(from, QTextCursor::KeepAnchor); + m_wordMarkSelections.insert(i, QPair + (selection, timeStamp)); + + preSelection.cursor = selection.cursor; + preSelection.format = selection.format; + + //添加第二段标记 + selection.cursor.setPosition(nCurrentPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nEndPos, QTextCursor::KeepAnchor); + m_wordMarkSelections.insert(i + 1, QPair + (selection, timeStamp)); + } + + bool bIsFind = false; + + //在记录标记的表中替换(按标记动作记录) + for (int j = 0; j < m_mapWordMarkSelections.count(); j++) { + auto list = m_mapWordMarkSelections.value(j); + for (int k = 0; k < list.count(); k++) { + if (list.value(k).cursor == wordMarkSelections.value(i).first.cursor + && list.value(k).format == wordMarkSelections.value(i).first.format) { + list.removeAt(k); + listSelections = list; + listSelections.insert(k, preSelection); + listSelections.insert(k + 1, selection); + bIsFind = true; + break; + } + } + + if (bIsFind) { + m_mapWordMarkSelections.remove(j); + m_mapWordMarkSelections.insert(j, listSelections); + break; + } + } + break; + + } else if (nCurrentPos == nEndPos) { //如果字符添加在标记后 + m_wordMarkSelections.removeAt(i); + selection.format.setBackground(strColor); + selection.cursor = textCursor(); + + if (m_bIsInputMethod) { + selection.cursor.setPosition(nStartPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nEndPos - m_qstrCommitString.count(), QTextCursor::KeepAnchor); + m_bIsInputMethod = false; + } else { + selection.cursor.setPosition(nStartPos, QTextCursor::MoveAnchor); + selection.cursor.setPosition(from + charsAdded, QTextCursor::KeepAnchor); + } + + m_wordMarkSelections.insert(i, QPair + (selection, timeStamp)); + + bool bIsFind = false; + for (int j = 0; j < m_mapWordMarkSelections.count(); j++) { + auto list = m_mapWordMarkSelections.value(j); + for (int k = 0; k < list.count(); k++) { + if (list.value(k).cursor == wordMarkSelections.value(i).first.cursor + && list.value(k).format == wordMarkSelections.value(i).first.format) { + list.removeAt(k); + listSelections = list; + listSelections.insert(k, selection); + bIsFind = true; + break; + } + } + + if (bIsFind) { + m_mapWordMarkSelections.remove(j); + m_mapWordMarkSelections.insert(j, listSelections); + break; + } + } + break; + } + } + } + + //渲染所有的指定字符格式 + renderAllSelections(); + + highlight(); +} + +void TextEdit::setCursorStart(int pos) +{ + m_cursorStart = pos; +} + + +void TextEdit::completionWord(QString word) +{ + QString wordAtCursor = getWordAtCursor(); + QTextCursor cursor = textCursor(); + + QString completionString = word.remove(0, wordAtCursor.size()); + if (completionString.size() > 0) { + cursor = textCursor(); + cursor.insertText(completionString); + setTextCursor(cursor); + } +} + +bool TextEdit::eventFilter(QObject *object, QEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: { + QTouchEvent *touchEvent = static_cast(event); + QList touchPoints = touchEvent->touchPoints(); + QMouseEvent *event2 = static_cast(event); + DPlainTextEdit::mousePressEvent(event2); + if (touchPoints.count() == 3) { + slot_translate(); + } + break; + } + default: break; + } + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + m_mouseClickPos = mouseEvent->pos(); + + if (object == m_pLeftAreaWidget->m_pBookMarkArea) { + m_mouseClickPos = mouseEvent->pos(); + if (mouseEvent->button() == Qt::RightButton) { + m_rightMenu->clear(); + m_rightMenu->deleteLater(); + m_rightMenu = nullptr; + m_rightMenu = new DMenu(this); + connect(m_rightMenu, &DMenu::destroyed, this, &TextEdit::removeHighlightWordUnderCursor); + int line = getLineFromPoint(mouseEvent->pos()); + if (m_listBookmark.contains(line)) { + m_rightMenu->addAction(m_cancelBookMarkAction); + if (m_listBookmark.count() > 1) { + m_rightMenu->addAction(m_preBookMarkAction); + m_rightMenu->addAction(m_nextBookMarkAction); + } + } else { + m_rightMenu->addAction(m_addBookMarkAction); + } + + if (!m_listBookmark.isEmpty()) { + m_rightMenu->addAction(m_clearBookMarkAction); + } + + m_rightMenu->exec(mouseEvent->globalPos()); + } else { + addOrDeleteBookMark(); + } + return true; + } else if (object == m_pLeftAreaWidget->m_pFlodArea) { + m_foldCodeShow->hide(); + if (mouseEvent->button() == Qt::LeftButton) { + int line = getLineFromPoint(mouseEvent->pos()); + m_markFoldHighLightSelections.clear(); + renderAllSelections(); + + //不同类型文件注释符号不同 梁卫东 2020-09-03 17:28:45 + bool bHasCommnent = false; + QString multiLineCommentMark; + QString singleLineCommentMark; + + if (m_commentDefinition.isValid()) { + multiLineCommentMark = m_commentDefinition.multiLineStart.trimmed(); + singleLineCommentMark = m_commentDefinition.singleLine.trimmed(); + //qDebug()<<"CommentMark:"<findBlockByNumber(line - 1).text().trimmed().startsWith(multiLineCommentMark); + if (!singleLineCommentMark.isEmpty()) bHasCommnent = document()->findBlockByNumber(line - 1).text().trimmed().startsWith(singleLineCommentMark); + } else { + bHasCommnent = false; + } + + // 当前行line-1 判断下行line是否隐藏 + if (document()->findBlockByNumber(line).isVisible() && document()->findBlockByNumber(line - 1).text().contains("{") && !bHasCommnent) { + getNeedControlLine(line - 1, false); + document()->adjustSize(); + + //折叠时出现点击光标选择行变短 + QPlainTextEdit::LineWrapMode curMode = this->lineWrapMode(); + QPlainTextEdit::LineWrapMode WrapMode = curMode == QPlainTextEdit::NoWrap ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap; this->setWordWrapMode(QTextOption::WrapAnywhere); + this->setLineWrapMode(WrapMode); + viewport()->update(); + m_pLeftAreaWidget->updateBookMark(); + m_pLeftAreaWidget->updateCodeFlod(); + m_pLeftAreaWidget->updateLineNumber(); + this->setLineWrapMode(curMode); + viewport()->update(); + + } else if (!document()->findBlockByNumber(line).isVisible() && document()->findBlockByNumber(line - 1).text().contains("{") && !bHasCommnent) { + getNeedControlLine(line - 1, true); + document()->adjustSize(); + + //折叠时出现点击光标选择行变短 + QPlainTextEdit::LineWrapMode curMode = this->lineWrapMode(); + QPlainTextEdit::LineWrapMode WrapMode = curMode == QPlainTextEdit::NoWrap ? QPlainTextEdit::WidgetWidth : QPlainTextEdit::NoWrap; this->setWordWrapMode(QTextOption::WrapAnywhere); + this->setLineWrapMode(WrapMode); + viewport()->update(); + m_pLeftAreaWidget->updateBookMark(); + m_pLeftAreaWidget->updateCodeFlod(); + m_pLeftAreaWidget->updateLineNumber(); + this->setLineWrapMode(curMode); + viewport()->update(); + } else { + //其他不做处理 + } + + } else { + m_mouseClickPos = mouseEvent->pos(); + m_rightMenu->clear(); + m_rightMenu->deleteLater(); + m_rightMenu = nullptr; + m_rightMenu = new DMenu(this); + connect(m_rightMenu, &DMenu::destroyed, this, &TextEdit::removeHighlightWordUnderCursor); + int line = getLineFromPoint(mouseEvent->pos()); + + if (m_listFlodIconPos.contains(line - 1)) { + m_rightMenu->addAction(m_flodAllLevel); + m_rightMenu->addAction(m_unflodAllLevel); + m_rightMenu->addAction(m_flodCurrentLevel); + m_rightMenu->addAction(m_unflodCurrentLevel); + } + if (document()->findBlockByNumber(line).isVisible()) { + m_unflodCurrentLevel->setEnabled(false); + m_flodCurrentLevel->setEnabled(true); + } else { + m_unflodCurrentLevel->setEnabled(true); + m_flodCurrentLevel->setEnabled(false); + } + + //展开/折叠所有层次后,对应的菜单项置灰 + if (m_listMainFlodAllPos.count() == 0) { + m_unflodAllLevel->setEnabled(false); + } else { + bool bExistVisible = false; + bool bExistInVisble = false; + for (int iLine : m_listMainFlodAllPos) { + if (document()->findBlockByNumber(iLine + 1).isVisible()) { + m_flodAllLevel->setEnabled(true); + bExistVisible = true; + } else { + m_unflodAllLevel->setEnabled(true); + bExistInVisble = true; + } + + if (bExistVisible && bExistInVisble) { + break; + } + } + if (!bExistVisible) { + m_flodAllLevel->setEnabled(false); + m_unflodAllLevel->setEnabled(true); + } + if (!bExistInVisble) { + m_unflodAllLevel->setEnabled(false); + m_flodAllLevel->setEnabled(true); + } + } + + m_rightMenu->exec(mouseEvent->globalPos()); + } + + return true; + } + + } else if (event->type() == QEvent::HoverMove) { + QHoverEvent *hoverEvent = static_cast(event); + int line = getLineFromPoint(hoverEvent->pos()); + + if (object == m_pLeftAreaWidget->m_pBookMarkArea) { + m_nBookMarkHoverLine = line; + m_pLeftAreaWidget->m_pBookMarkArea->update(); + } else if (object == m_pLeftAreaWidget->m_pFlodArea) { + m_markFoldHighLightSelections.clear(); + renderAllSelections(); + + if (m_listFlodIconPos.contains(line - 1)) { + if (!document()->findBlockByNumber(line).isVisible()) { + m_foldCodeShow->clear(); + m_foldCodeShow->setStyle(lineWrapMode());//enum LineWrapMode {NoWrap,WidgetWidth}; + getHideRowContent(line - 1); + m_foldCodeShow->show(); + m_foldCodeShow->hideFirstBlock(); + m_foldCodeShow->move(5, getLinePosYByLineNum(line)); + } else { + QTextCursor previousCursor = textCursor(); + int ivalue = this->verticalScrollBar()->value(); + int iLine = getHighLightRowContentLineNum(line - 1); + + if (line - 1 == iLine) return false; + + QTextEdit::ExtraSelection selection; + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + + QTextBlock startblock; + QTextBlock endblock = document()->findBlockByNumber(iLine); + startblock = document()->findBlockByNumber(line - 1); + + QTextCursor beginCursor(startblock); + beginCursor.setPosition(startblock.position() + startblock.text().indexOf("{"), QTextCursor::MoveAnchor); + + + beginCursor.setPosition(endblock.position() + endblock.text().indexOf("}") + 1, QTextCursor::KeepAnchor); + + if (iLine == document()->blockCount() - 1) + beginCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + + setTextCursor(beginCursor); + selection.cursor = textCursor(); + + QColor highlightBackground = DGuiApplicationHelper::instance()->applicationPalette().color(QPalette::Highlight); + highlightBackground.setAlphaF(0.4); + selection.format.setBackground(highlightBackground); + m_markFoldHighLightSelections.push_back(selection); + + renderAllSelections(); + setTextCursor(QTextCursor(document()->findBlockByNumber(line - 1))); + this->verticalScrollBar()->setValue(ivalue); + } + } else { + m_foldCodeShow->hide(); + } + + return true; + } + + } else if (event->type() == QEvent::HoverLeave) { + if (object == m_pLeftAreaWidget->m_pBookMarkArea) { + m_nBookMarkHoverLine = -1; + m_pLeftAreaWidget->m_pBookMarkArea->update(); + return true; + } else if (object == m_pLeftAreaWidget->m_pFlodArea) { + m_markFoldHighLightSelections.clear(); + m_foldCodeShow->hide(); + renderAllSelections(); + return true; + } + } else if (event->type() == QEvent::MouseButtonDblClick) { + m_bIsDoubleClick = true; + m_bBeforeIsDoubleClick = true; + } else if (object == m_colorMarkMenu) { + // 进行对于 color mark menu 的特殊按键处理 + if (event->type() == QEvent::KeyRelease) { + QKeyEvent *keyEvent = static_cast(event); + + // 当前仅处理 Tab 键 , 保留后续其他按键的处理 + if (keyEvent->key() == Qt::Key_Tab) { + // handleKey 作用是保留后续增加方向键处理 + int handleKey = keyEvent->key(); + + // 使用Timer进行后续处理,避免在此处处理后,和基类的处理造成混淆 + QTimer::singleShot(0, this, [ = ]() { + // 仅当 menu 可见时进行处理,当前仅处理Tab键 + if (m_colorMarkMenu->isVisible() && handleKey == Qt::Key_Tab) { + QAction *currentAction = m_colorMarkMenu->activeAction(); + QAction *nextAction = nullptr; + int currentIndex = -1; + + // 如果没有当前 focus item , 不需要进行处理 + if (currentAction == nullptr) { + return; + } + + // 遍历 Order List, 如果不符合 order list 规则,变更focus item + for (int i = 0; i < m_MarkColorMenuTabOrder.size(); i++) { + QPair orderItem = m_MarkColorMenuTabOrder.at(i); + + if (orderItem.first == currentAction) { + // 设置当前 item 位置 + currentIndex = i; + + if (orderItem.second == true) { + // 允许 focus, 不进行处理,退出 + return; + } else { + // 退出当前查找循环,进行后续处理 + break; + } + } + } + + if (currentIndex == -1) { + qWarning() << " can not find current item in tab order list , need check 'Mark Color Menu' tab order setting!"; + return; + } + + // 在 order list中,寻找下一个item + for (int j = currentIndex + 1; j < m_MarkColorMenuTabOrder.size(); j++) { + QPair newOrderItem = m_MarkColorMenuTabOrder.at(j); + + if (newOrderItem.second == true) { + nextAction = newOrderItem.first; + break; + } + } + + // 原 order list 中不存在后一个可用item, 从列表头开始头查找 + if (nextAction == nullptr) { + // 从头进行查找,因为i为当前位置,查找到i就足够 + for (int j = 0; j < currentIndex; j++) { + QPair newOrderItem = m_MarkColorMenuTabOrder.at(j); + + if (newOrderItem.second == true) { + nextAction = newOrderItem.first; + break; + } + } + } + + // 为找到的新item设置focus + if (nextAction != nullptr) { + m_colorMarkMenu->setActiveAction(nextAction); + } else { + qWarning() << " can not find valid item , need check 'Mark Color Menu' tab order setting!"; + } + } + }); + } + } + } + + return QPlainTextEdit::eventFilter(object, event); +} + +void TextEdit::adjustScrollbarMargins() +{ + QEvent event(QEvent::LayoutRequest); + QApplication::sendEvent(this, &event); + + QMargins margins = viewportMargins(); + setViewportMargins(0, 0, 5, 0); + setViewportMargins(margins); + if (!verticalScrollBar()->visibleRegion().isEmpty()) { + setViewportMargins(0, 0, 5, 0); //-verticalScrollBar()->sizeHint().width() 原本的第三个参数 + //setViewportMargins(0, 0, -verticalScrollBar()->sizeHint().width(), 0); + } else { + setViewportMargins(0, 0, 5, 0); + } +} + +void TextEdit::slotSelectionChanged() +{ + if (textCursor().hasSelection()) { + hideCursorBlink(); + } else { + showCursorBlink(); + } +} + +void TextEdit::slotCanRedoChanged(bool bCanRedo) +{ + Q_UNUSED(bCanRedo) + bool isModified = this->m_wrapper->isTemFile() | (m_pUndoStack->canUndo() || m_pUndoStack->index() != m_lastSaveIndex); + this->m_wrapper->window()->updateModifyStatus(m_sFilePath, isModified); + this->m_wrapper->OnUpdateHighlighter(); +} + +void TextEdit::slotCanUndoChanged(bool bCanUndo) +{ + bool isModified = this->m_wrapper->isTemFile() | (bCanUndo || m_pUndoStack->index() != m_lastSaveIndex); + this->m_wrapper->window()->updateModifyStatus(m_sFilePath, isModified); + this->m_wrapper->OnUpdateHighlighter(); +} + +bool TextEdit::containsExtraSelection(QList listSelections, QTextEdit::ExtraSelection selection) +{ + for (int i = 0; i < listSelections.count(); i++) { + if (listSelections.value(i).cursor == selection.cursor + && listSelections.value(i).format == selection.format) { + return true; + } + } + return false; +} + +void TextEdit::appendExtraSelection(QList wordMarkSelections + , QTextEdit::ExtraSelection selection, QString strColor + , QList *listSelections) +{ +// 没有使用的方法,应该去除,降低维护成本 +// 由于需要处理对应的单元测试,暂时不完全移除此函数,后期将统一进行处理 +#if 1 + // 去除参数未使用警告 + Q_UNUSED(wordMarkSelections) + Q_UNUSED(selection) + Q_UNUSED(strColor) + Q_UNUSED(listSelections) +#else + //如果文档中有标记 + if (wordMarkSelections.count() > 0) { + bool bIsContains = false;///< 是否占用已有标记 + int nWordMarkSelectionStart = 0,///< 已有标记起始位置 + nSelectionStart = 0,///< 标记起始位置 + nWordMarkSelectionEnd = 0,///< 已有标记结束位置 + nSelectionEnd = 0;///< 标记结束位置 + + //按大小确定标记的起始和结束位置 + if (selection.cursor.selectionStart() > selection.cursor.selectionEnd()) { + nSelectionStart = selection.cursor.selectionEnd(); + nSelectionEnd = selection.cursor.selectionStart(); + } else { + nSelectionStart = selection.cursor.selectionStart(); + nSelectionEnd = selection.cursor.selectionEnd(); + } + + for (int i = 0; i < wordMarkSelections.count(); i++) { + + //按大小确定已有标记的起始和结束位置 + if (wordMarkSelections.value(i).cursor.selectionStart() > wordMarkSelections.value(i).cursor.selectionEnd()) { + nWordMarkSelectionStart = wordMarkSelections.value(i).cursor.selectionEnd(); + nWordMarkSelectionEnd = wordMarkSelections.value(i).cursor.selectionStart(); + } else { + nWordMarkSelectionStart = wordMarkSelections.value(i).cursor.selectionStart(); + nWordMarkSelectionEnd = wordMarkSelections.value(i).cursor.selectionEnd(); + } + + //如果被已有标记包含 + if ((nWordMarkSelectionStart <= nSelectionStart && nWordMarkSelectionEnd > nSelectionEnd) + || (nWordMarkSelectionStart < nSelectionStart && nWordMarkSelectionEnd >= nSelectionEnd)) { + + bIsContains = true; + selection.format.setBackground(QColor(strColor)); + + //如果标记格式不相同 + if (wordMarkSelections.value(i).format != selection.format) { + int nRemPos = 0;///< 标记插入位置 + + //移除已有标记 + for (int j = 0; j < wordMarkSelections.count(); j++) { + if (m_wordMarkSelections.value(j).cursor == wordMarkSelections.value(i).cursor + && m_wordMarkSelections.value(j).format == wordMarkSelections.value(i).format) { + + m_wordMarkSelections.removeAt(j); + nRemPos = j; + break; + } + } + + //重新记录标记 + selection.cursor.setPosition(nWordMarkSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nSelectionStart, QTextCursor::KeepAnchor); + selection.format.setBackground(wordMarkSelections.value(i).format.background()); + + bool bIsInsert = false;///< 标记是否将原有标记分成两段 + + //如果第一段存在 + if (selection.cursor.selectedText() != "") { + bIsInsert = true; + m_wordMarkSelections.insert(nRemPos, selection); + } + + QTextEdit::ExtraSelection preSelection; + preSelection.format = selection.format; + preSelection.cursor = selection.cursor; + + selection.cursor.setPosition(nSelectionEnd, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nWordMarkSelectionEnd, QTextCursor::KeepAnchor); + + //如果第二段存在 + if (selection.cursor.selectedText() != "") { + if (bIsInsert) { + m_wordMarkSelections.insert(nRemPos + 1, selection); + } else { + m_wordMarkSelections.insert(nRemPos, selection); + } + } + + //从记录标记的表中替换原有标记(按标记动作记录) + QList selecList; + bool bIsFind = false;///< 是否有包含该标记的标记动作 + + for (int j = 0; j < m_mapWordMarkSelections.count(); j++) { + auto list = m_mapWordMarkSelections.value(j); + + for (int k = 0; k < list.count(); k++) { + if (list.value(k).cursor == wordMarkSelections.value(i).cursor + && list.value(k).format == wordMarkSelections.value(i).format) { + + list.removeAt(k); + selecList = list; + bIsInsert = false; + + if (preSelection.cursor.selectedText() != "") { + bIsInsert = true; + selecList.insert(k, preSelection); + } + + if (selection.cursor.selectedText() != "") { + if (bIsInsert) { + selecList.insert(k + 1, selection); + } else { + selecList.insert(k, selection); + } + } + + bIsFind = true; + break; + } + } + + if (bIsFind) { + m_mapWordMarkSelections.remove(j); + m_mapWordMarkSelections.insert(j, selecList); + break; + } + } + + //记录新添加的标记 + selection.cursor.setPosition(nSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nSelectionEnd, QTextCursor::KeepAnchor); + selection.format.setBackground(QColor(strColor)); + m_wordMarkSelections.append(selection); + listSelections->append(selection); + } + } else if (nWordMarkSelectionStart >= nSelectionStart && nWordMarkSelectionEnd <= nSelectionEnd) { //如果标记包含已有标记 + bIsContains = true; + selection.format.setBackground(QColor(strColor)); + + //移除已有标记 + for (int j = 0; j < wordMarkSelections.count(); j++) { + if (m_wordMarkSelections.value(j).cursor == wordMarkSelections.value(i).cursor + && m_wordMarkSelections.value(j).format == wordMarkSelections.value(i).format) { + m_wordMarkSelections.removeAt(j); + break; + } + } + + //记录新添加的标记 + m_wordMarkSelections.append(selection); + + //如果标记格式不相同 + if (wordMarkSelections.value(i).format != selection.format) { + + QList selecList; + bool bIsFind = false;///< 是否有包含该标记的标记动作 + + //从记录标记的表中替换原有标记(按标记动作记录) + for (int j = 0; j < m_mapWordMarkSelections.count(); j++) { + auto list = m_mapWordMarkSelections.value(j); + for (int k = 0; k < list.count(); k++) { + if (list.value(k).cursor == wordMarkSelections.value(i).cursor + && list.value(k).format == wordMarkSelections.value(i).format) { + + list.removeAt(k); + selecList = list; + bIsFind = true; + break; + } + } + + if (bIsFind) { + m_mapWordMarkSelections.remove(j); + m_mapWordMarkSelections.insert(j, selecList); + break; + } + } + } + + listSelections->append(selection); + } else if (nWordMarkSelectionEnd < nSelectionEnd && nWordMarkSelectionStart < nSelectionStart + && nWordMarkSelectionEnd > nSelectionStart) { //如果添加的标记占有原有标记的后段部分 + + selection.format.setBackground(QColor(strColor)); + int nRemPos = 0;///< 标记插入位置 + + //移除已有标记 + for (int j = 0; j < wordMarkSelections.count(); j++) { + if (m_wordMarkSelections.value(j).cursor == wordMarkSelections.value(i).cursor + && m_wordMarkSelections.value(j).format == wordMarkSelections.value(i).format) { + m_wordMarkSelections.removeAt(j); + nRemPos = j; + break; + } + } + + //如果标记格式不相同 + if (wordMarkSelections.value(i).format != selection.format) { + + //从记录标记的表中替换原有标记(分行记录) + selection.cursor.setPosition(nWordMarkSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nSelectionStart, QTextCursor::KeepAnchor); + selection.format.setBackground(wordMarkSelections.value(i).format.background()); + m_wordMarkSelections.insert(nRemPos, selection); + + QList selecList; + bool bIsFind = false;///< 是否有包含该标记的标记动作 + + //从记录标记的表中替换原有标记(按标记动作记录) + for (int j = 0; j < m_mapWordMarkSelections.count(); j++) { + auto list = m_mapWordMarkSelections.value(j); + for (int k = 0; k < list.count(); k++) { + if (list.value(k).cursor == wordMarkSelections.value(i).cursor + && list.value(k).format == wordMarkSelections.value(i).format) { + list.removeAt(k); + selecList = list; + selecList.insert(k, selection); + bIsFind = true; + break; + } + } + + if (bIsFind) { + m_mapWordMarkSelections.remove(j); + m_mapWordMarkSelections.insert(j, selecList); + break; + } + } + + //记录新添加的标记 + selection.cursor.setPosition(nSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nSelectionEnd, QTextCursor::KeepAnchor); + selection.format.setBackground(QColor(strColor)); + m_wordMarkSelections.append(selection); + } else { //如果标记格式相同 + selection.cursor.setPosition(nWordMarkSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nSelectionEnd, QTextCursor::KeepAnchor); + m_wordMarkSelections.insert(nRemPos, selection); + } + + if (!bIsContains) { + listSelections->append(selection); + } + + bIsContains = true; + } else if (nWordMarkSelectionEnd > nSelectionEnd && nWordMarkSelectionStart > nSelectionStart + && nWordMarkSelectionStart < nSelectionEnd) { //如果添加的标记占有原有标记的前段部分 + + selection.format.setBackground(QColor(strColor)); + int nRemPos = 0;///< 标记插入位置 + + //移除已有标记 + for (int j = 0; j < wordMarkSelections.count(); j++) { + if (m_wordMarkSelections.value(j).cursor == wordMarkSelections.value(i).cursor + && m_wordMarkSelections.value(j).format == wordMarkSelections.value(i).format) { + m_wordMarkSelections.removeAt(j); + nRemPos = j; + break; + } + } + + //如果标记格式不相同 + if (wordMarkSelections.value(i).format != selection.format) { + + //从记录标记的表中替换原有标记(分行记录) + selection.cursor.setPosition(nSelectionEnd, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nWordMarkSelectionEnd, QTextCursor::KeepAnchor); + selection.format.setBackground(wordMarkSelections.value(i).format.background()); + m_wordMarkSelections.insert(nRemPos, selection); + + QList selecList; + bool bIsFind = false; + + //从记录标记的表中替换原有标记(按标记动作记录) + for (int j = 0; j < m_mapWordMarkSelections.count(); j++) { + auto list = m_mapWordMarkSelections.value(j); + for (int k = 0; k < list.count(); k++) { + if (list.value(k).cursor == wordMarkSelections.value(i).cursor + && list.value(k).format == wordMarkSelections.value(i).format) { + list.removeAt(k); + selecList = list; + selecList.insert(k, selection); + bIsFind = true; + break; + } + } + + if (bIsFind) { + m_mapWordMarkSelections.remove(j); + m_mapWordMarkSelections.insert(j, selecList); + break; + } + } + + //记录新添加的标记 + selection.cursor.setPosition(nSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nSelectionEnd, QTextCursor::KeepAnchor); + selection.format.setBackground(QColor(strColor)); + m_wordMarkSelections.append(selection); + } else { //如果标记格式相同 + selection.cursor.setPosition(nSelectionStart, QTextCursor::MoveAnchor); + selection.cursor.setPosition(nWordMarkSelectionEnd, QTextCursor::KeepAnchor); + m_wordMarkSelections.insert(nRemPos, selection); + } + + if (!bIsContains) { + listSelections->append(selection); + } + bIsContains = true; + } + } + + if (!bIsContains) { + selection.format.setBackground(QColor(strColor)); + m_wordMarkSelections.append(selection); + listSelections->append(selection); + } + + } else { //如果文档中没有标记 + selection.format.setBackground(QColor(strColor)); + m_wordMarkSelections.append(selection); + listSelections->append(selection); + } +#endif +} + +void TextEdit::onSelectionArea() +{ + if (textCursor().hasSelection()) { + m_nSelectStart = textCursor().selectionStart(); + m_nSelectEnd = textCursor().selectionEnd(); + m_nSelectEndLine = document()->findBlock(textCursor().selectionEnd()).blockNumber() + 1; + } else { + m_nSelectEndLine = -1; + } + + //防止三次点击选中一整行的功能失效 + if (m_bIsDoubleClick == true) { + m_bIsDoubleClick = false; + return; + } else if (m_bBeforeIsDoubleClick == true && textCursor().selectedText() != "") { + m_bBeforeIsDoubleClick = false; + return; + } + + if (m_gestureAction != GA_null) { + QTextCursor cursor = textCursor(); + if (cursor.selectedText() != "") { + cursor.clearSelection(); + setTextCursor(cursor); + } + } +} + +void TextEdit::fingerZoom(QString name, QString direction, int fingers) +{ + if (name == "tap" && fingers == 3) { + slot_translate(); + } + // 当前窗口被激活,且有焦点 + if (hasFocus()) { + if (name == "pinch" && fingers == 2) { + if (direction == "in") { + // 捏合 in是手指捏合的方向 向内缩小 + qobject_cast(this->window())->decrementFontSize(); + } else if (direction == "out") { + // 捏合 out是手指捏合的方向 向外放大 + qobject_cast(this->window())->incrementFontSize(); + } + } + } +} + +void TextEdit::dragEnterEvent(QDragEnterEvent *event) +{ + QPlainTextEdit::dragEnterEvent(event); + qobject_cast(this->window())->requestDragEnterEvent(event); +} + +void TextEdit::dragMoveEvent(QDragMoveEvent *event) +{ + if (m_readOnlyMode) { + return; + } + + const QMimeData *data = event->mimeData(); + + if (data->hasUrls()) { + event->acceptProposedAction(); + } else { + QPlainTextEdit::dragMoveEvent(event); + } +} + +void TextEdit::dropEvent(QDropEvent *event) +{ + const QMimeData *data = event->mimeData(); + + // 判断是否存在url信息,需要注意即使hasUrls()为true, urls()仍可能返回空,使用urls().first()可能越界 + QList dataUrls; + if (data->hasUrls()) { + dataUrls = data->urls(); + } + + if (!dataUrls.isEmpty() && dataUrls.first().isLocalFile()) { + qobject_cast(this->window())->requestDropEvent(event); + } else if (data->hasText() && !m_readOnlyMode) { + //drag text in the same editor + if (event->source() && event->source()->parent() == this) { + auto cursor = this->textCursor(); + int srcpos = std::min(cursor.position(), cursor.anchor()); + //use default behavior to make the cursor blink normally + QPlainTextEdit::dropEvent(event); + cursor = this->textCursor(); + int dstpos = std::min(cursor.position(), cursor.anchor()) - data->text().size(); + + // 检测是否为拷贝文件而不是移动文件,使用Ctrl仅拷贝 + bool copyText = event->keyboardModifiers().testFlag(Qt::ControlModifier); + + //fall back to the original state + if (srcpos != dstpos) { + cursor.setPosition(dstpos); + cursor.setPosition(dstpos + data->text().size(), QTextCursor::KeepAnchor); + cursor.deleteChar(); + + cursor.setPosition(srcpos); + // 拷贝模式下不对原文本操作 + if (!copyText) { + cursor.insertText(data->text()); + } + } + if (srcpos < dstpos && !copyText) { + dstpos += data->text().size(); + } + + //perform moveText operation + moveText(srcpos, dstpos, data->text(), copyText); + + //drag text to another editor + } else if (event->source() && event->source()->parent() != this) { + + //use default behavior to make the cursor blink normally + QPlainTextEdit::dropEvent(event); + + //operations in the destination editor. + //firstly do the restore operation, + //then, insert the text + auto cursor = this->textCursor(); + int dstpos = std::min(cursor.position(), cursor.anchor()) - data->text().size(); + cursor.setPosition(dstpos); + cursor.setPosition(dstpos + data->text().size(), QTextCursor::KeepAnchor); + cursor.deleteChar(); + auto com = new InsertTextUndoCommand(cursor, data->text(), this); + m_pUndoStack->push(com); + + //operations in the source editor. + //firstly do the restore operation, + //then, delete the text + auto another = qobject_cast(event->source()->parent()); + auto cursor2 = another->textCursor(); + cursor2.insertText(data->text()); + cursor2.setPosition(cursor2.position() - data->text().size(), QTextCursor::KeepAnchor); + auto com2 = new DeleteBackCommand(cursor2, another); + another->m_pUndoStack->push(com2); + } else if (!data->text().isEmpty()) { + if (m_bReadOnlyPermission || m_readOnlyMode) { + return; + } + + QPlainTextEdit::dropEvent(event); + auto cursor = this->textCursor(); + int dstpos = std::min(cursor.position(), cursor.anchor()) - data->text().size(); + cursor.setPosition(dstpos); + cursor.setPosition(dstpos + data->text().size(), QTextCursor::KeepAnchor); + cursor.deleteChar(); + auto com = new InsertTextUndoCommand(cursor, data->text(), this); + m_pUndoStack->push(com); + } + } else { + QPlainTextEdit::dropEvent(event); + } +} + +void TextEdit::inputMethodEvent(QInputMethodEvent *e) +{ + m_bIsInputMethod = true; + + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + if (m_readOnlyMode || m_bReadOnlyPermission) { + return; + } + + if (m_isPreeditBefore) { + // 每次 preedit 都是完整的字符串,所以撤销上次的 preedit + undo_(); + + // 将光标移回原位 + if (Overwrite == m_cursorMode) { + auto cursor = textCursor(); + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, m_preeditLengthBefore); + setTextCursor(cursor); + } + } + bool isPreedit = !e->preeditString().isEmpty(); + if (isPreedit || !e->commitString().isEmpty()) { + const QString &text = isPreedit ? e->preeditString() : e->commitString(); + + //列编辑添加撤销重做 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + insertColumnEditTextEx(text); + } else { + // 覆盖模式下输入法输入时,单独处理,模拟选中替换处理 + if (Overwrite == m_cursorMode) { + auto cursor = this->textCursor(); + // 设置光标选中后续与当前输入法输入的文本相同长度 + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, text.size()); + // 使用此光标信息插入将输入的文本替换选中的长度 + insertSelectTextEx(cursor, text); + } else { + insertSelectTextEx(textCursor(), text); + } + } + + m_isSelectAll = false; + } + + m_isPreeditBefore = isPreedit; + m_preeditLengthBefore = e->preeditString().length(); + +} + +void TextEdit::mousePressEvent(QMouseEvent *e) +{ + if (m_bIsFindClose) { + m_bIsFindClose = false; + removeKeywords(); + } + if (e->button() != Qt::RightButton) + m_isSelectAll = false; + + if (Qt::MouseEventSynthesizedByQt == e->source()) { + m_startY = e->y(); + m_startX = e->x(); + } + if (e->source() == Qt::MouseEventSynthesizedByQt) { + m_lastTouchBeginPos = e->pos(); + + if (QScroller::hasScroller(this)) { + QScroller::scroller(this)->deleteLater(); + } + + if (m_updateEnableSelectionByMouseTimer) { + m_updateEnableSelectionByMouseTimer->stop(); + } else { + m_updateEnableSelectionByMouseTimer = new QTimer(this); + m_updateEnableSelectionByMouseTimer->setSingleShot(true); + + static QObject *theme_settings = reinterpret_cast(qvariant_cast(qApp->property("_d_theme_settings_object"))); + QVariant touchFlickBeginMoveDelay; + + if (theme_settings) { + touchFlickBeginMoveDelay = theme_settings->property("touchFlickBeginMoveDelay"); + } + + m_updateEnableSelectionByMouseTimer->setInterval(touchFlickBeginMoveDelay.isValid() ? touchFlickBeginMoveDelay.toInt() : 300); + connect(m_updateEnableSelectionByMouseTimer, &QTimer::timeout, m_updateEnableSelectionByMouseTimer, &QTimer::deleteLater); + } + + m_updateEnableSelectionByMouseTimer->start(); + } + + //add for single refers to the sliding + if (e->type() == QEvent::MouseButtonPress && e->source() == Qt::MouseEventSynthesizedByQt) { + m_lastMouseTimeX = e->timestamp(); + m_lastMouseTimeY = e->timestamp(); + m_lastMouseYpos = e->pos().y(); + m_lastMouseXpos = e->pos().x(); + + if (tweenY.activeY()) { + m_slideContinueY = true; + tweenY.stopY(); + } + + if (tweenX.activeX()) { + m_slideContinueX = true; + tweenX.stopX(); + } + } + + if (e->modifiers() == Qt::AltModifier) { + m_bIsAltMod = true; + //鼠标点击位置为光标位置  获取光标行列位置 + QMouseEvent *mouseEvent = static_cast(e); + m_altStartTextCursor = this->cursorForPosition(mouseEvent->pos()); + m_altStartTextCursor.clearSelection(); + this->setTextCursor(m_altStartTextCursor); + m_altModSelections.clear(); + } else { + if (e->button() != 2) { //右键,调用右键菜单时候不能清空 + m_bIsAltMod = false; + m_altModSelections.clear(); + } + } + + QPlainTextEdit::mousePressEvent(e); +} + +void TextEdit::mouseMoveEvent(QMouseEvent *e) +{ + if (Qt::MouseEventSynthesizedByQt == e->source()) { + m_endY = e->y(); + m_endX = e->x(); + } + + //add for single refers to the sliding + if (e->type() == QEvent::MouseMove && e->source() == Qt::MouseEventSynthesizedByQt) { + const ulong diffTimeX = e->timestamp() - m_lastMouseTimeX; + const ulong diffTimeY = e->timestamp() - m_lastMouseTimeY; + const int diffYpos = e->pos().y() - m_lastMouseYpos; + const int diffXpos = e->pos().x() - m_lastMouseXpos; + m_lastMouseTimeX = e->timestamp(); + m_lastMouseTimeY = e->timestamp(); + m_lastMouseYpos = e->pos().y(); + m_lastMouseXpos = e->pos().x(); + + if (m_gestureAction == GA_slide) { + QFont font = this->font(); + + /*开根号时数值越大衰减比例越大*/ + qreal direction = diffYpos > 0 ? 1.0 : -1.0; + slideGestureY(-direction * sqrt(abs(diffYpos)) / font.pointSize()); + qreal directionX = diffXpos > 0 ? 1.0 : -1.0; + slideGestureX(-directionX * sqrt(abs(diffXpos)) / font.pointSize()); + + /*预算惯性滑动时间*/ + m_stepSpeedY = static_cast(diffYpos) / static_cast(diffTimeY + 0.000001); + durationY = sqrt(abs(m_stepSpeedY)) * 1000; + m_stepSpeedX = static_cast(diffXpos) / static_cast(diffTimeX + 0.000001); + durationX = sqrt(abs(m_stepSpeedX)) * 1000; + + /*预算惯性滑动距离,4.0为调优数值*/ + m_stepSpeedY /= sqrt(font.pointSize() * 4.0); + changeY = m_stepSpeedY * sqrt(abs(m_stepSpeedY)) * 100; + m_stepSpeedX /= sqrt(font.pointSize() * 4.0); + changeX = m_stepSpeedX * sqrt(abs(m_stepSpeedX)) * 100; + + //return true; + } + + if (m_gestureAction != GA_null) { + //return true; + } + } + + // other apps will override their own cursor when opened + // so they need to be restored. + QApplication::restoreOverrideCursor(); + + if (viewport()->cursor().shape() != Qt::IBeamCursor) { + viewport()->setCursor(Qt::IBeamCursor); + } + + QPlainTextEdit::mouseMoveEvent(e); + + if (e->modifiers() == Qt::AltModifier && m_bIsAltMod) { + m_altModSelections.clear(); + QMouseEvent *mouseEvent = static_cast(e); + + QPoint curPos = mouseEvent->pos(); + m_altEndTextCursor = this->cursorForPosition(curPos); + + int column = m_altEndTextCursor.positionInBlock(); + int row = m_altEndTextCursor.blockNumber(); + + int startColumn = m_altStartTextCursor.positionInBlock(); + int startRow = m_altStartTextCursor.blockNumber(); + + int minColumn = startColumn < column ? startColumn : column; + int maxColumn = startColumn > column ? startColumn : column; + int minRow = startRow < row ? startRow : row; + int maxRow = startRow > row ? startRow : row; + + QTextCharFormat format; + QPalette palette; + QColor highlightBackground = DGuiApplicationHelper::instance()->applicationPalette().color(QPalette::Highlight); + format.setBackground(highlightBackground); + format.setForeground(palette.highlightedText()); + + for (int iRow = minRow; iRow <= maxRow; iRow++) { + QTextBlock block = document()->findBlockByNumber(iRow); + QTextCursor cursor(block); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); + + QPoint blockTailPos = this->cursorRect(cursor).bottomRight(); + + //位置从0开始 + int length = block.text().length(); + + //鼠标x坐标大于当前块最后字符位置 遍历获取最大块长度 + if (curPos.x() >= blockTailPos.x() && length > maxColumn) { + maxColumn = length; + } + } + + + for (int iRow = minRow; iRow <= maxRow; iRow++) { + QTextBlock block = document()->findBlockByNumber(iRow); + int length = block.text().size(); + + if (length < minColumn) continue; + + QTextEdit::ExtraSelection selection; + QTextCursor cursor = this->textCursor(); + cursor.clearSelection(); + setTextCursor(cursor); + cursor.setPosition(block.position() + minColumn, QTextCursor::MoveAnchor); + if (length < maxColumn) { + cursor.setPosition(block.position() + length, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(block.position() + maxColumn, QTextCursor::KeepAnchor); + } + + selection.cursor = cursor; + selection.format = format; + m_altModSelections << selection; + } + + renderAllSelections(); + update(); + } +} + +void TextEdit::mouseReleaseEvent(QMouseEvent *e) +{ + //add for single refers to the sliding + if (e->type() == QEvent::MouseButtonRelease && e->source() == Qt::MouseEventSynthesizedByQt) { + if (m_gestureAction == GA_slide) { + + tweenX.startX(0, 0, changeX, durationX, std::bind(&TextEdit::slideGestureX, this, std::placeholders::_1)); + tweenY.startY(0, 0, changeY, durationY, std::bind(&TextEdit::slideGestureY, this, std::placeholders::_1)); + } + + m_gestureAction = GA_null; + } + + int i = m_endY - m_startY; + int k = m_endX - m_startX; + if (Qt::MouseEventSynthesizedByQt == e->source() + && (i > 10 && this->verticalScrollBar()->value() != 0) + && (k > 10 && this->horizontalScrollBar()->value() != 0)) { + e->accept(); + return; + } + + if (e->button() == Qt::MidButton) { + bool midButtonPaste = m_settings->settings->option("advance.editor.allow_midbutton_paste")->value().toBool(); + if (midButtonPaste) { + // 只读模式过滤鼠标中间黏贴 + if (m_readOnlyMode || m_bReadOnlyPermission) { + popupNotify(tr("Read-Only mode is on")); + return; + } + + slotPasteAction(); + } + return; + } + + return QPlainTextEdit::mouseReleaseEvent(e); +} + +void TextEdit::keyPressEvent(QKeyEvent *e) +{ + Qt::KeyboardModifiers modifiers = e->modifiers(); + QString key = Utils::getKeyshortcut(e); + + //没有修改键 插入文件 + //按下esc的时候,光标退出编辑区,切换至标题栏 + if (modifiers == Qt::NoModifier && e->key() == Qt::Key_Escape) { + emit signal_setTitleFocus(); + return; + } + + if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "copy")) { + slotCopyAction(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "selectall")) { +#if 0 + //2021-2-25:setSelectAll()替换 + if (m_wrapper->getFileLoading()) { + return; + } + m_bIsAltMod = false; + selectAll(); +#endif + setSelectAll(); + return; + } + + if (m_readOnlyMode || m_bReadOnlyPermission) { + if (key == "J") { + nextLine(); + return; + } else if (key == "K") { + prevLine(); + return; + } else if (key == ",") { + moveToEnd(); + return; + } else if (key == ".") { + moveToStart(); + return; + } else if (key == "H") { + backwardChar(); + return; + } else if (key == "L") { + forwardChar(); + return; + } else if (key == "Space") { + scrollUp(); + return; + } else if (key == "V") { + scrollDown(); + return; + } else if (key == "F") { + forwardWord(); + return; + } else if (key == "B") { + backwardWord(); + return; + } else if (key == "A") { + moveToStartOfLine(); + return; + } else if (key == "E") { + moveToEndOfLine(); + return; + } else if (key == "M") { + moveToLineIndentation(); + return; + } else if (key == "Q" && m_bReadOnlyPermission == false) { +// setReadOnly(false); + toggleReadOnlyMode(); + return; + } else if (key == "Shfit+J") { + scrollLineUp(); + return; + } else if (key == "Shift+K") { + scrollLineDown(); + return; + } else if (key == "P") { + forwardPair(); + return; + } else if (key == "N") { + backwardPair(); + return; + } else if (key == "Shift+:") { + copyLines(); + return; + } else if ((key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "togglereadonlymode")/* || key=="Alt+Meta+L"*/) + && m_bReadOnlyPermission == false) { +// setReadOnly(false); + toggleReadOnlyMode(); + return; + } else if (key == "Shift+/" && e->modifiers() == Qt::ControlModifier) { + e->ignore(); + } else if (e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { + if (e->key() == Qt::Key_Return || e->key() == Qt::Key_D || e->key() == Qt::Key_K + || e->key() == Qt::Key_Up || e->key() == Qt::Key_Down) { + popupNotify(tr("Read-Only mode is on")); + return; + } else { + e->ignore(); + } + } else if (e->modifiers() == Qt::ControlModifier) { + if (e->key() == Qt::Key_Return || e->key() == Qt::Key_K || e->key() == Qt::Key_X || + e->key() == Qt::Key_V || e->key() == Qt::Key_J || e->key() == Qt::Key_Z || e->key() == Qt::Key_Y) { + popupNotify(tr("Read-Only mode is on")); + return; + } else { + e->ignore(); + } + } else if (e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift) { + e->ignore(); + } else if (e->key() == Qt::Key_F11 || e->key() == Qt::Key_F5) { + e->ignore(); + return; + } else if (e->modifiers() == Qt::NoModifier || e->modifiers() == Qt::KeypadModifier) { + popupNotify(tr("Read-Only mode is on")); + return; + } else { + // If press another key + // the main window does not receive + e->ignore(); + return; + } + } else { + if (isReadOnly()) { //原生接口setReadOnly不生效,在这里拦截模拟ReadOnly + return; + } + + // 左右移动光标后退出全选状态 + if (Qt::Key_Left == e->key() + || Qt::Key_Right == e->key()) { + m_isSelectAll = false; + // 继续后续判断 + } + + //插入键盘可现实字符 + if (modifiers == Qt::NoModifier && (e->key() <= Qt::Key_ydiaeresis && e->key() >= Qt::Key_Space) && !e->text().isEmpty()) { + + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + //非修改键盘按键加撤销重做栈 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + insertColumnEditTextEx(e->text()); + } else { + if (m_cursorMode == Overwrite) { + auto cursor = this->textCursor(); + cursor.clearSelection(); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); + this->setTextCursor(cursor); + } + insertSelectTextEx(textCursor(), e->text()); + } + + m_isSelectAll = false; + return; + } + + //键盘右边数字键 + if (modifiers == Qt::KeypadModifier && (e->key() <= Qt::Key_9 && e->key() >= Qt::Key_Asterisk) && !e->text().isEmpty()) { + + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + //非修改键盘按键加撤销重做栈 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + insertColumnEditTextEx(e->text()); + } else { + if (m_cursorMode == Overwrite) { + auto cursor = this->textCursor(); + cursor.clearSelection(); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor); + this->setTextCursor(cursor); + } + insertSelectTextEx(textCursor(), e->text()); + } + m_isSelectAll = false; + return; + } + + //插入空白字符 + if (modifiers == Qt::NoModifier && (e->key() == Qt::Key_Tab || e->key() == Qt::Key_Return) || + modifiers == Qt::KeypadModifier && (e->key() == Qt::Key_Enter)) { + + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + //列编辑添加撤销重做 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + insertColumnEditTextEx(e->text()); + } else { + auto cursor = this->textCursor(); + bool hassel = cursor.hasSelection(); + auto selectedtext = cursor.selectedText(); + + //calculate the startline and endline. + auto anchor = cursor.anchor(); + auto pos = cursor.position(); + cursor.setPosition(anchor); + auto line1 = cursor.blockNumber(); + cursor.setPosition(pos); + auto line2 = cursor.blockNumber(); + + //get the text of current line. + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + auto currentline = cursor.selectedText(); + + if (hassel && e->key() == Qt::Key_Tab && (line1 != line2 || selectedtext == currentline)) { + indentText(); + } else { + insertSelectTextEx(textCursor(), e->text()); + } + } + m_isSelectAll = false; + return; + } + + //列编辑 删除撤销重做 + if (modifiers == Qt::NoModifier && (e->key() == Qt::Key_Backspace)) { + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(m_altModSelections, this); + m_pUndoStack->push(pDeleteStack); + } else { + //修改backspace删除,在文档最末尾点击backspace,引起标签栏*出现问题 + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) { + cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); + } + QString m_delText = cursor.selectedText(); + if (m_delText.size() <= 0) return; + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(cursor, this); + m_pUndoStack->push(pDeleteStack); + } + m_isSelectAll = false; + return; + } + + //列编辑 向后删除撤销重做 + if (modifiers == Qt::NoModifier && (e->key() == Qt::Key_Delete)) { + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + DeleteBackAltCommand *commond = new DeleteBackAltCommand(m_altModSelections, this); + m_pUndoStack->push(commond); + } else { + //修改delete删除,在文档最末尾点击delete,引起标签栏*出现问题 + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) { + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + } + QString m_delText = cursor.selectedText(); + if (m_delText.size() <= 0) return; + + DeleteBackCommand *commond = new DeleteBackCommand(cursor, this); + m_pUndoStack->push(commond); + } + m_isSelectAll = false; + return; + } + + //fix 66710 输入的内容为英文符号时,文本编辑器未识别为临时文件 + //fix 75313 lxp 2021.4.22 + if ((modifiers == Qt::ShiftModifier || e->key() == Qt::Key_Shift) && !e->text().isEmpty()) { + + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + if (m_bIsAltMod) { + insertColumnEditTextEx(e->text()); + } else { + insertSelectTextEx(textCursor(), e->text()); + } + m_isSelectAll = false; + return; + } + + // alt+m 弹出编辑器右键菜单 + if (e->modifiers() == Qt::AltModifier && !e->text().compare(QString("m"), Qt::CaseInsensitive)) { + popRightMenu(); + return; + } + + //快捷建处理 + if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "undo")) { + this->undo_(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "redo")) { + this->redo_(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "cut")) { +#if 0 + //列编辑添加撤销重做 + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + QString data; + for (auto sel : m_altModSelections) data.append(sel.cursor.selectedText()); + //删除有选择 + for (int i = 0; i < m_altModSelections.size(); i++) { + if (m_altModSelections[i].cursor.hasSelection()) { + QUndoCommand *pDeleteStack = new DeleteTextUndoCommand(m_altModSelections[i].cursor); + m_pUndoStack->push(pDeleteStack); + } + } + //设置到剪切板 + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + } else { + QTextCursor cursor = textCursor(); + //有选择内容才剪切 + if (cursor.hasSelection()) { + QString data = cursor.selectedText(); + deleteTextEx(cursor); + QClipboard *clipboard = QApplication::clipboard(); //获取系统剪贴板指针 + clipboard->setText(data); + } + } +#endif + this->cut(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "paste")) { +#if 0 + //添加剪切板内容到撤销重做栈 + const QClipboard *clipboard = QApplication::clipboard(); //获取剪切版内容 + + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + insertColumnEditTextEx(clipboard->text()); + } else { + insertSelectTextEx(textCursor(), clipboard->text()); + } +#endif + slotPasteAction(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "scrollup")) { + //向上翻页 + scrollUp(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "scrolldown")) { + //向下翻页 + scrollDown(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "copylines")) { + copyLines(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "cutlines")) { + cutlines(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "indentline")) { + QPlainTextEdit::keyPressEvent(e); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "backindentline")) { + unindentText(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "forwardchar")) { + forwardChar(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "backwardchar")) { + backwardChar(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "forwardword")) { + forwardWord(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "backwardword")) { + backwardWord(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "nextline")) { + nextLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "prevline")) { + prevLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "newline")/* || key == "Return"*/) { + newline(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "opennewlineabove")) { + openNewlineAbove(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "opennewlinebelow")) { + openNewlineBelow(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "duplicateline")) { + duplicateLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "killline")) { + killLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "killcurrentline")) { + killCurrentLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "swaplineup")) { + moveLineDownUp(true); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "swaplinedown")) { + moveLineDownUp(false); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "scrolllineup")) { + scrollLineUp(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "scrolllinedown")) { + scrollLineDown(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "scrollup")) { + scrollUp(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "scrolldown")) { + scrollDown(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetoendofline")) { + moveToEndOfLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetostartofline")) { + moveToStartOfLine(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetostart")) { + moveToStart(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetoend")) { + moveToEnd(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetolineindentation")) { + moveToLineIndentation(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "upcaseword")) { + upcaseWord(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "downcaseword")) { + downcaseWord(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "capitalizeword")) { + capitalizeWord(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "killbackwardword")) { + killBackwardWord(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "killforwardword")) { + killForwardWord(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "forwardpair")) { + forwardPair(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "backwardpair")) { + backwardPair(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "transposechar")) { + transposeChar(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "setmark")) { + setMark(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "exchangemark")) { + exchangeMark(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "joinlines")) { + joinLines(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "togglereadonlymode")/*|| key=="Alt+Meta+L"*/) { + //setReadOnly(false); + toggleReadOnlyMode(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "togglecomment")) { + toggleComment(true); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "removecomment")) { + toggleComment(false); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "switchbookmark")) { + m_bIsShortCut = true; + addOrDeleteBookMark(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetoprebookmark")) { + moveToPreviousBookMark(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "movetonextbookmark")) { + moveToNextBookMark(); + return; + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "editor", "mark")) { + toggleMarkSelections(); + return; + } else if (e->key() == Qt::Key_Insert && key != "Shift+Ins" && e->modifiers() == Qt::NoModifier) { + setOverwriteMode(!overwriteMode()); + //update(); + if (!overwriteMode()) { + auto cursor = this->textCursor(); + cursor.clearSelection(); + cursor.movePosition(QTextCursor::Right); + this->setTextCursor(cursor); + + cursor = this->textCursor(); + cursor.movePosition(QTextCursor::Left); + this->setTextCursor(cursor); + } + + m_cursorMode = overwriteMode() ? Overwrite : Insert; + emit cursorModeChanged(m_cursorMode); + e->accept(); + } else { + // Post event to window widget if key match window key list. + for (auto option : m_settings->settings->group("shortcuts.window")->options()) { + if (key == m_settings->settings->option(option->key())->value().toString()) { + e->ignore(); + return; + } + } + + // Post event to window widget if match Alt+0 ~ Alt+9 + QRegularExpression re("^Alt\\+\\d"); + QRegularExpressionMatch match = re.match(key); + if (match.hasMatch()) { + e->ignore(); + return; + } + + /* qt原生控件QPlainTextEdit对Alt+Tab快捷键有接收响应,需求里无定义Alt+Tab快捷键响应功能,遇到该快捷键直接return即可 */ + if (key.contains(QString("Alt+Tab"))) { + return; + } + + // Text editor handle key self. + QPlainTextEdit::keyPressEvent(e); + } + + //return QPlainTextEdit::keyPressEvent(e); + } +} + +void TextEdit::wheelEvent(QWheelEvent *e) +{ + if (e->modifiers() & Qt::ControlModifier) { + const int deltaY = e->angleDelta().y(); + + if (deltaY < 0) { + qobject_cast(this->window())->decrementFontSize(); + } else { + qobject_cast(this->window())->incrementFontSize(); + } + + return; + } + + QPlainTextEdit::wheelEvent(e); +} + +void TextEdit::contextMenuEvent(QContextMenuEvent *event) +{ + popRightMenu(event->globalPos()); +} + +void TextEdit::paintEvent(QPaintEvent *e) +{ + DPlainTextEdit::paintEvent(e); + + if (m_altModSelections.length() > 0) { + for (auto sel : m_altModSelections) { + if (sel.cursor.hasSelection()) { + m_hasColumnSelection = true; + break; + } else { + m_hasColumnSelection = false; + } + } + } + + QColor lineColor = palette().text().color(); + + if (m_bIsAltMod && !m_altModSelections.isEmpty()) { + + QTextCursor textCursor = this->textCursor(); + int cursorWidth = this->cursorWidth(); + //int cursoColumn = textCursor.positionInBlock(); + QPainter painter(viewport()); + QPen pen; + pen.setColor(lineColor); + pen.setWidth(cursorWidth); + painter.setPen(pen); + + QList rowList; + for (int i = 0 ; i < m_altModSelections.size(); i++) { + //if(m_altModSelections[i].cursor.positionInBlock() == cursoColumn){ + int row = m_altModSelections[i].cursor.blockNumber(); + if (!rowList.contains(row)) { + rowList << row; + QRect textCursorRect = this->cursorRect(m_altModSelections[i].cursor); + painter.drawRect(textCursorRect); + } + // } + } + } +} + +void TextEdit::resizeEvent(QResizeEvent *e) +{ + if (m_isSelectAll) + selectTextInView(); + + // 显示区域变化时同时更新视图 + markAllKeywordInView(); + + QPlainTextEdit::resizeEvent(e); +} + +bool TextEdit::isComment(const QString &text, int index, const QString &commentType) +{ + int length = commentType.length(); + + Q_ASSERT(text.length() - index >= length); + + int i = 0; + while (i < length) { + if (text.at(index + i) != commentType.at(i)) + return false; + ++i; + } + return true; +} + + +void TextEdit::unCommentSelection() +{ + if (!m_commentDefinition.isValid()) + return; + + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + QTextCursor cursor = textCursor(); + QTextDocument *doc = cursor.document(); + + int pos = cursor.position(); + int anchor = cursor.anchor(); + int start = qMin(anchor, pos); + int end = qMax(anchor, pos); + bool anchorIsStart = (anchor == start); + + QTextBlock startBlock = doc->findBlock(start); + QTextBlock endBlock = doc->findBlock(end); + + if (end > start && endBlock.position() == end) { + --end; + endBlock = endBlock.previous(); + } + + bool doMultiLineStyleUncomment = false; + bool doMultiLineStyleComment = false; + bool doSingleLineStyleUncomment = false; + + bool hasSelection = cursor.hasSelection(); + + if (hasSelection && m_commentDefinition.hasMultiLineStyle()) { + + QString startText = startBlock.text(); + int startPos = start - startBlock.position(); + const int multiLineStartLength = m_commentDefinition.multiLineStart.length(); + bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty(); + + if (startPos >= multiLineStartLength + && isComment(startText, + startPos - multiLineStartLength, + m_commentDefinition.multiLineStart)) { + startPos -= multiLineStartLength; + start -= multiLineStartLength; + } + + bool hasSelStart = startPos <= startText.length() - multiLineStartLength + && isComment(startText, startPos, m_commentDefinition.multiLineStart); + + QString endText = endBlock.text(); + int endPos = end - endBlock.position(); + const int multiLineEndLength = m_commentDefinition.multiLineEnd.length(); + bool hasTrailingCharacters = + !endText.left(endPos).remove(m_commentDefinition.singleLine).trimmed().isEmpty() + && !endText.mid(endPos).trimmed().isEmpty(); + + if (endPos <= endText.length() - multiLineEndLength + && isComment(endText, endPos, m_commentDefinition.multiLineEnd)) { + endPos += multiLineEndLength; + end += multiLineEndLength; + } + + bool hasSelEnd = endPos >= multiLineEndLength + && isComment(endText, endPos - multiLineEndLength, m_commentDefinition.multiLineEnd); + + doMultiLineStyleUncomment = hasSelStart && hasSelEnd; + doMultiLineStyleComment = !doMultiLineStyleUncomment + && (hasLeadingCharacters + || hasTrailingCharacters + || !m_commentDefinition.hasSingleLineStyle()); + } else if (!hasSelection && !m_commentDefinition.hasSingleLineStyle()) { + + QString text = startBlock.text().trimmed(); + doMultiLineStyleUncomment = text.startsWith(m_commentDefinition.multiLineStart) + && text.endsWith(m_commentDefinition.multiLineEnd); + doMultiLineStyleComment = !doMultiLineStyleUncomment && !text.isEmpty(); + + start = startBlock.position(); + end = endBlock.position() + endBlock.length() - 1; + + if (doMultiLineStyleUncomment) { + int offset = 0; + text = startBlock.text(); + const int length = text.length(); + while (offset < length && text.at(offset).isSpace()) + ++offset; + start += offset; + } + } + + if (doMultiLineStyleUncomment) { + cursor.setPosition(end); + cursor.movePosition(QTextCursor::PreviousCharacter, + QTextCursor::KeepAnchor, + m_commentDefinition.multiLineEnd.length()); + //cursor.removeSelectedText(); + deleteTextEx(cursor); + cursor.setPosition(start); + cursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + m_commentDefinition.multiLineStart.length()); + //cursor.removeSelectedText(); + deleteTextEx(cursor); + } else if (doMultiLineStyleComment) { + cursor.setPosition(end); + insertTextEx(cursor, m_commentDefinition.multiLineEnd); + //cursor.insertText(m_commentDefinition.multiLineEnd); + cursor.setPosition(start); + insertTextEx(cursor, m_commentDefinition.multiLineStart); + //cursor.insertText(m_commentDefinition.multiLineStart); + } else { + endBlock = endBlock.next(); + doSingleLineStyleUncomment = true; + for (QTextBlock block = startBlock; block != endBlock; block = block.next()) { + QString text = block.text().trimmed(); + if (!text.isEmpty() && !text.startsWith(m_commentDefinition.singleLine)) { + doSingleLineStyleUncomment = false; + break; + } + } + + const int singleLineLength = m_commentDefinition.singleLine.length(); + for (QTextBlock block = startBlock; block != endBlock; block = block.next()) { + if (doSingleLineStyleUncomment) { + QString text = block.text(); + int i = 0; + while (i <= text.size() - singleLineLength) { + if (isComment(text, i, m_commentDefinition.singleLine)) { + cursor.setPosition(block.position() + i); + cursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + singleLineLength); + //cursor.removeSelectedText(); + deleteTextEx(cursor); + break; + } + if (i < text.size()) { + if (!text.at(i).isSpace()) + break; + } + + ++i; + } + } else { + const QString text = block.text(); + foreach (QChar c, text) { + if (!c.isSpace()) { + if (m_commentDefinition.isAfterWhiteSpaces) + cursor.setPosition(block.position() + text.indexOf(c)); + else + cursor.setPosition(block.position()); + insertTextEx(cursor, m_commentDefinition.singleLine); + break; + } + } + } + } + } + + // adjust selection when commenting out + if (hasSelection && !doMultiLineStyleUncomment && !doSingleLineStyleUncomment) { + cursor = textCursor(); + if (!doMultiLineStyleComment) + start = startBlock.position(); // move the comment into the selection + int lastSelPos = anchorIsStart ? cursor.position() : cursor.anchor(); + if (anchorIsStart) { + cursor.setPosition(start); + cursor.setPosition(lastSelPos, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(lastSelPos); + cursor.setPosition(start, QTextCursor::KeepAnchor); + } + setTextCursor(cursor); + } +} + +void TextEdit::setComment() +{ + //此函数是删除了unCommentSelection()的if-else的uncomment分支得来的 + if (!m_commentDefinition.isValid()) + return; + if (m_isSelectAll) + QPlainTextEdit::selectAll(); + + QTextCursor cursor = textCursor(); + if (cursor.isNull()) return; + + QTextDocument *doc = cursor.document(); + + int pos = cursor.position(); + int anchor = cursor.anchor(); + int start = qMin(anchor, pos); + int end = qMax(anchor, pos); + bool anchorIsStart = (anchor == start); + + QTextBlock startBlock = doc->findBlock(start); + QTextBlock endBlock = doc->findBlock(end); + if (end > start && endBlock.position() == end) { + --end; + endBlock = endBlock.previous(); + } + bool doMultiLineStyleUncomment = false; + bool doMultiLineStyleComment = false; + bool doSingleLineStyleUncomment = false; + + bool hasSelection = cursor.hasSelection(); + + if (hasSelection && m_commentDefinition.hasMultiLineStyle()) { + + QString startText = startBlock.text(); + int startPos = start - startBlock.position(); + const int multiLineStartLength = m_commentDefinition.multiLineStart.length(); + bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty(); + + if (startPos >= multiLineStartLength + && isComment(startText, + startPos - multiLineStartLength, + m_commentDefinition.multiLineStart)) { + startPos -= multiLineStartLength; + start -= multiLineStartLength; + } + + bool hasSelStart = startPos <= startText.length() - multiLineStartLength + && isComment(startText, startPos, m_commentDefinition.multiLineStart); + + QString endText = endBlock.text(); + int endPos = end - endBlock.position(); + const int multiLineEndLength = m_commentDefinition.multiLineEnd.length(); + bool hasTrailingCharacters = + !endText.left(endPos).remove(m_commentDefinition.singleLine).trimmed().isEmpty() + && !endText.mid(endPos).trimmed().isEmpty(); + + if (endPos <= endText.length() - multiLineEndLength + && isComment(endText, endPos, m_commentDefinition.multiLineEnd)) { + endPos += multiLineEndLength; + end += multiLineEndLength; + } + + bool hasSelEnd = endPos >= multiLineEndLength + && isComment(endText, endPos - multiLineEndLength, m_commentDefinition.multiLineEnd); + + doMultiLineStyleUncomment = hasSelStart && hasSelEnd; + doMultiLineStyleComment = !doMultiLineStyleUncomment + && (hasLeadingCharacters + || hasTrailingCharacters + || m_commentDefinition.hasMultiLineStyle()); + } else if (!hasSelection && !m_commentDefinition.hasSingleLineStyle()) { + QString text = startBlock.text().trimmed(); + doMultiLineStyleUncomment = text.startsWith(m_commentDefinition.multiLineStart) + && text.endsWith(m_commentDefinition.multiLineEnd); + doMultiLineStyleComment = !doMultiLineStyleUncomment && !text.isEmpty(); + + start = startBlock.position(); + end = endBlock.position() + endBlock.length() - 1; + + if (doMultiLineStyleUncomment) { + int offset = 0; + text = startBlock.text(); + const int length = text.length(); + while (offset < length && text.at(offset).isSpace()) + ++offset; + start += offset; + } + } + + if (doMultiLineStyleComment) { + // 压入添加信息,注意光标索引顺序不能调换 + QList > multiText; + cursor.setPosition(end); + multiText.append(qMakePair(cursor, m_commentDefinition.multiLineEnd)); + cursor.setPosition(start); + multiText.append(qMakePair(cursor, m_commentDefinition.multiLineStart)); + + // 同时将两组插入信息压入撤销栈 + insertMultiTextEx(multiText); + } else { + endBlock = endBlock.next(); + doSingleLineStyleUncomment = true; + for (QTextBlock block = startBlock; block != endBlock; block = block.next()) { + QString text = block.text().trimmed(); + if (!text.isEmpty() && !text.startsWith(m_commentDefinition.singleLine)) { + doSingleLineStyleUncomment = false; + break; + } + } + + QList > multiText; + for (QTextBlock block = startBlock; block != endBlock; block = block.next()) { + cursor.setPosition(block.position()); + multiText.append(qMakePair(cursor, m_commentDefinition.singleLine)); + } + // 同时将多组组插入信息压入撤销栈 + insertMultiTextEx(multiText); + } + + // adjust selection when commenting out + if (hasSelection && !doMultiLineStyleUncomment && !doSingleLineStyleUncomment) { + cursor = textCursor(); + if (!doMultiLineStyleComment) + start = startBlock.position(); // move the comment into the selection + int lastSelPos = anchorIsStart ? cursor.position() : cursor.anchor(); + if (anchorIsStart) { + cursor.setPosition(start); + cursor.setPosition(lastSelPos, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(lastSelPos); + cursor.setPosition(start, QTextCursor::KeepAnchor); + } + setTextCursor(cursor); + } +} + +void TextEdit::removeComment() +{ + //此函数是删除了unCommentSelection()的if-else的comment分支得来的 + if (!m_commentDefinition.isValid()) { + return; + } + + QString tep = m_commentDefinition.singleLine; + if (tep.isEmpty()) { + tep = m_commentDefinition.multiLineStart; + } + QString abb = tep.remove(QRegExp("\\s")); + + if (m_isSelectAll) { + QPlainTextEdit::selectAll(); + } + + QTextCursor cursor = textCursor(); + QTextDocument *doc = cursor.document(); + + int pos = cursor.position(); + int anchor = cursor.anchor(); + int start = qMin(anchor, pos); + int end = qMax(anchor, pos); + bool anchorIsStart = (anchor == start); + + QTextBlock startBlock = doc->findBlock(start); + QTextBlock endBlock = doc->findBlock(end); + + if (end > start && endBlock.position() == end) { + --end; + endBlock = endBlock.previous(); + } + + bool doMultiLineStyleUncomment = false; + bool doMultiLineStyleComment = false; + bool doSingleLineStyleUncomment = false; + + bool hasSelection = cursor.hasSelection(); + + if (hasSelection && m_commentDefinition.hasMultiLineStyle()) { + QString startText = startBlock.text(); + int startPos = start - startBlock.position(); + const int multiLineStartLength = m_commentDefinition.multiLineStart.length(); + bool hasLeadingCharacters = !startText.left(startPos).trimmed().isEmpty(); + + if (startPos >= multiLineStartLength + && isComment(startText, + startPos - multiLineStartLength, + m_commentDefinition.multiLineStart)) { + startPos -= multiLineStartLength; + start -= multiLineStartLength; + } + + bool hasSelStart = startPos <= startText.length() - multiLineStartLength + && isComment(startText, startPos, m_commentDefinition.multiLineStart); + + QString endText = endBlock.text(); + int endPos = end - endBlock.position(); + const int multiLineEndLength = m_commentDefinition.multiLineEnd.length(); + bool hasTrailingCharacters = + !endText.left(endPos).remove(m_commentDefinition.singleLine).trimmed().isEmpty() + && !endText.mid(endPos).trimmed().isEmpty(); + + if (endPos <= endText.length() - multiLineEndLength + && isComment(endText, endPos, m_commentDefinition.multiLineEnd)) { + endPos += multiLineEndLength; + end += multiLineEndLength; + } + + bool hasSelEnd = endPos >= multiLineEndLength + && isComment(endText, endPos - multiLineEndLength, m_commentDefinition.multiLineEnd); + doMultiLineStyleUncomment = hasSelStart && hasSelEnd; + doMultiLineStyleComment = !doMultiLineStyleUncomment + && (hasLeadingCharacters + || hasTrailingCharacters + || !m_commentDefinition.hasSingleLineStyle()); + } else if (!hasSelection && !m_commentDefinition.hasSingleLineStyle()) { + + QString text = startBlock.text().trimmed(); + doMultiLineStyleUncomment = text.startsWith(m_commentDefinition.multiLineStart) + && text.endsWith(m_commentDefinition.multiLineEnd); + doMultiLineStyleComment = !doMultiLineStyleUncomment && !text.isEmpty(); + start = startBlock.position(); + end = endBlock.position() + endBlock.length() - 1; + + if (doMultiLineStyleUncomment) { + int offset = 0; + text = startBlock.text(); + const int length = text.length(); + while (offset < length && text.at(offset).isSpace()) + ++offset; + start += offset; + } + } + + if (doMultiLineStyleUncomment) { + // 注意删除先后顺序不能调换 + QList multiText; + cursor.setPosition(end); + cursor.movePosition(QTextCursor::PreviousCharacter, + QTextCursor::KeepAnchor, + m_commentDefinition.multiLineEnd.length()); + multiText.append(cursor); + cursor.setPosition(start); + cursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + m_commentDefinition.multiLineStart.length()); + multiText.append(cursor); + + // 同时删除多组注释文本 + deleteMultiTextEx(multiText); + } else if (textCursor().hasSelection() && m_commentDefinition.singleLine.isEmpty()) { + doSingleLineStyleUncomment = false; + } else { + int tmp = 0;//备注偏移量,判断备注标记后面有没有空格 + endBlock = endBlock.next(); + doSingleLineStyleUncomment = true; + for (QTextBlock block = startBlock; block != endBlock; block = block.next()) { + QString text = block.text().trimmed(); + if (!text.isEmpty() && m_commentDefinition.singleLine.isEmpty()) { + if (text.startsWith(abb)) { + doSingleLineStyleUncomment = false; + break; + } + } + + if (!text.isEmpty() && (!text.startsWith(m_commentDefinition.singleLine) || (!text.startsWith(m_commentDefinition.multiLineStart)))) { + if (!text.startsWith(abb)) { + doSingleLineStyleUncomment = false; + break; + } + } + } + + int singleLineLength = m_commentDefinition.singleLine.length(); + QString text = startBlock.text().trimmed(); + + if (text.startsWith(m_commentDefinition.singleLine)) { + tmp = 0; + } else if (text.startsWith(abb)) { + tmp = 1; + } + QString check = ""; + + QList multiText; + for (QTextBlock block = startBlock; block != endBlock; block = block.next()) { + if (doSingleLineStyleUncomment) { + text = block.text(); + int i = 0; + if (tmp == 1) + check = abb; + else { + check = m_commentDefinition.singleLine; + } + while (i <= text.size() - singleLineLength) { + if (isComment(text, i, check)) { + cursor.setPosition(block.position() + i); + cursor.movePosition(QTextCursor::NextCharacter, + QTextCursor::KeepAnchor, + singleLineLength - tmp); + // 添加待删除的文本 + multiText.append(cursor); + break; + } + if (i < text.size()) { + if (!text.at(i).isSpace()) + break; + } + + ++i; + } + } + } + + if (!multiText.isEmpty()) { + // 同时删除多组注释文本 + deleteMultiTextEx(multiText); + } + } + + // adjust selection when commenting out + if (hasSelection && !doMultiLineStyleUncomment && !doSingleLineStyleUncomment) { + cursor = textCursor(); + if (!doMultiLineStyleComment) + start = startBlock.position(); // move the comment into the selection + int lastSelPos = anchorIsStart ? cursor.position() : cursor.anchor(); + if (anchorIsStart) { + cursor.setPosition(start); + cursor.setPosition(lastSelPos, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(lastSelPos); + cursor.setPosition(start, QTextCursor::KeepAnchor); + } + setTextCursor(cursor); + } +} + +bool TextEdit::blockContainStrBrackets(int line) +{ + //获取行数文本块 + QTextBlock curBlock = document()->findBlockByNumber(line); + QString text = curBlock.text(); + //若存在字符串行,多个字符串中间的 '{' '}' 同样被忽略 + QRegExp regExp("\".*\""); + if (text.contains(regExp)) { + QString curText = text.remove(regExp); + return curText.contains("{"); + } else { + return text.contains("{"); + } +} + +/** + * @brief 根据传入的起始行号 \a line ,查找在此行号下的折叠区域,查找后将返回查询过程中的折叠区域起始文本块 + * \a beginBlock 和结束文本块 \a endBlock 。 + * @param line 查找起始行号 + * @param beginBlock 起始文本块 + * @param endBlock 结束文本框 + * @param curBlock 行号对应文本块 + * @return 是否查找到折叠区域 + */ +bool TextEdit::findFoldBlock(int line, QTextBlock &beginBlock, QTextBlock &endBlock, QTextBlock &curBlock) +{ + //使用统一 折叠判断算法 根据左右"{""}"高亮算法 + QTextDocument *doc = document(); + //获取行号对应文本块 + curBlock = doc->findBlockByNumber(line); + + //开始本文块 结束文本块 + beginBlock = curBlock.next(); + endBlock = curBlock.next(); + + //如果是第一行不包括左括弧"{" + if (line == 0 && !curBlock.text().contains("{")) { + curBlock = curBlock.next(); + } + + //获取当前块文本左括弧所在光标 + int position = curBlock.position(); + int offset = curBlock.text().lastIndexOf('{'); + position += offset; + + //获取当前文本块第一个字符光标 + QChar begin = '{', end = '}'; + QTextCursor cursor = textCursor(); + cursor.setPosition(position, QTextCursor::MoveAnchor); + cursor.clearSelection(); + + //左括弧光标 右括弧光标 + QTextCursor bracketBeginCursor = cursor; + QTextCursor bracketEndCursor = cursor; + bracketBeginCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + + //获取最后右括弧光标 + int braceDepth = 0; + // 判断当前是否处于字符串内,字符串内的 { } 不进行统计 + bool inCodeString = false; + QChar c; + while (!(c = doc->characterAt(position)).isNull()) { + // 判断是否处于字符串内,已在字符串内将不处理其它字符,只判断结束处理 + if (inCodeString) { + // 判断 " 前是否存在转义字符,若不存在,则退出字符串 + if ('"' == c + && '\\' != doc->characterAt(position - 1)) { + inCodeString = false; + } + } else { + if (c == begin) { + braceDepth++; + } else if (c == end) { + braceDepth--; + + if (0 == braceDepth) { + bracketEndCursor = QTextCursor(doc); + bracketEndCursor.setPosition(position); + bracketEndCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + endBlock = bracketEndCursor.block(); + break; + } + } else if ('"' == c) { + inCodeString = true; + } + } + + position++; + } + + return 0 == braceDepth; +} + +/** + * @brief 文档内容变更时触发 + * 当前用于记录中键更新前后的动作并压入撤销栈,需要注意鼠标中键不会移除字符仅会插入选中的字符。 + * @param from 更新的光标位置 + * @param charsRemoved 移除的字符数 + * @param charsAdded 插入的字符数 + */ +void TextEdit::onTextContentChanged(int from, int charsRemoved, int charsAdded) +{ + Q_UNUSED(charsRemoved) + + // 判断是否正在执行中键黏贴动作 + if (m_MidButtonPatse) { + QUndoCommand *undo = new QUndoCommand; + m_pUndoStack->push(undo); + + // 记录鼠标中键变更,滞后插入撤销栈,在push()时不执行redo() + QTextCursor cursor = textCursor(); + cursor.setPosition(from); + cursor.setPosition(from + charsAdded, QTextCursor::KeepAnchor); + // 取得已插入的文本信息 + QString insertText = cursor.selectedText(); + cursor.setPosition(from); + (void)new MidButtonInsertTextUndoCommand(cursor, insertText, this, undo); + + m_MidButtonPatse = false; + } +} diff --git a/src/editor/dtextedit.h b/src/editor/dtextedit.h new file mode 100644 index 0000000000000000000000000000000000000000..e6865b5384d717e2aae62e6d5250051d61958e49 --- /dev/null +++ b/src/editor/dtextedit.h @@ -0,0 +1,865 @@ +// SPDX-FileCopyrightText: 2011-2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEXTEDIT_H +#define TEXTEDIT_H +#include "linenumberarea.h" +#include "bookmarkwidget.h" +#include "FlashTween.h" +#include "codeflodarea.h" +#include "../common/settings.h" +#include "../common/utils.h" +#include "../widgets/ColorSelectWdg.h" +#include "uncommentselection.h" +//添加自定义撤销重做栈 +#include "inserttextundocommand.h" +#include "deletetextundocommand.h" +#include "../widgets/bottombar.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum ConvertCase { UPPER, LOWER, CAPITALIZE }; + +class ShowFlodCodeWidget; +class LeftAreaTextEdit; +class EditWrapper; + +class TextEdit : public DPlainTextEdit +{ + Q_OBJECT + +public: + enum CursorMode { + Insert, + Overwrite, + Readonly + }; + + enum MarkOperationType { + MarkOnce, + MarkAllMatch, + MarkLine, + MarkAll + }; + enum UpdateOperationType { + Normal, + FileOpenBegin, + FileOpenEnd, + }; + enum OperationType { + CopyOperation, + PasteOperation + }; + + struct MarkOperation { + MarkOperationType type; // 标记操作类型 + QTextCursor cursor; // 在(MarkAll)时不使用 + QString color; // 标记颜色 + QString matchText; // 匹配文本,仅在全局标记匹配文本(MarkAllMatch)时使用 + + MarkOperation(): type(MarkOnce) {} + }; + + // 标记替换信息,包含光标的绝对信息 + struct MarkReplaceInfo { + MarkOperation opt; // 标记项操作 + int start; // 光标选中起始位置 + int end; // 光标选中结束位置 + qint64 time; // 标记的操作时间 + + MarkReplaceInfo(): start(0), end(0), time(0) {} + }; + + TextEdit(QWidget *parent = nullptr); + ~TextEdit() override; + + //直接插入文本 + void insertTextEx(QTextCursor, QString); + //同时插入多个位置的文本 + void insertMultiTextEx(const QList> &multiText); + + //直接删除字符 删除选择或一个字符 + void deleteTextEx(QTextCursor); + //同时删除多个选取的文本 + void deleteMultiTextEx(const QList &multiText); + + //插入选择文本字符 + void insertSelectTextEx(QTextCursor, QString); + + //插入列编辑文本字符 + void insertColumnEditTextEx(QString text); + //插入带选择字符 + void deleteSelectTextEx(QTextCursor); + + /* 处理快捷键“ctrl + k 和Ctrl +shift +K”,删除到行尾和删除整行的 删除和撤销功能; + * currLine 表示删除的是不是整行,true 整行,false 删除到行尾 ut002764 2021.6.19*/ + void deleteSelectTextEx(QTextCursor, QString text, bool currLine); + + //初始化右键菜单 + void initRightClickedMenu(); + + //弹窗右键菜单 + void popRightMenu(QPoint pos = QPoint()); + // + void setWrapper(EditWrapper *); + EditWrapper *getWrapper(); + + // 获取打开文件路径 + inline QString getFilePath() { return m_sFilePath;} + // 设置文件路径 + inline void setFilePath(const QString &file) { m_sFilePath = file;} + // 取得左侧的导航控件,包含行号、书签、折叠控件等 + inline LeftAreaTextEdit *getLeftAreaWidget() { return m_pLeftAreaWidget;} + + // 是否允许撤销重做操作 + bool isUndoRedoOpt(); + // 判断文档是否被修改 + bool getModified(); + + int getCurrentLine(); + int getCurrentColumn(); + int getPosition(); + int getScrollOffset(); + DMenu *getHighlightMenu(); + + void forwardChar(); + void backwardChar(); + void forwardWord(); + void backwardWord(); + void forwardPair(); + void backwardPair(); + + int blockCount() const; + int characterCount() const; + QTextBlock firstVisibleBlock(); + + void moveToStart(); + void moveToEnd(); + void moveToStartOfLine(); + void moveToEndOfLine(); + void moveToLineIndentation(); + void nextLine(); + void prevLine(); + void jumpToLine(int line, bool keepLineAtCenter); + + void moveCursorNoBlink(QTextCursor::MoveOperation operation, + QTextCursor::MoveMode mode = QTextCursor::MoveAnchor); + + void newline(); + void openNewlineAbove(); + void openNewlineBelow(); + void moveLineDownUp(bool up); + void scrollLineUp(); + void scrollLineDown(); + void scrollUp(); + void scrollDown(); + //copy current line and paste in the next line + void duplicateLine(); + void copyLines(); + + //剪切选中行或当前行至剪贴板中 + void cutlines(); + + // joinLines 合并行 + void joinLines(); + + void killLine(); + void killCurrentLine(); + void killBackwardWord(); + void killForwardWord(); + + void indentText(); + void unindentText(); + void setTabSpaceNumber(int number); + void convertWordCase(ConvertCase convertCase); + QString capitalizeText(QString text); + + void keepCurrentLineAtCenter(); + void scrollToLine(int scrollOffset, int row, int column); + + void setLineWrapMode(bool enable); + void setFontFamily(QString fontName); + void setFontSize(qreal fontSize); + void updateFont(); + + void replaceAll(const QString &replaceText, const QString &withText); + void replaceNext(const QString &replaceText, const QString &withText); + void replaceRest(const QString &replaceText, const QString &withText); + void beforeReplace(const QString &strReplaceText); + + bool findKeywordForward(const QString &keyword); + + void removeKeywords(); + bool highlightKeyword(QString keyword, int position); + bool highlightKeywordInView(QString keyword); + void clearFindMatchSelections(); + void updateCursorKeywordSelection(QString keyword, bool findNext); + void updateHighlightLineSelection(); + bool updateKeywordSelections(QString keyword, QTextCharFormat charFormat, QList &listSelection); + bool updateKeywordSelectionsInView(QString keyword, QTextCharFormat charFormat, QList *listSelection); + bool searchKeywordSeletion(QString keyword, QTextCursor cursor, bool findNext); + void renderAllSelections(); + + bool clearMarkOperationForCursor(QTextCursor cursor); + bool clearMarksForTextCursor(); + void markAllKeywordInView(); + bool markKeywordInView(QString keyword, QString color, qint64 timeStamp = -1); + void markAllInView(QString color, qint64 timeStamp = -1); + void toggleMarkSelections(); + + // 颜色标记操作列表和标记替换列表的互相转换函数 + static QList > convertReplaceToMark(const QList &replaceInfo); + static QList convertMarkToReplace(const QList > &markInfo); + // 手动更新所有的标记信息,用于撤销栈处理更新当前颜色标记操作 + void manualUpdateAllMark(const QList > &markInfo); + + // 文档篇幅视图有变更时(翻页/滚动条变化/鼠标滚轮变化/键盘上下键),动态更新绘制可视范围内字符颜色 + void updateMarkAllSelectColor(); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + void codeFLodAreaPaintEvent(QPaintEvent *event); + void setBookmarkFlagVisable(bool isVisable, bool bIsFirstOpen = false); + void setCodeFlodFlagVisable(bool isVisable, bool bIsFirstOpen = false); + void setTheme(const QString &path); + void removeHighlightWordUnderCursor(); + void setSettings(Settings *settings); + void copySelectedText(); + void cutSelectedText(); + void pasteText(); + void setMark(); + void unsetMark(); + bool tryUnsetMark(); + void exchangeMark(); + void saveMarkStatus(); + void restoreMarkStatus(); + void completionWord(QString word); + QString getWordAtMouse(); + QString getWordAtCursor(); + void toggleReadOnlyMode(bool notNotify = false); + void toggleComment(bool bValue); + int getNextWordPosition(QTextCursor &cursor, QTextCursor::MoveMode moveMode); + int getPrevWordPosition(QTextCursor cursor, QTextCursor::MoveMode moveMode); + bool atWordSeparator(int position); + void showCursorBlink(); + void hideCursorBlink(); + void setReadOnlyPermission(bool permission); + bool getReadOnlyPermission(); + bool getReadOnlyMode(); + void hideRightMenu(); + void flodOrUnflodAllLevel(bool isFlod); + void flodOrUnflodCurrentLevel(bool isFlod); + void getHideRowContent(int iLine); + bool isNeedShowFoldIcon(QTextBlock block); + int getHighLightRowContentLineNum(int iLine); + + //代码折叠绘制 + void paintCodeFlod(QPainter *painter, QRect rect, bool isFlod = false); + //获取背景颜色 + QColor getBackColor(); + //更新左侧widget宽度 + void updateLeftWidgetWidth(int width); + //获取行号宽度 + int lineNumberAreaWidth(); + + /** + * @author liumaochuan ut000616 + * @brief getLinePosYByLineNum 根据行号获得行Y轴坐标 + * @param iLine 行 + * @return 行Y轴坐标 + */ + int getLinePosYByLineNum(int iLine); + bool ifHasHighlight(); + + //书签功能相关 + /** + * @author liumaochuan ut000616 + * @brief bookMarkAreaPaintEvent 绘制书签 + * @param event 书签区域的绘制事件 + */ + void bookMarkAreaPaintEvent(QPaintEvent *event); + + /** + * @author liumaochuan ut000616 + * @brief getLineFromPoint 得到鼠标点击位置所在的行 + * @param point 鼠标点击位置 + * @return 鼠标点击位置所在的行 + */ + int getLineFromPoint(const QPoint &point); + + /** + * @author liumaochuan ut000616 + * @brief moveToPreviousBookMark 移动到上一个书签 + */ + void moveToPreviousBookMark(); + + /** + * @author liumaochuan ut000616 + * @brief moveToNextBookMark 移动到下一个书签 + */ + void moveToNextBookMark(); + + /** + * @author liumaochuan ut000616 + * @brief checkBookmarkLineMove 检测书签行移动 + * @param from 文本变化时光标位置 + * @param charsRemoved 移除的字符数 + * @param charsAdded 添加的字符数 + */ + void checkBookmarkLineMove(int from, int charsRemoved, int charsAdded); + + /** + * @author liumaochuan ut000616 + * @brief setIsFileOpen 设置是否在读取文件 + */ + void setIsFileOpen(); + + /** + * @author liumaochuan ut000616 + * @brief setTextFinished 读取文件结束 + */ + void setTextFinished(); + + /** + * @author liumaochuan ut000616 + * @brief readHistoryRecord 读取书签相关记录 + * @return 书签相关记录列表 + */ + QStringList readHistoryRecord(QString key); + + /** + * @author liumaochuan ut000616 + * @brief readHistoryRecordofBookmark 读取书签记录 + * @return 书签记录列表 + */ + QStringList readHistoryRecordofBookmark(); + + /** + * @author liumaochuan ut000616 + * @brief readHistoryRecordofFilePath 读取添加了书签的文件路径记录 + * @return 文件路径列表 + */ + QStringList readHistoryRecordofFilePath(QString key); + + //标记功能相关 + /** + * @author liumaochuan ut000616 + * @brief isMarkCurrentLine 标记或取消标记当前行 + * @param isMark true为标记,false为取消标记 + * @param strColor 标记格式 + */ + void isMarkCurrentLine(bool isMark, QString strColor = "", qint64 timeStamp = -1); + + /** + * @author liumaochuan ut000616 + * @brief isMarkAllLine 标记或取消标记所有 + * @param isMark true为标记,false为取消标记 + * @param strColor 标记格式 + */ + void isMarkAllLine(bool isMark, QString strColor = ""); + + /** + * @author liumaochuan ut000616 + * @brief cancelLastMark 取消上一个标记 + */ + void cancelLastMark(); + + /** + * @brief markSelectWord 标记选择的文本 + */ + void markSelectWord(); + + /** + * @author liumaochuan ut000616 + * @brief updateMark 更新标记 + * @param from 文本变化时光标位置 + * @param charsRemoved 移除的字符数 + * @param charsAdded 添加的字符数 + */ + void updateMark(int from, int charsRemoved, int charsAdded); + + //QTextEdit :: ExtraSelection结构提供了一种为文档中的给定选择,指定字符格式的方法。 + /** + * @author liumaochuan ut000616 + * @brief containsExtraSelection 指定字符格式列表是否包含该指定字符格式 + * @param listSelections 指定字符格式列表 + * @param selection 指定字符格式 + * @return true or false + */ + bool containsExtraSelection(QList listSelections, QTextEdit::ExtraSelection selection); + + /** + * @author liumaochuan ut000616 + * @brief appendExtraSelection 在指定字符格式列表添加指定字符格式 + * @param wordMarkSelections 指定字符格式列表 + * @param selection 指定字符格式 + * @param markColor 指定字符颜色格式 + * @param listSelections 添加的指定字符格式列表 + */ + void appendExtraSelection(QList wordMarkSelections, QTextEdit::ExtraSelection selection + , QString strColor, QList *listSelections); + + void setCursorStart(int pos); + void writeEncodeHistoryRecord(); + QStringList readEncodeHistoryRecord(); + /** + * @brief tellFindBarClose 通知查找框关闭 + */ + void tellFindBarClose(); + /** + * @author liumaochuan ut000616 + * @brief setEditPalette 设置textEdit的颜色 + * @param activeColor active时的颜色 + * @param inactiveColor inactive时的颜色 + */ + void setEditPalette(const QString &activeColor, const QString &inactiveColor); + /** + * @author liumaochuan ut000616 + * @brief setCodeFoldWidgetHide 代码折叠悬浮预览 + * @param isHidden 是否隐藏 + */ + void setCodeFoldWidgetHide(bool isHidden); + + /** + * @brief setTruePath 设置真实文件路径 + * @param qstrTruePath 真实文件路径 + */ + void setTruePath(QString qstrTruePath); + + /** + * @brief getTruePath 获取真实文件路径 + * @return 真实文件路径 + */ + QString getTruePath(); + + /** + * @brief getBookmarkInfo 得到书签信息 + * @return 书签信息 + */ + QList getBookmarkInfo(); + + /** + * @brief setBookMarkList 设置书签 + * @param bookMarkList 书签列表 + */ + void setBookMarkList(QList bookMarkList); + + /** + * 更新上次保存时的撤销回收栈的索引值 + */ + void updateSaveIndex(); + + static bool isComment(const QString &text, int index, const QString &commentType); + +signals: + void clickFindAction(); + void clickReplaceAction(); + void clickJumpLineAction(); + void clickFullscreenAction(); + void cursorMarkChanged(bool mark, QTextCursor cursor); + void cursorModeChanged(CursorMode mode); + void hightlightChanged(const QString &name); + void popupNotify(QString notify); + void signal_readingPath(); + void signal_setTitleFocus(); +public slots: + /** + * @author liumaochuan ut000616 + * @brief addOrDeleteBookMark 添加或删除书签 + */ + void addOrDeleteBookMark(); + //更新左边区域界面 梁卫东 2020-09-09 13:53:58 + void updateLeftAreaWidget(); + void handleScrollFinish(); + void setSyntaxDefinition(KSyntaxHighlighting::Definition def); + + void slot_translate(); + + //书签右键菜单功能 + void setHighLineCurrentLine(bool ok); + void upcaseWord(); + void downcaseWord(); + void capitalizeWord(); + void transposeChar(); + + void handleCursorMarkChanged(bool mark, QTextCursor cursor); + + void slotValueChanged(int iValue); + void adjustScrollbarMargins(); + void slotSelectionChanged(); + void slotCanRedoChanged(bool bCanRedo); + void slotCanUndoChanged(bool bCanUndo); + void onSelectionArea(); + void fingerZoom(QString name, QString direction, int fingers); + void cursorPositionChanged(); + + //剪切槽函数 + void cut(); + //复制槽函数 + void copy(); + //粘贴槽函数 + void paste(); + //修改后,高亮显示 + void highlight(); + //选中视口中可见的文本 + void selectTextInView(); + //设置"全部选中"(全选槽函数) + void setSelectAll(); + void slotSigColorSelected(bool bSelected, QColor color); + void slotSigColorAllSelected(bool bSelected, QColor color); + void slotCutAction(bool checked = false); + void slotCopyAction(bool checked = false); + void slotPasteAction(bool checked = false); + void slotDeleteAction(bool checked = false); + void slotSelectAllAction(bool checked = false); + bool slotOpenInFileManagerAction(bool checked = false); + void slotAddComment(bool checked = false); + void slotCancelComment(bool checked = false); + void slotVoiceReadingAction(bool checked = false); + bool slotStopReadingAction(bool checked = false); + void slotdictationAction(bool checked = false); + void slotColumnEditAction(bool checked = false); + void slotPreBookMarkAction(bool checked = false); + void slotNextBookMarkAction(bool checked = false); + void slotClearBookMarkAction(bool checked = false); + void slotFlodAllLevel(bool checked = false); + void slotUnflodAllLevel(bool checked = false); + void slotFlodCurrentLevel(bool checked = false); + void slotUnflodCurrentLevel(bool checked = false); + void slotCancleMarkAllLine(bool checked = false); + void slotCancleLastMark(bool checked = false); + void slotUndoAvailable(bool undoIsAvailable); + void slotRedoAvailable(bool redoIsAvailable); + + void redo_(); + void undo_(); + + void moveText(int from, int to, const QString& text, bool copy = false); + QTextCursor findCursor(const QString &substr, const QString &text, int from, bool backward = false, int cursorPos = 0); + void onPressedLineNumber(const QPoint& point); + QString selectedText(bool checkCRLF = false); + void onEndlineFormatChanged(BottomBar::EndlineFormat from,BottomBar::EndlineFormat to); + + // 当前程序调色板更新时重绘部分组件 + void onAppPaletteChanged(); + +protected: + bool event(QEvent *evt) override; //触摸屏event事件 + void dragEnterEvent(QDragEnterEvent *event) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; + void inputMethodEvent(QInputMethodEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + void wheelEvent(QWheelEvent *e) override; + bool eventFilter(QObject *object, QEvent *event) override; + void contextMenuEvent(QContextMenuEvent *event) override; + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + +private: + void unCommentSelection(); + void setComment(); + void removeComment(); + + //去除"*{*" "*}*" "*{*}*"跳过当做普通文本处理不折叠 梁卫东2020-09-01 17:16:41 + bool blockContainStrBrackets(int line); + bool setCursorKeywordSeletoin(int position, bool findNext); + void updateHighlightBrackets(const QChar &openChar, const QChar &closeChar); + + bool getNeedControlLine(int line, bool isVisable); + //触摸屏功能函数 + bool gestureEvent(QGestureEvent *event); + void tapGestureTriggered(QTapGesture *); + void tapAndHoldGestureTriggered(QTapAndHoldGesture *); + void panTriggered(QPanGesture *); + void pinchTriggered(QPinchGesture *); + void swipeTriggered(QSwipeGesture *); + //add for single refers to the sliding + void slideGestureY(qreal diff); + void slideGestureX(qreal diff); + + //只读权限不显示中文输入提示框 ut002764 2021.6.23 + void SendtoggleReadOnlyMode(); + void SendtoggleReadmessage(); + + // 读取可用内存,判断并解决操作是否可继续执行 + bool isAbleOperation(int iOperationType); + // 计算颜色标记替换信息列表 + void calcMarkReplaceList(QList &replaceList, const QString &oldText, + const QString &replaceText, const QString &withText, int offset = 0) const; + // 查找行号line起始的折叠区域 + bool findFoldBlock(int line, QTextBlock &beginBlock, QTextBlock &endBlock, QTextBlock &curBlock); + +private slots: + // 文档内容变更时触发 + void onTextContentChanged(int from, int charsRemoved, int charsAdded); + +public: + int getFirstVisibleBlockId() const; + void setLeftAreaUpdateState(UpdateOperationType statevalue); + UpdateOperationType getLeftAreaUpdateState(); + +public: + bool bIsSetLineNumberWidth = true; + bool m_pIsShowCodeFoldArea; + bool m_pIsShowBookmarkArea; + bool m_bIsMarkAllLine {false}; ///< 颜色“标记所有”标志 + +private: + EditWrapper *m_wrapper; + QPropertyAnimation *m_scrollAnimation {nullptr}; + + QList m_findMatchSelections;///< “查找”的字符格式(所有查找的字符) + QTextEdit::ExtraSelection m_beginBracketSelection; + QTextEdit::ExtraSelection m_endBracketSelection; + QTextEdit::ExtraSelection m_currentLineSelection;///< 光标所在当前行的样式 + QTextEdit::ExtraSelection m_findHighlightSelection;///< “查找”的字符格式(当前位置字符) + // 不再使用 + //QTextEdit::ExtraSelection m_wordUnderCursorSelection; + QList> m_wordMarkSelections;///< 记录标记的列表(分行记录) + QMap> m_mapWordMarkSelections; ///< 记录标记的表(按标记动作记录) + QList> m_markOperations; ///记录所有标记操作(包括单个标记和全文标记) + QMap>> m_mapKeywordMarkSelections; ///记录关键字对应的全文标记 + QTextEdit::ExtraSelection m_markAllSelection;///< “标记所有”的字符格式 + QList m_markFoldHighLightSelections; + + QTextCursor m_highlightWordCacheCursor; + QTextCursor m_wordUnderPointerCursor; + + int m_lineNumberPaddingX = 5; + + int m_restoreColumn; + int m_restoreRow; + + int m_tabSpaceNumber = 4; + + KSyntaxHighlighting::Repository m_repository; + KSyntaxHighlighting::SyntaxHighlighter *m_highlighter = nullptr; + + DMenu *m_rightMenu; + QAction *m_undoAction; + QAction *m_redoAction; + QAction *m_cutAction; + QAction *m_copyAction; + QAction *m_pasteAction; + QAction *m_deleteAction; + QAction *m_selectAllAction; + QAction *m_findAction; + QAction *m_replaceAction; + QAction *m_jumpLineAction; + QAction *m_enableReadOnlyModeAction; + QAction *m_disableReadOnlyModeAction; + QAction *m_fullscreenAction; + QAction *m_exitFullscreenAction; + QAction *m_openInFileManagerAction; + QAction *m_toggleCommentAction; + QAction *m_voiceReadingAction; + QAction *m_stopReadingAction; + QAction *m_dictationAction; + QAction *m_translateAction; + QAction *m_columnEditAction; + + QAction *m_addBookMarkAction; + QAction *m_cancelBookMarkAction; + QAction *m_clearBookMarkAction; + QAction *m_preBookMarkAction; + QAction *m_nextBookMarkAction; + QAction *m_flodAllLevel; + QAction *m_unflodAllLevel; + QAction *m_flodCurrentLevel; + QAction *m_unflodCurrentLevel; + + //yanyuhan + //颜色标记、折叠/展开、书签、列编辑、设置注释、取消注释; + //QAction *m_colorMarkAction; + DMenu *m_collapseExpandMenu; + DMenu *m_colorMarkMenu; + QAction *m_cancleMarkCurrentLine; + QAction *m_cancleMarkAllLine; + QAction *m_cancleLastMark; + + //颜色选择控件替换下面action 1 2 3 4 + QWidgetAction *m_actionColorStyles; + QAction *m_markCurrentAct; + + //颜色选择控件替换下面action 1 2 3 4 + QWidgetAction *m_actionAllColorStyles; + QAction *m_markAllAct; + QString m_strMarkAllLineColorName; ///< “标记所有”选择的颜色名称 + + // 增加对于颜色选择的 Tab 顺序控制 + QList> m_MarkColorMenuTabOrder; + + QAction *m_addComment; + QAction *m_cancelComment; + + DMenu *m_convertCaseMenu; + QAction *m_upcaseAction; + QAction *m_downcaseAction; + QAction *m_capitalizeAction; + + ShowFlodCodeWidget *m_foldCodeShow; + + bool m_canUndo {false}; + bool m_canRedo {false}; + bool m_HightlightYes {false}; + bool m_haveWordUnderCursor {false}; + + bool m_cursorMark = false; + int m_markStartLine = -1; + + Settings *m_settings {nullptr}; + + bool m_readOnlyMode = false; + bool m_cursorMarkStatus = false; + int m_cursorMarkPosition = 0; + int m_cursorWidthChangeDelay = 2000; + bool m_bReadOnlyPermission = false; + + qreal m_fontSize = 16; + QString m_fontName; + + Comment::CommentDefinition m_commentDefinition; + + QStringList m_wordSepartors = QStringList({ + // English separator. + ".", ",", "?", "!", "@", "#", "$", ":", ";", "-", "<", ">", "[", "]", "(", ")", "{", "}", "=", "/", "+", "%", "&", "^", "*", "\"", "'", "`", "~", "|", "\\", "\n", + // Chinese separator. + "。", ",", "?", "!", "¥", ":", ";", "《", "》", "【", "】", "(", ")", " " + }); + + QColor m_currentLineColor; + QColor m_backgroundColor; + QColor m_lineNumbersColor; + QColor m_currentLineNumberColor; + QColor m_regionMarkerColor; + QColor m_selectionColor; + QColor m_selectionBgColor; + + QPoint m_mouseClickPos;///< 鼠标点击位置 + QPoint m_menuPos; + + bool m_highlighted = false; + + QTextCharFormat m_bracketMatchFormat; + QTextCharFormat m_findMatchFormat; + QTextCharFormat m_findHighlightFormat; + CursorMode m_cursorMode; + + DMenu *m_hlGroupMenu {nullptr}; + QActionGroup *m_hlActionGroup {nullptr}; + + QPoint m_lastTouchBeginPos; + QPointer m_updateEnableSelectionByMouseTimer; + int m_touchTapDistance = -1; + + QFont m_fontLineNumberArea;///< 绘制行号的字体 + QList m_listBookmark;///< 存储书签的list + int m_nBookMarkHoverLine;///< 悬浮效果书签所在的行 + int m_nLines;///< 文本总行数 + bool m_bIsFileOpen;///< 是否在读取文件(导致文本变化) + bool m_bIsShortCut;///< 是否在使用书签快捷键 + + //存储所有有折叠标记的位置,包含不可见区域 + QList m_listMainFlodAllPos; + //包含当前可见区域的标志 + QList m_listFlodIconPos; + + QString m_qstrCommitString;///< 输入法输入的字符 + bool m_bIsInputMethod;///< 是否是输入法输入 + int m_nSelectEndLine;///< 选择结束时后鼠标所在行 + int m_nSelectStart;///< 选择开始时的鼠标位置 + int m_nSelectEnd;///< 选择结束时的鼠标位置 + + int m_cursorStart = -1; + QString m_textEncode; + + //触摸屏 + enum GestureAction { + GA_null, + GA_tap, + GA_slide, + GA_pinch, + GA_hold, + GA_pan, + GA_swipe + }; + + qreal m_scaleFactor = 1; + qreal m_currentStepScaleFactor = 1; + qint64 m_tapBeginTime = 0; + Qt::GestureState m_tapStatus = Qt::NoGesture; + GestureAction m_gestureAction = GA_null; + + //add for single refers to the sliding + FlashTween tweenX; + FlashTween tweenY; + qreal changeY = {0.0}; + qreal changeX = {0.0}; + qreal durationY = {0.0}; + qreal durationX = {0.0}; + bool m_slideContinueX {false}; + bool m_slideContinueY {false}; + int m_lastMouseYpos; + int m_lastMouseXpos; + ulong m_lastMouseTimeX; + ulong m_lastMouseTimeY; + qreal m_stepSpeedY = 0; + qreal m_stepSpeedX = 0; + bool m_bIsDoubleClick {false}; + bool m_bBeforeIsDoubleClick {false}; + + QList m_altModSelections; + QTextCursor m_altStartTextCursor;//开始按住alt鼠标点击光标位置 + QTextCursor m_altEndTextCursor;//结束按住alt鼠标点击光标位置 + bool m_bIsAltMod = false; + int m_redoCount = 0; + QStringList m_pastText; + bool m_hasColumnSelection = false; + + //鼠标事件的位置 + int m_startX = 0; + int m_startY = 0; + int m_endX = 0; + int m_endY = 0; + + bool m_bIsFindClose = false;///< 关闭查找框事件是否发生 + QString m_qstrTruePath;///< 源文件路径 + + bool m_isSelectAll {false}; + +private: + LeftAreaTextEdit *m_pLeftAreaWidget = nullptr; + QString m_sFilePath;///<打开文件路径 + //自定义撤销重做栈 + QUndoStack *m_pUndoStack = nullptr; + int m_lastSaveIndex = 0; + + //只读权限模式执行一次的判断变量 ut002764 2021.6.23 + bool m_Permission = false; + bool m_Permission2 = false; + //左边栏更新标记 + UpdateOperationType m_LeftAreaUpdateState; + + bool m_MidButtonPatse = false; // 鼠标中键黏贴处理 + bool m_isPreeditBefore = false; // 上一个输入法时间是否是 preedit + int m_preeditLengthBefore = 0; +}; +#endif diff --git a/src/editor/editwrapper.cpp b/src/editor/editwrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ccb53b5287d547f19f866a310fa6842b81dcb18 --- /dev/null +++ b/src/editor/editwrapper.cpp @@ -0,0 +1,1465 @@ +// SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../widgets/window.h" +#include "../encodes/detectcode.h" +#include "../common/fileloadthread.h" +#include "../widgets/pathsettintwgt.h" +#include "editwrapper.h" +#include "../common/utils.h" +#include "leftareaoftextedit.h" +#include "drecentmanager.h" +#include "../common/settings.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DCORE_USE_NAMESPACE + +enum ReadLengthType { + EReadStepSize = 1 * 1024 * 1024, // 单次读取文件最大长度 +}; + +/** + * @brief 处理文件时使用的事件类型,处理解析文件数据时, + * 将此事件抛给事件队列,使用事件队列分发解析任务 + */ +class ParseFileEvent : public QEvent +{ +public: + enum Type { + EParseFile = QEvent::User + 1024, + }; + + ParseFileEvent(); + virtual ~ParseFileEvent(); + + // 返回此事件的克隆对象,用于下次任务。 + ParseFileEvent *clone(); + + // 内部公开数据 + int m_alreadyReadOffset = 0; // 当前已读取文本大小 + QByteArray m_contentData; // 文本内容 + QTextCursor m_cursor; // 插入光标 + QTextCodec *m_codec = nullptr; // 编码 +}; + +ParseFileEvent::ParseFileEvent() + : QEvent(static_cast(EParseFile)) +{ +} + +ParseFileEvent::~ParseFileEvent() +{ +} + +ParseFileEvent *ParseFileEvent::clone() +{ + // 创建克隆对象,复制数据(浅拷贝) + ParseFileEvent *cloneEvent = new ParseFileEvent; + cloneEvent->m_contentData = this->m_contentData; + cloneEvent->m_alreadyReadOffset = this->m_alreadyReadOffset; + cloneEvent->m_cursor = this->m_cursor; + cloneEvent->m_codec = this->m_codec; + return cloneEvent; +} + + +EditWrapper::EditWrapper(Window *window, QWidget *parent) + : QWidget(parent), + m_pWindow(window), + m_pTextEdit(new TextEdit(this)), + m_pBottomBar(new BottomBar(this)), + m_pWaringNotices(new WarningNotices(WarningNotices::ResidentType, this)) + +{ + m_bQuit = false; + m_pWaringNotices->hide(); + // Init layout and widgets. + QHBoxLayout *m_layout = new QHBoxLayout; + m_pLeftAreaTextEdit = m_pTextEdit->getLeftAreaWidget(); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->setSpacing(0); + m_layout->addWidget(m_pLeftAreaTextEdit); + m_layout->addWidget(m_pTextEdit); + m_pTextEdit->setWrapper(this); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addLayout(m_layout); + mainLayout->addWidget(m_pBottomBar); + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->setSpacing(0); + setLayout(mainLayout); + + connect(m_pTextEdit, &TextEdit::cursorModeChanged, this, &EditWrapper::handleCursorModeChanged); + connect(m_pWaringNotices, &WarningNotices::reloadBtnClicked, this, &EditWrapper::reloadModifyFile); + connect(m_pWaringNotices, &WarningNotices::saveAsBtnClicked, m_pWindow, &Window::saveAsFile); + connect(m_pTextEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, [this](int) { + OnUpdateHighlighter(); + if ((m_pWindow->findBarIsVisiable() || m_pWindow->replaceBarIsVisiable()) && + (QString::compare(m_pWindow->getKeywordForSearchAll(), m_pWindow->getKeywordForSearch(), Qt::CaseInsensitive) == 0)) { + m_pTextEdit->highlightKeywordInView(m_pWindow->getKeywordForSearchAll()); + } + + m_pTextEdit->markAllKeywordInView(); + }); +} + +EditWrapper::~EditWrapper() +{ + if (m_pTextEdit != nullptr) { + disconnect(m_pTextEdit); + delete m_pTextEdit; + m_pTextEdit = nullptr; + } + if (m_pBottomBar != nullptr) { + disconnect(m_pBottomBar); + delete m_pBottomBar; + m_pBottomBar = nullptr; + } + //delete 之后,如果出现文件被修改,需要重新加载弹框,之后,点击标签关闭,闪退问题 78042 ut002764 +// if (m_pWaringNotices != nullptr) { +// disconnect(m_pWaringNotices); +// delete m_pWaringNotices; +// m_pWaringNotices = nullptr; +// } +} + +void EditWrapper::setQuitFlag() +{ + m_bQuit = true; +} + +bool EditWrapper::isQuit() +{ + return m_bQuit; +} + +bool EditWrapper::getFileLoading() +{ + return (m_bQuit || m_bFileLoading); +} + +void EditWrapper::openFile(const QString &filepath, QString qstrTruePath, bool bIsTemFile) +{ + m_bIsTemFile = bIsTemFile; + // update file path. + updatePath(filepath, qstrTruePath); + m_pTextEdit->setIsFileOpen(); + // 设置预处理标识位 + m_bHasPreProcess = false; + + if (!bIsTemFile && !isDraftFile()) { + Settings::instance()->setSavePath(PathSettingWgt::LastOptBox, QFileInfo(qstrTruePath).absolutePath()); + Settings::instance()->setSavePath(PathSettingWgt::CurFileBox, QFileInfo(qstrTruePath).absolutePath()); + } + + FileLoadThread *thread = new FileLoadThread(filepath); + // begin to load the file. + connect(thread, &FileLoadThread::sigPreProcess, this, &EditWrapper::handleFilePreProcess); + connect(thread, &FileLoadThread::sigLoadFinished, this, &EditWrapper::handleFileLoadFinished); + connect(thread, &FileLoadThread::finished, thread, &FileLoadThread::deleteLater); + thread->start(); +} + +/** + * @brief 按文件编码 \a encode 读取当前文件数据,若文件存在异常,则返回读取失败。 + * \a encode 可缺省,按文件默认编码读取。 + * @param encode 文件编码 + * @return 是否成功读取文件数据 + */ +bool EditWrapper::readFile(QByteArray encode) +{ + QFile file(m_pTextEdit->getTruePath()); + if (file.open(QIODevice::ReadOnly)) { + QByteArray fileContent = file.readAll(); + QByteArray newEncode = encode; + if (newEncode.isEmpty()) { + // 接口修改,补充文件头内容,最多读取1MB文件头数据 + newEncode = DetectCode::GetFileEncodingFormat( + m_pTextEdit->getFilePath(), fileContent.left(DATA_SIZE_1024 * DATA_SIZE_1024)); + m_sFirstEncode = newEncode; + } + + QByteArray Outdata; + DetectCode::ChangeFileEncodingFormat(fileContent, Outdata, newEncode, QString("UTF-8")); + loadContent(Outdata); + file.close(); + m_sCurEncode = newEncode; + updateModifyStatus(false); + return true; + } + return false; +} + +/** + * @brief 将当前文件内容按编码格式 \a encodeName 保存到指定路径 \a newFilePath + * @param newFilePath 另存的文件路径 + * @param encodeName 文件保存时指定的文件格式 + * @return 是否成功另存文件 + */ +bool EditWrapper::saveAsFile(const QString &newFilePath, const QByteArray &encodeName) +{ + // use QSaveFile for safely save files. + QSaveFile saveFile(newFilePath); + saveFile.setDirectWriteFallback(true); + + if (!saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + qWarning() << Q_FUNC_INFO << "Open save file path error, " << saveFile.errorString(); + QWidget *curWidget = this->window()->getStackedWgt()->currentWidget(); + if (curWidget) { + DMessageManager::instance()->sendMessage(curWidget, QIcon(":/images/warning.svg"), + QString(tr("You do not have permission to save %1")).arg(saveFile.fileName())); + } + return false; + } + + QFile file(newFilePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + return false; + } + + //auto append new line char to end of file when file's format is Linux/MacOS + QByteArray fileContent; + getPlainTextContent(fileContent); + + QByteArray Outdata; + bool convertSucc = DetectCode::ChangeFileEncodingFormat(fileContent, Outdata, QString("UTF-8"), encodeName); + + // 转换存在异常 + if (!convertSucc) { + qWarning() << QString("iconv Encode Transformat from '%1' to '%2' Fail! start QTextCodec Encode Transformat.") + .arg(QString("UTF-8")).arg(m_sCurEncode); + // 使用 QTextCodec 进行转换尝试 + QTextCodec *codec = QTextCodec::codecForName(encodeName); + if (codec) { + QByteArray encodedString = codec->fromUnicode(fileContent); + if (encodedString.isEmpty()) { + qWarning() << qPrintable("Both iconv and QTextCodec Encode Transformat Fail!"); + } else { + qInfo() << QString("QTextCodec Encode Transformat from '%1' to '%2' Success!") + .arg(QString("UTF-8")).arg(m_sCurEncode); + + Outdata = encodedString; + convertSucc = true; + } + + } else { + qWarning() << qPrintable("Unsupported QTextCodec Encode") << m_sCurEncode; + } + } + + if (!Outdata.isEmpty()) { + // 如果新数据为空,不进行文件写入,以降低文件内容损失 + file.write(Outdata); + } + + // close and delete file. + QFileDevice::FileError error = file.error(); + file.close(); + + // flush file. + if (!saveFile.flush()) { + return false; + } + + // ensure that the file is written to disk + fsync(saveFile.handle()); + QFileInfo fi(filePath()); + m_tModifiedDateTime = fi.lastModified(); + + // did save work? + // only finalize if stream status == OK + return convertSucc && (error == QFileDevice::NoError); +} + +bool EditWrapper::saveAsFile() +{ + DFileDialog dialog(this, tr("Save")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.addComboBox(QObject::tr("Encoding"), QStringList() << m_sFirstEncode); + dialog.setDirectory(QDir::homePath()); + dialog.setNameFilter("*.txt"); + + int mode = dialog.exec(); + hideWarningNotices(); + + if (QDialog::Accepted == mode) { + const QString newFilePath = dialog.selectedFiles().value(0); + if (newFilePath.isEmpty()) + return false; + + QFile qfile(newFilePath); + + if (!qfile.open(QFile::WriteOnly | QIODevice::Truncate)) { + return false; + } + + // 以新的编码保存内容到文件,无论何种格式,展示的文本编码为UTF-8 + QByteArray inputData = m_pTextEdit->toPlainText().toUtf8(); + QByteArray outData; + DetectCode::ChangeFileEncodingFormat(inputData, outData, QString("UTF-8"), m_sFirstEncode); + qfile.write(outData); + qfile.close(); + + return true; + } + + return false; +} + +/** + * @brief 按文件编码 \a encode 重新加载文件,并返回是否加载成功。文件有变更会提示是否保存。 + * @param encode 文件编码 + * @return 返回是否加载成功 + */ +bool EditWrapper::reloadFileEncode(QByteArray encode) +{ + //切换编码相同不重写加载 + if (m_sCurEncode == encode) { + return false; + } + + //草稿文件 空白文件不保存 + if (Utils::isDraftFile(m_pTextEdit->getFilePath()) && m_pTextEdit->toPlainText().isEmpty()) { + m_sCurEncode = encode; + m_sFirstEncode = encode; + return true; + } + + //temporarily use '*' to determine whether the text has been modified. + auto tabname = this->window()->getTabbar()->currentName(); + bool hasFlag = false; + if (tabname.size() > 0 && "*" == tabname[0]) { + hasFlag = true; + } + + //1.如果修改切换编码提示用户是否保存,不保存重新打开文件读取.2.没有修改是否另存为 + if (m_pTextEdit->getModified() || hasFlag) { + DDialog *dialog = new DDialog(tr("Encoding changed. Do you want to save the file now?"), "", this); + //dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnBottomHint); + dialog->setIcon(QIcon::fromTheme("deepin-editor")); + dialog->addButton(QString(tr("Cancel")), false, DDialog::ButtonNormal); //取消 + //dialog->addButton(QString(tr("Discard")), false, DDialog::ButtonNormal);//不保存 + dialog->addButton(QString(tr("Save")), true, DDialog::ButtonRecommend); //保存 + int res = dialog->exec();//0 1 + + //关闭对话框 + if (res == 0) { + return false; + } + + //不保存,重写载入 +#if 0 + if (res == 1) { + bool ok = readFile(encode); + //if(ok && m_sCurEncode != m_sFirstEncode) m_pTextEdit->setTabbarModified(true); + return ok; + } +#endif + + //保存 + if (res == 1) { + // 保存文件前缓存当前文件的编码格式,文件将按之前的编码格式保存 + QString tempEncode = m_sCurEncode; + + //草稿文件 + bool reloadSucc = false; + if (Utils::isDraftFile(m_pTextEdit->getFilePath())) { + QString newFilePath; + if (saveDraftFile(newFilePath)) { + reloadSucc = readFile(encode); + } + } else { + if (this->window()->saveAsFile()) { + reloadSucc = readFile(encode); + } + } + + if (reloadSucc) { + // 保存成功,更新编码格式 + m_pBottomBar->setEncodeName(encode); + } else { + // 未成功保存,复位编码格式 + m_sCurEncode = tempEncode; + } + return reloadSucc; + } + + return false; + } else { + return readFile(encode); + } +} + +/** + * @brief 根据高亮格式文件的名称 \a definitionName 查询高亮格式配置,并格式化文档。 + * 若未查找到格式,例如“None”,则移除高亮效果。 + * @param definitionName 高亮格式文件名称 + */ +void EditWrapper::reloadFileHighlight(QString definitionName) +{ + m_Definition = m_Repository.definitionForName(definitionName); + if (m_Definition.isValid() && !m_Definition.filePath().isEmpty()) { + if (!m_pSyntaxHighlighter) m_pSyntaxHighlighter = new CSyntaxHighlighter(m_pTextEdit->document()); + QString m_themePath = Settings::instance()->settings->option("advance.editor.theme")->value().toString(); + if (m_themePath.contains("dark")) { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)); + } else { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + } + if (m_pSyntaxHighlighter) m_pSyntaxHighlighter->setDefinition(m_Definition);; + m_pTextEdit->setSyntaxDefinition(m_Definition); + + // 获取当前展示区域文本块 + QPoint startPoint = QPoint(0, 0); + QTextBlock beginBlock = m_pTextEdit->cursorForPosition(startPoint).block(); + QTextBlock endBlock; + + QScrollBar *pScrollBar = m_pTextEdit->verticalScrollBar(); + if (pScrollBar->maximum() > 0) { + QPoint endPoint = QPointF(0, 1.5 * m_pTextEdit->height()).toPoint(); + endBlock = m_pTextEdit->cursorForPosition(endPoint).block(); + } else { + endBlock = m_pTextEdit->document()->lastBlock(); + } + + // 移除当前页面旧的高亮内容 + QTextCursor cursor(beginBlock); + cursor.beginEditBlock(); + for (QTextBlock var = beginBlock; var.isValid(); var = var.next()) { + var.layout()->clearFormats(); + if (var == endBlock) { + break; + } + } + cursor.endEditBlock(); + // 复位标识位 + m_bHighlighterAll = false; + + // 重新高亮当前界面 + OnUpdateHighlighter(); + } else { + // 不允许的高亮格式或无对应的高亮格式文件,例如“None”,移除高亮效果 + m_bHighlighterAll = false; + m_Definition = KSyntaxHighlighting::Definition(); + if (m_pSyntaxHighlighter) { + m_pSyntaxHighlighter->deleteLater(); + m_pSyntaxHighlighter = nullptr; + } + m_pTextEdit->setSyntaxDefinition(m_Definition); + } +} + +void EditWrapper::reloadModifyFile() +{ + hideWarningNotices(); + + int curPos = m_pTextEdit->textCursor().position(); + int yoffset = m_pTextEdit->verticalScrollBar()->value(); + int xoffset = m_pTextEdit->horizontalScrollBar()->value(); + + bool bIsModified = m_pTextEdit->getModified(); + + if (m_pWindow->getTabbar()->textAt(m_pWindow->getTabbar()->currentIndex()).front() == "*") { + bIsModified = true; + } + //如果文件修改提示用户是否保存 如果临时文件保存就是另存为 + if (bIsModified) { + DDialog *dialog = new DDialog(tr("Do you want to save this file?"), "", this); + dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnBottomHint); + dialog->setIcon(QIcon::fromTheme("deepin-editor")); + dialog->addButton(QString(tr("Cancel")), false, DDialog::ButtonNormal);//不保存 + dialog->addButton(QString(tr("Discard")), false, DDialog::ButtonNormal);//取消 + dialog->addButton(QString(tr("Save")), true, DDialog::ButtonRecommend);//保存 + dialog->setCloseButtonVisible(false); + int res = dialog->exec();//0 1 + + //点击关闭 + if (res == 0) { + return; + } + + //不保存 + if (res == 1) { + //重写加载文件 + readFile(); + m_bIsTemFile = false; + } + //另存 + if (res == 2) { + //临时文件保存另存为 需要删除源草稿文件文件 + if (Utils::isDraftFile(m_pTextEdit->getFilePath())) { + QString newFilePath; + if (!saveDraftFile(newFilePath)) { + return; + } + } else { + if (!this->window()->saveAsFile()) { + return; + } + } + //重写加载文件 + readFile(); + m_bIsTemFile = false; + } + + } else { + //重写加载文件 + readFile(); + } + m_pTextEdit->setBookMarkList(QList()); + QFileInfo fi(m_pTextEdit->getTruePath()); + m_tModifiedDateTime = fi.lastModified(); + + QTextCursor textcur = m_pTextEdit->textCursor(); + textcur.setPosition(curPos); + m_pTextEdit->setTextCursor(textcur); + m_pTextEdit->verticalScrollBar()->setValue(yoffset); + m_pTextEdit->horizontalScrollBar()->setValue(xoffset); +} + +QString EditWrapper::getTextEncode() +{ + return m_sCurEncode; +} + +/** + * @brief 保存当前文件数据,若设置了特定的编码格式 \a encode , 则按此编码格式存储, + * 否则使用当前显示的文本编码。 + * @param encode 文件编码 + * @return 是否成功保存文件数据 + */ +bool EditWrapper::saveFile(QByteArray encode) +{ + QString qstrFilePath = m_pTextEdit->getTruePath(); + QFile file(qstrFilePath); + hideWarningNotices(); + + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QByteArray fileContent; + getPlainTextContent(fileContent); + + if (!encode.isEmpty()) { + m_sCurEncode = encode; + // 更新底栏编码格式 + m_pBottomBar->setEncodeName(encode); + } + + if (!fileContent.isEmpty()) { + QByteArray Outdata; + DetectCode::ChangeFileEncodingFormat(fileContent, Outdata, QString("UTF-8"), m_sCurEncode); + // 如果 iconv 转换错误 + if (Outdata.isEmpty()) { + qWarning() << qPrintable(QString("iconv Encode Transformat from '%1' to '%2' Fail! start QTextCodec Encode Transformat.") + .arg(QString("UTF-8")).arg(m_sCurEncode)); + // 使用 QTextCodec 进行转换尝试 + QTextCodec *codec = QTextCodec::codecForName(m_sCurEncode.toUtf8()); + if (codec) { + QByteArray encodedString = codec->fromUnicode(fileContent); + + if (encodedString.isEmpty()) { + qWarning() << qPrintable("Both iconv and QTextCodec Encode Transformat Fail!"); + } else { + qWarning() << qPrintable(QString("QTextCodec Encode Transformat from '%1' to '%2' Success!") + .arg(QString("UTF-8")).arg(m_sCurEncode)); + Outdata = encodedString; + } + + } else { + qWarning() << qPrintable("Unsupported QTextCodec format:") << m_sCurEncode; + } + } + + if (Outdata.isEmpty() == false) { + // 如果新数据为空,不进行文件写入,以降低文件内容损失 + // 此时如果写入,整个文件将被清空 + file.write(Outdata); + } + + QFileDevice::FileError error = file.error(); + file.close(); + m_sFirstEncode = m_sCurEncode; + + QFileInfo fi(qstrFilePath); + m_tModifiedDateTime = fi.lastModified(); + + // did save work? + // only finalize if stream status == OK + // 增加对于转换失败的判断,新数据为空,ok返回false + bool ok = (Outdata.isEmpty() == false && error == QFileDevice::NoError); + + // update status. + if (ok) updateModifyStatus(false); + m_bIsTemFile = false; + return ok; + } else { + file.write(fileContent); + QFileDevice::FileError error = file.error(); + file.close(); + m_sFirstEncode = m_sCurEncode; + + QFileInfo fi(qstrFilePath); + m_tModifiedDateTime = fi.lastModified(); + + // did save work? + // only finalize if stream status == OK + bool ok = (error == QFileDevice::NoError); + + // update status. + if (ok) updateModifyStatus(false); + m_bIsTemFile = false; + return ok; + } + } else { + DMessageManager::instance()->sendMessage(this->window()->getStackedWgt()->currentWidget(), QIcon(":/images/warning.svg") + , QString(tr("You do not have permission to save %1")).arg(file.fileName())); + return false; + } +} + +void EditWrapper::getPlainTextContent(QByteArray &plainTextContent) +{ + QString strPlainText = m_pTextEdit->toPlainText(); + if (BottomBar::EndlineFormat::Windows == m_pBottomBar->getEndlineFormat()) { + strPlainText.replace("\n", "\r\n"); + } + + qint64 iPlainTextAllLen = strPlainText.length(); + qint64 iStep = 300 * DATA_SIZE_1024 * DATA_SIZE_1024; + /* qt开发分析结论:大文本情况下toLocal8Bit()转换会引起应用闪退,此闪退问题qt方无法处理 */ + /* 如果文本框里的文本内容小于等于300MB,无需分段转换 */ + if (iPlainTextAllLen <= iStep) { + plainTextContent = QByteArray(strPlainText.toLocal8Bit()); + return; + } + + /* + * 如果文本框里的文本内容大于300MB,则采用分段转换,每段以300MB为单位 + * 规避大文toLocal8Bit()转换时导致应用闪退的qt缺陷问题 + */ + qint64 iSections = iPlainTextAllLen / (300 * DATA_SIZE_1024 * DATA_SIZE_1024); + qint64 iResidue = iPlainTextAllLen % iStep; + + for (int i = 0; i < iSections; i++) { + plainTextContent += strPlainText.mid(i * iStep, iStep).toLocal8Bit(); + QApplication::processEvents(); + + if (i == iSections - 1 && iResidue > 0) { + plainTextContent += strPlainText.mid(iSections * iStep, iResidue).toLocal8Bit(); + } + } +} + +/** + * @brief saveTemFile 保存备份文件 + * @param qstrDir 备份文件路径 + * @return true or false + */ +bool EditWrapper::saveTemFile(QString qstrDir) +{ + QFile file(qstrDir); + + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QByteArray fileContent; + getPlainTextContent(fileContent); + QByteArray Outdata; + DetectCode::ChangeFileEncodingFormat(fileContent, Outdata, QString("UTF-8"), m_sCurEncode); + file.write(Outdata); + QFileDevice::FileError error = file.error(); + file.close(); + m_sFirstEncode = m_sCurEncode; + + // did save work? + // only finalize if stream status == OK + bool ok = (error == QFileDevice::NoError); + + // update status. + if (ok) { + updateModifyStatus(isModified()); + } + return ok; + +#if 0 + } else { + file.write(fileContent); + QFileDevice::FileError error = file.error(); + file.close(); + m_sFirstEncode = m_sCurEncode; + + did save work ? + only finalize if stream status == OK + bool ok = (error == QFileDevice::NoError); + + // update status. + if (ok) updateModifyStatus(true); + return ok; + } +#endif +} else +{ + return false; +} +} + +void EditWrapper::updatePath(const QString &file, QString qstrTruePath) +{ + if (qstrTruePath.isEmpty()) { + qstrTruePath = file; + } + + QFileInfo fi(qstrTruePath); + m_tModifiedDateTime = fi.lastModified(); + + m_pTextEdit->setFilePath(file); + m_pTextEdit->setTruePath(qstrTruePath); +} + +bool EditWrapper::isModified() +{ + //编码改变内容没有修改也算是文件修改 + // bool modified = (m_sFirstEncode != m_sCurEncode || m_pTextEdit->document()->isModified()); + bool modified = m_pTextEdit->getModified(); + + return modified | m_bIsTemFile; +} + +bool EditWrapper::isDraftFile() +{ + return Utils::isDraftFile(m_pTextEdit->getFilePath()); +} + +/** + * @return 返回当前编辑文件是否为备份文件 + */ +bool EditWrapper::isBackupFile() +{ + return Utils::isBackupFile(m_pTextEdit->getFilePath()); +} + +bool EditWrapper::isPlainTextEmpty() +{ + return m_pTextEdit->document()->isEmpty(); +} + +bool EditWrapper::isTemFile() +{ + return m_bIsTemFile; +} + +/** + * @brief 保存草稿文件,若保存成功,新文件路径通过 \a newFilePath 返回, + * 且对应标签页已更新为新的文件信息。 + * @param newFilePath 保存的新文件路径 + * @return 是否保存成功 + */ +bool EditWrapper::saveDraftFile(QString &newFilePath) +{ + DFileDialog dialog(this, tr("Save")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setDirectory(QDir::homePath()); + dialog.setNameFilter("*.txt"); + + // 允许选取保存的编码格式 + DFileDialog::DComboBoxOptions encodingOptions; + encodingOptions.editable = false; + encodingOptions.defaultValue = getTextEncode(); + encodingOptions.data = Utils::getSupportEncodingList(); + dialog.addComboBox(QObject::tr("Encoding"), encodingOptions); + + if (m_pWindow) { + m_pWindow = this->window(); + QRegularExpression reg("[^*](.+)"); + QRegularExpressionMatch match = reg.match(m_pWindow->getTabbar()->currentName()); + dialog.selectFile(match.captured(0) + ".txt"); + } + + int mode = dialog.exec(); // 0表示取消 1保存 + hideWarningNotices(); + + if (mode == 1) { + const QByteArray encode = dialog.getComboBoxValue(QObject::tr("Encoding")).toUtf8(); + newFilePath = dialog.selectedFiles().value(0); + if (newFilePath.isEmpty()) + return false; + + QFile qfile(newFilePath); + + if (!qfile.open(QFile::WriteOnly)) { + return false; + } + + // 以新的编码保存内容到文件 + QByteArray inputData = m_pTextEdit->toPlainText().toUtf8(); + QByteArray outData; + DetectCode::ChangeFileEncodingFormat(inputData, outData, QString("UTF-8"), encode); + qfile.write(outData); + qfile.close(); + + //草稿文件保存 等同于重写打开 + m_sFirstEncode = m_sCurEncode; + QFile(m_pTextEdit->getFilePath()).remove(); + updateSaveAsFileName(m_pTextEdit->getFilePath(), newFilePath); + m_pTextEdit->document()->setModified(false); + m_bIsTemFile = false; + return true; + } + + return false; +} + +void EditWrapper::hideWarningNotices() +{ + if (m_pWaringNotices->isVisible()) { + m_pWaringNotices->hide(); + } +} + +//除草稿文件 检查文件是否被删除,是否被修复 +void EditWrapper::checkForReload() +{ + if (Utils::isDraftFile(m_pTextEdit->getTruePath())) { + return; + } + + QFileInfo fi(m_pTextEdit->getTruePath()); + + QTimer::singleShot(50, [ = ]() { + if (fi.lastModified() == m_tModifiedDateTime || m_pWaringNotices->isVisible()) { + return; + } + + QFileInfo finfo(m_pTextEdit->getTruePath()); + + if (!finfo.exists()) { + m_pWaringNotices->setMessage(tr("File removed on the disk. Save it now?")); + m_pWaringNotices->setSaveAsBtn(); + m_pWaringNotices->show(); + DMessageManager::instance()->sendMessage(m_pTextEdit, m_pWaringNotices); + } else if (!m_tModifiedDateTime.toString().isEmpty() && finfo.lastModified().toString() != m_tModifiedDateTime.toString()) { + m_pWaringNotices->setMessage(tr("File has changed on disk. Reload?")); + m_pWaringNotices->setReloadBtn(); + m_pWaringNotices->show(); + DMessageManager::instance()->sendMessage(m_pTextEdit, m_pWaringNotices); + } + }); +} + +void EditWrapper::showNotify(const QString &message) +{ + if (m_pTextEdit->getReadOnlyPermission() || m_pTextEdit->getReadOnlyMode()) { + DMessageManager::instance()->sendMessage(m_pTextEdit, QIcon(":/images/warning.svg"), message); + } else { + DMessageManager::instance()->sendMessage(m_pTextEdit, QIcon(":/images/ok.svg"), message); + } +} + + +void EditWrapper::handleCursorModeChanged(TextEdit::CursorMode mode) +{ + switch (mode) { + case TextEdit::Insert: + m_pBottomBar->setCursorStatus(tr("INSERT")); + break; + case TextEdit::Overwrite: + m_pBottomBar->setCursorStatus(tr("OVERWRITE")); + break; + case TextEdit::Readonly: + m_pBottomBar->setCursorStatus(tr("R/O")); + break; + } +} + +/** + * @brief 处理文件预加载服务 + * @param encode 文件编码 + * @param content 文件内容,不超过1MB + * + * @note 预加载的数据量较小(1MB),且可能分割字符,在文件完成读取后,预加载的数据将被清空并重新加载完整文档。 + */ +void EditWrapper::handleFilePreProcess(const QByteArray &encode, const QByteArray &content) +{ + // 重新加载处理 + reinitOnFileLoad(encode); + // 已进行预处理标识 + m_bHasPreProcess = true; + + // 设置界面交互效果 + QApplication::setOverrideCursor(Qt::WaitCursor); + m_pTextEdit->clear(); + m_pTextEdit->setLeftAreaUpdateState(TextEdit::FileOpenBegin); + QTextCursor cursor = m_pTextEdit->textCursor(); + + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + if (!codec) { + qInfo() << "QTextCodec::codecForName \"UTF-8\" return nullptr"; + return; + } + + // 直接加载数据到文档页面 + QString data = codec->toUnicode(content.constData(), content.size()); + cursor.insertText(data); + // 界面语法高亮 + OnUpdateHighlighter(); + + m_pTextEdit->setLeftAreaUpdateState(TextEdit::FileOpenEnd); + QApplication::restoreOverrideCursor(); +} + +/** + * @brief 处理文件加载完成服务,取得加载完成的所有文件数据,重新初始化界面 + * @param encode 文件编码 + * @param content 完整文件内容 + */ +void EditWrapper::handleFileLoadFinished(const QByteArray &encode, const QByteArray &content, bool error) +{ + // 判断是否预加载,若已预加载,则无需重新初始化 + if (!m_bHasPreProcess) { + reinitOnFileLoad(encode); + } + + if (!error) { + bool flag = m_pTextEdit->getReadOnlyPermission(); + if (flag == true) { + // note: 特殊处理,由于需要TextEdit处于可编辑状态追加文件数据,临时设置非只读状态 + m_pTextEdit->setReadOnly(false); + } + + m_bFileLoading = true; + + //备份显示修改状态 + if (m_bIsTemFile) { + updateModifyStatus(true); + } + + // 判断处理前后对象状态 + QPointer checkPtr(this); + // 加载数据 + loadContent(content); + if (checkPtr.isNull()) { + return; + } + + m_bFileLoading = false; + if (flag == true) { + m_pTextEdit->setReadOnly(true); + } + + if (m_bQuit) { + return; + } + } else { + // 清除之前读取的数据 + m_pTextEdit->clear(); + } + + m_pTextEdit->setTextFinished(); + + QStringList temFileList = Settings::instance()->settings->option("advance.editor.browsing_history_temfile")->value().toStringList(); + + for (int var = 0; var < temFileList.count(); ++var) { + QJsonParseError jsonError; + // 转化为 JSON 文档 + QJsonDocument doucment = QJsonDocument::fromJson(temFileList.value(var).toUtf8(), &jsonError); + // 解析未发生错误 + if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { + if (doucment.isObject()) { + // JSON 文档为对象 + QJsonObject object = doucment.object(); // 转化为对象 + + if (object.contains("localPath") || object.contains("temFilePath")) { + // 包含指定的 key + QJsonValue localPathValue = object.value("localPath"); // 获取指定 key 对应的 value + QJsonValue temFilePathValue = object.value("temFilePath"); // 获取指定 key 对应的 value + + if (localPathValue.toString() == m_pTextEdit->getFilePath() + || temFilePathValue.toString() == m_pTextEdit->getFilePath()) { + QJsonValue value = object.value("cursorPosition"); // 获取指定 key 对应的 value + + if (value.isString()) { + QTextCursor cursor = m_pTextEdit->textCursor(); + cursor.setPosition(value.toString().toInt()); + m_pTextEdit->setTextCursor(cursor); + OnUpdateHighlighter(); + break; + } + } + } + } + } + } + + //备份显示修改状态 + if (m_bIsTemFile) { + updateModifyStatus(true); + } + + if (m_pSyntaxHighlighter) { + m_pSyntaxHighlighter->setEnableHighlight(true); + OnUpdateHighlighter(); + } + + m_pBottomBar->setEncodeName(m_sCurEncode); + + // 提示读取错误信息 + if (error) { + // 设置文本为只读模式,且不显示通知 + if (!m_pTextEdit->getReadOnlyMode()) { + m_pTextEdit->toggleReadOnlyMode(true); + } + + m_pWaringNotices->setMessage(tr("The file cannot be read, which may be too large or has been damaged!")); + m_pWaringNotices->clearBtn(); + m_pWaringNotices->show(); + DMessageManager::instance()->sendMessage(m_pTextEdit, m_pWaringNotices); + } +} + + +void EditWrapper::OnThemeChangeSlot(QString theme) +{ + QVariantMap jsonMap = Utils::getThemeMapFromPath(theme); + QString backgroundColor = jsonMap["editor-colors"].toMap()["background-color"].toString(); + QString textColor = jsonMap["Normal"].toMap()["text-color"].toString(); + + //设置底部栏 + QPalette palette = m_pBottomBar->palette(); + palette.setColor(QPalette::Background, backgroundColor); + palette.setColor(QPalette::Text, textColor); + m_pBottomBar->setPalette(palette); + + //设置编辑器 + if (m_pSyntaxHighlighter) { + if (QColor(backgroundColor).lightness() < 128) { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)); + } else { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + } + m_pSyntaxHighlighter->rehighlight(); + } + + m_pTextEdit->setTheme(theme); +} + +void EditWrapper::UpdateBottomBarWordCnt(int cnt) +{ + m_pBottomBar->updateWordCount(cnt); +} + +void EditWrapper::OnUpdateHighlighter() +{ + if (m_pSyntaxHighlighter && !m_bQuit && !m_bHighlighterAll) { + QScrollBar *pScrollBar = m_pTextEdit->verticalScrollBar(); + QPoint startPoint = QPoint(0, 0); + QTextBlock beginBlock = m_pTextEdit->cursorForPosition(startPoint).block(); + QTextBlock endBlock; + + if (pScrollBar->maximum() > 0) { + QPoint endPoint = QPointF(0, 1.5 * m_pTextEdit->height()).toPoint(); + endBlock = m_pTextEdit->cursorForPosition(endPoint).block(); + } else { + endBlock = m_pTextEdit->document()->lastBlock(); + } + + // 判断当前文件是否支持高亮处理 + if (m_pSyntaxHighlighter->definition().isValid()) { + // NOTE: 同样需要考虑极限条件下遍历全部文本的情况 + // 限制最多向上查找512个文本块 + static int s_MaxFindCount = 512; + int maxFindBlockNumber = qMax(0, (beginBlock.blockNumber() - s_MaxFindCount)); + + QChar begin = '{', end = '}'; + int braceDepth = 0; + bool foundBrace = false; + // 判断是否此文本块为折叠区域起始的文本块,判断'{''}'处理 + QTextBlock prevBlock = endBlock; + while (prevBlock.isValid() + && !foundBrace + && maxFindBlockNumber < prevBlock.blockNumber()) { + // 逆序查询文本块数据,查找起始文本块 + QString text = prevBlock.text(); + for (int i = text.size() - 1; i >= 0; i--) { + if (text.at(i) == end) { + braceDepth++; + } else if (text.at(i) == begin) { + braceDepth--; + + // 防止'{'处于展示文本块中间的情况,查询不准确 + if (braceDepth < 0) { + braceDepth = 0; + } + + // 判断是否查找到完整折叠区域 + if (0 == braceDepth + && prevBlock.blockNumber() <= beginBlock.blockNumber()) { + foundBrace = true; + break; + } + } + } + + prevBlock = prevBlock.previous(); + } + + // 无论是否查询到折叠区域,均更新起始文本块 + beginBlock = prevBlock; + } + + if (!beginBlock.isValid() || !endBlock.isValid()) { + return; + } + + for (QTextBlock var = beginBlock; var != endBlock; var = var.next()) { + m_pSyntaxHighlighter->setEnableHighlight(true); + m_pSyntaxHighlighter->rehighlightBlock(var); + m_pSyntaxHighlighter->setEnableHighlight(false); + } + + m_pSyntaxHighlighter->setEnableHighlight(true); + m_pSyntaxHighlighter->rehighlightBlock(endBlock); + m_pSyntaxHighlighter->setEnableHighlight(false); + } +} + +void EditWrapper::setTemFile(bool value) +{ + m_bIsTemFile = value; +} + +void EditWrapper::updateHighlighterAll() +{ + if (m_pSyntaxHighlighter && !m_bQuit && !m_bHighlighterAll) { + QTextBlock beginBlock = m_pTextEdit->document()->firstBlock(); + QTextBlock endBlock = m_pTextEdit->document()->lastBlock(); + + if (!beginBlock.isValid() || !endBlock.isValid()) { + return; + } + + for (QTextBlock var = beginBlock; var != endBlock; var = var.next()) { + m_pSyntaxHighlighter->setEnableHighlight(true); + m_pSyntaxHighlighter->rehighlightBlock(var); + m_pSyntaxHighlighter->setEnableHighlight(false); + } + + m_pSyntaxHighlighter->setEnableHighlight(true); + m_pSyntaxHighlighter->rehighlightBlock(endBlock); + m_pSyntaxHighlighter->setEnableHighlight(false); + + m_bHighlighterAll = true; + } +} + +QDateTime EditWrapper::getLastModifiedTime() const +{ + return m_tModifiedDateTime; +} + +void EditWrapper::setLastModifiedTime(const QString &time) +{ + m_tModifiedDateTime = QDateTime::fromString(time); +} +void EditWrapper::updateModifyStatus(bool bModified) +{ + if (getFileLoading()) return; + if (!bModified) + m_pTextEdit->updateSaveIndex(); + m_pTextEdit->document()->setModified(bModified); + Window *pWindow = static_cast(QWidget::window()); + pWindow->updateModifyStatus(m_pTextEdit->getFilePath(), bModified); +} + +void EditWrapper::updateSaveAsFileName(QString strOldFilePath, QString strNewFilePath) +{ + m_pWindow->updateSaveAsFileName(strOldFilePath, strNewFilePath); +} + +//yanyuhan +void EditWrapper::setLineNumberShow(bool bIsShow, bool bIsFirstShow) +{ + if (bIsShow && !bIsFirstShow) { + //int lineNumberAreaWidth = m_pTextEdit->getLeftAreaWidget()->m_pLineNumberArea->width(); + //int leftAreaWidth = m_pTextEdit->getLeftAreaWidget()->width(); + m_pTextEdit->getLeftAreaWidget()->m_pLineNumberArea->show(); + //m_pTextEdit->getLeftAreaWidget()->setFixedWidth(leftAreaWidth + lineNumberAreaWidth); + + } else if (!bIsShow) { + // int lineNumberAreaWidth = m_pTextEdit->getLeftAreaWidget()->m_pLineNumberArea->width(); + //int leftAreaWidth = m_pTextEdit->getLeftAreaWidget()->width(); + m_pTextEdit->getLeftAreaWidget()->m_pLineNumberArea->hide(); + //m_pTextEdit->getLeftAreaWidget()->setFixedWidth(leftAreaWidth - lineNumberAreaWidth); + } + m_pTextEdit->bIsSetLineNumberWidth = bIsShow; + m_pTextEdit->updateLeftAreaWidget(); +} + +//显示空白符 +void EditWrapper::setShowBlankCharacter(bool ok) +{ + if (ok) { + QTextOption opts = m_pTextEdit->document()->defaultTextOption(); + QTextOption::Flags flag = opts.flags(); + flag |= QTextOption::ShowTabsAndSpaces; + // flag |= QTextOption::ShowLineAndParagraphSeparators; + opts.setFlags(flag); + m_pTextEdit->document()->setDefaultTextOption(opts); + } else { + QTextOption opts = m_pTextEdit->document()->defaultTextOption(); + QTextOption::Flags flag = opts.flags(); + flag &= ~QTextOption::ShowTabsAndSpaces; + // flag &= ~QTextOption::ShowLineAndParagraphSeparators; + opts.setFlags(flag); + m_pTextEdit->document()->setDefaultTextOption(opts); + } +} + +BottomBar *EditWrapper::bottomBar() +{ + return m_pBottomBar; +} + +QString EditWrapper::filePath() +{ + return m_pTextEdit->getFilePath(); +} + +TextEdit *EditWrapper::textEditor() +{ + return m_pTextEdit; +} + +Window *EditWrapper::window() +{ + Window *window = static_cast(QWidget::window()); + + if (m_pWindow != window) { + m_pWindow = window; + } + + return m_pWindow; +} + +void EditWrapper::customEvent(QEvent *e) +{ + // 处理解析文件任务,大文件不会在单次事件任务中处理,而是每次读取一部分并将下次任务抛出 + if (static_cast(ParseFileEvent::EParseFile) == e->type()) { + // 中途退出则不继续处理 + if (m_bQuit) { + return; + } + + ParseFileEvent *parseEvent = static_cast(e); + int needReadLen = parseEvent->m_contentData.length() - parseEvent->m_alreadyReadOffset; + + // 调整最大读取长度(单次读取最大长度) + if (needReadLen > EReadStepSize) { + needReadLen = EReadStepSize; + } + + // 转码数据并插入光标位置 + QByteArray text = parseEvent->m_contentData.mid(parseEvent->m_alreadyReadOffset, needReadLen); + QTextCodec::ConverterState state; + QString data = parseEvent->m_codec->toUnicode(text.constData(), text.size(), &state); + parseEvent->m_cursor.insertText(data); + + // 当前为首次读取 + if (0 == parseEvent->m_alreadyReadOffset) { + QTextCursor firstLineCursor = m_pTextEdit->textCursor(); + firstLineCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + m_pTextEdit->setTextCursor(firstLineCursor); + //秒开界面语法高亮 + OnUpdateHighlighter(); + } + + // 此次读取后的偏移量 + int curReadOffset = parseEvent->m_alreadyReadOffset + needReadLen; + + // 是否已读取完成 + if (parseEvent->m_contentData.length() == curReadOffset) { + // 异步读取结束 + m_bAsyncReadFileFinished = true; + } else { + ParseFileEvent *nextEvent = parseEvent->clone(); + // 调整已读取偏移位置 + nextEvent->m_alreadyReadOffset = curReadOffset; + // 抛出下一次处理的事件,根据当前是否显示界面调整优先级 + qApp->postEvent(this, nextEvent, isVisible() ? Qt::NormalEventPriority : (Qt::LowEventPriority - 1)); + } + } +} + +//支持大文本加载 界面不卡顿 秒关闭 +void EditWrapper::loadContent(const QByteArray &strContent) +{ + if (m_pBottomBar != nullptr) { + m_pBottomBar->setChildEnabled(false); + } + if (m_pWindow != nullptr) { + m_pWindow->setPrintEnabled(false); + } + + QApplication::setOverrideCursor(Qt::WaitCursor); + m_pTextEdit->clear(); + m_pTextEdit->setReadOnly(true); + m_pTextEdit->setLeftAreaUpdateState(TextEdit::FileOpenBegin); + m_bQuit = false; + //QTextDocument *doc = m_pTextEdit->document(); + QTextCursor cursor = m_pTextEdit->textCursor(); + + /* 如此转换后打开1G以上的文本会闪退,Qt QString类的缺陷 */ + //QString strContent = content.data(); + + + QTextCodec::ConverterState state; + QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + if (nullptr == codec) { + qInfo() << "QTextCodec::codecForName return nullptr"; + return; + } + + int len = strContent.length(); + //初始化显示文本大小 + int InitContentPos = 5 * 1024; + int max = 40 * 1024 * 1024; + + QString data; + int inserted = 0; + + if (len > max) { + // 当读取大文件时,采用事件队列方式处理 + ParseFileEvent *parseEvent = new ParseFileEvent; + parseEvent->m_contentData = strContent; + parseEvent->m_cursor = cursor; + parseEvent->m_codec = codec; + + // 将处理事件追加到事件队列 + qApp->postEvent(this, parseEvent, Qt::HighEventPriority); + + // 使用QPointer判断对象状态 + QPointer checkPtr(this); + + // 程序未退出且读取未完成的情况,持续处理事件 + m_bAsyncReadFileFinished = false; + while (!checkPtr.isNull() && !m_bQuit && !m_bAsyncReadFileFinished) { + QApplication::processEvents(); + } + + // 判断当前对象是否已析构,使用processEvents()可能导致在处理事件时,当前编辑控件关闭, + // 且在事件循环中进行了析构,导致processEvents()退出时,this对象已析构,无法访问对象成员 + if (checkPtr.isNull()) { + QApplication::restoreOverrideCursor(); + return; + } + } else if (len > 0) { + //初始化秒开 + if (!m_bQuit && len > InitContentPos) { + //data = strContent.mid(0, InitContentPos); + QByteArray text = strContent.mid(0, InitContentPos); + data = codec->toUnicode(text.constData(), text.size(), &state); + cursor.insertText(data); + QTextCursor firstLineCursor = m_pTextEdit->textCursor(); + firstLineCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + m_pTextEdit->setTextCursor(firstLineCursor); + //秒开界面语法高亮 + OnUpdateHighlighter(); + QApplication::processEvents(); + inserted += InitContentPos; + double progress = (inserted * 1.0) / len * 100; + m_pBottomBar->setProgress(static_cast(progress)); + if (!m_bQuit) { + //data = strContent.mid(InitContentPos, len - InitContentPos); + QByteArray text = strContent.mid(InitContentPos, len - InitContentPos); + data = codec->toUnicode(text.constData(), text.size(), &state); + cursor.insertText(data); + inserted += (len - InitContentPos); + progress = (inserted * 1.0) / len * 100; + m_pBottomBar->setProgress(static_cast(progress)); + } + } else { + if (!m_bQuit) { + //cursor.insertText(strContent); + data = codec->toUnicode(strContent.constData(), strContent.size(), &state); + cursor.insertText(data); + QTextCursor firstLineCursor = m_pTextEdit->textCursor(); + firstLineCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + m_pTextEdit->setTextCursor(firstLineCursor); + //秒开界面语法高亮 + OnUpdateHighlighter(); + inserted += len; + double progress = (inserted * 1.0) / len * 100; + m_pBottomBar->setProgress(static_cast(progress)); + } + } + } + if (m_pWindow != nullptr) { + m_pWindow->setPrintEnabled(true); + } + if (m_pBottomBar != nullptr) { + m_pBottomBar->setChildEnabled(true); + auto format = BottomBar::getEndlineFormat(strContent); + m_pBottomBar->setEndlineMenuText(format); + } + m_pTextEdit->setReadOnly(false); + m_pTextEdit->setLeftAreaUpdateState(TextEdit::FileOpenEnd); + QApplication::restoreOverrideCursor(); + + +} + +/** + * @brief 文件加载时重新执行初始化,包括重置文件高亮配置、记录文件信息。 + * @param encode 当前文件解析的编码 + */ +void EditWrapper::reinitOnFileLoad(const QByteArray &encode) +{ + m_Definition = m_Repository.definitionForFileName(m_pTextEdit->getFilePath()); + if (m_Definition.isValid() && !m_Definition.filePath().isEmpty()) { + if (!m_pSyntaxHighlighter) m_pSyntaxHighlighter = new CSyntaxHighlighter(m_pTextEdit->document()); + QString m_themePath = Settings::instance()->settings->option("advance.editor.theme")->value().toString(); + if (m_themePath.contains("dark")) { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)); + } else { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + } + + if (m_pSyntaxHighlighter) m_pSyntaxHighlighter->setDefinition(m_Definition); + m_pTextEdit->setSyntaxDefinition(m_Definition); + m_pBottomBar->getHighlightMenu()->setCurrentTextOnly(m_Definition.translatedName()); + } + + if (!Utils::isDraftFile(m_pTextEdit->getFilePath())) { + DRecentData data; + data.appName = "Deepin Editor"; + data.appExec = "deepin-editor"; + DRecentManager::addItem(m_pTextEdit->getFilePath(), data); + } + + // 初始化设置编码 + m_sCurEncode = encode; + m_sFirstEncode = encode; +} + +void EditWrapper::clearDoubleCharaterEncode() +{ + if (QFileInfo(filePath()).baseName().contains("double") + || QFileInfo(filePath()).baseName().contains("user") + || QFileInfo(filePath()).baseName().contains("four")) { + if (QFileInfo(filePath()).size() > 500 * 1024) { + return; + } + emit sigClearDoubleCharaterEncode(); + } +} diff --git a/src/editor/editwrapper.h b/src/editor/editwrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..588f3299987a24b705da8f1b1a14e0134c047bef --- /dev/null +++ b/src/editor/editwrapper.h @@ -0,0 +1,183 @@ +// SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef EDITORBUFFER_H +#define EDITORBUFFER_H + +#include "../editor/dtextedit.h" +#include "../widgets/bottombar.h" +#include "../controls/warningnotices.h" +#include "../editor/leftareaoftextedit.h" +#include "../common/CSyntaxHighlighter.h" +#include "../common/utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Window; +class EditWrapper : public QWidget +{ + Q_OBJECT + +public: + struct FileStateItem { + QDateTime modified; + QFile::Permissions permissions; + }; + + EditWrapper(Window *window = nullptr, QWidget *parent = nullptr); + ~EditWrapper(); + + //清除焦点 梁卫东 2020-09-14 11:00:50 + void clearAllFocus(); + void setQuitFlag(); + bool isQuit(); + bool getFileLoading(); + + /** + * @brief openFile 打开文件 + * @param filepath 打开文件路径 + * @param qstrTruePath 真实文件路径 + * @param bIsTemFile 修改状态 + */ + void openFile(const QString &filepath, QString qstrTruePath, bool bIsTemFile = false); + // 以编码 encode 重新读取文件 + bool readFile(QByteArray encode = ""); + // 按编码 encode 保存文件 + bool saveFile(QByteArray encode = ""); + /** + * @brief getPlainTextContent 获取文本框里的文本内容 + * @param plainTextConteng 存放获取到的内容 + */ + void getPlainTextContent(QByteArray &plainTextContent); + //重新加载文件编码 + bool saveAsFile(const QString &newFilePath, const QByteArray &encodeName); + //保存草稿文件 + bool saveDraftFile(QString &newFilePath); + //另存为第一次打开文件编码文件 + bool saveAsFile(); + //重新加载文件编码 1.文件修改 2.文件未修改处理逻辑一样 切换编码重新加载和另存为 梁卫东 + bool reloadFileEncode(QByteArray encode); + // 重新加载文件高亮类型 + void reloadFileHighlight(QString definitionName); + //重写加载修改文件 + void reloadModifyFile(); + //获取文件编码 + QString getTextEncode(); + + // 保存备份文件 + bool saveTemFile(QString qstrDir); + //更新路径 + void updatePath(const QString &file, QString qstrTruePath = QString()); + //判断是否修改 + bool isModified(); + //判断是否草稿文件 + bool isDraftFile(); + //判断是否为备份文件 + bool isBackupFile(); + //判断内容是否为空 + bool isPlainTextEmpty(); + + bool isTemFile(); + + void hideWarningNotices(); + void checkForReload(); + void initToastPosition(); + void showNotify(const QString &message); + bool getTextChangeFlag(); + void setTextChangeFlag(bool bFlag); + void setLineNumberShow(bool bIsShow, bool bIsFirstShow = false); + void setShowBlankCharacter(bool ok); + void handleCursorModeChanged(TextEdit::CursorMode mode); + void clearDoubleCharaterEncode(); + // + BottomBar *bottomBar(); + QString filePath(); + TextEdit *textEditor(); + Window *window(); + void updateHighlighterAll(); + + //get and set m_tModifiedDateTime + QDateTime getLastModifiedTime() const; + void setLastModifiedTime(const QString &time); + + void updateModifyStatus(bool isModified); + void updateSaveAsFileName(QString strOldFilePath, QString strNewFilePath); + + // 取得当前编辑器使用的高亮处理(用于打印高亮) + inline CSyntaxHighlighter *getSyntaxHighlighter() const + { return m_pSyntaxHighlighter; } + +signals: + void sigClearDoubleCharaterEncode(); + +protected: + // 处理文件加载事件 + virtual void customEvent(QEvent *e) override; + +private: + // 类似setPlainText(QString) 接口支持大文本加载 不卡顿 秒退出 梁卫东 2020年11月11日16:56:27 + void loadContent(const QByteArray &); + void handleHightlightChanged(const QString &name); + int GetCorrectUnicode1(const QByteArray &ba); + // 文件加载时重新初始化部分设置 + void reinitOnFileLoad(const QByteArray &encode); + +public slots: + // 处理文档预加载数据 + void handleFilePreProcess(const QByteArray &encode, const QByteArray &content); + void handleFileLoadFinished(const QByteArray &encode, const QByteArray &content, bool error); + void OnThemeChangeSlot(QString theme); + void UpdateBottomBarWordCnt(int cnt); + void OnUpdateHighlighter(); + //set the value of m_bIsTemFile + void setTemFile(bool value); + +private: + //第一次打开文件编码 + QString m_sFirstEncode = QString("UTF-8"); + //当前切换文件编码 + QString m_sCurEncode = QString("UTF-8"); + + //左边栏 标记 行号 折叠三合一控件 + LeftAreaTextEdit *m_pLeftAreaTextEdit = nullptr; + // + Window *m_pWindow = nullptr; + // + TextEdit *m_pTextEdit = nullptr; + // + BottomBar *m_pBottomBar = nullptr; + // + WarningNotices *m_pWaringNotices = nullptr; + + QDateTime m_tModifiedDateTime; + //退出 + bool m_bQuit = false; + //文件是否加载 + bool m_bFileLoading = false; + bool m_bIsTemFile = false; + //撤销重做栈操作任务文件修改 + bool m_bUndoRedoOption = false; + //语法高亮 + KSyntaxHighlighting::Repository m_Repository; + KSyntaxHighlighting::Definition m_Definition; + //KSyntaxHighlighting::SyntaxHighlighter *m_pSyntaxHighlighter = nullptr; + CSyntaxHighlighter *m_pSyntaxHighlighter = nullptr; + bool m_bHighlighterAll = false; + + bool m_bAsyncReadFileFinished = false; + bool m_bHasPreProcess = false; // 预处理标识 +}; + +#endif diff --git a/src/editor/endlineformatcommond.cpp b/src/editor/endlineformatcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83f7861870e180106f00eae9c14cde157512485a --- /dev/null +++ b/src/editor/endlineformatcommond.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "endlineformatcommond.h" +EndlineFormartCommand::EndlineFormartCommand(TextEdit* edit,BottomBar* bar,BottomBar::EndlineFormat from,BottomBar::EndlineFormat to): + m_edit(edit), + m_bar(bar), + m_from(from), + m_to(to) +{ + +} +EndlineFormartCommand::~EndlineFormartCommand() +{ + +} + +void EndlineFormartCommand::undo() +{ + m_bar->setEndlineMenuText(m_from); +} +void EndlineFormartCommand::redo() +{ + auto cursor = m_edit->textCursor(); + auto pos = cursor.position(); + cursor.insertText(" "); + cursor.setPosition(pos); + cursor.deleteChar(); + m_bar->setEndlineMenuText(m_to); +} diff --git a/src/editor/endlineformatcommond.h b/src/editor/endlineformatcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..19550592311dec62e280dfe23e99d4a7047bee6f --- /dev/null +++ b/src/editor/endlineformatcommond.h @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef EndlineFormartCommand_H +#define EndlineFormartCommand_H +#include +#include "../widgets/bottombar.h" +#include "dtextedit.h" + + +class EndlineFormartCommand:public QUndoCommand +{ +public: + EndlineFormartCommand(TextEdit* edit,BottomBar* bar,BottomBar::EndlineFormat from,BottomBar::EndlineFormat to); + virtual ~EndlineFormartCommand(); + +protected: + virtual void undo(); + virtual void redo(); + +private: + BottomBar* m_bar=nullptr; + BottomBar::EndlineFormat m_from; + BottomBar::EndlineFormat m_to; + TextEdit* m_edit=nullptr; + +}; + + + +#endif // UndoList_H diff --git a/src/editor/indenttextcommond.cpp b/src/editor/indenttextcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eec4fe07ec83fa68eff4b862c2556a2f11d681ce --- /dev/null +++ b/src/editor/indenttextcommond.cpp @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "indenttextcommond.h" +#include "dtextedit.h" + +IndentTextCommand::IndentTextCommand(TextEdit* edit,int startpos,int endpos,int startline,int endline): + m_edit(edit), + m_startpos(startpos), + m_endpos(endpos), + m_startline(startline), + m_endline(endline) +{ + m_hasselected = m_edit->textCursor().hasSelection(); +} +IndentTextCommand::~IndentTextCommand() +{ + +} + +void IndentTextCommand::redo() +{ + auto cursor = m_edit->textCursor(); + + //insert "\t" in front of multiple lines. + cursor.setPosition(m_startpos); + for(int i=m_startline;i<=m_endline;i++){ + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.insertText("\t"); + + cursor.movePosition(QTextCursor::NextBlock); + } + + //reset selection. + if(m_hasselected){ + if(m_startline == m_endline){ + cursor.setPosition(m_startpos); + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.movePosition(QTextCursor::EndOfBlock,QTextCursor::KeepAnchor); + m_edit->setTextCursor(cursor); + } + else{ + cursor.setPosition(m_startpos+1); + cursor.setPosition(m_endpos + m_endline - m_startline +1,QTextCursor::KeepAnchor); + m_edit->setTextCursor(cursor); + } + + } +} + + + +void IndentTextCommand::undo() +{ + auto cursor = m_edit->textCursor(); + + //delete "\t" in front of multiple lines. + cursor.setPosition(m_startpos); + for(int i=m_startline;i<=m_endline;i++){ + cursor.movePosition(QTextCursor::StartOfBlock); + cursor.deleteChar(); + + cursor.movePosition(QTextCursor::NextBlock); + } + + //reset selection + if(m_hasselected){ + cursor.setPosition(m_startpos); + cursor.setPosition(m_endpos,QTextCursor::KeepAnchor); + m_edit->setTextCursor(cursor); + } +} diff --git a/src/editor/indenttextcommond.h b/src/editor/indenttextcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..10730424483e59d8bc11de4eab8e912b730e3ec2 --- /dev/null +++ b/src/editor/indenttextcommond.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef IndentTextCommand_H +#define IndentTextCommand_H + +#include +#include +#include +#include +class TextEdit; +//indent text in front of multiple lines +class IndentTextCommand:public QUndoCommand +{ +public: + IndentTextCommand(TextEdit* edit,int startpos,int endpos,int startline,int endline); + virtual ~IndentTextCommand(); + + virtual void redo(); + virtual void undo(); + +private: + + TextEdit* m_edit=nullptr; + //the start postion of selected text. + int m_startpos=0; + //the end postion of selected text. + int m_endpos=0; + //the start line of selected text. + int m_startline=0; + //the end line of selected text. + int m_endline=0; + bool m_hasselected=false; + +}; + +#endif // IndentTextCommand_H diff --git a/src/editor/insertblockbytextcommond.cpp b/src/editor/insertblockbytextcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f33971ccacca59762bc1e1616bd44bc46f420992 --- /dev/null +++ b/src/editor/insertblockbytextcommond.cpp @@ -0,0 +1,102 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "insertblockbytextcommond.h" +#include "inserttextundocommand.h" +#include +#include "dtextedit.h" +#include "editwrapper.h" +#include "../widgets/window.h" +#include "../widgets/bottombar.h" + +InsertBlockByTextCommand::InsertBlockByTextCommand(const QString &text,TextEdit *edit,EditWrapper* wrapper): + m_text(text), + m_edit(edit), + m_wrapper(wrapper) +{ + if(nullptr == m_edit || m_text.isEmpty() || nullptr == m_wrapper) + return; + + auto cursor = m_edit->textCursor(); + if(cursor.hasSelection()){ + m_selected = cursor.selectedText(); + m_insertPos = std::min(cursor.anchor(),cursor.position()); + } +} + +InsertBlockByTextCommand::~InsertBlockByTextCommand() +{ + +} + +void InsertBlockByTextCommand::redo() +{ + treat(true); + insertByBlock(); + treat(false); +} + +void InsertBlockByTextCommand::undo() +{ + treat(true); + + auto cursor = m_edit->textCursor(); + cursor.setPosition(m_delPos); + cursor.setPosition(m_delPos - m_text.size(),QTextCursor::KeepAnchor); + cursor.deleteChar(); + + if(!m_selected.isEmpty()){ + cursor.setPosition(m_insertPos); + cursor.insertText(m_selected); + } + + treat(false); +} + +void InsertBlockByTextCommand::treat(bool isStart) +{ + if(m_wrapper!=nullptr){ + + Window* window = m_wrapper->window(); + BottomBar* bar = m_wrapper->bottomBar(); + if(window){ + window->setPrintEnabled(!isStart); + } + if(bar){ + bar->setChildEnabled(!isStart); + } + } + + if(!isStart) + QObject::connect(m_edit, &QPlainTextEdit::cursorPositionChanged, m_edit, &TextEdit::cursorPositionChanged); + else + QObject::disconnect(m_edit, &QPlainTextEdit::cursorPositionChanged, m_edit, &TextEdit::cursorPositionChanged); +} + +void InsertBlockByTextCommand::insertByBlock() +{ + auto cursor = m_edit->textCursor(); + int block = 1 * 1024 * 1024 ; + int size = m_text.size(); + if(size > block){ + int n = size / (block); + int y = size % (block); + int k=0; + for(;kisQuit()){ + QString insertText = m_text.mid(k*block,block); + cursor.insertText(insertText); + QApplication::processEvents(); + } + } + if(y){ + if(m_wrapper!=nullptr && !m_wrapper->isQuit()){ + QString insertText = m_text.mid(k*block,y); + cursor.insertText(insertText); + QApplication::processEvents(); + } + } + } + m_delPos = cursor.position(); +} diff --git a/src/editor/insertblockbytextcommond.h b/src/editor/insertblockbytextcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..ef13081211cbe99cab9747f9bd2f381ac91cdf20 --- /dev/null +++ b/src/editor/insertblockbytextcommond.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef INSERTBLOCKBYTEXTCOMMOND_H +#define INSERTBLOCKBYTEXTCOMMOND_H + +#include +#include +#include +#include +class TextEdit; +class EditWrapper; + +//分块插入文本-撤销重做 +class InsertBlockByTextCommand:public QUndoCommand +{ +public: + InsertBlockByTextCommand(const QString& text,TextEdit* edit,EditWrapper* wrapper); + virtual ~InsertBlockByTextCommand(); + + virtual void redo(); + virtual void undo(); + +private: + void treat(bool isStart = true); + void insertByBlock(); + +private: + QString m_text; + TextEdit* m_edit; + EditWrapper* m_wrapper; + int m_insertPos; + int m_delPos {0}; + QString m_selected; +}; + +#endif // INSERTBLOCKBYTEXTCOMMOND_H diff --git a/src/editor/inserttextundocommand.cpp b/src/editor/inserttextundocommand.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b5b76e9f6ab978a983021e0f9e6fe8f7ff39ba4 --- /dev/null +++ b/src/editor/inserttextundocommand.cpp @@ -0,0 +1,140 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "inserttextundocommand.h" + +InsertTextUndoCommand::InsertTextUndoCommand(QTextCursor textcursor, QString text, QPlainTextEdit *edit, QUndoCommand *parent) + : QUndoCommand(parent) + , m_pEdit(edit) + , m_textCursor(textcursor) + , m_sInsertText(text) +{ + m_sInsertText.replace("\r\n", "\n"); +} + +InsertTextUndoCommand::InsertTextUndoCommand(QList &selections, QString text, QPlainTextEdit *edit, QUndoCommand *parent) + : QUndoCommand(parent) + , m_pEdit(edit) + , m_sInsertText(text) + , m_ColumnEditSelections(selections) +{ + m_sInsertText.replace("\r\n", "\n"); +} + +void InsertTextUndoCommand::undo() +{ + if (m_ColumnEditSelections.isEmpty()) { + // 注意部分字符显示占位超过1 + m_textCursor.setPosition(m_endPostion); + m_textCursor.setPosition(m_beginPostion, QTextCursor::KeepAnchor); + m_textCursor.deleteChar(); + if (m_selectText != QString()) { + m_textCursor.insertText(m_selectText); + m_textCursor.setPosition(m_textCursor.position() - m_selectText.length(), QTextCursor::KeepAnchor); + } + + // 进行撤销/恢复时将光标移动到撤销位置 + if (m_pEdit) { + m_pEdit->setTextCursor(m_textCursor); + } + } else { + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + m_ColumnEditSelections[i].cursor.deleteChar(); + } + + if (m_pEdit && !m_ColumnEditSelections.isEmpty()) { + m_pEdit->setTextCursor(m_ColumnEditSelections.last().cursor); + } + } + +} + +void InsertTextUndoCommand::redo() +{ + if (m_ColumnEditSelections.isEmpty()) { + if (m_textCursor.hasSelection()) { + m_selectText = m_textCursor.selectedText(); + m_textCursor.removeSelectedText(); + } + + m_textCursor.insertText(m_sInsertText); + m_textCursor.setPosition(m_textCursor.position() - m_sInsertText.length(), QTextCursor::KeepAnchor); + m_beginPostion = m_textCursor.selectionStart(); + m_endPostion = m_textCursor.selectionEnd(); + + // 进行撤销/恢复时将光标移动到撤销位置 + if (m_pEdit) { + QTextCursor curCursor = m_pEdit->textCursor(); + curCursor.setPosition(m_endPostion); + m_pEdit->setTextCursor(curCursor); + } + } else { + int cnt = m_ColumnEditSelections.size(); + for (int i = 0; i < cnt; i++) { + m_ColumnEditSelections[i].cursor.insertText(m_sInsertText); + m_ColumnEditSelections[i].cursor.setPosition(m_ColumnEditSelections[i].cursor.position() - m_sInsertText.length() + 1, + QTextCursor::KeepAnchor); + } + + if (m_pEdit && !m_ColumnEditSelections.isEmpty()) { + QTextCursor curCursor = m_pEdit->textCursor(); + curCursor.setPosition(m_ColumnEditSelections.last().cursor.selectionEnd()); + m_pEdit->setTextCursor(curCursor); + } + } +} + + +/** + * @class MidButtonInsertTextUndoCommand + * @brief 用于鼠标中键黏贴的插入撤销项,使用 QClipboard::Selection 类型插入选中的数据, + * 需要注意中键插入不会覆盖被选中的文本。 + */ +MidButtonInsertTextUndoCommand::MidButtonInsertTextUndoCommand(QTextCursor textcursor, QString text, QPlainTextEdit *edit, QUndoCommand *parent) + : QUndoCommand(parent) + , m_pEdit(edit) + , m_textCursor(textcursor) + , m_sInsertText(text) +{ + m_sInsertText.replace("\r\n", "\n"); + // 中键黏贴需要构造时计算一次光标位置 + m_beginPostion = m_textCursor.position(); + m_endPostion = m_textCursor.position() + m_sInsertText.length(); +} + +/** + * @brief 撤销插入动作,移除已被插入的文本。 + */ +void MidButtonInsertTextUndoCommand::undo() +{ + m_textCursor.setPosition(m_endPostion); + m_textCursor.setPosition(m_beginPostion, QTextCursor::KeepAnchor); + m_textCursor.deleteChar(); + + // 进行撤销/恢复时将光标移动到撤销位置 + if (m_pEdit) { + m_pEdit->setTextCursor(m_textCursor); + } +} + +/** + * @brief 重新执行插入文本,用于恢复动作。 + * 当前中键插入使用默认流程,数据已插入至文本后再添加撤销项, + * 首次 redo() 不执行,通过插入撤销栈后再添加子撤销项规避。 + */ +void MidButtonInsertTextUndoCommand::redo() +{ + m_textCursor.insertText(m_sInsertText); + m_textCursor.setPosition(m_textCursor.position() - m_sInsertText.length(), QTextCursor::KeepAnchor); + m_beginPostion = m_textCursor.selectionStart(); + m_endPostion = m_textCursor.selectionEnd(); + + // 进行撤销/恢复时将光标移动到撤销位置 + if (m_pEdit) { + QTextCursor curCursor = m_pEdit->textCursor(); + curCursor.setPosition(m_endPostion); + m_pEdit->setTextCursor(curCursor); + } +} diff --git a/src/editor/inserttextundocommand.h b/src/editor/inserttextundocommand.h new file mode 100644 index 0000000000000000000000000000000000000000..5f91db9b9e5e83f1d68a0312bfcfc34353d0026c --- /dev/null +++ b/src/editor/inserttextundocommand.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef INSERTTEXTUNDOCOMMAND_H +#define INSERTTEXTUNDOCOMMAND_H + +#include +#include +#include +#include +#include + +class InsertTextUndoCommand : public QUndoCommand +{ +public: + explicit InsertTextUndoCommand(QTextCursor textcursor, QString text, QPlainTextEdit *edit, QUndoCommand *parent = nullptr); + explicit InsertTextUndoCommand(QList &selections, QString text, QPlainTextEdit *edit, QUndoCommand *parent = nullptr); + virtual void undo(); + virtual void redo(); + +private: + QPlainTextEdit *m_pEdit = nullptr; + QTextCursor m_textCursor; + int m_beginPostion {0}; + int m_endPostion {0}; + QString m_sInsertText; + QList m_ColumnEditSelections; + QString m_selectText = QString(); +}; + +/** + * @brief 鼠标中键插入字符时使用的文本插入撤销项, 需要注意中键插入不会覆盖被选中的文本。 + */ +class MidButtonInsertTextUndoCommand : public QUndoCommand +{ +public: + explicit MidButtonInsertTextUndoCommand(QTextCursor textcursor, QString text, QPlainTextEdit *edit, QUndoCommand *parent = nullptr); + + virtual void undo(); + virtual void redo(); + +private: + QPlainTextEdit *m_pEdit = nullptr; // 关联的文本编辑控件 + QTextCursor m_textCursor; // 插入前的光标 + QString m_sInsertText; // 插入文本 + int m_beginPostion = 0; // 维护插入位置的标记 + int m_endPostion = 0; +}; + +#endif // INSERTTEXTUNDOCOMMAND_H diff --git a/src/editor/leftareaoftextedit.cpp b/src/editor/leftareaoftextedit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..03c6ccd793b5bcba0274bad71b8e4509def9fcd4 --- /dev/null +++ b/src/editor/leftareaoftextedit.cpp @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "leftareaoftextedit.h" +#include "linenumberarea.h" +#include "bookmarkwidget.h" +#include "codeflodarea.h" +#include "dtextedit.h" + +#include +#include + + +LeftAreaTextEdit::LeftAreaTextEdit(TextEdit *textEdit) : + m_pTextEdit(textEdit) +{ + QHBoxLayout *pHLayout = new QHBoxLayout(this); + m_pLineNumberArea = new LineNumberArea(this); + m_pBookMarkArea = new BookMarkWidget(this); + m_pFlodArea = new CodeFlodArea(this); + + m_pBookMarkArea->setContentsMargins(0, 0, 0, 0); + m_pFlodArea->setContentsMargins(0, 0, 0, 0); + m_pLineNumberArea->setContentsMargins(0, 0, 0, 0); + //m_pBookMarkArea->setFixedWidth(14); + // m_pFlodArea->setFixedWidth(18); + //m_pBookMarkArea->setFixedWidth(textEdit->cursorRect(textEdit->textCursor()).height()); + // m_pFlodArea->setFixedWidth(textEdit->cursorRect(textEdit->textCursor()).height()); + + pHLayout->addWidget(m_pBookMarkArea); + pHLayout->addWidget(m_pLineNumberArea); + pHLayout->addWidget(m_pFlodArea); + pHLayout->setContentsMargins(0, 0, 0, 0); + pHLayout->setSpacing(0); + this->setLayout(pHLayout); +} + +LeftAreaTextEdit::~LeftAreaTextEdit() +{ + +} + +void LeftAreaTextEdit::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + m_pTextEdit->lineNumberAreaPaintEvent(event); +} + +int LeftAreaTextEdit::lineNumberAreaWidth() +{ + int digits = 1; + int max = qMax(1, m_pTextEdit->document()->blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + return 13 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits + 40; +} + + +void LeftAreaTextEdit::bookMarkAreaPaintEvent(QPaintEvent *event) +{ + m_pTextEdit->bookMarkAreaPaintEvent(event); +} + +void LeftAreaTextEdit::codeFlodAreaPaintEvent(QPaintEvent *event) +{ + m_pTextEdit->codeFLodAreaPaintEvent(event); +} + +void LeftAreaTextEdit::updateLineNumber() +{ + if (m_pLineNumberArea) m_pLineNumberArea->update(); +} + +void LeftAreaTextEdit::updateBookMark() +{ + if (m_pBookMarkArea) m_pBookMarkArea->update(); +} + +void LeftAreaTextEdit::updateCodeFlod() +{ + if (m_pFlodArea) m_pFlodArea->update(); +} + +void LeftAreaTextEdit::updateAll() +{ + if (m_pLineNumberArea) m_pLineNumberArea->update(); + if (m_pBookMarkArea) m_pBookMarkArea->update(); + if (m_pFlodArea) m_pFlodArea->update(); +} + +void LeftAreaTextEdit::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + QColor bdColor; + if (m_pTextEdit->getBackColor().lightness() < 128) { + bdColor = palette().brightText().color(); + bdColor.setAlphaF(0.06); + } else { + bdColor = palette().brightText().color(); + bdColor.setAlphaF(0.03); + } + painter.fillRect(event->rect(), bdColor); +} + + +TextEdit* LeftAreaTextEdit::getEdit() +{ + return m_pTextEdit; +} + + diff --git a/src/editor/leftareaoftextedit.h b/src/editor/leftareaoftextedit.h new file mode 100644 index 0000000000000000000000000000000000000000..d6e3cbf37a5619d1df3931f9a2d8dea6dbcf4c1e --- /dev/null +++ b/src/editor/leftareaoftextedit.h @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef LEFTAREAOFTEXTEDIT_H +#define LEFTAREAOFTEXTEDIT_H + +#include + +class CodeFlodArea; +class BookMarkWidget; +class LineNumberArea; +class TextEdit; + +class LeftAreaTextEdit : public QWidget +{ + Q_OBJECT +public: + explicit LeftAreaTextEdit(TextEdit *textEdit); + ~LeftAreaTextEdit() override; + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + void bookMarkAreaPaintEvent(QPaintEvent *event); + void codeFlodAreaPaintEvent(QPaintEvent *event); + void updateLineNumber(); + void updateBookMark(); + void updateCodeFlod(); + void updateAll(); + TextEdit* getEdit(); +protected: + void paintEvent(QPaintEvent *event); +public: + LineNumberArea *m_pLineNumberArea = nullptr; + BookMarkWidget *m_pBookMarkArea = nullptr; + CodeFlodArea *m_pFlodArea = nullptr; + +private: + TextEdit *m_pTextEdit = nullptr; +}; + +#endif // LEFTAREAOFTEXTEDIT_H diff --git a/src/editor/linenumberarea.cpp b/src/editor/linenumberarea.cpp new file mode 100644 index 0000000000000000000000000000000000000000..468a09661d5c2e834cce1c66d5be7d78ff04a921 --- /dev/null +++ b/src/editor/linenumberarea.cpp @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2017-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "linenumberarea.h" +#include "dtextedit.h" +#include "leftareaoftextedit.h" +#include +#include + +LineNumberArea::LineNumberArea(LeftAreaTextEdit *leftAreaWidget) +{ + m_leftAreaWidget = leftAreaWidget; + setContentsMargins(0, 0, 0, 0); + //m_textEdit = textEdit; +} + +LineNumberArea::~LineNumberArea() +{ +} + +void LineNumberArea::paintEvent(QPaintEvent *e) +{ + //qDebug() << "LineNumberArea::paintEvent "; + m_leftAreaWidget->lineNumberAreaPaintEvent(e); + //m_textEdit->lineNumberAreaPaintEvent(e); +} + +QSize LineNumberArea::sizeHint() const +{ + return QSize(m_leftAreaWidget->lineNumberAreaWidth(), 0); +} + + +void LineNumberArea::mousePressEvent(QMouseEvent *e) +{ +// m_pressPoint = e->pos(); +// m_leftAreaWidget->update(); + m_leftAreaWidget->getEdit()->onPressedLineNumber(e->pos()); + QWidget::mousePressEvent(e); +} + +QPoint LineNumberArea::getPressPoint() +{ + return m_pressPoint; +} diff --git a/src/editor/linenumberarea.h b/src/editor/linenumberarea.h new file mode 100644 index 0000000000000000000000000000000000000000..aecf5d9359ae91e8db62a8e2cbc7ca224875cf7a --- /dev/null +++ b/src/editor/linenumberarea.h @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2017-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef LINENUMBERAREA_H +#define LINENUMBERAREA_H + +#include + +class LeftAreaTextEdit; +class TextEdit; + +class LineNumberArea : public QWidget +{ + Q_OBJECT + +public: + explicit LineNumberArea(LeftAreaTextEdit *leftAreaWidget); + ~LineNumberArea() override; + QPoint getPressPoint(); + +protected: + void paintEvent(QPaintEvent *e) override; + QSize sizeHint() const override; + void mousePressEvent(QMouseEvent *e) override; + +private: + LeftAreaTextEdit *m_leftAreaWidget; + QPoint m_pressPoint; +}; + +#endif diff --git a/src/editor/replaceallcommond.cpp b/src/editor/replaceallcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4aa0d85a0da9b7a817b76a4a4b652b484142c5e6 --- /dev/null +++ b/src/editor/replaceallcommond.cpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "replaceallcommond.h" + + + +ReplaceAllCommand::ReplaceAllCommand(QString &oldText, QString &newText, QTextCursor cursor, QUndoCommand *parent) + : QUndoCommand(parent) + , m_oldText(oldText) + , m_newText(newText) + , m_cursor(cursor) +{ + +} + +ReplaceAllCommand::~ReplaceAllCommand() +{ + +} + +void ReplaceAllCommand::redo() +{ + m_cursor.setPosition(0); + m_cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + m_cursor.deleteChar(); + + m_cursor.insertText(m_newText); +} + +void ReplaceAllCommand::undo() +{ + m_cursor.setPosition(0); + m_cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + m_cursor.deleteChar(); + + m_cursor.insertText(m_oldText); +} diff --git a/src/editor/replaceallcommond.h b/src/editor/replaceallcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..9b9c69ad73aa3c8b0fc7d5834247a888efa1814b --- /dev/null +++ b/src/editor/replaceallcommond.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef REPLACEALLCOMMOND_H +#define REPLACEALLCOMMOND_H + +#include +#include +#include +#include +#include +#include "dtextedit.h" + +// 全部替换撤销-重做 +class ReplaceAllCommand: public QUndoCommand +{ +public: + ReplaceAllCommand(QString &oldText, QString &newText, QTextCursor cursor, QUndoCommand *parent = nullptr); + virtual ~ReplaceAllCommand(); + + virtual void redo(); + virtual void undo(); + +private: + QString m_oldText; + QString m_newText; + QTextCursor m_cursor; +}; + +#endif // REPLACEALLCOMMOND_H diff --git a/src/editor/showflodcodewidget.cpp b/src/editor/showflodcodewidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..99f235c89a4b1f8f25bb68c108612e4b482d49d8 --- /dev/null +++ b/src/editor/showflodcodewidget.cpp @@ -0,0 +1,136 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "showflodcodewidget.h" +#include +#include +#include +#include +#include +#include +#include + +namespace KSyntaxHighlighting { + class SyntaxHighlighter; +} + +ShowFlodCodeWidget::ShowFlodCodeWidget(DWidget *parent) + : DFrame(parent) +{ + //setFrameRounded(false); + QGraphicsDropShadowEffect *effert = new QGraphicsDropShadowEffect(this); + effert->setOffset(0,6); + effert->setBlurRadius(20); + QColor color(0,0,0); + color.setAlphaF(0.2); + effert->setColor(color); + this->setGraphicsEffect(effert); + QVBoxLayout *pSubLayout = new QVBoxLayout(); + m_pContentEdit = new DPlainTextEdit(this); + m_pContentEdit->setWordWrapMode(QTextOption::WrapAnywhere); + m_pContentEdit->setFrameStyle(0); + m_pContentEdit->setReadOnly(true); + m_pContentEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_pContentEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + pSubLayout->addWidget(m_pContentEdit); + this->setLayout(pSubLayout); + m_highlighter = new KSyntaxHighlighting::SyntaxHighlighter(m_pContentEdit->document()); +} + +ShowFlodCodeWidget::~ShowFlodCodeWidget() +{ + m_highlighter->deleteLater(); + m_highlighter = nullptr; +} + +void ShowFlodCodeWidget::clear() +{ + m_pContentEdit->document()->clear(); + m_nTextWidth = 0; + adjustSize(); +} + +void ShowFlodCodeWidget::initHighLight(QString filepath, bool bIsLight) +{ + if (m_highlighter != nullptr) { + if (!bIsLight) { + m_highlighter->setTheme(m_repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)); + } else { + m_highlighter->setTheme(m_repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + } + } + // m_highlighter->rehighlight(); + const auto def = m_repository.definitionForFileName(QFileInfo(filepath).fileName()); + m_highlighter->setDefinition(def); +} + +void ShowFlodCodeWidget::setStyle(bool bIsLineWrap) +{ + QPalette pa = palette(); + QColor color(25,25,25); + + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::ColorType::DarkType) { + color.setAlphaF(0.8); + pa.setColor(QPalette::Base,color); + m_pContentEdit->setPalette(pa); + pa.setColor(QPalette::Base,QColor(25,25,25)); + setPalette(pa); + } else { + color = QColor(247,247,247); + color.setAlphaF(0.6); + pa.setColor(QPalette::Base,color); + m_pContentEdit->setPalette(pa); + pa.setColor(QPalette::Base,QColor(247,247,247)); + setPalette(pa); + } + + if (bIsLineWrap) { + m_pContentEdit->setLineWrapMode(QPlainTextEdit::WidgetWidth); + } else { + m_pContentEdit->setLineWrapMode(QPlainTextEdit::NoWrap); + } +} + +void ShowFlodCodeWidget::hideFirstBlock() +{ + m_pContentEdit->document()->firstBlock().setVisible(false); + m_pContentEdit->document()->lastBlock().setVisible(false); + int editHight = 0; + + for (auto block = m_pContentEdit->document()->firstBlock(); block.isValid(); block = block.next()) { + + if (block == m_pContentEdit->document()->lastBlock()) { + break; + } + + editHight += m_pContentEdit->document()->documentLayout()->blockBoundingRect(block).toRect().height(); + } + + m_pContentEdit->setFixedHeight(editHight + 10); +} + +void ShowFlodCodeWidget::appendText(QString strText, int maxWidth) +{ + int textWidth = m_pContentEdit->fontMetrics().width(strText) + 10; + + if (m_nTextWidth < textWidth) { + m_nTextWidth = textWidth; + if (m_nTextWidth > maxWidth - 50) { + m_nTextWidth = maxWidth - 50; + } + } + + m_pContentEdit->setFixedWidth(m_nTextWidth); + + if (m_pContentEdit->document()->isEmpty()) { + m_pContentEdit->setPlainText(strText); + } else { + m_pContentEdit->appendPlainText(strText); + } + + QTextCursor cursor = m_pContentEdit->textCursor(); + cursor.movePosition(QTextCursor::Start); + m_pContentEdit->setTextCursor(cursor); +} + diff --git a/src/editor/showflodcodewidget.h b/src/editor/showflodcodewidget.h new file mode 100644 index 0000000000000000000000000000000000000000..f829ed3557ec13093286728be252421834ac78b6 --- /dev/null +++ b/src/editor/showflodcodewidget.h @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SHOWFLODCODEWIDGET_H +#define SHOWFLODCODEWIDGET_H +#include +#include +#include +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class ShowFlodCodeWidget: public DFrame +{ + Q_OBJECT +public: + explicit ShowFlodCodeWidget(DWidget *parent = nullptr); + ~ShowFlodCodeWidget(); + + /** + * @author liumaochuan ut000616 + * @brief appendText 添加文本 + * @param strText 文本 + * @param maxWidth 当前窗口宽度 + */ + void appendText(QString strText, int maxWidth); + + void clear(); + + /** + * @author liumaochuan ut000616 + * @brief initHighLight 设置语法高亮 + * @param filepath 当前文件路径 + */ + void initHighLight(QString filepath, bool bIsLight); + + /** + * @author liumaochuan ut000616 + * @brief setStyle 设置样式 + * @param bIsLineWrap 是否换行 + */ + void setStyle(bool bIsLineWrap); + + /** + * @author liumaochuan ut000616 + * @brief hideFirstAndLastBlock 隐藏首末行 + */ + void hideFirstBlock(); + +private: + DPlainTextEdit *m_pContentEdit; + int m_nTextWidth = 0;///< 代码预览框宽度 + KSyntaxHighlighting::Repository m_repository; + KSyntaxHighlighting::SyntaxHighlighter *m_highlighter; +}; + +#endif // SHOWFLODCODEWIDGET_H diff --git a/src/editor/uncommentselection.cpp b/src/editor/uncommentselection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c721c96c09350f2674cc119bb956861e5dec65f8 --- /dev/null +++ b/src/editor/uncommentselection.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "uncommentselection.h" +#include + +using namespace Comment; + +CommentDefinition::CommentDefinition() : + isAfterWhiteSpaces(false) +{} + +void CommentDefinition::setComments(QString singleLineComment, QString multiLineCommentStart, QString multiLineCommentEnd) +{ + singleLine = singleLineComment; + multiLineStart = multiLineCommentStart; + multiLineEnd = multiLineCommentEnd; +} + +bool CommentDefinition::isValid() const +{ + return hasSingleLineStyle() || hasMultiLineStyle(); +} + +bool CommentDefinition::hasSingleLineStyle() const +{ + return !singleLine.isEmpty(); +} + +bool CommentDefinition::hasMultiLineStyle() const +{ + return !multiLineStart.isEmpty() && !multiLineEnd.isEmpty(); +} + diff --git a/src/editor/uncommentselection.h b/src/editor/uncommentselection.h new file mode 100644 index 0000000000000000000000000000000000000000..4f504386beb6a99608c65a7efaeaae6cfd30714e --- /dev/null +++ b/src/editor/uncommentselection.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "../common/comment_global.h" +#include +#include + +namespace Comment { + class COMMENT_EXPORT CommentDefinition + { + public: + CommentDefinition(); + + enum Style { NoStyle, CppStyle, HashStyle }; + void setComments(QString singleLineComment, QString multiLineCommentStart, QString multiLineCommentEnd); + + bool isValid() const; + bool hasSingleLineStyle() const; + bool hasMultiLineStyle() const; + + public: + bool isAfterWhiteSpaces; + QString singleLine; + QString multiLineStart; + QString multiLineEnd; + }; +} diff --git a/src/editor/undolist.cpp b/src/editor/undolist.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6f0c1babb6b24169247d12599803bfe280638a9 --- /dev/null +++ b/src/editor/undolist.cpp @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "undolist.h" +UndoList::UndoList() +{ + +} +UndoList::~UndoList() +{ + for (auto& it : m_coms) { + if(nullptr != it){ + delete it; + it = nullptr; + } + } + + m_coms.clear(); +} +void UndoList::appendCom(QUndoCommand* com) +{ + if(nullptr != com){ + m_coms.push_back(com); + } +} +void UndoList::undo() +{ + //do the undo operation in the reverse order. + for(auto it = m_coms.rbegin();it!=m_coms.rend();it++){ + (*it)->undo(); + } +} +void UndoList::redo() +{ + foreach (auto it, m_coms) { + it->redo(); + } +} diff --git a/src/editor/undolist.h b/src/editor/undolist.h new file mode 100644 index 0000000000000000000000000000000000000000..70c6ccda542d9e560629dcdd2b4dad9b3b506afe --- /dev/null +++ b/src/editor/undolist.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UndoList_H +#define UndoList_H +#include +#include +#include +#include + +//combine multiple undo/redo commands in one commond. +//notice:make sure that multiple commands are independent of each other. +class UndoList:public QUndoCommand +{ +public: + UndoList(); + virtual ~UndoList(); + void appendCom(QUndoCommand* com); +protected: + virtual void undo(); + virtual void redo(); + +private: + QList m_coms; + +}; + + + +#endif // UndoList_H diff --git a/src/editorapplication.cpp b/src/editorapplication.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e0247ac995df428701c58e5362fd61ba3241e81c --- /dev/null +++ b/src/editorapplication.cpp @@ -0,0 +1,95 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "editorapplication.h" +#include "common/settings.h" +#include + +EditorApplication::EditorApplication(int &argc, char *argv[]) : DApplication(argc, argv) +{ + const char *descriptionText = QT_TRANSLATE_NOOP( + "MainWindow", "Text Editor is a powerful tool for viewing and editing text files."); + const QString acknowledgementLink = "https://www.deepin.org/original/deepin-editor/"; + + setAttribute(Qt::AA_UseHighDpiPixmaps); + loadTranslator(); + setOrganizationName("deepin"); + setApplicationName("deepin-editor"); + setApplicationDisplayName(QObject::tr("Text Editor")); + setApplicationVersion(VERSION); + setProductIcon(QIcon::fromTheme("deepin-editor")); + setProductName(DApplication::translate("MainWindow", "Text Editor")); + setApplicationDescription(DApplication::translate("MainWindow", descriptionText) + "\n"); + setApplicationAcknowledgementPage(acknowledgementLink); + setQuitOnLastWindowClosed(false); +} + +EditorApplication::~EditorApplication() +{ + // app结束时,释放 + if (nullptr != StartManager::instance()) { + delete StartManager::instance(); + } +} + +void EditorApplication::handleQuitAction() +{ + activeWindow()->close(); +} + +bool EditorApplication::notify(QObject *object, QEvent *event) +{ + // ALT+M = 右键 + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyevent = static_cast(event); + /***add begin by ut001121 zhangmeng 20200801 截获DPushButton控件回车按键事件并模拟空格键点击事件,用以解决回车键不响应的问题***/ + // 回车键 恢复默认 添健按钮 + if ((object->metaObject()->className() == QStringLiteral("QPushButton") + // 远程和自定义列表的返回按钮,编辑按钮 + || object->metaObject()->className() == QStringLiteral("IconButton") + // 搜索框的上下搜索 + || object->metaObject()->className() == QStringLiteral("Dtk::Widget::DIconButton") + // 设置里面的单选框 + || object->metaObject()->className() == QStringLiteral("QCheckBox") + // 设置字体组合框 + || object->metaObject()->className() == QStringLiteral("QComboBox") + // 设置窗口组合框 + || object->metaObject()->className() == QStringLiteral("ComboBox")) + && (keyevent->key() == Qt::Key_Return || keyevent->key() == Qt::Key_Enter)) { + DPushButton *pushButton = static_cast(object); + // 模拟空格键按下事件 + pressSpace(pushButton); + return true; + } + /***add end by ut001121***/ + // 左键 + // 远程和自定义列表的返回按钮 Key_Left + if ((object->objectName() == QStringLiteral("CustomRebackButton") + || object->objectName() == QStringLiteral("RemoteSearchRebackButton") + || object->objectName() == QStringLiteral("RemoteGroupRebackButton")) + && keyevent->key() == Qt::Key_Left) { + DPushButton *pushButton = static_cast(object); + // 模拟空格键按下事件 + pressSpace(pushButton); + return true; + } + + return QApplication::notify(object, event); + } + + return QApplication::notify(object, event); +} + +void EditorApplication::pressSpace(DPushButton *pushButton) +{ + // 模拟空格键按下事件 + QKeyEvent pressSpace(QEvent::KeyPress, Qt::Key_Space, Qt::NoModifier, " "); + QApplication::sendEvent(pushButton, &pressSpace); + // 设置定时 + QTimer::singleShot(80, this, [pushButton]() { + // 模拟空格键松开事件 + QKeyEvent releaseSpace(QEvent::KeyRelease, Qt::Key_Space, Qt::NoModifier, " "); + QApplication::sendEvent(pushButton, &releaseSpace); + }); +} diff --git a/src/editorapplication.h b/src/editorapplication.h new file mode 100644 index 0000000000000000000000000000000000000000..20820b0149c18a7a8b1ec7158b2d9fc57776d531 --- /dev/null +++ b/src/editorapplication.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef EDITORAPPLICATION_H +#define EDITORAPPLICATION_H +#include "environments.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "startmanager.h" + +DWIDGET_USE_NAMESPACE + +class EditorApplication:public DApplication +{ + Q_OBJECT +public: + EditorApplication(int &argc, char *argv[]); + ~EditorApplication() override; +protected: + void handleQuitAction()override; + bool notify(QObject *object, QEvent *event) override; +private: + // 模拟键盘space键按压 + void pressSpace(DPushButton *pushButton); +}; + +#endif // EDITORAPPLICATION_H diff --git a/src/encodes/detectcode.cpp b/src/encodes/detectcode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..774a1abeada5670f0b58d80a4c7f5c0389b8803d --- /dev/null +++ b/src/encodes/detectcode.cpp @@ -0,0 +1,864 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "detectcode.h" +#include "../common/config.h" + +#include +#include +#include +#include +#include + +#include + +#define DISABLE_TEXTCODEC + +QMap DetectCode::sm_LangsMap; + +// 最低的检测准确度判断,低于90%需要调整策略 +static const float gs_dMinConfidence = 0.9f; + +// 手动添加 UTF BOM 信息 +static QMap gs_byteOrderMark = {{"UTF-16LE", QByteArray::fromHex("FFFE")}, + {"UTF-16BE", QByteArray::fromHex("FEFF")}, + {"UTF-32LE", QByteArray::fromHex("FFFE0000")}, + {"UTF-32BE", QByteArray::fromHex("0000FEFF")}}; + +/** + # GB18030-2022 - UTF-8 编码转换处理 + 为适配 GB18030-2022 规范,{gs_UTF8MapGB18030Data} 为 GB18030-UTF8 PUA 区域映射表,对应 GB18030-2022 规范附录D 表D.1 + 替换2005和2022规范中转换存在差异的部分, 见 \l{https://en.wikipedia.org/wiki/GB_18030} + */ +static QHash gs_UTF8MapGB18030Data{ + {"\uE81E", 0x37903582}, {"\uE826", 0x38903582}, {"\uE82B", 0x39903582}, {"\uE82C", 0x30913582}, {"\uE832", 0x31913582}, + {"\uE843", 0x32913582}, {"\uE854", 0x33913582}, {"\uE864", 0x34913582}, {"\uE78D", 0x36823184}, {"\uE78F", 0x37823184}, + {"\uE78E", 0x38823184}, {"\uE790", 0x39823184}, {"\uE791", 0x30833184}, {"\uE792", 0x31833184}, {"\uE793", 0x32833184}, + {"\uE794", 0x33833184}, {"\uE795", 0x34833184}, {"\uE796", 0x35833184}, /*{"\uE816", 0x31903295}, {"\uE817", 0x33903295}, + {"\uE818", 0x30973295}, {"\uE831", 0x37B93695}, {"\uE83B", 0x35BA3096}, {"\uE855", 0x30B63596}*/}; + +/** + # GB18030-2022 规范附录D 表D.2处理 + GB18030 -> UTF8 编码转换时需要特殊处理,保留GB18030特殊编码的字符 + 在转换 0xFE51...0xFE91 编码时,GB18030 规范和 Unciode 4.1 规范转换后的编码不同,以 0xFE51 为例: + 1. 按 GB18030-2022 编码规范,0xFE51 转换为 \uE816 ,而非 \u20087,因此在转码前将 0xFE51 替换为转码标识 0xFFFFFF01 ; + 2. iconv 在转码遇到 0xFFFFFF01 时将报错退出,此时将 0xFFFFFF01 转换为 GB18030-2022 编码 \uE816 ; + 3. 由于根据 Unciode 4.1 规范,转换 UTF-8 到 GB18030 编码时,\uE816 不应存在,此时同样保存,手动还原编码为 0xFE51。 + */ +static QHash gs_ReplaceFromGB18030_2005Error{ + {QByteArray::fromHex("FE51"), QByteArray::fromHex("FFFFFF01")}, + {QByteArray::fromHex("FE52"), QByteArray::fromHex("FFFFFF02")}, + {QByteArray::fromHex("FE53"), QByteArray::fromHex("FFFFFF03")}, + {QByteArray::fromHex("FE6C"), QByteArray::fromHex("FFFFFF04")}, + {QByteArray::fromHex("FE76"), QByteArray::fromHex("FFFFFF05")}, + {QByteArray::fromHex("FE91"), QByteArray::fromHex("FFFFFF06")}}; +static QHash gs_ReplaceToUTF8_2005Error{{"\uE816", QByteArray::fromHex("FFFFFF01")}, + {"\uE817", QByteArray::fromHex("FFFFFF02")}, + {"\uE818", QByteArray::fromHex("FFFFFF03")}, + {"\uE831", QByteArray::fromHex("FFFFFF04")}, + {"\uE83B", QByteArray::fromHex("FFFFFF05")}, + {"\uE855", QByteArray::fromHex("FFFFFF06")}}; +static QHash gs_ReplaceUtf8ToGB18030_2005Error{{"\uE816", QByteArray::fromHex("FE51")}, + {"\uE817", QByteArray::fromHex("FE52")}, + {"\uE818", QByteArray::fromHex("FE53")}, + {"\uE831", QByteArray::fromHex("FE6C")}, + {"\uE83B", QByteArray::fromHex("FE76")}, + {"\uE855", QByteArray::fromHex("FE91")}}; + +/** + 同样,由于 0xFE51 和 0x95329031 在 Unciode 4.1 规范,均转换为 \u20087 ,但反向转换时,\u20087 转换为 0xFE51 。 + 导致数据互转时,源数据出现了变更,因此同样需要特殊处理,在 UTF-8 转换为 GB18030-2022 时,将 0xF0A08287(\u20087) 替换, + 并在实际转换过程中替换为 0x95329031 ,保证 GB18030-2022 编码转换准确 + */ +static QHash gs_ReplaceFromUtf8_2020Error{ + {QByteArray::fromHex("95329031"), QByteArray::fromHex("FFFF11")}, + {QByteArray::fromHex("95329033"), QByteArray::fromHex("FFFF12")}, + {QByteArray::fromHex("95329730"), QByteArray::fromHex("FFFF13")}, + {QByteArray::fromHex("9536B937"), QByteArray::fromHex("FFFF14")}, + {QByteArray::fromHex("9630BA35"), QByteArray::fromHex("FFFF15")}, + {QByteArray::fromHex("9635B630"), QByteArray::fromHex("FFFF16")}, +}; +// 0xF0A08287 为 \u20087 的 UTF-8 HEX 编码 +static QHash gs_ReplaceToGB18030_2020Error{ + {QByteArray::fromHex("F0A08287"), QByteArray::fromHex("FFFF11")}, + {QByteArray::fromHex("F0A08289"), QByteArray::fromHex("FFFF12")}, + {QByteArray::fromHex("F0A0838C"), QByteArray::fromHex("FFFF13")}, + {QByteArray::fromHex("F0A19797"), QByteArray::fromHex("FFFF14")}, + {QByteArray::fromHex("F0A2A68F"), QByteArray::fromHex("FFFF15")}, + {QByteArray::fromHex("F0A487BE"), QByteArray::fromHex("FFFF16")}, +}; +static QHash gs_ReplaceFromUtf8ToGB18030_2020Error{ + {QByteArray::fromHex("95329031"), "\u20087"}, + {QByteArray::fromHex("95329033"), "\u20089"}, + {QByteArray::fromHex("95329730"), "\u200CC"}, + {QByteArray::fromHex("9536B937"), "\u215D7"}, + {QByteArray::fromHex("9630BA35"), "\u2298F"}, + {QByteArray::fromHex("9635B630"), "\u241FE"}, +}; + +// 见QTextCodec::mibEnum() +enum MibEncoding { + UnknownMib = 0, + UTF_8 = 106, + GB18030 = 114, + UTF_16BE = 1013, + UTF_16LE = 1014, + UTF_16 = 1015, + UTF_32 = 1017, + UTF_32BE = 1018, + UTF_32LE = 1019, +}; + +DetectCode::DetectCode() {} + +/** + * @brief 根据文件头内容 \a content 取得文件 \a filepath 字符编码格式 + * @param filepath 待获取字符编码文件 + * @param content 文件头内容 + * @return 文件字符编码格式 + * + * @note 对于大文本文件,文件头内容 \a content 可能在文件中间截断,\a content 尾部带有被截断的字符, + * 极大的降低字符编码识别率。为此,在识别率过低时裁剪尾部数据,重新检测以提高文本识别率。 + */ +QByteArray DetectCode::GetFileEncodingFormat(QString filepath, QByteArray content) +{ + QString charDetectedResult; + QByteArray ucharDetectdRet; + QByteArrayList icuDetectRetList; + QByteArray detectRet; + float chardetconfidence = 0.0f; + + /* chardet识别编码 */ + QString str(content); + // 匹配的是中文(仅在UTF-8编码下) + bool bFlag = str.contains(QRegExp("[\\x4e00-\\x9fa5]+")); + if (bFlag) { + const QByteArray suffix = "为增加探测率保留的中文"; + QByteArray newContent = content; + //手动添加中文字符,避免字符长度太短而导致判断编码错误 + newContent += suffix; + DetectCode::ChartDet_DetectingTextCoding(newContent, charDetectedResult, chardetconfidence); + + // 大文本数据存在从文档中间截断的可能,导致unicode中文字符被截断,解析为乱码,处理部分情况 + // 根据文本中断的情况,每次尝试解析编码后移除尾部字符,直到识别率达到90%以上 + int tryCount = 5; + while (chardetconfidence < gs_dMinConfidence && newContent.size() > suffix.size() && tryCount-- > 0) { + // 移除可能的乱码尾部字符 + newContent.remove(newContent.size() - suffix.size(), 1); + DetectCode::ChartDet_DetectingTextCoding(newContent, charDetectedResult, chardetconfidence); + } + } else { + DetectCode::ChartDet_DetectingTextCoding(content, charDetectedResult, chardetconfidence); + + // 部分非unicode编码同为中文,例如 GB18030, BIG5 等中文编码,同样判断识别率,识别率较低手动干预多次检测 + int tryCount = 5; + QByteArray newContent = content; + while (chardetconfidence < gs_dMinConfidence && !newContent.isEmpty() && tryCount-- > 0) { + newContent.chop(1); + DetectCode::ChartDet_DetectingTextCoding(newContent, charDetectedResult, chardetconfidence); + } + } + ucharDetectdRet = charDetectedResult.toLatin1(); + + // uchardet识别编码 若识别率过低, 考虑是否非单字节编码格式。 + if (ucharDetectdRet.contains("unknown") || ucharDetectdRet.contains("ASCII") || ucharDetectdRet.contains("???") || + ucharDetectdRet.isEmpty() || chardetconfidence < gs_dMinConfidence) { + ucharDetectdRet = DetectCode::UchardetCode(filepath); + } + + // icu识别编码 + icuDetectTextEncoding(filepath, icuDetectRetList); + detectRet = selectCoding(ucharDetectdRet, icuDetectRetList, chardetconfidence); + + if (detectRet.contains("ASCII") || detectRet.isEmpty()) { + detectRet = "UTF-8"; + } + + return detectRet.toUpper(); +} + +QByteArray DetectCode::UchardetCode(QString filepath) +{ + FILE *fp; + QByteArray charset; + + size_t buffer_size = 0x10000; + char *buff = new char[buffer_size]; + memset(buff, 0, buffer_size); + + /* 通过样本字符分析文本编码 */ + uchardet_t handle = uchardet_new(); + + /* 打开被检测文本文件,并读取一定数量的样本字符 */ + fp = fopen(filepath.toLocal8Bit().data(), "rb"); + + if (fp) { + while (!feof(fp)) { + size_t len = fread(buff, 1, buffer_size, fp); + int retval = uchardet_handle_data(handle, buff, len); + if (retval != 0) { + continue; + } + + break; + } + fclose(fp); + + uchardet_data_end(handle); + charset = uchardet_get_charset(handle); + } + + uchardet_delete(handle); + delete[] buff; + buff = nullptr; + + if (charset == "MAC-CENTRALEUROPE") + charset = "MACCENTRALEUROPE"; + if (charset == "MAC-CYRILLIC") + charset = "MACCYRILLIC"; + if (charset.contains("WINDOWS-")) + charset = charset.replace("WINDOWS-", "CP"); + return charset; +} + +/** + * @author guoshao + * @brief icuDetectTextEncoding() icu库编码识别 + * @param filePath:文件路径,listDetectRet:编码识别结果存在的变量 + **/ +void DetectCode::icuDetectTextEncoding(const QString &filePath, QByteArrayList &listDetectRet) +{ + FILE *file; + file = fopen(filePath.toLocal8Bit().data(), "rb"); + if (file == nullptr) { + qInfo() << "fopen file failed."; + return; + } + + size_t iBuffSize = 4096; + char *detected = nullptr; + char *buffer = new char[iBuffSize]; + memset(buffer, 0, iBuffSize); + + int readed = 0; + while (!feof(file)) { + size_t len = fread(buffer, 1, iBuffSize, file); + readed += len; + if (readed > 1 * 1024 * 1024) { + break; + } + + if (detectTextEncoding(buffer, len, &detected, listDetectRet)) { + break; + } + } + + delete[] buffer; + buffer = nullptr; + fclose(file); +} + +/** + * @author guoshao + * @brief detectTextEncoding() icu库编码识别内层函数 + * @param data:要识别的内容,len:要识别的内容的长度,detected:编码识别结果存在的变量, + * listDetectRet:编码识别结果存在的list + * @return true:识别成功,false:识别失败 + **/ +bool DetectCode::detectTextEncoding(const char *data, size_t len, char **detected, QByteArrayList &listDetectRet) +{ + Q_UNUSED(detected); + + UCharsetDetector *csd; + const UCharsetMatch **csm; + int32_t matchCount = 0; + + UErrorCode status = U_ZERO_ERROR; + csd = ucsdet_open(&status); + if (status != U_ZERO_ERROR) { + return false; + } + + ucsdet_setText(csd, data, len, &status); + if (status != U_ZERO_ERROR) { + return false; + } + + csm = ucsdet_detectAll(csd, &matchCount, &status); + if (status != U_ZERO_ERROR) { + return false; + } + + int readMax = 0; + // 提高GB18030识别率时,拓展允许读取的编码列表 + if (Config::instance()->enableImproveGB18030()) { + readMax = qMin(6, matchCount); + } else { + readMax = qMin(3, matchCount); + } + + for (int i = 0; i < readMax; i++) { + auto str = ucsdet_getName(csm[i], &status); + if (status != U_ZERO_ERROR) { + return false; + } + listDetectRet << QByteArray(str); + } + + ucsdet_close(csd); + return true; +} + +/** + * @author guoshao + * @brief selectCoding() 筛选识别出来的编码 + * @param ucharDetectdRet:chardet/uchardet识别的编码结果,icuDetectRetList:编码识别结果存在的list + * @return 筛选编码的结果 + **/ +QByteArray DetectCode::selectCoding(QByteArray ucharDetectdRet, QByteArrayList icuDetectRetList, float confidence) +{ + // 列表不允许为空 + if (icuDetectRetList.isEmpty()) { + return QByteArray(); + } + + if (!ucharDetectdRet.isEmpty()) { + // 获取是否允许提高GB18030编码的策略 + if (Config::instance()->enableImproveGB18030()) { + // 中文环境优先匹配GB18030编码 + if (QLocale::Chinese == QLocale::system().language()) { + if (confidence < gs_dMinConfidence && icuDetectRetList.contains("GB18030")) { + return QByteArray("GB18030"); + } + + if (QByteArray("ASCII") == ucharDetectdRet) { + return QByteArray("GB18030"); + } + } + } + + if (ucharDetectdRet.contains(icuDetectRetList[0])) { + return ucharDetectdRet; + } else { + if (icuDetectRetList.contains("GB18030")) { + return QByteArray("GB18030"); + } else { + // 筛选部分带后缀的编码格式,例如 UTF-16 BE 和 UTF-16 + if (icuDetectRetList[0].contains(ucharDetectdRet)) { + return icuDetectRetList[0]; + } + + return ucharDetectdRet; + } + } + } + + if (ucharDetectdRet.isEmpty()) { + if (icuDetectRetList.contains("GB18030")) { + return QByteArray("GB18030"); + } else { + return icuDetectRetList[0]; + } + } + + return QByteArray(); +} + +#if 0 /* 因为开源协议存在法律冲突,停止使用libenca0编码识别库 */ +QByteArray DetectCode::EncaDetectCode(QString filepath) +{ + /* + * 编码区域对应的简称 + *"zh"中文 "be"俄罗斯 "bg"保加利亚 "cs"捷克文 "et"爱沙尼亚语 "hr"克罗地亚人[语]; "hu"匈牙利语 "lt"立陶宛 + * "lv"拉脱维亚语 "pl"波兰语 "ru"俄语 "sk"斯洛伐克人(语) "sl"斯洛文尼亚人(语) "uk"乌克兰人(语) + */ + + sm_LangsMap.clear(); + const char *langArray[] = {"zh", "be", "bg", "cs", "et", "hr", "hu", "lt", "lv", "pl", "ru", "sk", "sl", "uk"}; +#if 0 /* EncaAnalyserState */ + size_t size; + const char **lang = enca_get_languages(&size); + QStringList langs; + for (size_t i = 0; i < size; i++) { + langs << lang[i]; + } +#endif + + QByteArray charset; + + for (size_t i = 0; i < sizeof(langArray) / sizeof(const char *); i++) { + + EncaAnalyser analyser = nullptr; + analyser = enca_analyser_alloc(langArray[i]); + enca_set_threshold(analyser, 1.38); + enca_set_multibyte(analyser, 1); + enca_set_ambiguity(analyser, 1); + enca_set_garbage_test(analyser, 1); + + size_t buffer_size = 0x10000; + + unsigned char *buff = new unsigned char[buffer_size]; + memset(buff, 0, buffer_size); + + /* 打开被检测文本文件,并读取一定数量的样本字符 */ + FILE *fp; /* the processed file */ + fp = fopen(filepath.toLocal8Bit().data(), "rb"); + + if (fp) { + while (!feof(fp)) { + size_t len = fread(buff, 1, buffer_size, fp); + EncaEncoding encoding = enca_analyse(analyser, buff, len); + charset = enca_charset_name(encoding.charset, EncaNameStyle::ENCA_NAME_STYLE_MIME); + qDebug() << QStringLiteral("ENCA文本的编码方式是:") << charset; + //识别文本编码识别 + if (encoding.charset == -1) continue; + break; + } + + enca_analyser_free(analyser); + analyser = nullptr; + + delete [] buff; + buff = nullptr; + + fclose(fp); + } else { + qDebug() << QStringLiteral("ENCA打开失败:") << filepath; + } + + if (charset == "US-ASCII") charset = "ASCII"; + if (charset == "GB2312" || charset == "GBK") charset = "GB18030"; + if (charset == "ISO-10646-UCS-2") charset = "UTF-16BE"; + sm_LangsMap[langArray[i]] = charset; + + if (!charset.isEmpty()) { + break; + } + } + + return charset; +} +#endif + +/** + * @brief ChartDet_DetectingTextCoding libchardet1编码识别库识别编码 + */ +int DetectCode::ChartDet_DetectingTextCoding(const char *str, QString &encoding, float &confidence) +{ + DetectObj *obj = detect_obj_init(); + + if (obj == nullptr) { + // qInfo() << "Memory Allocation failed\n"; + return CHARDET_MEM_ALLOCATED_FAIL; + } + + /* 另一种编码识别逻辑,暂且保留*/ + /*size_t buffer_size = 1024; + char *buff = new char[buffer_size]; + memset(buff, 0, buffer_size); + + FILE *fp; + fp = fopen(filepath.toLocal8Bit().data(), "rb"); + if (fp) { + while (!feof(fp)) { + size_t len = fread(buff, 1, buffer_size, fp); + detect(buff, &obj); + QString encoding = obj->encoding; + qInfo() << "==== encoding: " << encoding; + if (encoding == "") { + continue; + } else if (!encoding.isEmpty()) { + break; + } + fclose(fp); + } + } + + delete [] buff; + buff = nullptr;*/ + +#ifndef CHARDET_BINARY_SAFE + // before 1.0.5. This API is deprecated on 1.0.5 + switch (detect(str, &obj)) +#else + // from 1.0.5 + switch (detect_r(str, strlen(str), &obj)) +#endif + { + case CHARDET_OUT_OF_MEMORY: + qInfo() << "On handle processing, occured out of memory\n"; + detect_obj_free(&obj); + return CHARDET_OUT_OF_MEMORY; + case CHARDET_NULL_OBJECT: + qInfo() << "2st argument of chardet() is must memory allocation with detect_obj_init API\n"; + return CHARDET_NULL_OBJECT; + } + +#ifndef CHARDET_BOM_CHECK + // qInfo() << "encoding:" << obj->encoding << "; confidence: " << obj->confidence; +#else + // from 1.0.6 support return whether exists BOM + qInfo() << "encoding:" << obj->encoding << "; confidence: " << obj->confidence << "; bom: " << obj->bom; +#endif + + encoding = obj->encoding; + confidence = obj->confidence; + detect_obj_free(&obj); + + return CHARDET_SUCCESS; +} + +/** + * @return 根据 UTF-8 字符编码,返回传入的字符串 \a buf 头部字符可能占用的字节数量 + * @note 不同编码UTF-8字节划分示例,除首个字节为0外 + * 如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。 + * 0000 0000-0000 007F | 0xxxxxxx + * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * @link https://zh.wikipedia.org/wiki/UTF-8 + */ +int utf8MultiByteCount(char *buf, size_t size) +{ + // UTF 字符类型,单字符,中间字符,双字节,三字节,四字节 + enum UtfCharType { + Single, + Mid, + DoubleBytes, + ThreeBytes, + FourBytes, + }; + + // 取得 UTF-8 字节序数值 + auto LeftBitFunc = [](char data) -> int { + // 返回前导1的个数 + int res = 0; + while (data & 0x80) { + res++; + data <<= 1; + } + return res; + }; + + int count = 0; + while (size > 0 && count < FourBytes) { + int leftBits = LeftBitFunc(*buf); + switch (leftBits) { + case Mid: + count++; + break; + case DoubleBytes: + case ThreeBytes: + case FourBytes: + return leftBits; + default: + // 超过4字节或单字节,均返回1 + return 1; + } + + buf++; + size--; + } + + return count; +} + +/** + @brief 检测 GB18030 转换 UTF-8 时PUA区域异常处理 + + @note GB18030 PUA区域编码转换各版本异同 + iconv当前使用2022标志,遇到PUA区域将报错(2022不再支持),此处兼容2005设计, + GB18030 - UTF-8 互转时,将PUA区域字符按2005标准转换 + | GB18030 原始数据(HEX) | GB18030-2005 to UTF8 | GB18030-2022 toUtf8 | + |------------------------|-----------------------|-----------------------| + | 0x37903582 | \uE81E | \u9FB4 | + | 0x38903582 | \uE826 | \u9FB5 | + | 0x39903582 | \uE82B | \u9FB6 | + | 0x30913582 | \uE82C | \u9FB7 | + | 0x31913582 | \uE832 | \u9FB8 | + | 0x32913582 | \uE843 | \u9FB9 | + | 0x33913582 | \uE854 | \u9FBA | + | 0x34913582 | \uE864 | \u9FBB | + | 0x36823184 | \uE78D | \uFE10 | + | 0x37823184 | \uE78F | \uFE11 | + | 0x38823184 | \uE78E | \uFE12 | + | 0x39823184 | \uE790 | \uFE13 | + | 0x30833184 | \uE791 | \uFE14 | + | 0x31833184 | \uE792 | \uFE15 | + | 0x32833184 | \uE793 | \uFE16 | + | 0x33833184 | \uE794 | \uFE17 | + | 0x34833184 | \uE795 | \uFE18 | + | 0x35833184 | \uE796 | \uFE19 | + + 以下为特殊字符,2005和2022转换后编码,映射Unicode编码 + | GB18030 原始数据(HEX) | GB18030 to UTF8 | Unicode 4.1映射 | + |------------------------|----------------------|------------------------| + | 0x31903295 | U+E816 | \u20087 | + | 0x33903295 | U+E817 | \u20089 | + | 0x30973295 | U+E818 | \u200CC | + | 0x37B93695 | U+E831 | \u215D7 | + | 0x35BA3096 | U+E83B | \u2298F | + | 0x30B63596 | U+E855 | \u241FE | + */ +bool checkGB18030ToUtf8Error(char *buf, size_t size, size_t &replaceLen, QByteArray &appendChar) +{ + // 对于GB18030-2005编码规范PUA区域的字符,iconv报错,替换为对应的字符序。 + static const int sc_minGB18030PUACharLen = 4; + if (size < sc_minGB18030PUACharLen) { + replaceLen = 1; + appendChar = "?"; + return false; + } + + quint32 puaChar = *reinterpret_cast(buf); + appendChar = gs_UTF8MapGB18030Data.key(puaChar); + if (appendChar.isEmpty()) { + // FFFFFF0X -> \uE816...\uE855 + appendChar = gs_ReplaceToUTF8_2005Error.key(QByteArray(buf, sc_minGB18030PUACharLen)); + } + + if (appendChar.isEmpty()) { + replaceLen = 1; + appendChar = "?"; + return false; + } else { + replaceLen = sc_minGB18030PUACharLen; + return true; + } +} + +/** + @brief 检测 UTF-8 转换 GB18030 时PUA区域异常处理 + */ +bool checkUTF8ToGB18030Error(char *buf, size_t size, size_t &replaceLen, QByteArray &appendChar) +{ + // 待转换的PUA字符均为3 + static const int sc_minUTFPUACharLen = 3; + if (size < sc_minUTFPUACharLen) { + replaceLen = 1; + appendChar = "?"; + return false; + } + + QByteArray puaChar(buf, sc_minUTFPUACharLen); + quint32 gb18030char = gs_UTF8MapGB18030Data.value(puaChar, 0); + if (!gb18030char) { + // \uE816 -> 0xFE51 + appendChar = gs_ReplaceUtf8ToGB18030_2005Error.value(puaChar); + if (appendChar.isEmpty()) { + // 0xFFFF11 -> 0x95329031 + appendChar = gs_ReplaceFromUtf8_2020Error.key(puaChar); + } + + if (!appendChar.isEmpty()) { + replaceLen = sc_minUTFPUACharLen; + return true; + } + + replaceLen = 1; + appendChar = "?"; + return false; + } else { + replaceLen = sc_minUTFPUACharLen; + appendChar = QByteArray(reinterpret_cast(&gb18030char), sizeof(gb18030char)); + return true; + } +} + +/** + * @brief 将输入的字符序列 \a inputStr 从编码 \a fromCode 转换为编码 \a toCode, 并返回转换后的字符序列。 + * @return 字符编码转换是否成功 + */ +bool DetectCode::ChangeFileEncodingFormat(QByteArray &inputStr, + QByteArray &outStr, + const QString &fromCode, + const QString &toCode) +{ + if (fromCode == toCode) { + outStr = inputStr; + return true; + } + + if (inputStr.isEmpty()) { + outStr.clear(); + return true; + } + +#ifndef DISABLE_TEXTCODEC + // 使用QTextCodec对部分编码进行处理 + static QStringList codecList{"GB18030"}; + if (codecList.contains(fromCode) || codecList.contains(toCode)) { + return convertEncodingTextCodec(inputStr, outStr, fromCode, toCode); + } +#endif + + iconv_t handle = iconv_open(toCode.toLocal8Bit().data(), fromCode.toLocal8Bit().data()); + if (handle != reinterpret_cast(-1)) { + MibEncoding fromMib = UnknownMib; + MibEncoding toMib = UnknownMib; + QTextCodec *fromCodec = QTextCodec::codecForName(fromCode.toUtf8()); + if (fromCodec) { + fromMib = static_cast(fromCodec->mibEnum()); + } + QTextCodec *toCodec = QTextCodec::codecForName(toCode.toUtf8()); + if (toCodec) { + toMib = static_cast(toCodec->mibEnum()); + } + + // 替换需手动修改 UTF-8 和 GB180303 编码转换的部分 + if (GB18030 == fromMib && UTF_8 == toMib) { + for (auto itr = gs_ReplaceFromGB18030_2005Error.begin(); itr != gs_ReplaceFromGB18030_2005Error.end(); ++itr) { + inputStr.replace(itr.key(), itr.value()); + } + } else if (UTF_8 == fromMib && GB18030 == toMib) { + for (auto itr = gs_ReplaceToGB18030_2020Error.begin(); itr != gs_ReplaceToGB18030_2020Error.end(); ++itr) { + inputStr.replace(itr.key(), itr.value()); + } + } + + char *inbuf = inputStr.data(); + size_t inbytesleft = static_cast(inputStr.size()); + size_t outbytesleft = 4 * inbytesleft; + char *outbuf = new char[outbytesleft]; + char *bufferHeader = outbuf; + size_t maxBufferSize = outbytesleft; + + memset(outbuf, 0, outbytesleft); + + int errorNum = 0; + try { + size_t ret = 0; + do { + ret = iconv(handle, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + if (static_cast(-1) == ret) { + // 记录错误信息 + errorNum = errno; + + // 遇到错误的输入,错误码 EILSEQ (84),跳过当前位置并添加'?' + if (EILSEQ == errorNum) { + // 缓冲区不足跳出 + if (outbytesleft == 0) { + break; + } + + size_t replaceLen = 1; + // 跳过错误字符,设置错误字符为'?' + QByteArray appendChar = "?"; + + switch (fromMib) { + case UTF_8: { + // 特殊处理,若为UTF-8 到 GB18030的转换,优先排查异常数据 + if (GB18030 == toMib) { + if (checkUTF8ToGB18030Error(inbuf, inbytesleft, replaceLen, appendChar)) { + break; + } + } + + // 源编码为 UTF-8 时,可计算需跳过的字符数 + replaceLen = static_cast(utf8MultiByteCount(inbuf, inbytesleft)); + } break; + case GB18030: + // 特殊处理,若为GB18030 到 UTF-8 的转换,优先排查异常数据 + if (UTF_8 == toMib) { + if (checkGB18030ToUtf8Error(inbuf, inbytesleft, replaceLen, appendChar)) { + break; + } + } + break; + default: + break; + } + + qWarning() << "Text code error, replace to: " << appendChar.toHex(); + + // 替换错误字符为对应字符 + size_t appendSize = static_cast(appendChar.size()); + if (outbytesleft < appendSize) { + break; + } + + outbytesleft -= appendSize; + ::memcpy(outbuf, appendChar.data(), appendSize); + outbuf += appendSize; + + if (inbytesleft <= replaceLen) { + // 移动至末尾 + inbuf += inbytesleft; + inbytesleft = 0; + break; + } + + inbuf += replaceLen; + inbytesleft -= replaceLen; + } else { + break; + } + } + } while (static_cast(-1) == ret); + + } catch (const std::exception &e) { + qWarning() << Q_FUNC_INFO << qPrintable("iconv convert encoding catching exception") << qPrintable(e.what()); + } + + if (errorNum) { + qWarning() << Q_FUNC_INFO << qPrintable("iconv() convert text encoding error, errocode:") << errorNum; + } + iconv_close(handle); + + // 手动添加 UTF BOM 信息 + outStr.append(gs_byteOrderMark.value(toCode)); + + // 计算 iconv() 实际转换的字节数 + size_t realConvertSize = maxBufferSize - outbytesleft; + outStr += QByteArray(bufferHeader, static_cast(realConvertSize)); + + delete[] bufferHeader; + bufferHeader = nullptr; + + return true; + + } else { + qWarning() << Q_FUNC_INFO << qPrintable("Text encoding convert error, iconv_open() failed."); + // 尝试使用QTextCodec加载 + return convertEncodingTextCodec(inputStr, outStr, fromCode, toCode); + } +} + +/** + * @brief 使用QTextCodec将输入的字符序列 \a inputStr 从编码 \a fromCode 转换为编码 \a toCode, 并返回转换后的字符序列。 + * @return 字符编码转换是否成功 + */ +bool DetectCode::convertEncodingTextCodec(QByteArray &inputStr, + QByteArray &outStr, + const QString &fromCode, + const QString &toCode) +{ + QString convertData; + if (fromCode != "UTF-8") { + QTextCodec *fromCodec = QTextCodec::codecForName(fromCode.toUtf8()); + if (!fromCodec) { + return false; + } + + convertData = fromCodec->toUnicode(inputStr); + } else { + convertData = QString::fromUtf8(inputStr); + } + + if (toCode != "UTF-8") { + QTextCodec *toCodec = QTextCodec::codecForName(toCode.toUtf8()); + if (!toCodec) { + return false; + } + + outStr = toCodec->fromUnicode(convertData); + } else { + outStr = convertData.toUtf8(); + } + + // 手动添加 UTF BOM 信息 + outStr.append(gs_byteOrderMark.value(toCode)); + return true; +} diff --git a/src/encodes/detectcode.h b/src/encodes/detectcode.h new file mode 100644 index 0000000000000000000000000000000000000000..2a4d4cca0c8d733a23e2dc60bd8984d9d5ab1149 --- /dev/null +++ b/src/encodes/detectcode.h @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef DETECTCODE_H +#define DETECTCODE_H + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * + * 文本编码识别引用第三库识别 chardet1 uchardet + * chardet识别不了使用uchardet + * 编码转换库使用iconv + * + * author:梁卫东 2020年10月15日16:56:11 + * + */ + +class QByteArray; +class QString; + +class DetectCode +{ +public: + DetectCode(); + +// enca 识别文本编码 +#if 0 /* 因为开源协议存在法律冲突,停止使用libenca0编码识别库 */ + static QByteArray EncaDetectCode (QString filepath); +#endif + + // libchardet1编码识别库识别编码 + static int ChartDet_DetectingTextCoding(const char *str, QString &encoding, float &confidence); + // uchardet 识别文编编码 + static QByteArray UchardetCode(QString filepath); + // icu库编码识别 + static void icuDetectTextEncoding(const QString &filePath, QByteArrayList &listDetectRet); + + // icu库编码识别内层函数 + static bool detectTextEncoding(const char *data, size_t len, char **detected, QByteArrayList &listDetectRet); + // 筛选识别出来的编码 + static QByteArray selectCoding(QByteArray ucharDetectdRet, QByteArrayList icuDetectRetList, float confidence); + // 获取文件编码方式 + static QByteArray GetFileEncodingFormat(QString filepath, QByteArray content = QByteArray("")); + // 转换文本编码格式 + static bool ChangeFileEncodingFormat(QByteArray &inputStr, + QByteArray &outStr, + const QString &fromCode, + const QString &toCode = QString("UTF-8")); + + static bool convertEncodingTextCodec(QByteArray &inputStr, + QByteArray &outStr, + const QString &fromCode, + const QString &toCode = QString("UTF-8")); + +private: + static QMap sm_LangsMap; +}; + +#endif // DETECTCODE_H diff --git a/src/encodes/encodes.ini b/src/encodes/encodes.ini new file mode 100644 index 0000000000000000000000000000000000000000..4aa3b35d99a2ccc3b575f1b09a355e7d5f89e26b --- /dev/null +++ b/src/encodes/encodes.ini @@ -0,0 +1,34 @@ +[Unicode] +encodes=UTF-8,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE +[WesternEuropean] +encodes=ISO-8859-1,ISO-8859-15,CP1252 +[CentralEuropean] +encodes=ISO-8859-2,ISO-8859-3,CP1125,CP1250,MACCENTRALEUROPE,IBM852 +[Baltic] +encodes=ISO-8859-4,ISO-8859-10,ISO-8859-13,CP1257,IBM775 +[Cyrillic] +encodes=ISO-8859-5,CP1251,KOI8-R,KOI8-U,MACCYRILLIC,IBM855,IBM866 +[Arabic] +encodes=ISO-8859-6,CP1256 +[Greek] +encodes=ISO-8859-7,CP1253 +[Hebrew] +encodes=ISO-8859-8,CP1255 +[Turkish] +encodes=ISO-8859-9,CP1254 +[Thai] +encodes=ISO-8859-11,TIS-620 +[Celtic] +encodes=ISO-8859-14 +[SouthEasternEuropean] +encodes=ISO-8859-16 +[ChineseSimplified] +encodes=GB18030,ISO-2022-CN +[ChineseTraditional] +encodes=BIG5,EUC-TW +[Japanese] +encodes=EUC-JP,SHIFT_JIS,ISO-2022-JP +[Korean] +encodes=EUC-KR,ISO-2022-KR +[Vietnamese] +encodes=CP1258 diff --git a/src/encodes/encodes1.ini b/src/encodes/encodes1.ini new file mode 100644 index 0000000000000000000000000000000000000000..0e1632fd31b04a6a76932e45b66ea125373b0a6a --- /dev/null +++ b/src/encodes/encodes1.ini @@ -0,0 +1,66 @@ +[Unicode] +encodes=UTF-8,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE +[Arabic] +encodes=ISO-8859-6,CP1256 +[Belarussian] +encodes=CP1251,IBM855,IBM866,ISO-8859-5,KOI8-U +[Bulgarian] +encodes=CP1251,ISO-8859-5,IBM855 +[Chinese] +encodes=GB18030,BIG5,HZ,EUC-TW,ISO-2022-CN +[Czech] +encodes=ISO-8859-2,CP1250,IBM852,MACCENTRALEUROPE +[Croatian] +encodes=ISO-8859-2,IBM852,ISO-8859-13,ISO-8859-16,MACCENTRALEUROPE,CP1250 +[Danish] +encodes=ISO-8859-1,ISO-8859-5,ISO-8859-15,CP1252 +[Estonian] +encodes=ISO-8859-4,ISO-8859-13,CP1252,CP1257,IBM775 +[Finnish] +encodes=ISO-8859-1,ISO-8859-4,ISO-8859-9,ISO-8859-13,ISO-8859-15,CP1252 +[French] +encodes=ISO-8859-1,ISO-8859-15,CP1252 +[German] +encodes=ISO-8859-1,CP1252 +[Greek] +encodes=ISO-8859-7,CP1253 +[Hebrew] +encodes=ISO-8859-8,CP1255 +[Hungarian] +encodes=ISO-8859-2,CP1250,IBM852 +[Japanese] +encodes=ISO-2022-JP,SHIFT_JIS,EUC-JP +[Korean] +encodes=ISO-2022-KR,EUC-KR,UHC +[Irish Gaelic] +encodes=ISO-8859-1,ISO-8859-9,ISO-8859-15,CP1252 +[Italian] +encodes=ISO-8859-1,ISO-8859-3,ISO-8859-9,ISO-8859-15,CP1252 +[Lithuanian] +encodes=ISO-8859-4,ISO-8859-10,ISO-8859-13,CP1257,IBM775 +[Latvian] +encodes=ISO-8859-4,ISO-8859-10,ISO-8859-13,CP1257,IBM775 +[Polish] +encodes=ISO-8859-2,ISO-8859-13,ISO-8859-16,CP1250,IBM852,MACCENTRALEUROPE +[Portuguese] +encodes=ISO-8859-1,ISO-8859-9,ISO-8859-15,CP1252 +[Russian] +encodes=CP1251,ISO-8859-5,MACCYRILLIC,IBM855,IBM866,KOI8-R +[Romanian] +encodes=ISO-8859-2,ISO-8859-16,CP1250,IBM852 +[Slovak] +encodes=ISO-8859-2,IBM852,MACCENTRALEUROPE,CP1250 +[Slovenian] +encodes=ISO-8859-2,ISO-8859-16,CP1250,IBM852,MACCENTRALEUROPE +[Spanish] +encodes=ISO-8859-1,ISO-8859-15,CP1252 +[Swedish] +encodes=ISO-8859-1,ISO-8859-4,ISO-8859-9,ISO-8859-15,CP1252 +[Thai] +encodes=TIS-620,ISO-8859-11 +[Turkish] +encodes=ISO-8859-3,ISO-8859-9 +[Ukrainian] +encodes=CP1251,CP1125,IBM855,ISO-8859-5,KOI8-U +[Vietnamese] +encodes=VISCII,CP1258 diff --git a/src/environments.h.in b/src/environments.h.in new file mode 100644 index 0000000000000000000000000000000000000000..8c829ddafda677f475ca198b88202224fef60c24 --- /dev/null +++ b/src/environments.h.in @@ -0,0 +1,6 @@ +#ifndef __ENVIRONMENTS_H_ +#define __ENVIRONMENTS_H_ + +#define VERSION "@VERSION@" + +#endif // __ENVIRONMENTS_H_ diff --git a/src/images/arrow_dark.svg b/src/images/arrow_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..e1a74742e32b8bdaed03a460c84e9f59fc08fe11 --- /dev/null +++ b/src/images/arrow_dark.svg @@ -0,0 +1,11 @@ + + + arrow_dark + + + + + + + + \ No newline at end of file diff --git a/src/images/arrow_light.svg b/src/images/arrow_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..698f1c31bb0196b3f3a8aa216246f8a2512008cc --- /dev/null +++ b/src/images/arrow_light.svg @@ -0,0 +1,11 @@ + + + arrow_light + + + + + + + + \ No newline at end of file diff --git a/src/images/bar_close_hover_dark.svg b/src/images/bar_close_hover_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..4c296037776947e675731504ca2d39ba8bd99213 --- /dev/null +++ b/src/images/bar_close_hover_dark.svg @@ -0,0 +1,12 @@ + + + + close_hover_dark + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/bar_close_hover_light.svg b/src/images/bar_close_hover_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..e22b2a3debf82b3d6802a192556ac8284c7d715d --- /dev/null +++ b/src/images/bar_close_hover_light.svg @@ -0,0 +1,12 @@ + + + + close_hover_light + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/bar_close_normal_dark.svg b/src/images/bar_close_normal_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..dcdb6eb40cdc651d8450c11ea1aa0225faec8fa3 --- /dev/null +++ b/src/images/bar_close_normal_dark.svg @@ -0,0 +1,12 @@ + + + + close_normal_dark + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/bar_close_normal_light.svg b/src/images/bar_close_normal_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..af54236522bb6e514d83242d84b98f2c30ded775 --- /dev/null +++ b/src/images/bar_close_normal_light.svg @@ -0,0 +1,12 @@ + + + + close_normal_light + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/bar_close_press_dark.svg b/src/images/bar_close_press_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..ed6cf74450e80a3ac84b73a649bfee62261cdfa7 --- /dev/null +++ b/src/images/bar_close_press_dark.svg @@ -0,0 +1,12 @@ + + + + close_press_dark + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/bar_close_press_light.svg b/src/images/bar_close_press_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..e440a342960dcebd0246f2bf8050d506800b8f42 --- /dev/null +++ b/src/images/bar_close_press_light.svg @@ -0,0 +1,12 @@ + + + + close_press_light + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/bookmark.svg b/src/images/bookmark.svg new file mode 100644 index 0000000000000000000000000000000000000000..48e70ad70749944778e11b461433b6d81e4b9281 --- /dev/null +++ b/src/images/bookmark.svg @@ -0,0 +1,13 @@ + + + + like + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/images/close_hover_dark.svg b/src/images/close_hover_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..4ba0fd2263e23cdde68466b3dae1b1e49d8a3a3b --- /dev/null +++ b/src/images/close_hover_dark.svg @@ -0,0 +1,12 @@ + + + + input_clear_dark_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/close_hover_light.svg b/src/images/close_hover_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..985ba11cdf160db96782a25e35db659a6bf77298 --- /dev/null +++ b/src/images/close_hover_light.svg @@ -0,0 +1,12 @@ + + + + input_clear_hover + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/close_normal_dark.svg b/src/images/close_normal_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..2d08eccbd58b2cf4ae85d6bcf3af0d152fbc7c28 --- /dev/null +++ b/src/images/close_normal_dark.svg @@ -0,0 +1,12 @@ + + + + input_clear_dark_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/close_normal_light.svg b/src/images/close_normal_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..00c0b5d127a18ce9620e3a7e26bd575db5883318 --- /dev/null +++ b/src/images/close_normal_light.svg @@ -0,0 +1,12 @@ + + + + input_clear_normal + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/close_press_dark.svg b/src/images/close_press_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..3f7df2eba139f3295f820064200e0ff2222b4cb0 --- /dev/null +++ b/src/images/close_press_dark.svg @@ -0,0 +1,14 @@ + + + + input_clear_dark_press + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/images/close_press_light.svg b/src/images/close_press_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..d0024e25eacb2a9f978047763c22367cc7244550 --- /dev/null +++ b/src/images/close_press_light.svg @@ -0,0 +1,12 @@ + + + + input_clear_press + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/images/d-d.svg b/src/images/d-d.svg new file mode 100644 index 0000000000000000000000000000000000000000..aebb326ffee56c11b6135f1a7ab27fc62a750142 --- /dev/null +++ b/src/images/d-d.svg @@ -0,0 +1,11 @@ + + + + d-d + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/images/d-l.svg b/src/images/d-l.svg new file mode 100644 index 0000000000000000000000000000000000000000..351cd46bcbea39a16c8f5b5b66c51aeeedfc9e24 --- /dev/null +++ b/src/images/d-l.svg @@ -0,0 +1,11 @@ + + + + d-l + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/images/deepin-editor.svg b/src/images/deepin-editor.svg new file mode 100644 index 0000000000000000000000000000000000000000..33d30d2f716cf7c71bd7427f46aead50ab359a43 --- /dev/null +++ b/src/images/deepin-editor.svg @@ -0,0 +1,39 @@ + + + + deepin-terminal-32px 2 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/images/dropdown_arrow_dark.svg b/src/images/dropdown_arrow_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..9480f41021292147c2a9bd879e245ea55d7e4dfe --- /dev/null +++ b/src/images/dropdown_arrow_dark.svg @@ -0,0 +1,14 @@ + + + + dropdown_arrow + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/images/dropdown_arrow_light.svg b/src/images/dropdown_arrow_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..8dcb71d16a7d828ec474bb38042758545d4c2208 --- /dev/null +++ b/src/images/dropdown_arrow_light.svg @@ -0,0 +1,14 @@ + + + + dropdown_arrow + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/images/like_hover_dark.svg b/src/images/like_hover_dark.svg new file mode 100644 index 0000000000000000000000000000000000000000..86b6b817483fdff6d9c33ba34047c71ea4b365a8 --- /dev/null +++ b/src/images/like_hover_dark.svg @@ -0,0 +1,13 @@ + + + + like_hover + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/images/like_hover_light.svg b/src/images/like_hover_light.svg new file mode 100644 index 0000000000000000000000000000000000000000..ceb07abfc48f1ead077a421f618fe31622761dad --- /dev/null +++ b/src/images/like_hover_light.svg @@ -0,0 +1,13 @@ + + + + like_hover + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/src/images/logo_24.svg b/src/images/logo_24.svg new file mode 100644 index 0000000000000000000000000000000000000000..33d30d2f716cf7c71bd7427f46aead50ab359a43 --- /dev/null +++ b/src/images/logo_24.svg @@ -0,0 +1,39 @@ + + + + deepin-terminal-32px 2 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/images/logo_48.svg b/src/images/logo_48.svg new file mode 100644 index 0000000000000000000000000000000000000000..5d5404c24f19d0813c1c6d327b7b6d9dff328b96 --- /dev/null +++ b/src/images/logo_48.svg @@ -0,0 +1,25 @@ + + + + deepin-editor + Created with Sketch. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/images/logo_96.svg b/src/images/logo_96.svg new file mode 100644 index 0000000000000000000000000000000000000000..e740fdc53d0f7c413977d7db2a608d3334e63f48 --- /dev/null +++ b/src/images/logo_96.svg @@ -0,0 +1,27 @@ + + + + deepin-editor + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/images/ok.svg b/src/images/ok.svg new file mode 100644 index 0000000000000000000000000000000000000000..7ea52097d213a54dcd4511d4750eb4cc379c5abd --- /dev/null +++ b/src/images/ok.svg @@ -0,0 +1,33 @@ + + + + ok + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/images/u-d.svg b/src/images/u-d.svg new file mode 100644 index 0000000000000000000000000000000000000000..5d8aa769fc3076fd97eca970829b91a828a9ce9d --- /dev/null +++ b/src/images/u-d.svg @@ -0,0 +1,11 @@ + + + + u-d + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/images/u-l.svg b/src/images/u-l.svg new file mode 100644 index 0000000000000000000000000000000000000000..c65d06f306b3dbe898e00c5ae75c0ad87aeca2fd --- /dev/null +++ b/src/images/u-l.svg @@ -0,0 +1,11 @@ + + + + u-l + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/images/warning.svg b/src/images/warning.svg new file mode 100644 index 0000000000000000000000000000000000000000..8ae605940f419596ca22eb8fe5d719944023dd18 --- /dev/null +++ b/src/images/warning.svg @@ -0,0 +1,33 @@ + + + + warning 2 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68fab874ddd29bab311805dad194abbd5d08a49c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "environments.h" +#include "utils.h" +#include "window.h" +#include "urlinfo.h" +#include "editorapplication.h" +#include "performancemonitor.h" +#include "eventlogutils.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +int main(int argc, char *argv[]) +{ + DCORE_USE_NAMESPACE + DLogManager::registerConsoleAppender(); + DLogManager::registerFileAppender(); + PerformanceMonitor::initializeAppStart(); + if (!QString(qgetenv("XDG_CURRENT_DESKTOP")).toLower().startsWith("deepin")) { + setenv("XDG_CURRENT_DESKTOP", "Deepin", 1); + } + + qputenv("QT_WAYLAND_SHELL_INTEGRATION", "kwayland-shell"); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + // QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + + EditorApplication app(argc, argv); + // save theme + DApplicationSettings savetheme; + + // Parser input arguments. + QCommandLineParser parser; + const QCommandLineOption newWindowOption("w", "Open file in new window"); + const QCommandLineOption helpOption = parser.addHelpOption(); + parser.addOption(newWindowOption); + parser.process(app); + + QStringList urls; + QStringList arguments = parser.positionalArguments(); + + for (const QString &path : arguments) { + UrlInfo info(path); + urls << info.url.toLocalFile(); + } + qInfo() << Q_FUNC_INFO << "Open file urls" << urls; + + bool hasWindowFlag = parser.isSet(newWindowOption); + + QDBusConnection dbus = QDBusConnection::sessionBus(); + // Start editor process if not found any editor use DBus. + if (dbus.registerService("com.deepin.Editor")) { + StartManager *startManager = StartManager::instance(); + //埋点记录启动数据 + QJsonObject objStartEvent{ + {"tid", Eventlogutils::StartUp}, + {"version", VERSION}, + {"mode", 1}, + }; + Eventlogutils::GetInstance()->writeLogs(objStartEvent); + + bool save_tab_before_close = + Settings::instance()->settings->option("advance.startup.save_tab_before_close")->value().toBool(); + if (!save_tab_before_close && urls.isEmpty()) { + auto window = startManager->createWindow(true); + window->addBlankTab(); + } else { + if (hasWindowFlag) { + startManager->openFilesInWindow(urls); + } else { + startManager->openFilesInTab(urls); + } + } + + dbus.registerObject("/com/deepin/Editor", startManager, QDBusConnection::ExportScriptableSlots); + + PerformanceMonitor::initializAppFinish(); + return app.exec(); + } + // Just send dbus message to exist editor process. + else { + QDBusInterface notification( + "com.deepin.Editor", "/com/deepin/Editor", "com.deepin.Editor", QDBusConnection::sessionBus()); + + QList args; + args << urls; + + if (hasWindowFlag) { + notification.callWithArgumentList(QDBus::AutoDetect, "openFilesInWindow", args); + } else { + notification.callWithArgumentList(QDBus::AutoDetect, "openFilesInTab", args); + } + } + + return 0; +} diff --git a/src/qss/main.qss b/src/qss/main.qss new file mode 100644 index 0000000000000000000000000000000000000000..7047b7da85460501dc4ad21fe6b9e7451821da24 --- /dev/null +++ b/src/qss/main.qss @@ -0,0 +1,5 @@ +QTabBar, +QTabBar::tab +{ + font-size: 13px; +} diff --git a/src/resources/settings.json b/src/resources/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..d84ccfd457fca349bfeb338dffa06948ba85b5ce --- /dev/null +++ b/src/resources/settings.json @@ -0,0 +1,2167 @@ +{ + "groups": [ + { + "key": "base", + "name": "Basic", + "groups": [ + { + "key": "font", + "name": "Font Style", + "options": [ + { + "key": "family", + "name": "Font", + "type": "fontcombobox", + "default": "Noto Mono" + }, + { + "key": "size", + "name": "Font Size", + "type": "spinbutton", + "default": 12, + "max": 50, + "min": 8 + }, + { + "key": "wordwrap", + "name": "Word Wrap", + "type": "checkbox", + "text": "Word wrap", + "default": "true" + }, + { + + "key":"codeflod", + "name":"CODE FLOD", + "type":"checkbox", + "text":"Code folding flag", + "default":"true" + }, + { + "key": "showlinenumber", + "name": "Show line number", + "type": "checkbox", + "text": "Show line numbers", + "default": "true" + }, + { + "key": "hightlightcurrentline", + "name": "hightlight current line", + "type": "checkbox", + "text": "Highlight current line", + "default": "true" + }, + { + "key": "showbookmark", + "name": "Show bookmarks icon", + "type": "checkbox", + "text": "Show bookmarks icon", + "default": "false" + }, + { + "key": "showblankcharacter", + "name": "Show whitespaces and tabs", + "type": "checkbox", + "text": "Show whitespaces and tabs", + "default": "false" + } + ] + } + ] + }, + { + "key": "shortcuts", + "name": "Shortcuts", + "groups": [ + { + "key" : "keymap", + "name" : "Keymap", + "options" : [ + { + "key": "keymap", + "name": "Keymap", + "type": "combobox", + "default": "standard" + } + ] + }, + { + "key": "window", + "name": "Window", + "options": [ + { + "key": "addblanktab", + "name": "New tab", + "type": "keySequenceEdit", + "default": "Ctrl+T" + }, + { + "key": "newwindow", + "name": "New window", + "type": "keySequenceEdit", + "default": "Ctrl+N" + }, + { + "key": "savefile", + "name": "Save", + "type": "keySequenceEdit", + "default": "Ctrl+S" + }, + { + "key": "saveasfile", + "name": "Save as", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+S" + }, + { + "key": "selectnexttab", + "name": "Next tab", + "type": "keySequenceEdit", + "default": "Ctrl+Tab" + }, + { + "key": "selectprevtab", + "name": "Previous tab", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+Backtab" + }, + { + "key": "closetab", + "name": "Close tab", + "type": "keySequenceEdit", + "default": "Ctrl+W" + }, + { + "key": "closeothertabs", + "name": "Close other tabs", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+W" + }, + { + "key": "restoretab", + "name": "Restore tab", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+T" + }, + { + "key": "openfile", + "name": "Open file", + "type": "keySequenceEdit", + "default": "Ctrl+O" + }, + { + "key": "incrementfontsize", + "name": "Increment font size", + "type": "keySequenceEdit", + "default": "Ctrl+=" + }, + { + "key": "decrementfontsize", + "name": "Decrement font size", + "type": "keySequenceEdit", + "default": "Ctrl+-" + }, + { + "key": "resetfontsize", + "name": "Reset font size", + "type": "keySequenceEdit", + "default": "Ctrl+0" + }, + { + "key": "togglefullscreen", + "name": "Toggle fullscreen", + "type": "keySequenceEdit", + "default": "F11" + }, + { + "key": "help", + "name": "Help", + "type": "keySequenceEdit", + "default": "F1" + }, + { + "key": "find", + "name": "Find", + "type": "keySequenceEdit", + "default": "Ctrl+F" + }, + { + "key": "findNext", + "name": "Find Next", + "type": "keySequenceEdit", + "default": "F3" + }, + { + "key": "findPrev", + "name": "Find Previous", + "type": "keySequenceEdit", + "default": "Shift+F3" + }, + { + "key": "replace", + "name": "Replace", + "type": "keySequenceEdit", + "default": "Ctrl+H" + }, + { + "key": "jumptoline", + "name": "Go to line", + "type": "keySequenceEdit", + "default": "Ctrl+G" + }, + { + "key": "saveposition", + "name": "Save cursor position", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+>" + }, + { + "key": "restoreposition", + "name": "Reset cursor position", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+<" + }, + { + "key": "escape", + "name": "Exit", + "type": "keySequenceEdit", + "default": "Esc" + }, + { + "key": "displayshortcuts", + "name": "Display shortcuts", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+?" + }, + { + "key": "print", + "name": "Print", + "type": "keySequenceEdit", + "default": "Ctrl+P" + } + ] + }, + { + "key": "editor", + "name": "Editor", + "options": [ + { + "key": "indentline", + "name": "Increase indent", + "type": "keySequenceEdit", + "default": "Tab" + }, + { + "key": "backindentline", + "name": "Decrease indent", + "type": "keySequenceEdit", + "default": "Shift+Backtab" + }, + { + "key": "forwardchar", + "name": "Forward character", + "type": "keySequenceEdit", + "default": "Right" + }, + { + "key": "backwardchar", + "name": "Backward character", + "type": "keySequenceEdit", + "default": "Left" + }, + { + "key": "forwardword", + "name": "Forward word", + "type": "keySequenceEdit", + "default": "Ctrl+Right" + }, + { + "key": "backwardword", + "name": "Backward word", + "type": "keySequenceEdit", + "default": "Ctrl+Left" + }, + { + "key": "nextline", + "name": "Next line", + "type": "keySequenceEdit", + "default": "Down" + }, + { + "key": "prevline", + "name": "Previous line", + "type": "keySequenceEdit", + "default": "Up" + }, + { + "key": "newline", + "name": "New line", + "type": "keySequenceEdit", + "default": "Enter" + }, + { + "key": "opennewlineabove", + "name": "New line above", + "type": "keySequenceEdit", + "default": "Ctrl+Enter" + }, + { + "key": "opennewlinebelow", + "name": "New line below", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+Enter" + }, + { + "key": "duplicateline", + "name": "Duplicate line", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+D" + }, + { + "key": "killline", + "name": "Delete to end of line", + "type": "keySequenceEdit", + "default": "Ctrl+K" + }, + { + "key": "killcurrentline", + "name": "Delete current line", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+K" + }, + { + "key": "swaplineup", + "name": "Swap line up", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+Up" + }, + { + "key": "swaplinedown", + "name": "Swap line down", + "type": "keySequenceEdit", + "default": "Ctrl+Shift+Down" + }, + { + "key": "scrolllineup", + "name": "Scroll up one line", + "type": "keySequenceEdit", + "default": "Meta+Shift+Up" + }, + { + "key": "scrolllinedown", + "name": "Scroll down one line", + "type": "keySequenceEdit", + "default": "Meta+Shift+Down" + }, + { + "key": "scrollup", + "name": "Page up", + "type": "keySequenceEdit", + "default": "PgUp" + }, + { + "key": "scrolldown", + "name": "Page down", + "type": "keySequenceEdit", + "default": "PgDown" + }, + { + "key": "movetoendofline", + "name": "Move to end of line", + "type": "keySequenceEdit", + "default": "End" + }, + { + "key": "movetostartofline", + "name": "Move to start of line", + "type": "keySequenceEdit", + "default": "Home" + }, + { + "key": "movetoend", + "name": "Move to end of text", + "type": "keySequenceEdit", + "default": "Ctrl+End" + }, + { + "key": "movetostart", + "name": "Move to start of text", + "type": "keySequenceEdit", + "default": "Ctrl+Home" + }, + { + "key": "movetolineindentation", + "name": "Move to line indentation", + "type": "keySequenceEdit", + "default": "Ctrl+M" + }, + { + "key": "upcaseword", + "name": "Upper case", + "type": "keySequenceEdit", + "default": "Alt+U" + }, + { + "key": "downcaseword", + "name": "Lower case", + "type": "keySequenceEdit", + "default": "Alt+L" + }, + { + "key": "capitalizeword", + "name": "Capitalize", + "type": "keySequenceEdit", + "default": "Alt+C" + }, + { + "key": "killbackwardword", + "name": "Delete backward word", + "type": "keySequenceEdit", + "default": "Alt+Shift+N" + }, + { + "key": "killforwardword", + "name": "Delete forward word", + "type": "keySequenceEdit", + "default": "Alt+Shift+M" + }, + { + "key": "forwardpair", + "name": "Forward over a pair", + "type": "keySequenceEdit", + "default": "Alt+P" + }, + { + "key": "backwardpair", + "name": "Backward over a pair", + "type": "keySequenceEdit", + "default": "Alt+N" + }, + { + "key": "selectall", + "name": "Select all", + "type": "keySequenceEdit", + "default": "Ctrl+A" + }, + { + "key": "copy", + "name": "Copy", + "type": "keySequenceEdit", + "default": "Ctrl+C" + }, + { + "key": "cut", + "name": "Cut", + "type": "keySequenceEdit", + "default": "Ctrl+X" + }, + { + "key": "paste", + "name": "Paste", + "type": "keySequenceEdit", + "default": "Ctrl+V" + }, + { + "key": "transposechar", + "name": "Transpose character", + "type": "keySequenceEdit", + "default": "Alt+T" + }, + { + "key": "setmark", + "name": "Mark", + "type": "keySequenceEdit", + "default": "Alt+H" + }, + { + "key": "exchangemark", + "name": "Unmark", + "type": "keySequenceEdit", + "default": "Alt+Shift+H" + }, + { + "key": "copylines", + "name": "Copy line", + "type": "keySequenceEdit", + "default": "Meta+C" + }, + { + "key": "cutlines", + "name": "Cut line", + "type": "keySequenceEdit", + "default": "Meta+X" + }, + { + "key": "joinlines", + "name": "Merge lines", + "type": "keySequenceEdit", + "default": "Ctrl+J" + }, + { + "key": "togglereadonlymode", + "name": "Read-Only mode", + "type": "keySequenceEdit", + "default": "Meta+Alt+L" + }, + { + "key": "togglecomment", + "name": "Add comment", + "type": "keySequenceEdit", + "default": "Alt+A" + }, + { + "key": "removecomment", + "name": "Remove comment", + "type": "keySequenceEdit", + "default": "Alt+Z" + }, + { + "key": "undo", + "name": "Undo", + "type": "keySequenceEdit", + "default": "Ctrl+Z" + }, + { + "key": "switchbookmark", + "name": "Add/Remove bookmark", + "type": "keySequenceEdit", + "default": "Ctrl+F2" + }, + { + "key": "movetoprebookmark", + "name": "Move to previous bookmark", + "type": "keySequenceEdit", + "default": "F2" + }, + { + "key": "movetonextbookmark", + "name": "Move to next bookmark", + "type": "keySequenceEdit", + "default": "Shift+F2" + }, + { + "key": "redo", + "name": "Redo", + "type": "keySequenceEdit", + "default": "Ctrl+Y" + }, + { + "key": "mark", + "name": "Color mark", + "type": "keySequenceEdit", + "default": "Ctrl+F6" + } + + ] + }, + { + "key": "window_keymap_standard", + "name": "Standard window keymap", + "hide" : true, + "options": [ + { + "key": "addblanktab", + "hide" : true, + "reset" : false, + "default": "Ctrl+T" + }, + { + "key": "newwindow", + "hide" : true, + "reset" : false, + "default": "Ctrl+N" + }, + { + "key": "savefile", + "hide" : true, + "reset" : false, + "default": "Ctrl+S" + }, + { + "key": "saveasfile", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+S" + }, + { + "key": "selectnexttab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Tab" + }, + { + "key": "selectprevtab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Backtab" + }, + { + "key": "closetab", + "hide" : true, + "reset" : false, + "default": "Ctrl+W" + }, + { + "key": "closeothertabs", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+W" + }, + { + "key": "restoretab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+T" + }, + { + "key": "openfile", + "hide" : true, + "reset" : false, + "default": "Ctrl+O" + }, + { + "key": "incrementfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+=" + }, + { + "key": "decrementfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+-" + }, + { + "key": "resetfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+0" + }, + { + "key": "togglefullscreen", + "hide" : true, + "reset" : false, + "default": "F11" + }, + { + "key": "help", + "hide": true, + "reset": false, + "default": "F1" + }, + { + "key": "findNext", + "hide" : true, + "reset" : false, + "default": "F3" + }, + { + "key": "findPrev", + "hide" : true, + "reset" : false, + "default": "Shift+F3" + }, + { + "key": "find", + "hide" : true, + "reset" : false, + "default": "Ctrl+F" + }, + { + "key": "replace", + "hide" : true, + "reset" : false, + "default": "Ctrl+H" + }, + { + "key": "jumptoline", + "hide" : true, + "reset" : false, + "default": "Ctrl+G" + }, + { + "key": "saveposition", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+>" + }, + { + "key": "restoreposition", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+<" + }, + { + "key": "escape", + "hide" : true, + "reset" : false, + "default": "Esc" + }, + { + "key": "displayshortcuts", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+?" + }, + { + "key": "print", + "hide" : true, + "reset" : false, + "default": "Ctrl+P" + } + ] + }, + { + "key": "editor_keymap_standard", + "name": "Standard editor keymap", + "hide" : true, + "options": [ + { + "key": "indentline", + "hide" : true, + "reset" : false, + "default": "Tab" + }, + { + "key": "backindentline", + "hide" : true, + "reset" : false, + "default": "Shift+Backtab" + }, + { + "key": "forwardchar", + "hide" : true, + "reset" : false, + "default": "Right" + }, + { + "key": "backwardchar", + "hide" : true, + "reset" : false, + "default": "Left" + }, + { + "key": "forwardword", + "hide" : true, + "reset" : false, + "default": "Ctrl+Right" + }, + { + "key": "backwardword", + "hide" : true, + "reset" : false, + "default": "Ctrl+Left" + }, + { + "key": "nextline", + "hide" : true, + "reset" : false, + "default": "Down" + }, + { + "key": "prevline", + "hide" : true, + "reset" : false, + "default": "Up" + }, + { + "key": "newline", + "hide" : true, + "reset" : false, + "default": "Enter" + }, + { + "key": "opennewlineabove", + "hide" : true, + "reset" : false, + "default": "Ctrl+Enter" + }, + { + "key": "opennewlinebelow", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Enter" + }, + { + "key": "duplicateline", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+D" + }, + { + "key": "killline", + "hide" : true, + "reset" : false, + "default": "Ctrl+K" + }, + { + "key": "killcurrentline", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+K" + }, + { + "key": "swaplineup", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Up" + }, + { + "key": "swaplinedown", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Down" + }, + { + "key": "scrolllineup", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+Up" + }, + { + "key": "scrolllinedown", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+Down" + }, + { + "key": "scrollup", + "hide" : true, + "reset" : false, + "default": "PgUp" + }, + { + "key": "scrolldown", + "hide" : true, + "reset" : false, + "default": "PgDown" + }, + { + "key": "movetoendofline", + "hide" : true, + "reset" : false, + "default": "End" + }, + { + "key": "movetostartofline", + "hide" : true, + "reset" : false, + "default": "Home" + }, + { + "key": "movetoend", + "hide" : true, + "reset" : false, + "default": "Ctrl+End" + }, + { + "key": "movetostart", + "hide" : true, + "reset" : false, + "default": "Ctrl+Home" + }, + { + "key": "movetolineindentation", + "hide" : true, + "reset" : false, + "default": "Ctrl+M" + }, + { + "key": "upcaseword", + "hide" : true, + "reset" : false, + "default": "Alt+U" + }, + { + "key": "downcaseword", + "hide" : true, + "reset" : false, + "default": "Alt+L" + }, + { + "key": "capitalizeword", + "hide" : true, + "reset" : false, + "default": "Alt+C" + }, + { + "key": "killbackwardword", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+N" + }, + { + "key": "killforwardword", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+M" + }, + { + "key": "forwardpair", + "hide" : true, + "reset" : false, + "default": "Alt+P" + }, + { + "key": "backwardpair", + "hide" : true, + "reset" : false, + "default": "Alt+N" + }, + { + "key": "selectall", + "hide" : true, + "reset" : false, + "default": "Ctrl+A" + }, + { + "key": "copy", + "hide" : true, + "reset" : false, + "default": "Ctrl+C" + }, + { + "key": "cut", + "hide" : true, + "reset" : false, + "default": "Ctrl+X" + }, + { + "key": "paste", + "hide" : true, + "reset" : false, + "default": "Ctrl+V" + }, + { + "key": "transposechar", + "hide" : true, + "reset" : false, + "default": "Alt+T" + }, + { + "key": "setmark", + "hide" : true, + "reset" : false, + "default": "Alt+H" + }, + { + "key": "exchangemark", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+H" + }, + { + "key": "copylines", + "hide" : true, + "reset" : false, + "default": "Meta+C" + }, + { + "key": "cutlines", + "hide" : true, + "reset" : false, + "default": "Meta+X" + }, + { + "key": "joinlines", + "hide" : true, + "reset" : false, + "default": "Ctrl+J" + }, + { + "key": "selectnextcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+," + }, + { + "key": "selectprevcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+." + }, + { + "key": "selectfirstcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+>" + }, + { + "key": "selectlastcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+<" + }, + { + "key": "togglereadonlymode", + "hide" : true, + "reset" : false, + "default": "Meta+Alt+L" + }, + { + "key": "togglecomment", + "hide" : true, + "reset" : false, + "default": "Alt+A" + }, + { + "key": "removecomment", + "hide" : true, + "reset" : false, + "default": "Alt+Z" + }, + { + "key": "undo", + "hide" : true, + "reset" : false, + "default": "Ctrl+Z" + }, + { + "key": "switchbookmark", + "hide" : true, + "reset" : false, + "default": "Ctrl+F2" + }, + { + "key": "movetoprebookmark", + "hide" : true, + "reset" : false, + "default": "F2" + }, + { + "key": "movetonextbookmark", + "hide" : true, + "reset" : false, + "default": "Shift+F2" + }, + { + "key": "redo", + "hide" : true, + "reset" : false, + "default": "Ctrl+Y" + }, + { + "key": "mark", + "hide" : true, + "reset" : false, + "default": "Ctrl+F6" + } + ] + }, + { + "key": "window_keymap_emacs", + "name": "Emacs window keymap", + "hide" : true, + "options": [ + { + "key": "addblanktab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+T" + }, + { + "key": "newwindow", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+N" + }, + { + "key": "savefile", + "hide" : true, + "reset" : false, + "default": "Ctrl+X" + }, + { + "key": "saveasfile", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+X" + }, + { + "key": "selectnexttab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Tab" + }, + { + "key": "selectprevtab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Backtab" + }, + { + "key": "closetab", + "hide" : true, + "reset" : false, + "default": "Ctrl+C" + }, + { + "key": "closeothertabs", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+C" + }, + { + "key": "restoretab", + "hide" : true, + "reset" : false, + "default": "Ctrl+'" + }, + { + "key": "openfile", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+O" + }, + { + "key": "incrementfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+=" + }, + { + "key": "decrementfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+-" + }, + { + "key": "resetfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+0" + }, + { + "key": "togglefullscreen", + "hide" : true, + "reset" : false, + "default": "F11" + }, + { + "key": "help", + "hide" : true, + "reset" : false, + "default": "F1" + }, + { + "key": "findNext", + "hide" : true, + "reset" : false, + "default": "F3" + }, + { + "key": "findPrev", + "hide" : true, + "reset" : false, + "default": "Shift+F3" + }, + { + "key": "find", + "hide" : true, + "reset" : false, + "default": "Ctrl+S" + }, + { + "key": "replace", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+%" + }, + { + "key": "jumptoline", + "hide" : true, + "reset" : false, + "default": "Alt+G" + }, + { + "key": "saveposition", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+>" + }, + { + "key": "restoreposition", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+<" + }, + { + "key": "escape", + "hide" : true, + "reset" : false, + "default": "Ctrl+G" + }, + { + "key": "displayshortcuts", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+H" + }, + { + "key": "print", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+P" + } + ] + }, + { + "key": "editor_keymap_emacs", + "name": "Emacs editor keymap", + "hide" : true, + "options": [ + { + "key": "indentline", + "hide" : true, + "reset" : false, + "default": "Alt+I" + }, + { + "key": "backindentline", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+I" + }, + { + "key": "forwardchar", + "hide" : true, + "reset" : false, + "default": "Ctrl+F" + }, + { + "key": "backwardchar", + "hide" : true, + "reset" : false, + "default": "Ctrl+B" + }, + { + "key": "forwardword", + "hide" : true, + "reset" : false, + "default": "Alt+F" + }, + { + "key": "backwardword", + "hide" : true, + "reset" : false, + "default": "Alt+B" + }, + { + "key": "nextline", + "hide" : true, + "reset" : false, + "default": "Ctrl+N" + }, + { + "key": "prevline", + "hide" : true, + "reset" : false, + "default": "Ctrl+P" + }, + { + "key": "newline", + "hide" : true, + "reset" : false, + "default": "Ctrl+M" + }, + { + "key": "opennewlineabove", + "hide" : true, + "reset" : false, + "default": "Ctrl+O" + }, + { + "key": "opennewlinebelow", + "hide" : true, + "reset" : false, + "default": "Ctrl+L" + }, + { + "key": "duplicateline", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+L" + }, + { + "key": "killline", + "hide" : true, + "reset" : false, + "default": "Ctrl+K" + }, + { + "key": "killcurrentline", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+K" + }, + { + "key": "swaplineup", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+P" + }, + { + "key": "swaplinedown", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+N" + }, + { + "key": "scrolllineup", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+J" + }, + { + "key": "scrolllinedown", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+K" + }, + { + "key": "scrollup", + "hide" : true, + "reset" : false, + "default": "Ctrl+V" + }, + { + "key": "scrolldown", + "hide" : true, + "reset" : false, + "default": "Alt+V" + }, + { + "key": "movetoendofline", + "hide" : true, + "reset" : false, + "default": "Ctrl+E" + }, + { + "key": "movetostartofline", + "hide" : true, + "reset" : false, + "default": "Ctrl+A" + }, + { + "key": "movetoend", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+<" + }, + { + "key": "movetostart", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+>" + }, + { + "key": "movetolineindentation", + "hide" : true, + "reset" : false, + "default": "Alt+M" + }, + { + "key": "upcaseword", + "hide" : true, + "reset" : false, + "default": "Alt+U" + }, + { + "key": "downcaseword", + "hide" : true, + "reset" : false, + "default": "Alt+L" + }, + { + "key": "capitalizeword", + "hide" : true, + "reset" : false, + "default": "Alt+C" + }, + { + "key": "killbackwardword", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+N" + }, + { + "key": "killforwardword", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+M" + }, + { + "key": "forwardpair", + "hide" : true, + "reset" : false, + "default": "Alt+P" + }, + { + "key": "backwardpair", + "hide" : true, + "reset" : false, + "default": "Alt+N" + }, + { + "key": "selectall", + "hide" : true, + "reset" : false, + "default": "Ctrl+Z" + }, + { + "key": "copy", + "hide" : true, + "reset" : false, + "default": "Alt+W" + }, + { + "key": "cut", + "hide" : true, + "reset" : false, + "default": "Ctrl+W" + }, + { + "key": "paste", + "hide" : true, + "reset" : false, + "default": "Ctrl+Y" + }, + { + "key": "transposechar", + "hide" : true, + "reset" : false, + "default": "Ctrl+T" + }, + { + "key": "setmark", + "hide" : true, + "reset" : false, + "default": "Alt+H" + }, + { + "key": "exchangemark", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+H" + }, + { + "key": "copylines", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+W" + }, + { + "key": "cutlines", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+W" + }, + { + "key": "joinlines", + "hide" : true, + "reset" : false, + "default": "Ctrl+J" + }, + { + "key": "selectnextcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+," + }, + { + "key": "selectprevcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+." + }, + { + "key": "selectfirstcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+>" + }, + { + "key": "selectlastcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+<" + }, + { + "key": "togglereadonlymode", + "hide" : true, + "reset" : false, + "default": "Meta+Alt+L" + }, + { + "key": "togglecomment", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+:" + }, + { + "key": "removecomment", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+;" + }, + { + "key": "undo", + "hide" : true, + "reset" : false, + "default": "Ctrl+/" + }, + { + "key": "switchbookmark", + "hide" : true, + "reset" : false, + "default": "Ctrl+F2" + }, + { + "key": "movetoprebookmark", + "hide" : true, + "reset" : false, + "default": "F2" + }, + { + "key": "movetonextbookmark", + "hide" : true, + "reset" : false, + "default": "Shift+F2" + }, + { + "key": "redo", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+?" + }, + { + "key": "mark", + "hide" : true, + "reset" : false, + "default": "Ctrl+F6" + } + ] + }, + { + "key": "window_keymap_customize", + "name": "Customize window keymap", + "hide" : true, + "options": [ + { + "key": "addblanktab", + "hide" : true, + "reset" : false, + "default": "Ctrl+T" + }, + { + "key": "newwindow", + "hide" : true, + "reset" : false, + "default": "Ctrl+N" + }, + { + "key": "savefile", + "hide" : true, + "reset" : false, + "default": "Ctrl+S" + }, + { + "key": "saveasfile", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+S" + }, + { + "key": "selectnexttab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Tab" + }, + { + "key": "selectprevtab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Backtab" + }, + { + "key": "closetab", + "hide" : true, + "reset" : false, + "default": "Ctrl+W" + }, + { + "key": "closeothertabs", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+W" + }, + { + "key": "restoretab", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+T" + }, + { + "key": "openfile", + "hide" : true, + "reset" : false, + "default": "Ctrl+O" + }, + { + "key": "incrementfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+=" + }, + { + "key": "decrementfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+-" + }, + { + "key": "resetfontsize", + "hide" : true, + "reset" : false, + "default": "Ctrl+0" + }, + { + "key": "togglefullscreen", + "hide" : true, + "reset" : false, + "default": "F11" + }, + { + "key": "help", + "hide" : true, + "reset" : false, + "default": "F1" + }, + { + "key": "findNext", + "hide" : true, + "reset" : false, + "default": "F3" + }, + { + "key": "findPrev", + "hide" : true, + "reset" : false, + "default": "Shift+F3" + }, + { + "key": "find", + "hide" : true, + "reset" : false, + "default": "Ctrl+F" + }, + { + "key": "replace", + "hide" : true, + "reset" : false, + "default": "Ctrl+H" + }, + { + "key": "jumptoline", + "hide" : true, + "reset" : false, + "default": "Ctrl+G" + }, + { + "key": "saveposition", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+>" + }, + { + "key": "restoreposition", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+<" + }, + { + "key": "escape", + "hide" : true, + "reset" : false, + "default": "Esc" + }, + { + "key": "displayshortcuts", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+?" + }, + { + "key": "print", + "hide" : true, + "reset" : false, + "default": "Ctrl+P" + } + ] + }, + { + "key": "editor_keymap_customize", + "name": "Customize editor keymap", + "hide" : true, + "options": [ + { + "key": "indentline", + "hide" : true, + "reset" : false, + "default": "Alt+I" + }, + { + "key": "backindentline", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+I" + }, + { + "key": "forwardchar", + "hide" : true, + "reset" : false, + "default": "Right" + }, + { + "key": "backwardchar", + "hide" : true, + "reset" : false, + "default": "Left" + }, + { + "key": "forwardword", + "hide" : true, + "reset" : false, + "default": "Ctrl+Right" + }, + { + "key": "backwardword", + "hide" : true, + "reset" : false, + "default": "Ctrl+Left" + }, + { + "key": "nextline", + "hide" : true, + "reset" : false, + "default": "Down" + }, + { + "key": "prevline", + "hide" : true, + "reset" : false, + "default": "Up" + }, + { + "key": "newline", + "hide" : true, + "reset" : false, + "default": "Enter" + }, + { + "key": "opennewlineabove", + "hide" : true, + "reset" : false, + "default": "Ctrl+Enter" + }, + { + "key": "opennewlinebelow", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Enter" + }, + { + "key": "duplicateline", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+D" + }, + { + "key": "killline", + "hide" : true, + "reset" : false, + "default": "Ctrl+K" + }, + { + "key": "killcurrentline", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+K" + }, + { + "key": "swaplineup", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Up" + }, + { + "key": "swaplinedown", + "hide" : true, + "reset" : false, + "default": "Ctrl+Shift+Down" + }, + { + "key": "scrolllineup", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+Up" + }, + { + "key": "scrolllinedown", + "hide" : true, + "reset" : false, + "default": "Meta+Shift+Down" + }, + { + "key": "scrollup", + "hide" : true, + "reset" : false, + "default": "PgUp" + }, + { + "key": "scrolldown", + "hide" : true, + "reset" : false, + "default": "PgDown" + }, + { + "key": "movetoendofline", + "hide" : true, + "reset" : false, + "default": "End" + }, + { + "key": "movetostartofline", + "hide" : true, + "reset" : false, + "default": "Home" + }, + { + "key": "movetoend", + "hide" : true, + "reset" : false, + "default": "Ctrl+End" + }, + { + "key": "movetostart", + "hide" : true, + "reset" : false, + "default": "Ctrl+Home" + }, + { + "key": "movetolineindentation", + "hide" : true, + "reset" : false, + "default": "Ctrl+M" + }, + { + "key": "upcaseword", + "hide" : true, + "reset" : false, + "default": "Alt+U" + }, + { + "key": "downcaseword", + "hide" : true, + "reset" : false, + "default": "Alt+L" + }, + { + "key": "capitalizeword", + "hide" : true, + "reset" : false, + "default": "Alt+C" + }, + { + "key": "killbackwardword", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+N" + }, + { + "key": "killforwardword", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+M" + }, + { + "key": "forwardpair", + "hide" : true, + "reset" : false, + "default": "Alt+P" + }, + { + "key": "backwardpair", + "hide" : true, + "reset" : false, + "default": "Alt+N" + }, + { + "key": "selectall", + "hide" : true, + "reset" : false, + "default": "Ctrl+A" + }, + { + "key": "copy", + "hide" : true, + "reset" : false, + "default": "Ctrl+C" + }, + { + "key": "cut", + "hide" : true, + "reset" : false, + "default": "Ctrl+X" + }, + { + "key": "paste", + "hide" : true, + "reset" : false, + "default": "Ctrl+V" + }, + { + "key": "transposechar", + "hide" : true, + "reset" : false, + "default": "Alt+T" + }, + { + "key": "setmark", + "hide" : true, + "reset" : false, + "default": "Alt+H" + }, + { + "key": "exchangemark", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+H" + }, + { + "key": "copylines", + "hide" : true, + "reset" : false, + "default": "Meta+C" + }, + { + "key": "cutlines", + "hide" : true, + "reset" : false, + "default": "Meta+X" + }, + { + "key": "joinlines", + "hide" : true, + "reset" : false, + "default": "Ctrl+J" + }, + { + "key": "selectnextcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+," + }, + { + "key": "selectprevcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+." + }, + { + "key": "selectfirstcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+>" + }, + { + "key": "selectlastcompletion", + "hide" : true, + "reset" : false, + "default": "Alt+Shift+<" + }, + { + "key": "togglereadonlymode", + "hide" : true, + "reset" : false, + "default": "Meta+Alt+L" + }, + { + "key": "togglecomment", + "hide" : true, + "reset" : false, + "default": "Alt+A" + }, + { + "key": "removecomment", + "hide" : true, + "reset" : false, + "default": "Alt+Z" + }, + { + "key": "undo", + "hide" : true, + "reset" : false, + "default": "Ctrl+Z" + }, + { + "key": "switchbookmark", + "hide" : true, + "reset" : false, + "default": "Ctrl+F2" + }, + { + "key": "movetoprebookmark", + "hide" : true, + "reset" : false, + "default": "F2" + }, + { + "key": "movetonextbookmark", + "hide" : true, + "reset" : false, + "default": "Shift+F2" + }, + { + "key": "redo", + "hide" : true, + "reset" : false, + "default": "Ctrl+Y" + }, + { + "key": "mark", + "hide" : true, + "reset" : false, + "default": "Ctrl+F6" + } + ] + } + ] + }, + { + "key": "advance", + "name": "Advanced", + "groups": [ + { + "key": "startup", + "name": "Startup", + "options": [ + { + "key": "save_tab_before_close", + "name": "Reopen last closed tabs", + "text": "Reopen last closed tabs", + "type": "checkbox", + "default": true + } + ] + }, + { + "key": "window", + "name": "Window", + "options": [ + { + "key": "windowstate", + "name": "Window size", + "type": "combobox", + "default": "window_normal" + }, + { + "key": "window_width", + "hide" : true, + "reset" : false, + "default": 0.6 + }, + { + "key": "window_height", + "hide" : true, + "reset" : false, + "default": 0.6 + } + ] + }, + { + "key": "editor", + "name": "Editor", + "options": [ + { + "key": "tabspacenumber", + "name": "Tab width", + "type": "spinbutton", + "default": 4, + "min": 1, + "max": 24 + }, + { + "key": "allow_midbutton_paste", + "name": "Paste by pressing a middle mouse button", + "text": "Paste by pressing a middle mouse button", + "type": "checkbox", + "default": true + }, + { + "key": "file_dialog_dir", + "hide": true, + "reset": false, + "default": "" + }, + { + "key": "browsing_history_file", + "hide": true, + "reset": false, + "default": "" + }, + { + "key": "browsing_encode_history", + "hide": true, + "reset": false, + "default": "" + }, + { + "key": "browsing_history_temfile", + "hide": true, + "reset": false, + "default": "" + }, + { + "key": "theme", + "hide": true, + "reset": true, + "default": "/usr/share/deepin-editor/themes/deepin.theme" + }, + { + "key": "bookmark", + "hide": true, + "reset": false, + "default": "" + } + ] + }, + { + "key": "open_save_setting", + "name": "Open/Save Settings", + "options": [ + { + "key": "savingpathwgt", + "type": "savingpathwgt", + "default":"0" + }, + { + "key": "open_save_curfile_path", + "hide": true + }, + { + "key": "open_save_lastopt_path", + "hide": true + }, + { + "key": "open_save_custom_path", + "hide": true + } + ] + + } + + ] + } + ] +} diff --git a/src/startmanager.cpp b/src/startmanager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66786a9f819d77718009a90e48a510c36d7ef279 --- /dev/null +++ b/src/startmanager.cpp @@ -0,0 +1,946 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "startmanager.h" +//#include + +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +DWIDGET_USE_NAMESPACE + +// 备份定时器间隔 +enum BackupInterval { + EAutoBackupInterval = 5 * 60 * 1000, ///< 周期自动备份定时 5分钟 + EDelayBackupInterval = 20, ///< 延迟备份间隔 20ms +}; + +// 用于配置文件书签的标识 +static const QString s_bookMarkKey = "advance.editor.bookmark"; + +StartManager *StartManager::m_instance = nullptr; + +StartManager *StartManager::instance() +{ + if (m_instance == nullptr) { + m_instance = new StartManager; + } + + return m_instance; +} + +StartManager::StartManager(QObject *parent) + : QObject(parent) +{ + //m_bIsDragEnter = false; + //Create blank directory if it not exist. + + initBlockShutdown(); + + m_blankFileDir = QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("blank-files"); + m_backupDir = QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("backup-files"); + m_autoBackupDir = QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("autoBackup-files"); + + if (!QFileInfo(m_blankFileDir).exists()) { + QDir().mkpath(m_blankFileDir); + } + + if (!QFileInfo(m_backupDir).exists()) { + QDir().mkpath(m_backupDir); + } + + m_qlistTemFile = Settings::instance()->settings->option("advance.editor.browsing_history_temfile")->value().toStringList(); + // 初始化书签信息记录表 + initBookmark(); + + //按时间自动备份(5分钟) + m_pTimer = new QTimer; + connect(m_pTimer, &QTimer::timeout, this, &StartManager::autoBackupFile); + m_pTimer->start(EAutoBackupInterval); +} + +bool StartManager::checkPath(const QString &file) +{ + for (int i = 0; i < m_windows.count(); i++) { + EditWrapper *wrapper = m_windows.value(i)->wrapper(file); + + if (wrapper != nullptr) { + FileTabInfo info = getFileTabInfo(wrapper->textEditor()->getFilePath()); + // Open exist tab if file has opened. + popupExistTabs(info); + return false; + } + } + + return true; +} + +bool StartManager::ifKlu() +{ + auto e = QProcessEnvironment::systemEnvironment(); + QString XDG_SESSION_TYPE = e.value(QStringLiteral("XDG_SESSION_TYPE")); + QString WAYLAND_DISPLAY = e.value(QStringLiteral("WAYLAND_DISPLAY")); + + if (XDG_SESSION_TYPE == QLatin1String("wayland") || WAYLAND_DISPLAY.contains(QLatin1String("wayland"), Qt::CaseInsensitive)) { + return true; + } else { + return false; + } +} + +bool StartManager::isMultiWindow() +{ + if (m_windows.count() > 1) { + return true; + } + + return false; +} + +bool StartManager::isTemFilesEmpty() +{ + bool bIsEmpty = false; + + for (auto temFile : m_qlistTemFile) { + if (temFile.isEmpty()) { + bIsEmpty = true; + } + } + + return bIsEmpty; +} + +void StartManager::autoBackupFile() +{ + // 标签页在拖拽状态时不执行备份 + if (m_bIsTagDragging) { + return; + } + + //如果自动备份文件夹不存在,创建自动备份文件夹 + if (!QFileInfo(m_autoBackupDir).exists()) { + QDir().mkpath(m_autoBackupDir); + } else { + //有用户备份时删除用户备份 + if (!QDir(m_backupDir).isEmpty()) { + QDir(m_backupDir).removeRecursively(); + } + } + + QMap wrappers; + QStringList listBackupInfo; + QString filePath, localPath, curPos; + QFileInfo fileInfo; + m_qlistTemFile.clear(); + listBackupInfo = Settings::instance()->settings->option("advance.editor.browsing_history_temfile")->value().toStringList(); + + //记录所有的文件信息 + for (int var = 0; var < m_windows.count(); ++var) { + wrappers = m_windows.value(var)->getWrappers(); + QStringList list = wrappers.keys(); + + for (EditWrapper *wrapper : wrappers) { + //大文件加载时不备份 + if (wrapper->getFileLoading()) continue; + + filePath = wrapper->textEditor()->getFilePath(); + localPath = wrapper->textEditor()->getTruePath(); + + StartManager::FileTabInfo tabInfo = StartManager::instance()->getFileTabInfo(filePath); + curPos = QString::number(wrapper->textEditor()->textCursor().position()); + fileInfo.setFile(localPath); + + //json格式记录文件信息 + QJsonObject jsonObject; + QJsonDocument document; + jsonObject.insert("localPath", localPath); //记录源文件路径 + jsonObject.insert("cursorPosition", curPos); //记录鼠标位置 + jsonObject.insert("modify", wrapper->isModified()); //记录修改状态 + jsonObject.insert("window", var); //记录窗口Index + + //记录书签 + QList bookmarkList = wrapper->textEditor()->getBookmarkInfo(); + + if (!bookmarkList.isEmpty()) { + QString bookmarkInfo; + + for (int i = 0; i < bookmarkList.count(); i++) { + if (i == bookmarkList.count() - 1) { + bookmarkInfo.append(QString::number(bookmarkList.value(i))); + } else { + bookmarkInfo.append(QString::number(bookmarkList.value(i)) + ","); + } + } + + jsonObject.insert("bookMark", bookmarkInfo); + + // 更新记录全局书签信息 + m_bookmarkTable.insert(localPath, bookmarkList); + } else { + // 无书签,移除 + m_bookmarkTable.remove(localPath); + } + + //记录活动页 + if (m_windows.value(var)->isActiveWindow()) { + if (wrapper == m_windows.value(var)->currentWrapper()) { + jsonObject.insert("focus", true); + } + } + + //保存备份文件 + if (Utils::isDraftFile(filePath)) { + wrapper->saveTemFile(filePath); + } else { + if (wrapper->isModified()) { + QString name = fileInfo.absolutePath().replace("/", "_"); + QString qstrFilePath = m_autoBackupDir + "/" + Utils::getStringMD5Hash(fileInfo.baseName()) + "." + name + "." + fileInfo.suffix(); + jsonObject.insert("temFilePath", qstrFilePath); + wrapper->saveTemFile(qstrFilePath); + } + } + + //使用json串形式保存 + document.setObject(jsonObject); + QByteArray byteArray = document.toJson(QJsonDocument::Compact); + list.replace(tabInfo.tabIndex, byteArray); + } + + m_qlistTemFile.append(list); + } + + //将json串列表写入配置文件 + Settings::instance()->settings->option("advance.editor.browsing_history_temfile")->setValue(m_qlistTemFile); + // 备份书签信息 + saveBookmark(); +} + +int StartManager::recoverFile(Window *window) +{ + Window *pFocusWindow = nullptr; + QString focusPath; + bool bIsTemFile = false; + QStringList blankFiles = QDir(m_blankFileDir).entryList(QStringList(), QDir::Files); + int recFilesSum = 0; + QStringList files = blankFiles; + QFileInfo fileInfo; + QString lastmodifiedtime; + //去除非新建文件 + for (auto file : blankFiles) { + if (!file.contains("blank_file")) { + files.removeOne(file); + } + } + + int windowIndex = -1; + + //根据备份信息恢复文件 + for (int i = 0; i < m_qlistTemFile.count(); i++) { + QJsonParseError jsonError; + // 转化为 JSON 文档 + QJsonDocument doucment = QJsonDocument::fromJson(m_qlistTemFile.value(i).toUtf8(), &jsonError); + // 解析未发生错误 + if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { + if (doucment.isObject()) { + QString temFilePath; + QString localPath; + // JSON 文档为对象 + QJsonObject object = doucment.object(); // 转化为对象 + + //得到恢复文件对应的窗口 + if (object.contains("window")) { // 包含指定的 key + QJsonValue value = object.value("window"); // 获取指定 key 对应的 value + + if (value.isDouble()) { + if (windowIndex == -1) { + windowIndex = static_cast(value.toDouble()); + } else { + if (windowIndex != static_cast(value.toDouble())) { + windowIndex = static_cast(value.toDouble()); + window = createWindow(true); + window->showCenterWindow(false); + } + } + } + } + + //得到备份文件路径 + if (object.contains("temFilePath")) { // 包含指定的 key + QJsonValue value = object.value("temFilePath"); // 获取指定 key 对应的 value + + if (value.isString()) { // 判断 value 是否为字符串 + temFilePath = value.toString(); // 将 value 转化为字符串 + } + } + + //得到文件修改状态 + if (object.contains("modify")) { // 包含指定的 key + QJsonValue value = object.value("modify"); // 获取指定 key 对应的 value + + if (value.isBool()) { // 判断 value 是否为字符串 + bIsTemFile = value.toBool(); + } + } + if (object.contains("lastModifiedTime")) { + auto v = object.value("lastModifiedTime"); + if (v.isString()) { + lastmodifiedtime = v.toString(); + } + } + + //得到真实文件路径 + if (object.contains("localPath")) { // 包含指定的 key + QJsonValue value = object.value("localPath"); // 获取指定 key 对应的 value + + if (value.isString()) { // 判断 value 是否为字符串 + localPath = value.toString(); // 将 value 转化为字符串 + fileInfo.setFile(localPath); + if (!fileInfo.exists()) { + continue; + } + } + } + + //打开文件 + if (!temFilePath.isEmpty()) { + if (Utils::fileExists(temFilePath)) { + window->addTemFileTab(temFilePath, fileInfo.fileName(), localPath, lastmodifiedtime, bIsTemFile); + + //打开文件后设置书签 + if (object.contains("bookMark")) { // 包含指定的 key + QJsonValue value = object.value("bookMark"); // 获取指定 key 对应的 value + + if (value.isString()) { + QList bookmarkList; + bookmarkList = analyzeBookmakeInfo(value.toString()); + window->wrapper(temFilePath)->textEditor()->setBookMarkList(bookmarkList); + } + } else if (m_bookmarkTable.contains(temFilePath)) { + // 若文件已有配置,则以文件为准,否则以全局配置为准 + window->wrapper(localPath)->textEditor()->setBookMarkList(m_bookmarkTable.value(temFilePath)); + } + + if (object.contains("focus")) { // 包含指定的 key + QJsonValue value = object.value("focus"); // 获取指定 key 对应的 value + + if (value.isBool() && value.toBool()) { + pFocusWindow = window; + focusPath = temFilePath; + } + } + + recFilesSum++; + } + } else { + if (!localPath.isEmpty() && Utils::fileExists(localPath)) { + // 若为草稿文件或不支持的MIMETYPE文件,显示默认名称标签 + if (Utils::isDraftFile(localPath) || !Utils::isMimeTypeSupport(localPath)) { + //得到新建文件名称 + int index = files.indexOf(QFileInfo(localPath).fileName()); + + if (index >= 0) { + QString fileName = tr("Untitled %1").arg(index + 1); + window->addTemFileTab(localPath, fileName, localPath, lastmodifiedtime, bIsTemFile); + + } + } else { + window->addTemFileTab(localPath, fileInfo.fileName(), localPath, lastmodifiedtime, bIsTemFile); + } + + //打开文件后设置书签 + if (object.contains("bookMark")) { // 包含指定的 key + QJsonValue value = object.value("bookMark"); // 获取指定 key 对应的 value + + if (value.isString()) { + QList bookmarkList; + bookmarkList = analyzeBookmakeInfo(value.toString()); + window->wrapper(localPath)->textEditor()->setBookMarkList(bookmarkList); + } + } else if (m_bookmarkTable.contains(localPath)) { + // 若文件已有配置,则以文件为准,否则以全局配置为准 + window->wrapper(localPath)->textEditor()->setBookMarkList(m_bookmarkTable.value(localPath)); + } + + if (object.contains("focus")) { // 包含指定的 key + QJsonValue value = object.value("focus"); // 获取指定 key 对应的 value + + if (value.isBool() && value.toBool()) { + pFocusWindow = window; + focusPath = localPath; + } + } + + recFilesSum++; + } + } + } + } + } + + //当前活动页 + if (pFocusWindow != nullptr && !focusPath.isNull()) { + FileTabInfo info; + info.windowIndex = m_windows.indexOf(pFocusWindow); + info.tabIndex = pFocusWindow->getTabIndex(focusPath); + popupExistTabs(info); + } + + return recFilesSum; +} + +void StartManager::openFilesInWindow(QStringList files) +{ + // Open window with blank tab if no files need open. + if (files.isEmpty()) { + if (m_windows.count() >= 20) return; + Window *window = createWindow(); + + if (m_windows.count() > 0) { + window->showCenterWindow(false); + } else { + window->showCenterWindow(true); + } + + window->addBlankTab(); + window->activateWindow(); + } else { + for (const QString &file : files) { + FileTabInfo info = getFileTabInfo(file); + + // Open exist tab if file has opened. + if (info.windowIndex != -1) { + popupExistTabs(info); + } + // Add new tab in current window. + else { + Window *window = createWindow(); + window->showCenterWindow(true); + window->addTab(file); + } + } + } +} + +void StartManager::openFilesInTab(QStringList files) +{ + if (files.isEmpty()) { + QDir blankDirectory = QDir(QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("blank-files")); + QStringList blankFiles = blankDirectory.entryList(QStringList(), QDir::Files); + + if (m_windows.isEmpty()) { + Window *window = createWindow(true); + window->showCenterWindow(true); + + if (!isTemFilesEmpty()) { + if (recoverFile(window) == 0) { + window->addBlankTab(); + } + } else { + if (blankFiles.isEmpty()) { + window->addBlankTab(); + } else { + for (auto file : blankFiles) { + if (file.contains("blank_file")) { + blankDirectory.remove(file); + } + } + + window->addBlankTab(); + } + } + } + // Just active first window if no file is need opened. + else { + Window *window = createWindow(); + window->show(); + window->addBlankTab(); + } + } else { + for (const QString &file : files) { + + if (!checkPath(file)) { + // 存在已打开文件时,进行下一文件判断 + continue; + } + + FileTabInfo info = getFileTabInfo(file); + + // Open exist tab if file has opened. + if (info.windowIndex != -1) { + popupExistTabs(info); + } + // Create new window with file if haven't window exist. + else if (m_windows.size() == 0) { + Window *window = createWindow(true); + window->showCenterWindow(true); + QTimer::singleShot(50, [ = ] { + recoverFile(window); + window->addTab(file); + }); + } + // Open file tab in first window of window list. + else { + Window *window = m_windows[0]; + window->addTab(file); + //window->setWindowState(Qt::WindowActive); + //通过dbus接口从任务栏激活窗口 + if (!Q_LIKELY(Utils::activeWindowFromDock(window->winId()))) { + window->activateWindow(); + } + } + } + } +} + +void StartManager::createWindowFromWrapper(const QString &tabName, const QString &filePath, const QString &qstrTruePath, EditWrapper *buffer, bool isModifyed) +{ + Window *pWindow = createWindow(); + //window->showCenterWindow(); + QRect rect = pWindow->rect(); + QPoint pos = QCursor::pos() ;/*- window->topLevelWidget()->pos();*/ + QRect desktopRect = QApplication::desktop()->rect(); + QPoint startPos = pos; + + if ((pos.x() + rect.width()) > desktopRect.width()) { + startPos.setX(desktopRect.width() - rect.width()); + } else if (pos.x() < 0) { + startPos.setX(0); + } + + if ((pos.y() + rect.height()) > desktopRect.height()) { + startPos.setY(desktopRect.height() - rect.height()); + } else if (pos.y() < 0) { + startPos.setY(0); + } + + QRect startRect(startPos, Tabbar::sm_pDragPixmap->rect().size()); + //QRect startRect(startPos, QSize(0,0)); + QRect endRect(startPos, pWindow->rect().size()); + pWindow->move(startPos); +#if 0 + // window->setFixedSize(Tabbar::sm_pDragPixmap->rect().size()); + QLabel *pLab = new QLabel(); + //pLab->resize(Tabbar::sm_pDragPixmap->rect().size()); + pLab->move(pos); + pLab->setPixmap(*Tabbar::sm_pDragPixmap); + pLab->show(); +#endif + //添加编辑窗口drop动态显示效果 梁卫东 2020-08-25 09:54:57 + QPropertyAnimation *geometry = new QPropertyAnimation(pWindow, "geometry"); + geometry->setDuration(200); + geometry->setStartValue(startRect); + geometry->setEndValue(endRect); + geometry->setEasingCurve(QEasingCurve::InCubic); + + //OutCubic InCubic +#if 0 + QPropertyAnimation *Opacity = new QPropertyAnimation(this, "windowOpacity"); + connect(Opacity, &QPropertyAnimation::finished, Opacity, &QPropertyAnimation::deleteLater); + Opacity->setDuration(200); + Opacity->setStartValue(1.0); + Opacity->setEndValue(0); + Opacity->setEasingCurve(QEasingCurve::InCirc); +#endif + + QParallelAnimationGroup *group = new QParallelAnimationGroup; + connect(group, &QParallelAnimationGroup::finished, this, [/*window,geometry,Opacity,group,*/ = ]() { + pWindow->show(); + pWindow->showCenterWindow(false); + geometry->deleteLater(); + group->deleteLater(); + + pWindow->addTabWithWrapper(buffer, filePath, qstrTruePath, tabName); + pWindow->currentWrapper()->updateModifyStatus(isModifyed); + pWindow->currentWrapper()->OnUpdateHighlighter(); + pWindow->setFocus(); + pWindow->setFontSizeWithConfig(pWindow->currentWrapper()); + }); + + group->addAnimation(geometry); + // group->addAnimation(Opacity); + group->start(); +} + +void StartManager::loadTheme(const QString &themeName) +{ + for (Window *window : m_windows) { + window->loadTheme(themeName); + } +} + +Window *StartManager::createWindow(bool alwaysCenter) +{ + // Create window. + Window *window = new Window; + connect(window, &Window::themeChanged, this, &StartManager::loadTheme, Qt::QueuedConnection); + connect(window, &Window::sigJudgeBlockShutdown, this, &StartManager::slotCheckUnsaveTab, Qt::QueuedConnection); + connect(window, &Window::tabChanged, this, &StartManager::slotDelayBackupFile, Qt::QueuedConnection); + + // Quit application if close last window. + connect(window, &Window::closeWindow, this, &StartManager::slotCloseWindow); +// connect(window, &Window::closeWindow, this, [ = ] { +// int windowIndex = m_windows.indexOf(window); +// //qDebug() << "Close window " << windowIndex; + +// Window *pWindow = static_cast(sender()); +// if (windowIndex >= 0) +// { +// m_windows.takeAt(windowIndex); +// } + +// if (m_windows.isEmpty()) +// { +// QDir path = QDir::currentPath(); +// if (!path.exists()) { +// return ; +// } +// path.setFilter(QDir::Files); +// QStringList nameList = path.entryList(); +// foreach (auto name, nameList) { +// if (name.contains("tabPaths.txt")) { +// QFile file(name); +// file.remove(); +// } +// } +// QApplication::quit(); +// PerformanceMonitor::closeAPPFinish(); +// } +// }); + + // Init window position. + initWindowPosition(window, alwaysCenter); + + connect(window, &Window::newWindow, this, &StartManager::slotCreatNewwindow); + + // 标签页拖拽状态变更时触发,防止在拖拽过程中备份导致获取的标签状态异常 + connect(window->getTabbar(), &DTabBar::dragStarted, this, [this](){ + m_bIsTagDragging = true; + }); + connect(window->getTabbar(), &DTabBar::dragEnd, this, [this](){ + m_bIsTagDragging = false; + slotDelayBackupFile(); + }); + + // Append window in window list. + m_windows << window; + + return window; +} + + +void StartManager::slotCloseWindow() +{ + Window *pWindow = static_cast(sender()); + int windowIndex = m_windows.indexOf(pWindow); + + if (windowIndex >= 0) { + m_windows.takeAt(windowIndex); + } + + if (m_windows.isEmpty()) { + // 保存书签信息 + saveBookmark(); + + QDir path = QDir::currentPath(); + if (!path.exists()) { + return ; + } + path.setFilter(QDir::Files); + QStringList nameList = path.entryList(); + foreach (auto name, nameList) { + if (name.contains("tabPaths.txt")) { + QFile file(name); + file.remove(); + } + } + + // 在程序退出前(最后一个窗口关闭后),手动注销DBus服务,防止重启文本编辑器时判断应用仍在占用总线 + // 导致被附加到上一文本编辑器进程 + QDBusConnection::sessionBus().unregisterService("com.deepin.Editor"); + + QTimer::singleShot(1000, []() { + QApplication::quit(); + }); + + PerformanceMonitor::closeAPPFinish(); + } +} + +void StartManager::slotDelayBackupFile() +{ + // 判断定时器是否已在触发状态,防止短时间内的多次触发,标签页拖拽状态不触发 + if (!m_DelayTimer.isActive() && !m_bIsTagDragging) { + m_DelayTimer.start(EDelayBackupInterval, this); + } +} + +void StartManager::timerEvent(QTimerEvent *e) +{ + // 判断是否为延迟备份 + if (e->timerId() == m_DelayTimer.timerId()) { + m_DelayTimer.stop(); + // 执行配置文件备份 + autoBackupFile(); + + // 重启周期定时备份 + m_pTimer->start(EAutoBackupInterval); + } +} + +void StartManager::slotCreatNewwindow() +{ + openFilesInWindow(QStringList()); +} + +void StartManager::initWindowPosition(Window *window, bool alwaysCenter) +{ + if (m_windows.isEmpty() || alwaysCenter) { + //Dtk::Widget::moveToCenter(window); + } else { + // Add window offset to avoid all editor window popup at same coordinate. + int windowOffset = m_windows.size() * 50; + QRect screenGeometry = qApp->desktop()->screenGeometry(QCursor::pos()); + window->move(screenGeometry.x() + windowOffset, screenGeometry.y() + windowOffset); + } +} + +void StartManager::popupExistTabs(FileTabInfo info) +{ + Window *window = m_windows[info.windowIndex]; + //window->showNormal(); + window->activeTab(info.tabIndex); + //window->setWindowState(Qt::WindowActive); + //通过dbus接口从任务栏激活窗口 + if (!Q_LIKELY(Utils::activeWindowFromDock(window->winId()))) { + window->activateWindow(); + } + +#if 0 + int indexid = 0; + uint winid = 0; + QDBusInterface dock("com.deepin.dde.daemon.Dock", + "/com/deepin/dde/daemon/Dock", + "com.deepin.dde.daemon.Dock", + QDBusConnection::sessionBus() + ); + QDBusReply rep = dock.call("GetEntryIDs"); + + for (auto name : rep.value()) { + if (name == "deepin-editor") { + indexid = rep.value().indexOf(name); + } + } + + m_pDock.reset(new Dock("com.deepin.dde.daemon.Dock", + "/com/deepin/dde/daemon/Dock", + QDBusConnection::sessionBus(), + this + ) + ); + QList list = m_pDock->entries(); + + m_pEntry.reset(new Entry("com.deepin.dde.daemon.Dock", + list[indexid].path(), + QDBusConnection::sessionBus(), + this)); + winid = m_pEntry->currentWindow() ; + + + QDBusMessage active = QDBusMessage::createMethodCall("com.deepin.dde.daemon.Dock", + "/com/deepin/dde/daemon/Dock", + "com.deepin.dde.daemon.Dock", + "ActivateWindow"); + active << winid; + QDBusConnection::sessionBus().call(active, QDBus::BlockWithGui); +#endif +} + +StartManager::FileTabInfo StartManager::getFileTabInfo(QString file) +{ + FileTabInfo info = {-1, -1}; + + //qDebug() << "Windows size: " << m_windows.size(); + + for (Window *window : m_windows) { + int tabIndex = window->getTabIndex(file); + if (tabIndex >= 0) { + info.windowIndex = m_windows.indexOf(window); + info.tabIndex = tabIndex; + break; + } + } + + return info; +} + +QList StartManager::analyzeBookmakeInfo(QString bookmarkInfo) +{ + QList bookmarkList; + int nLeftPosition = 0; + int nRightPosition = bookmarkInfo.indexOf(","); + bookmarkList << bookmarkInfo.mid(nLeftPosition, nRightPosition - nLeftPosition).toInt(); + nLeftPosition = nRightPosition; + + while (nRightPosition != -1) { + nRightPosition = bookmarkInfo.indexOf(",", nRightPosition + 1); + bookmarkList << bookmarkInfo.mid(nLeftPosition + 1, nRightPosition - nLeftPosition - 1).toInt(); + nLeftPosition = nRightPosition; + } + + return bookmarkList; +} + +/** + * @brief 主动更新记录书签信息 + * @param localPath 文件路径 + * @param bookmark 书签信息 + */ +void StartManager::recordBookmark(const QString &localPath, const QList &bookmark) +{ + m_bookmarkTable.insert(localPath, bookmark); +} + +/** + * @return 返回文件 \a localPath 的书签记录 + */ +QList StartManager::findBookmark(const QString &localPath) +{ + return m_bookmarkTable.value(localPath); +} + +void StartManager::initBlockShutdown() +{ + if (m_reply.value().isValid()) { + //qDebug() << "m_reply.value().isValid():" << m_reply.value().isValid(); + return; + } + + m_pLoginManager = new QDBusInterface("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QDBusConnection::systemBus()); + + m_arg << QString("shutdown") // what + << qApp->applicationDisplayName() // who + << QObject::tr("File not saved") // why + << QString("delay"); // mode + + m_reply = m_pLoginManager->callWithArgumentList(QDBus::Block, "Inhibit", m_arg); + if (m_reply.isValid()) { + m_reply.value().fileDescriptor(); + } +} + +/** + * @brief 从配置文件中获取全局的书签信息,包括已关闭的所有文件书签, + * 会遍历每个书签记录并判断文件是否存在,若文件被删除或移动,则不再记录对应的书签信息。 + */ +void StartManager::initBookmark() +{ + // 遍历书签信息列表 + QStringList bookmarkInfoList = Settings::instance()->settings->value(s_bookMarkKey).toStringList(); + for (const QString &bookmarkInfo : bookmarkInfoList) { + QJsonParseError readError; + QJsonDocument doc = QJsonDocument::fromJson(bookmarkInfo.toUtf8(), &readError); + if (QJsonParseError::NoError == readError.error + && !doc.isNull()) { + QJsonObject obj = doc.object(); + QString filePath = obj.value("localPath").toString(); + + // 判断文件是否仍存在,若不存在,则不保留书签信息 + if (!filePath.isEmpty() + && QFileInfo::exists(filePath)) { + QString bookmarkStr = obj.value("bookmark").toString(); + if (!bookmarkStr.isEmpty()) { + QList bookmarkList = analyzeBookmakeInfo(bookmarkStr); + if (!bookmarkList.isEmpty()) { + // 文件存在且书签标记非空,缓存书签信息 + m_bookmarkTable.insert(filePath, bookmarkList); + } + } + } + } + } +} + +/** + * @brief 将当前记录的所有文件的书签信息转换为Json数据列表记录到配置信息中, + * 被删除或移动文件的书签将被销毁。 + */ +void StartManager::saveBookmark() +{ + QStringList recordInfo; + // 遍历记录 + for (auto itr = m_bookmarkTable.begin(); itr != m_bookmarkTable.end();) { + if (!QFileInfo::exists(itr.key()) + || itr.value().isEmpty()) { + // 文件不存在则销毁记录 + itr = m_bookmarkTable.erase(itr); + } else { + QJsonObject obj; + obj.insert("localPath", itr.key()); + + // 遍历书签信息并组合 + QString bookmarkInfo; + const auto &markList = itr.value(); + for (int i = 0; i < markList.count(); i++) { + if (i == itr.value().count() - 1) { + bookmarkInfo.append(QString::number(markList.value(i))); + } else { + bookmarkInfo.append(QString::number(markList.value(i)) + ","); + } + } + obj.insert("bookmark", bookmarkInfo); + + QJsonDocument doc(obj); + recordInfo.append(doc.toJson(QJsonDocument::Compact)); + + ++itr; + } + } + + // 将书签信息保存至配置文件 + Settings::instance()->settings->option(s_bookMarkKey)->setValue(recordInfo); +} + +void StartManager::slotCheckUnsaveTab() +{ + for (Window *pWindow : m_windows) { + //如果返回true,则表示有未保存的tab项,则阻塞系统关机 + bool bRet = pWindow->checkBlockShutdown(); + if (bRet == true) { + m_reply = m_pLoginManager->callWithArgumentList(QDBus::Block, "Inhibit", m_arg); + if (m_reply.isValid()) { + } + + return; + } + } + + //如果for结束则表示没有发现未保存的tab项,则放开阻塞关机 + if (m_reply.isValid()) { + m_reply = QDBusReply(); + } +} + +void StartManager::closeAboutForWindow(Window *window) +{ + if (qApp != nullptr) { + DAboutDialog *pAboutDialog = qApp->aboutDialog(); + if (pAboutDialog != nullptr) { + if (pAboutDialog->parent() != nullptr) { + if (pAboutDialog->parent() == window) { + pAboutDialog->close(); + } + } + } + } +} diff --git a/src/startmanager.h b/src/startmanager.h new file mode 100644 index 0000000000000000000000000000000000000000..d387830c79907e6a7975613e9d7b6696b299c60c --- /dev/null +++ b/src/startmanager.h @@ -0,0 +1,129 @@ +// SPDX-FileCopyrightText: 2011-2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef STARTMANAGER_H +#define STARTMANAGER_H + +#include "widgets/window.h" +#include "editor/editwrapper.h" + +#include +#include +#include + +using Dock = com::deepin::dde::daemon::Dock; +using Entry = com::deepin::dde::daemon::dock::Entry; + + +class StartManager : public QObject +{ + Q_OBJECT + + Q_CLASSINFO("D-Bus Interface", "com.deepin.Editor") + +public: + struct FileTabInfo { + int windowIndex; + int tabIndex; + }; + + static StartManager *instance(); + explicit StartManager(QObject *parent = nullptr); + bool checkPath(const QString &file); + bool ifKlu(); + + /** + * @brief isMultiWindow 是否是多窗口 + * @return true or false + */ + bool isMultiWindow(); + + /** + * @brief isTemFilesEmpty 是否需要备份 + * @return true or false + */ + bool isTemFilesEmpty(); + + /** + * @brief autoBackupFile 自动备份 + */ + void autoBackupFile(); + + /** + * @brief recoverFile 备份恢复 + * @param window 从哪个窗口进行恢复 + * @return 恢复完成的文件数量 + */ + int recoverFile(Window *window); + + /** + * @brief analyzeBookmakeInfo 解析书签信息 + * @param bookmarkInfo 书签信息 + * @return 书签列表 + */ + QList analyzeBookmakeInfo(QString bookmarkInfo); + + // 主动更新记录书签信息 + void recordBookmark(const QString &localPath, const QList &bookmark); + // 查找文件对应的书签记录 + QList findBookmark(const QString &localPath); + +public slots: + Q_SCRIPTABLE void openFilesInTab(QStringList files); + Q_SCRIPTABLE void openFilesInWindow(QStringList files); + + void createWindowFromWrapper(const QString &tabName, const QString &filePath, const QString &qstrTruePath, EditWrapper *buffer, bool isModifyed); + void loadTheme(const QString &themeName); + + Window *createWindow(bool alwaysCenter = false); + void initWindowPosition(Window *window, bool alwaysCenter = false); + void popupExistTabs(FileTabInfo info); + FileTabInfo getFileTabInfo(QString file); + + void slotCheckUnsaveTab(); + + void closeAboutForWindow(Window *window); + + //信号封装 ut002764 2021.6.28 + void slotCreatNewwindow(); + void slotCloseWindow(); + + // 延迟备份定时器,超时后备份配置文件 + void slotDelayBackupFile(); + +protected: + // 接收延迟更新定时任务,执行备份配置文件 + virtual void timerEvent(QTimerEvent *e) override; + +private: + void initBlockShutdown(); + // 初始化书签信息 + void initBookmark(); + // 保存书签信息 + void saveBookmark(); + +private: + static StartManager *m_instance; + QList m_windows; + + QDBusReply m_reply; + QDBusInterface *m_pLoginManager = nullptr; + QList m_arg; + + QDBusPendingReply m_inhibitReply; + QScopedPointer m_pDock; + QScopedPointer m_pEntry; + QStringList m_qlistTemFile; ///< 备份信息列表 + QHash> m_bookmarkTable; ///< 书签标记信息表 + QTimer *m_pTimer; + QBasicTimer m_DelayTimer; ///< 延迟备份定时器 + QString m_blankFileDir; ///< 新建文件目录 + QString m_backupDir; ///< 用户备份文件目录 + QString m_autoBackupDir; ///< 自动备份文件目录 + Window *pFocusWindow; + + bool m_bIsTagDragging = false; ///< 当前Tab页处于拖拽状态时,部分处理被延后 +}; + +#endif diff --git a/src/thememodule/themeitemdelegate.cpp b/src/thememodule/themeitemdelegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5c9954ccade0e8ff0ed8d795257e2c81a5e9201 --- /dev/null +++ b/src/thememodule/themeitemdelegate.cpp @@ -0,0 +1,140 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "themeitemdelegate.h" +#include "themelistmodel.h" +#include "../common/utils.h" +#include +#include + +ThemeItemDelegate::ThemeItemDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ + +} + +ThemeItemDelegate::~ThemeItemDelegate() +{ +} + +void ThemeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + const QString &themePath = index.data(ThemeListModel::ThemePath).toString(); + const QString &themeName = index.data(ThemeListModel::ThemeName).toString(); + QVariantMap jsonMap = Utils::getThemeMapFromPath(themePath); + const QString &importColor = jsonMap["text-styles"].toMap()["Import"].toMap()["text-color"].toString(); + const QString &stringColor = jsonMap["text-styles"].toMap()["String"].toMap()["text-color"].toString(); + const QString &builtInColor = jsonMap["text-styles"].toMap()["BuiltIn"].toMap()["text-color"].toString(); + const QString &keywordColor = jsonMap["text-styles"].toMap()["Keyword"].toMap()["text-color"].toString(); + const QString &commentColor = jsonMap["text-styles"].toMap()["Comment"].toMap()["text-color"].toString(); + const QString &functionColor = jsonMap["text-styles"].toMap()["Function"].toMap()["text-color"].toString(); + const QString &normalColor = jsonMap["text-styles"].toMap()["Normal"].toMap()["text-color"].toString(); + const QString &otherColor = jsonMap["text-styles"].toMap()["Others"].toMap()["text-color"].toString(); + const QString &backgroundColor = jsonMap["editor-colors"].toMap()["background-color"].toString(); + + const QString &frameNormalColor = index.data(ThemeListModel::FrameNormalColor).toString(); + const QString &frameSelectedColor = index.data(ThemeListModel::FrameSelectedColor).toString(); + + const QRect &rect = option.rect; + + painter->setRenderHint(QPainter::Antialiasing, true); + + QFont font; + font.setPointSize(10); + painter->setFont(font); + + int paddingX = 15; + int paddingY = 8; + + // draw background. + QPainterPath backgroundPath; + backgroundPath.addRoundedRect(QRect(rect.x() + paddingX, + rect.y() + paddingY, + rect.width() - paddingX * 2, + rect.height() - paddingY * 2), + m_frameRadius, m_frameRadius); + + painter->setOpacity(0.8); + painter->fillPath(backgroundPath, QColor(backgroundColor)); + + // draw frame. + QPainterPath framePath; + framePath.addRoundedRect(QRect(rect.x() + paddingX, + rect.y() + paddingY, + rect.width() - paddingX * 2, + rect.height() - paddingY * 2), + m_frameRadius, m_frameRadius); + QPen framePen; + + if (option.state & QStyle::State_Selected) { + painter->setOpacity(1); + framePen = QPen(QColor(frameSelectedColor), 2); + } else { + painter->setOpacity(0.3); + framePen = QPen(QColor(frameNormalColor), 1); + } + + painter->setPen(framePen); + painter->drawPath(framePath); + + // draw syntax highlight. + painter->setOpacity(1); + QFontMetrics fm(font); + int lineHeight = 20; + + int includeX = paddingX + 8; + int includeY = paddingY + 8; + painter->setPen(QPen(QColor(otherColor))); + painter->drawText(QRect(rect.x() + includeX, rect.y() + includeY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "#include"); + + int headerX = includeX + fm.width("#include "); + int headerY = includeY; + painter->setPen(QPen(QColor(importColor))); + painter->drawText(QRect(rect.x() + headerX, rect.y() + headerY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "\"deepin.h\""); + + int keywordX = includeX; + int keywordY = includeY + lineHeight; + painter->setPen(QPen(QColor(keywordColor))); + painter->drawText(QRect(rect.x() + keywordX, rect.y() + keywordY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "QString"); + + int functionX = includeX + fm.width("QString "); + int functionY = includeY + lineHeight; + painter->setPen(QPen(QColor(functionColor))); + painter->drawText(QRect(rect.x() + functionX, rect.y() + functionY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "theme"); + + int functionArgX = includeX + fm.width("QString theme"); + int functionArgY = includeY + lineHeight; + painter->setPen(QPen(QColor(normalColor))); + painter->drawText(QRect(rect.x() + functionArgX, rect.y() + functionArgY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "() {"); + + int commentX = includeX + fm.width("QStr"); + int commentY = includeY + lineHeight * 2; + painter->setPen(QPen(QColor(commentColor))); + painter->drawText(QRect(rect.x() + commentX, rect.y() + commentY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "// Return theme name."); + + int builtInX = includeX + fm.width("QStr"); + int builtInY = includeY + lineHeight * 3; + painter->setPen(QPen(QColor(builtInColor))); + painter->drawText(QRect(rect.x() + builtInX, rect.y() + builtInY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "return"); + + int stringX = includeX + fm.width("QStr") + fm.width("return "); + int stringY = includeY + lineHeight * 3; + painter->setPen(QPen(QColor(stringColor))); + painter->drawText(QRect(rect.x() + stringX, rect.y() + stringY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, QString("\"%1\"").arg(themeName)); + + int semicolonX = includeX + fm.width("QStr") + fm.width("return ") + fm.width(QString("\"%1\"").arg(themeName)); + int semicolonY = includeY + lineHeight * 3; + painter->setPen(QPen(QColor(normalColor))); + painter->drawText(QRect(rect.x() + semicolonX, rect.y() + semicolonY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, ";"); + + int bracketX = includeX; + int bracketY = includeY + lineHeight * 4; + painter->setPen(QPen(QColor(normalColor))); + painter->drawText(QRect(rect.x() + bracketX, rect.y() + bracketY, rect.width(), lineHeight), Qt::AlignLeft | Qt::AlignTop, "}"); +} + +QSize ThemeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(-1, 130); +} diff --git a/src/thememodule/themeitemdelegate.h b/src/thememodule/themeitemdelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..617c0962d42ad30684967917a33ecf91b729cb6f --- /dev/null +++ b/src/thememodule/themeitemdelegate.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef THEMEITEMDELEGATE_H +#define THEMEITEMDELEGATE_H + +#include +#include + +class ThemeItemDelegate : public QAbstractItemDelegate +{ + Q_OBJECT + +public: + ThemeItemDelegate(QObject *parent = nullptr); + ~ThemeItemDelegate(); + +protected: + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + +private: + int m_itemPaddingY = 8; + int m_itemPaddingX = 20; + int m_frameRadius = 5; +}; + +#endif diff --git a/src/thememodule/themelistmodel.cpp b/src/thememodule/themelistmodel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a3dab7a724d75332077fdfd34552163fbe9703f --- /dev/null +++ b/src/thememodule/themelistmodel.cpp @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "themelistmodel.h" +#include "../common/utils.h" +#include +#include +#include +#include +#include + +#ifndef LINGLONG_PREFIX +#define LINGLONG_PREFIX "/usr/" +#endif + +ThemeListModel::ThemeListModel(QObject *parent) + : QAbstractListModel(parent) +{ + initThemes(); +} + +ThemeListModel::~ThemeListModel() +{ +} + +void ThemeListModel::setFrameColor(const QString &selectedColor, const QString &normalColor) +{ + m_frameSelectedColor = selectedColor; + m_frameNormalColor = normalColor; +} + +void ThemeListModel::setSelection(const QString &path) +{ + for (auto pair : m_themes) { + if (path == pair.second) { + const int row = m_themes.indexOf(pair); + const QModelIndex &idx = QAbstractListModel::index(row, 0); + emit requestCurrentIndex(idx); + break; + } + } +} + +int ThemeListModel::rowCount(const QModelIndex &parent) const +{ + return m_themes.size(); +} + +QVariant ThemeListModel::data(const QModelIndex &index, int role) const +{ + const int r = index.row(); + + const QString &name = m_themes.at(r).first; + const QString &path = m_themes.at(r).second; + + switch (role) { + case ThemeName: + return name; + case ThemePath: + return path; + case FrameNormalColor: + return m_frameNormalColor; + case FrameSelectedColor: + return m_frameSelectedColor; + } + + return QVariant(); +} + +void ThemeListModel::initThemes() +{ + QFileInfoList infoList = QDir(QString("%1share/deepin-editor/themes").arg(LINGLONG_PREFIX)).entryInfoList(QDir::Files | QDir::NoDotAndDotDot); + + for (QFileInfo info : infoList) { + QVariantMap jsonMap = Utils::getThemeMapFromPath(info.filePath()); + QPair pair; + pair.first = jsonMap["metadata"].toMap()["name"].toString(); + pair.second = info.filePath(); + + m_themes << pair; + } + + std::sort(m_themes.begin(), m_themes.end(), + [=] (QPair &a, QPair &b) { + QVariantMap firstMap = Utils::getThemeMapFromPath(a.second); + QVariantMap secondMap = Utils::getThemeMapFromPath(b.second); + + const QString &firstColor = firstMap["editor-colors"].toMap()["background-color"].toString(); + const QString &secondColor = secondMap["editor-colors"].toMap()["background-color"].toString(); + + return QColor(firstColor).lightness() < QColor(secondColor).lightness(); + }); +} diff --git a/src/thememodule/themelistmodel.h b/src/thememodule/themelistmodel.h new file mode 100644 index 0000000000000000000000000000000000000000..3e946a5f1aea98f8c807abb9bade975837bebda9 --- /dev/null +++ b/src/thememodule/themelistmodel.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef THEMELISTMODEL_H +#define THEMELISTMODEL_H + +#include + +class ThemeListModel : public QAbstractListModel +{ + Q_OBJECT + +public: + + enum ThemeRole { + ThemeName = Qt::DisplayRole, + ThemePath = Qt::UserRole, + ThemeMap, + FrameNormalColor, + FrameSelectedColor + }; + + ThemeListModel(QObject *parent = nullptr); + ~ThemeListModel(); + + void setFrameColor(const QString &selectedColor, const QString &normalColor); + void setSelection(const QString &path); + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + +signals: + void requestCurrentIndex(const QModelIndex &idx); + +private: + void initThemes(); + +private: + // first is theme name. + // second is theme file path. + QList> m_themes; + + QString m_frameNormalColor; + QString m_frameSelectedColor; +}; + +#endif diff --git a/src/thememodule/themelistview.cpp b/src/thememodule/themelistview.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5dafd5d257619bb515c3bbf007412ee20f105d6 --- /dev/null +++ b/src/thememodule/themelistview.cpp @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "themelistview.h" +#include "themelistmodel.h" +#include +#include +#include + +ThemeListView::ThemeListView(QWidget *parent) + : QListView(parent) +{ + installEventFilter(this); + + setVerticalScrollMode(ScrollPerPixel); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + connect(verticalScrollBar(), &QScrollBar::rangeChanged, this, &ThemeListView::adjustScrollbarMargins); +} + +ThemeListView::~ThemeListView() +{ +} + +void ThemeListView::adjustScrollbarMargins() +{ + if (!isVisible()) { + return; + } + + QEvent event(QEvent::LayoutRequest); + QApplication::sendEvent(this, &event); + + if (!verticalScrollBar()->visibleRegion().isEmpty()) { + setViewportMargins(0, 0,5, 0); + } else { + setViewportMargins(0, 0, 5, 0); + } +} + +bool ThemeListView::eventFilter(QObject *, QEvent *event) +{ + if (event->type() == QEvent::FocusOut) { + emit focusOut(); + } + + return false; +} + +void ThemeListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + QListView::selectionChanged(selected, deselected); + + QModelIndexList list = selectionModel()->selectedIndexes(); + for (const QModelIndex &index : list) { + const QString &themePath = index.data(ThemeListModel::ThemePath).toString(); + + emit themeChanged(themePath); + } +} diff --git a/src/thememodule/themelistview.h b/src/thememodule/themelistview.h new file mode 100644 index 0000000000000000000000000000000000000000..cfee628351ff02c30b390bdbbf3cf014ee00601d --- /dev/null +++ b/src/thememodule/themelistview.h @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef THEMELISTVIEW_H +#define THEMELISTVIEW_H + +#include +#include + +class ThemeListView : public QListView +{ + Q_OBJECT + +public: + ThemeListView(QWidget *parent = nullptr); + ~ThemeListView(); + + void adjustScrollbarMargins(); + +signals: + void themeChanged(const QString &path); + +protected: + bool eventFilter(QObject *, QEvent *event); + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + +signals: + void focusOut(); +}; + +#endif diff --git a/src/thememodule/themepanel.cpp b/src/thememodule/themepanel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1db1ec013431a4062e33fdda511cfdbe2320ac7 --- /dev/null +++ b/src/thememodule/themepanel.cpp @@ -0,0 +1,120 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "themepanel.h" +#include "../widgets/window.h" + +#include +#include +#include +#include +#include + +ThemePanel::ThemePanel(QWidget *parent) + : QWidget(parent), + m_themeView(new ThemeListView), + m_themeModel(new ThemeListModel), + m_window(static_cast(parent)) +{ + // init view. + m_themeView->setModel(m_themeModel); + m_themeView->setItemDelegate(new ThemeItemDelegate(this)); + + QScroller::grabGesture(m_themeView, QScroller::TouchGesture); + + // init layout. + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(m_themeView); + + layout->setMargin(0); + layout->setSpacing(0); + + setFixedWidth(250); + + QWidget::hide(); + connect(m_themeView, &ThemeListView::focusOut, this, &ThemePanel::hide); + connect(m_themeView, &ThemeListView::themeChanged, this, &ThemePanel::themeChanged); + connect(m_themeModel, &ThemeListModel::requestCurrentIndex, this, [=] (const QModelIndex &idx) { + m_themeView->setCurrentIndex(idx); + m_themeView->scrollTo(idx); + }); +} + +ThemePanel::~ThemePanel() +{ +} + +void ThemePanel::paintEvent(QPaintEvent *e) +{ + QPainter painter(this); + + QPainterPath backgroundPath; + backgroundPath.addRect(QRect(rect().x() + 1, rect().y(), rect().width() - 1, rect().height())); + painter.setOpacity(0.9); + painter.fillPath(backgroundPath, m_backgroundColor); + + QPainterPath separatorPath; + separatorPath.addRect(QRect(rect().x(), rect().y(), 1, rect().height())); + painter.setOpacity(0.1); + painter.fillPath(separatorPath, m_frameColor); +} + +void ThemePanel::setBackground(const QString &color) +{ + m_backgroundColor = QColor(color); + + if (m_backgroundColor.lightness() < 128) { + m_frameColor = m_frameDarkColor; + } else { + m_frameColor = m_frameLightColor; + } + + update(); +} + +void ThemePanel::popup() +{ + QWidget::show(); + QWidget::raise(); + + m_themeView->setFocus(); + + QRect rect = geometry(); + QRect windowRect = m_window->geometry(); + QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry"); + animation->setDuration(250); + animation->setEasingCurve(QEasingCurve::OutQuad); + animation->setStartValue(QRect(windowRect.width(), rect.y(), rect.width(), rect.height())); + animation->setEndValue(QRect(windowRect.width() - rect.width(), rect.y(), rect.width(), rect.height())); + animation->start(); + + connect(animation, &QPropertyAnimation::valueChanged, this, [=] { m_themeView->adjustScrollbarMargins(); }); + connect(animation, &QPropertyAnimation::finished, animation, &QPropertyAnimation::deleteLater); +} + +void ThemePanel::hide() +{ + QRect rect = geometry(); + QRect windowRect = m_window->geometry(); + QPropertyAnimation *animation = new QPropertyAnimation(this, "geometry"); + animation->setDuration(250); + animation->setEasingCurve(QEasingCurve::OutQuad); + animation->setStartValue(QRect(windowRect.width() - rect.width(), rect.y(), rect.width(), rect.height())); + animation->setEndValue(QRect(windowRect.width(), rect.y(), rect.width(), rect.height())); + + animation->start(); + + connect(animation, &QPropertyAnimation::finished, this, &QWidget::hide); + connect(animation, &QPropertyAnimation::finished, animation, &QPropertyAnimation::deleteLater); +} + +void ThemePanel::setFrameColor(const QString &selectedColor, const QString &normalColor) +{ + m_themeModel->setFrameColor(selectedColor, normalColor); +} + +void ThemePanel::setSelectionTheme(const QString &path) +{ + m_themeModel->setSelection(path); +} diff --git a/src/thememodule/themepanel.h b/src/thememodule/themepanel.h new file mode 100644 index 0000000000000000000000000000000000000000..63a46d34ee7faab3a0c715afd5b49f6d33cc7e52 --- /dev/null +++ b/src/thememodule/themepanel.h @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef THEMEPANEL_H +#define THEMEPANEL_H + +#include +#include +#include "themelistview.h" +#include "themelistmodel.h" +#include "themeitemdelegate.h" + +class Window; +class ThemePanel : public QWidget +{ + Q_OBJECT + +public: + ThemePanel(QWidget *parent = nullptr); + ~ThemePanel(); + + void setBackground(const QString &color); + void popup(); + void hide(); + + void setFrameColor(const QString &selectedColor, const QString &normalColor); + void setSelectionTheme(const QString &path); + +signals: + void themeChanged(const QString &path); + +protected: + void paintEvent(QPaintEvent *); + +private: + ThemeListView *m_themeView; + ThemeListModel *m_themeModel; + Window *m_window; + + QColor m_frameLightColor = QColor("#000000"); + QColor m_frameDarkColor = QColor("#FFFFFF"); + QColor m_backgroundColor; + QColor m_frameColor; +}; + +#endif diff --git a/src/themes/atom_dark.theme b/src/themes/atom_dark.theme new file mode 100644 index 0000000000000000000000000000000000000000..adefaeb754061db2e178ff1db6711214a6e98f97 --- /dev/null +++ b/src/themes/atom_dark.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Atom Dark", + "author" : "Atom", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#ABB2BF", + "selected-bg-color" : "#3E4451", + "selected-text-color" : "#C2CAD9", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#282C34", + "code-folding" : "#224e65", + "bracket-match-bg" : "#6E9DFF", + "bracket-match-fg" : "#000000", + "current-line" : "#2C313A", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#5D667A", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#683C23", + "find-match-foreground" : "#CCCCCC", + "find-highlight-background" : "#515C6A", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#2d5c76", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#568AF2", + "tab-background-start-color" : "(33, 37, 43, 90%)", + "tab-background-end-color" : "(33, 37, 43, 90%)", + "tab-dnd-start" : "(45, 50, 59, 90%)", + "tab-dnd-end" : "(45, 50, 59, 90%)", + "themebar-frame-selected" : "#568AF2", + "themebar-frame-normal" : "#FFFFFF" + } +} diff --git a/src/themes/deepin.theme b/src/themes/deepin.theme new file mode 100644 index 0000000000000000000000000000000000000000..5111893b94172400feb337ceab52a9814596a425 --- /dev/null +++ b/src/themes/deepin.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Deepin", + "author" : "Deepin", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#1f1c1b", + "selected-bg-color" : "#2CA7F8", + "selected-text-color" : "#FFFFFF", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Function" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Variable" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "ControlFlow" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Operator" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff" + }, + "BuiltIn" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886", + "bold" : true + }, + "Extension" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + }, + "Attribute" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "Char" : { + "text-color" : "#924c9d", + "selected-text-color" : "#6c2477" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#fcfcfc" + }, + "String" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "VerbatimString" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "SpecialString" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "Import" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "DataType" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "DecVal" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "BaseN" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Float" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Constant" : { + "text-color" : "#aa5500", + "selected-text-color" : "#5e2f00" + }, + "Comment" : { + "text-color" : "#898887", + "selected-text-color" : "#5e5d5d" + }, + "Documentation" : { + "text-color" : "#607880", + "selected-text-color" : "#46585e" + }, + "Annotation" : { + "text-color" : "#ca60ca", + "selected-text-color" : "#a44ea4" + }, + "CommentVar" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff" + }, + "RegionMarker" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e", + "background-color" : "#e0e9f8" + }, + "Information" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Warning" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "Alert" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "background-color" : "#f7e6e6", + "bold" : true + }, + "Error" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "underline" : true + }, + "Others" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + } + }, + "editor-colors": { + "background-color" : "#f8f8f8", + "code-folding" : "#94caef", + "bracket-match-bg" : "#ffff00", + "bracket-match-fg" : "#000000", + "current-line" : "#F2F2F2", + "icon-border" : "#f0f0f0", + "indentation-line" : "#d2d2d2", + "line-numbers" : "#000000", + "current-line-number" : "#1e1e1e", + "mark-bookmark" : "#0000ff", + "mark-breakpoint-active" : "#ff0000", + "mark-breakpoint-reached" : "#ffff00", + "mark-breakpoint-disabled" : "#ff00ff", + "mark-execution" : "#a0a0a4", + "mark-warning" : "#00ff00", + "mark-error" : "#ff0000", + "modified-lines" : "#fdbc4b", + "replace-highlight" : "#00ff00", + "saved-lines" : "#2ecc71", + "find-match-background" : "#ffff00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2CA7F8", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#94caef", + "separator" : "#898887", + "spell-checking" : "#bf0303", + "tab-marker" : "#d2d2d2", + "template-background" : "#d6d2d0", + "template-placeholder" : "#baf8ce", + "template-focused-placeholder" : "#76da98", + "template-read-only-placeholder" : "#f6e6e6", + "word-wrap-marker" : "#ededed" + }, + "app-colors" : { + "tab-active" : "#2CA7F8", + "tab-background-start-color" : "(255, 255, 255, 90%)", + "tab-background-end-color" : "(245, 245, 245, 90%)", + "tab-dnd-start" : "(0, 0, 0, 10%)", + "tab-dnd-end" : "(0, 0, 0, 5%)", + "themebar-frame-selected" : "#2CA7F8", + "themebar-frame-normal" : "#000000" + } +} diff --git a/src/themes/deepin_dark.theme b/src/themes/deepin_dark.theme new file mode 100644 index 0000000000000000000000000000000000000000..66a8ffa0de22794f295a3a8a9eadb62cffe96490 --- /dev/null +++ b/src/themes/deepin_dark.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Deepin Dark", + "author" : "Rekols", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#cfcfc2", + "selected-bg-color" : "#2D5C76", + "selected-text-color" : "#FFFFFF", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#252525", + "code-folding" : "#224e65", + "bracket-match-bg" : "#045998", + "bracket-match-fg" : "#FFFFFF", + "current-line" : "#2A2E32", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#ffffff", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#CCCC00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2D5C76", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#2d5c76", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#2CA7F8", + "tab-background-start-color" : "(20, 21, 23, 90%)", + "tab-background-end-color" : "(20, 21, 23, 90%)", + "tab-dnd-start" : "(35, 38, 41, 90%)", + "tab-dnd-end" : "(35, 38, 41, 90%)", + "themebar-frame-selected" : "#2CA7F8", + "themebar-frame-normal" : "#FFFFFF" + } +} diff --git a/src/themes/solarized_dark.theme b/src/themes/solarized_dark.theme new file mode 100644 index 0000000000000000000000000000000000000000..9771fd35f6abba744505541a6ed139a3b185c703 --- /dev/null +++ b/src/themes/solarized_dark.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Solarized Dark", + "author" : "Ethan Schoonover", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#93A1A1", + "selected-bg-color" : "#0B5366", + "selected-text-color" : "#cfcfc2", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#002B36", + "code-folding" : "#224e65", + "bracket-match-bg" : "#586E75", + "bracket-match-fg" : "#AFBFBF", + "current-line" : "#073642", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#7a7c7d", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#ffff00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2CA7F8", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#224659", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#93A1A1", + "tab-background-start-color" : "(0, 37, 46, 90%)", + "tab-background-end-color" : "(0, 37, 46, 90%)", + "tab-dnd-start" : "(7, 54, 66, 90%)", + "tab-dnd-end" : "(10, 77, 94, 90%)", + "themebar-frame-selected" : "#93A1A1", + "themebar-frame-normal" : "#FFFFFF" + } +} diff --git a/src/themes/solarized_light.theme b/src/themes/solarized_light.theme new file mode 100644 index 0000000000000000000000000000000000000000..081c393206da6de31e511a25d3200ca658fc0996 --- /dev/null +++ b/src/themes/solarized_light.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Solarized Light", + "author" : "Ethan Schoonover", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#445257", + "selected-bg-color" : "#586E75", + "selected-text-color" : "#F2F2E2", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Function" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Variable" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "ControlFlow" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Operator" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff" + }, + "BuiltIn" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886", + "bold" : true + }, + "Extension" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + }, + "Attribute" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "Char" : { + "text-color" : "#924c9d", + "selected-text-color" : "#6c2477" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#fcfcfc" + }, + "String" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "VerbatimString" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "SpecialString" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "Import" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "DataType" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "DecVal" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "BaseN" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Float" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Constant" : { + "text-color" : "#aa5500", + "selected-text-color" : "#5e2f00" + }, + "Comment" : { + "text-color" : "#898887", + "selected-text-color" : "#5e5d5d" + }, + "Documentation" : { + "text-color" : "#607880", + "selected-text-color" : "#46585e" + }, + "Annotation" : { + "text-color" : "#ca60ca", + "selected-text-color" : "#a44ea4" + }, + "CommentVar" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff" + }, + "RegionMarker" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e", + "background-color" : "#e0e9f8" + }, + "Information" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Warning" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "Alert" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "background-color" : "#f7e6e6", + "bold" : true + }, + "Error" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "underline" : true + }, + "Others" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + } + }, + "editor-colors": { + "background-color" : "#FDF6E3", + "code-folding" : "#224e65", + "bracket-match-bg" : "#739099", + "bracket-match-fg" : "#F2F2E2", + "current-line" : "#EEE8D5", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#7a7c7d", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#ffff00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2CA7F8", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#224659", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#403513", + "tab-background-start-color" : "(253, 246, 227, 90%)", + "tab-background-end-color" : "(245, 238, 220, 90%)", + "tab-dnd-start" : "(238, 232, 213, 90%)", + "tab-dnd-end" : "(238, 232, 213, 90%)", + "themebar-frame-selected" : "#739099", + "themebar-frame-normal" : "#000000" + } +} diff --git a/src/widgets/ColorSelectWdg.cpp b/src/widgets/ColorSelectWdg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..451499601c76e55bbf45b79eb496f150d38d5f75 --- /dev/null +++ b/src/widgets/ColorSelectWdg.cpp @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ColorSelectWdg.h" +#include "../common/utils.h" +#include "../common/settings.h" +#include +#include +#include + +ColorLabel::ColorLabel(QColor color,QWidget *parent) : DWidget(parent), + m_color(color) +{ + setMouseTracking(true); +} + +void ColorLabel::setColorSelected(bool bSelect) +{ + if(m_bSelected == bSelect) return; + + m_bSelected = bSelect; + + update(); +} + +bool ColorLabel::isSelected() +{ + return m_bSelected; +} + +QColor ColorLabel::getColor() +{ + return m_color; +} + +void ColorLabel::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + int distance = 2; + + QRect r = rect(); + + QPainter painter(this); + painter.setRenderHints(QPainter::Antialiasing |QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting); + + + QPainterPath bigCircle; + bigCircle.addEllipse(r); + + QPainterPath smallCircle; + smallCircle.addEllipse(r.adjusted(2*distance,2*distance,-2*distance,-2*distance)); + + //先画小圆 + painter.fillPath(smallCircle,m_color); + + + //如果点击选择画 圆环 + if(m_bSelected){ + r = rect(); + QPainterPath sencondCircle; + sencondCircle.addEllipse(r.adjusted(distance,distance,-distance,-distance)); + //大圆减小圆等于圆环 + QPainterPath path = bigCircle - sencondCircle; + painter.fillPath(path,m_color); + } + + painter.end(); +} + +void ColorLabel::mousePressEvent(QMouseEvent *e) +{ + //没有选择点击有效 + if(e->button() == Qt::LeftButton){ + m_bSelected = true; + update(); + emit sigColorClicked(m_bSelected,m_color); + } +} + +ColorSelectWdg::ColorSelectWdg(QString text,QWidget *parent):DWidget (parent),m_text(text) +{ + setFocusPolicy(Qt::NoFocus); + setMouseTracking(true); + if(!text.isEmpty())setFixedHeight(60); + else setFixedHeight(35); + initWidget(); +} + +ColorSelectWdg::~ColorSelectWdg() +{ + if (m_pHLayout2 != nullptr) { + delete m_pHLayout2; + m_pHLayout2=nullptr; + } + + if (m_pHLayout1 != nullptr) { + delete m_pHLayout1; + m_pHLayout1=nullptr; + } + + if (m_pMainLayout != nullptr) { + delete m_pMainLayout; + m_pMainLayout=nullptr; + } +} + +void ColorSelectWdg::initWidget() +{ + if(m_text.isEmpty()){ + m_pHLayout2 = new QHBoxLayout(this); + } + else { + m_pMainLayout = new QVBoxLayout(this); + m_pHLayout2 = new QHBoxLayout; + } + + if(!m_text.isEmpty()){ + m_pButton = new DPushButton(m_text,this); + m_pButton->setMinimumSize(80,25); + m_pButton->setFlat(true); + connect(m_pButton,&QPushButton::clicked,this,[this](){ + //发送选择信号 + emit this->sigColorSelected(true,m_defaultColor); + }); + } + + QList colors = Utils::getHiglightColorList(); + for (int i = 0;isetFixedSize(m_labelWidth,m_labelHeight); + + //第一个设置默认标记颜色 + if(i == 0){ + m_defaultColor = colors[i]; + colorlabel->setColorSelected(true); + } + + m_pHLayout2->addWidget(colorlabel); + m_colorLabels.append(colorlabel); + + connect(colorlabel,&ColorLabel::sigColorClicked,this,[this,colorlabel](bool bSelect,QColor color){ + if(bSelect){ + foreach(ColorLabel* pLabel,m_colorLabels){ + //如果选择 设置其他颜色label为未选中状态 + if(pLabel != colorlabel && pLabel->isSelected()) pLabel->setColorSelected(false); + } + m_defaultColor = color; + //发送选择信号 + emit this->sigColorSelected(bSelect,color); + } + }); + } + + if(!m_text.isEmpty()){ + m_pHLayout1 = new QHBoxLayout; + m_pHLayout1->addWidget(m_pButton); + m_pHLayout1->addSpacerItem(new QSpacerItem(100,25,QSizePolicy::Expanding,QSizePolicy::Preferred)); + + m_pHLayout1->setContentsMargins(20,1,0,0); + m_pHLayout2->setContentsMargins(5,2,5,2); + + m_pMainLayout->addLayout(m_pHLayout1); + m_pMainLayout->addLayout(m_pHLayout2); + m_pMainLayout->setContentsMargins(0,0,0,0); + //this->setLayout(m_pMainLayout); + }else { + m_pHLayout2->setContentsMargins(8+m_labelWidth,0,8+m_labelWidth,0); + //this->setLayout(m_pHLayout2); + } +} + + +void ColorSelectWdg::setTheme(const QString &theme) +{ + //获取主题颜色 + if(theme == "light") { + m_textColor = "#1f1c1b"; + }else if(theme == "dark"){ + m_textColor = "#cfcfc2"; + } +} + +QColor ColorSelectWdg::getDefaultColor() +{ + return m_defaultColor; +} + +bool ColorSelectWdg::eventFilter(QObject *object, QEvent *event) +{ + if(object == m_pLabel){ + if(event->type() == QEvent::MouseButtonPress){ + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton){ + //发送选择信号 + emit this->sigColorSelected(true,m_defaultColor); + return true; + } + } + return false; + } + + return DWidget::eventFilter(object,event); +} diff --git a/src/widgets/ColorSelectWdg.h b/src/widgets/ColorSelectWdg.h new file mode 100644 index 0000000000000000000000000000000000000000..312f7fc33a94bf4298ee379bd40becee9ac94cea --- /dev/null +++ b/src/widgets/ColorSelectWdg.h @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef COLORSELECTWDG_H +#define COLORSELECTWDG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Dtk::Widget; + +//单个颜色显示控件 +/* + *  编辑区域右键菜单 标记颜色action添加显示标记颜色控件 梁卫东 2020-08-13 09:40:49 + * + * ColorLabel 颜色显示控件 +*/ +class ColorLabel : public DWidget +{ + Q_OBJECT +public: + explicit ColorLabel(QColor color,QWidget *parent = nullptr); + + void setColorSelected(bool bSelect); + bool isSelected(); + QColor getColor(); +signals: + void sigColorClicked(bool bSelect,QColor color); +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *e); +private: + //颜色选择标记 + + bool m_bSelected = false; + QColor m_color; +}; + +/* +* 编辑区域右键菜单 标记颜色action添加显示标记颜色控件 梁卫东 2020-08-13 09:40:49 +* +* ColorSelectWdg 颜色选择控件 +*/ +//自定义ColorSelectWdg +class ColorSelectWdg: public DWidget +{ + Q_OBJECT +public: + explicit ColorSelectWdg(QString text,QWidget *parent = nullptr); + ~ColorSelectWdg(); + + void setTheme(const QString &theme); + QColor getDefaultColor(); + +signals: + void sigColorSelected(bool bSelect,QColor color); + +private: + void initWidget(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + QPointer m_pMainLayout {nullptr}; + QPointer m_pHLayout1 {nullptr}; + QPointer m_pHLayout2 {nullptr}; + QList m_colorLabels; + int m_labelWidth = 23; + int m_labelHeight = 23; + DPushButton* m_pButton = nullptr; + DLabel* m_pLabel = nullptr; + QString m_text; + QColor m_defaultColor; + QString m_textColor; +}; + + +#endif // COLORSELECTWDG_H diff --git a/src/widgets/bottombar.cpp b/src/widgets/bottombar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a52d8d7ca02e99bef76403402a6c17f2d3bde60 --- /dev/null +++ b/src/widgets/bottombar.cpp @@ -0,0 +1,388 @@ +// SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include +#include +#include +#include +#include "bottombar.h" +#include "../common/utils.h" +#include "../editor/editwrapper.h" +#include "../widgets/window.h" +#include "../editor/replaceallcommond.h" + +BottomBar::BottomBar(QWidget *parent) + : QWidget(parent), + m_pWrapper(static_cast(parent)), + m_pPositionLabel(new DLabel), + m_pCharCountLabel(new DLabel), + m_pCursorStatus(new DLabel), + m_pEncodeMenu(DDropdownMenu::createEncodeMenu()), + m_pHighlightMenu(DDropdownMenu::createHighLightMenu()), + m_rowStr(tr("Row")), + m_columnStr(tr("Column")), + m_chrCountStr(tr("Characters %1")), + m_scaleLabel(new DLabel), + m_progressLabel(new DLabel), + m_progressBar(new DProgressBar) +{ + QFont font; + m_pPositionLabel->setFont(font); + m_pCharCountLabel->setFont(font); + m_pCursorStatus->setFont(font); + m_scaleLabel->setFont(font); + m_progressLabel->setFont(font); + m_progressLabel->setText(tr("Loading:")); + m_progressBar->setRange(0,100); + m_progressBar->setTextVisible(false); + m_progressBar->setMinimumWidth(80); + QHBoxLayout* progressLayout = new QHBoxLayout; + progressLayout->addWidget(m_progressLabel); + progressLayout->addWidget(m_progressBar); + // progressLayout->addStretch(); + + DFontSizeManager::instance()->bind(m_pPositionLabel, DFontSizeManager::T9); + DFontSizeManager::instance()->bind(m_pCharCountLabel, DFontSizeManager::T9); + DFontSizeManager::instance()->bind(m_pCursorStatus, DFontSizeManager::T9); + DFontSizeManager::instance()->bind(m_scaleLabel, DFontSizeManager::T9); + DFontSizeManager::instance()->bind(m_progressLabel, DFontSizeManager::T9); + + initFormatMenu(); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(29, 1, 10, 0); + layout->addLayout(progressLayout); + // layout->addStretch(); + layout->addWidget(m_pPositionLabel); + layout->addStretch(); + layout->addSpacerItem(new QSpacerItem(110,20,QSizePolicy::Expanding,QSizePolicy::Fixed)); + layout->addWidget(m_pCharCountLabel); + + m_progressBar->hide(); + m_progressLabel->hide(); + + m_pCursorStatus->setText(qApp->translate("EditWrapper", "INSERT")); + m_pPositionLabel->setText(QString("%1 %2 %3 %4").arg(m_rowStr, "1",m_columnStr, "1")); + + m_pCharCountLabel->setText(m_chrCountStr.arg("0")); + m_pHighlightMenu->setCurrentTextOnly(qApp->translate("TextEdit", "None")); + m_pEncodeMenu->setCurrentTextOnly(QString("UTF-8")); + + DVerticalLine *pVerticalLine1 = new DVerticalLine(); + DVerticalLine *pVerticalLine2 = new DVerticalLine(); + pVerticalLine1->setFixedSize(1, 15); + pVerticalLine2->setFixedSize(1, 15); + DVerticalLine *pVerticalLine3 = new DVerticalLine(); + pVerticalLine3->setFixedSize(1, 15); + + layout->addStretch(); + layout->addWidget(m_scaleLabel); + layout->addStretch(); + layout->addWidget(m_pCursorStatus); + layout->addSpacing(10); + layout->addWidget(pVerticalLine1); + layout->addWidget(m_pEncodeMenu); + layout->addWidget(pVerticalLine2); + layout->addWidget(m_formatMenu); + layout->addWidget(pVerticalLine3); + layout->addWidget(m_pHighlightMenu); + setFixedHeight(32); + + //切换编码 + connect(m_pEncodeMenu, &DDropdownMenu::currentActionChanged, this,[this](QAction* pAct){ + // 保持界面统一 + QString previousText = m_pEncodeMenu->getCurrentText(); + + // 处于文件加载状态或转换失败则恢复默认编码格式 + if (m_pWrapper->getFileLoading() || !m_pWrapper->reloadFileEncode(pAct->text().toLocal8Bit())) { + m_pEncodeMenu->setCurrentTextOnly(previousText); + } else { + // 存储完成后更新底栏显示文本,重载时可能需要保存旧文本 + m_pEncodeMenu->setCurrentTextOnly(pAct->text()); + } + }); + + //切换文件类型 + connect(m_pHighlightMenu, &DDropdownMenu::currentActionChanged, this,[this](QAction* pAct) { + m_pHighlightMenu->setCurrentTextOnly(pAct->text()); + + // 更新使用格式高亮类型 + m_pWrapper->reloadFileHighlight(pAct->text()); + }); + + //编码按钮/文本类型按钮失去焦点后,设置光标回到文本框里 + connect(m_pEncodeMenu, &DDropdownMenu::sigSetTextEditFocus, this, &BottomBar::slotSetTextEditFocus); + connect(m_pHighlightMenu, &DDropdownMenu::sigSetTextEditFocus, this, &BottomBar::slotSetTextEditFocus); + connect(m_formatMenu,&DDropdownMenu::sigSetTextEditFocus, this, &BottomBar::slotSetTextEditFocus); +} + +BottomBar::~BottomBar() +{ + if (m_pEncodeMenu != nullptr) { + delete m_pEncodeMenu; + m_pEncodeMenu = nullptr; + } + + if (m_pHighlightMenu != nullptr) { + delete m_pHighlightMenu; + m_pHighlightMenu = nullptr; + } +} + +void BottomBar::updatePosition(int row, int column) +{ + m_pPositionLabel->setText(QString("%1 %2 %3 %4").arg(m_rowStr, QString::number(row), + m_columnStr, QString::number(column))); +} + +void BottomBar::updateWordCount(int charactorCount) +{ + m_pCharCountLabel->setText(m_chrCountStr.arg(QString::number(charactorCount-1))); +} + +void BottomBar::setEncodeName(const QString &name) +{ + m_pEncodeMenu->setCurrentTextOnly(name); +} + +void BottomBar::setCursorStatus(const QString &text) +{ + m_pCursorStatus->setText(text); +} + +void BottomBar::setPalette(const QPalette &palette) +{ + DPalette paPositionLabel = DApplicationHelper::instance()->applicationPalette(); + DPalette paCharCountLabel = DApplicationHelper::instance()->applicationPalette(); + DPalette paCursorStatus = DApplicationHelper::instance()->applicationPalette(); + DPalette paEncodeMenu = DApplicationHelper::instance()->applicationPalette(); + DPalette paHighlightMenu = DApplicationHelper::instance()->applicationPalette(); + + QColor colorFont = paPositionLabel.textTips().color(); + + paPositionLabel.setColor(DPalette::WindowText, colorFont); + paCharCountLabel.setColor(DPalette::WindowText, colorFont); + paCursorStatus.setColor(DPalette::WindowText, colorFont); + paEncodeMenu.setColor(DPalette::WindowText, colorFont); + paHighlightMenu.setColor(DPalette::WindowText, colorFont); + + + m_pPositionLabel->setPalette(paPositionLabel); + m_pCharCountLabel->setPalette(paCharCountLabel); + m_pCursorStatus->setPalette(paCursorStatus); + m_pEncodeMenu->getButton()->setPalette(paEncodeMenu); + m_pHighlightMenu->getButton()->setPalette(paHighlightMenu); + m_scaleLabel->setPalette(paPositionLabel); + m_formatMenu->getButton()->setPalette(paEncodeMenu); + + QString theme = (palette.color(QPalette::Background).lightness() < 128) ? "dark" : "light"; + m_pEncodeMenu->setTheme(theme); + m_pHighlightMenu->setTheme(theme); + m_formatMenu->setTheme(theme); + + QWidget::setPalette(palette); +} + +void BottomBar::updateSize(int size, bool bIsFindOrReplace) +{ + setFixedHeight(size); + m_bIsFindOrReplace = bIsFindOrReplace; +} + +void BottomBar::setChildEnabled(bool enabled) +{ + m_pEncodeMenu->setEnabled(enabled); + m_pHighlightMenu->setEnabled(enabled); + m_pEncodeMenu->setRequestMenu(enabled); + m_pHighlightMenu->setRequestMenu(enabled); + m_formatMenu->setEnabled(enabled); +} + +void BottomBar::setChildrenFocus(bool ok,QWidget* preOrderWidget) +{ + m_pEncodeMenu->setChildrenFocus(ok); + m_pHighlightMenu->setChildrenFocus(ok); + m_formatMenu->setChildrenFocus(ok); + if(ok) { + if(preOrderWidget) setTabOrder(preOrderWidget,m_pEncodeMenu->getButton()); + + setTabOrder(m_pEncodeMenu->getButton(),m_formatMenu->getButton()); + setTabOrder(m_formatMenu->getButton(),m_pHighlightMenu->getButton()); + } +} + +void BottomBar::setScaleLabelText(qreal fontSize) +{ + int maxFont = 50; + int minFont = 8; + int midFont = 12; + QString text; + if (qFuzzyCompare(fontSize, midFont)) { + text = "100%"; + } + else if(fontSize > midFont){ + float delta = (500-100)*1.0/(maxFont - midFont); + int target = 100 + qRound(delta * (fontSize-midFont)); + text = QString("%1%").arg(target); + } + else { + float delta = (100-10)*1.0/(midFont - minFont); + int target = 100 + qRound(delta * (fontSize-midFont)); + target = std::max(10,target); + text = QString("%1%").arg(target); + } + + m_scaleLabel->setText(text); +} + +void BottomBar::setProgress(int progress) +{ + if(progress<0){ + return; + } + m_progressBar->show(); + m_progressLabel->show(); + m_progressBar->setValue(progress); + if(progress >= 100){ + m_progressBar->hide(); + m_progressLabel->hide(); + } +} + +DDropdownMenu *BottomBar::getEncodeMenu() +{ + return m_pEncodeMenu; +} + +DDropdownMenu *BottomBar::getHighlightMenu() +{ + return m_pHighlightMenu; +} + +void BottomBar::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setOpacity(1); + + QColor backgroundColor = palette().color(QPalette::Background); + QColor bottombarBackgroundColor; + if (backgroundColor.lightness() < 128) { + bottombarBackgroundColor = palette().base().color(); + if (bottombarBackgroundColor.name() != "#202020") { + bottombarBackgroundColor = QColor("#202020"); + } + bottombarBackgroundColor.setAlphaF(0.7); + + } else { + bottombarBackgroundColor = palette().base().color(); + if (bottombarBackgroundColor.name() != "#ffffff") { + bottombarBackgroundColor = QColor("#ffffff"); + } + + bottombarBackgroundColor.setAlphaF(0.7); + } + + QPainterPath path; + path.addRect(rect()); + painter.fillPath(path, bottombarBackgroundColor); + + QColor splitLineColor; + if (backgroundColor.lightness() < 128) { + splitLineColor = palette().brightText().color(); + if (splitLineColor.name() != "#ffffff") { + splitLineColor = QColor("#ffffff"); + } + splitLineColor.setAlphaF(0.5); + } else { + splitLineColor = palette().brightText().color(); + if (splitLineColor.name() != "#000000") { + splitLineColor = QColor("#000000"); + } + splitLineColor.setAlphaF(0.5); + } + + if (!m_bIsFindOrReplace) { + QPainterPath framePath; + framePath.addRect(QRect(rect().x(), rect().y(), rect().width(), 1)); + painter.setOpacity(0.1); + painter.fillPath(framePath, splitLineColor); + } +} + +void BottomBar::slotSetTextEditFocus() +{ + Window *pWindow = static_cast(m_pWrapper->window()); + emit pWindow->pressEsc(); +} + +BottomBar::EndlineFormat BottomBar::getEndlineFormat(const QByteArray& text) +{ + for(int i=0;isetExclusive(true); + m_formatMenu->setMenuActionGroup(actionGroup); + + m_unixAction = menu->addAction("Unix"); + m_windowsAction = menu->addAction("Windows"); + m_unixAction->setProperty(FormatActionType,EndlineFormat::Unix); + m_windowsAction->setProperty(FormatActionType,EndlineFormat::Windows); + actionGroup->addAction(m_unixAction); + actionGroup->addAction(m_windowsAction); + connect(actionGroup, &QActionGroup::triggered, this,&BottomBar::onFormatMenuTrigged); + + m_formatMenu->setMenu(menu); + m_formatMenu->setCurrentTextOnly("Unix"); +} + +//行尾格式action槽函数 +void BottomBar::onFormatMenuTrigged(QAction* action) +{ + if(!action){ + return; + } + int type = action->property(FormatActionType).toInt(); + if(m_endlineFormat == type){ + return; + } + + m_pWrapper->textEditor()->onEndlineFormatChanged(m_endlineFormat,(EndlineFormat)type); + m_endlineFormat = (EndlineFormat)type; + +} + +//设置行尾menu text +void BottomBar::setEndlineMenuText(EndlineFormat format) +{ + if(format == EndlineFormat::Unix || format == EndlineFormat::Unknow){ + m_formatMenu->setCurrentTextOnly("Unix"); + m_endlineFormat = EndlineFormat::Unix; + + } + else { + m_formatMenu->setCurrentTextOnly("Windows"); + m_endlineFormat = EndlineFormat::Windows; + } +} diff --git a/src/widgets/bottombar.h b/src/widgets/bottombar.h new file mode 100644 index 0000000000000000000000000000000000000000..399485afda3a03bbcfb2f96d77d0f7c5c4ffce98 --- /dev/null +++ b/src/widgets/bottombar.h @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef BOTTOMBAR_H +#define BOTTOMBAR_H + +#include +#include +#include +#include "ddropdownmenu.h" +#include +#include +#include +#include + +#define FormatActionType "format-action-type" + +class EditWrapper; +class BottomBar : public QWidget +{ + Q_OBJECT + +public: + enum EndlineFormat{ + Unknow = -1, + Unix, + Windows + }; + +public: + explicit BottomBar(QWidget *parent = nullptr); + ~BottomBar(); + + void updatePosition(int row, int column); + void updateWordCount(int charactorCount); + void setEncodeName(const QString &name); + void setCursorStatus(const QString &text); + void setPalette(const QPalette &palette); + void updateSize(int size, bool bIsFindOrReplace); + void setChildEnabled(bool enabled); + //设置所有焦点 梁卫东 2020-09-14 10:55:22 + void setChildrenFocus(bool ok,QWidget* preOrderWidget = nullptr); + void setScaleLabelText(qreal fontSize); + void setProgress(int progress); + + DDropdownMenu* getEncodeMenu(); + DDropdownMenu* getHighlightMenu(); + static EndlineFormat getEndlineFormat(const QByteArray& text); + EndlineFormat getEndlineFormat(); + void setEndlineMenuText(EndlineFormat format); + +protected: + void paintEvent(QPaintEvent *); + +private: + void initFormatMenu(); +private slots: + void onFormatMenuTrigged(QAction* action); + +private: + EditWrapper *m_pWrapper {nullptr}; + DLabel *m_pPositionLabel {nullptr}; + DLabel *m_pCharCountLabel {nullptr}; + DLabel *m_pCursorStatus {nullptr}; + DDropdownMenu *m_pEncodeMenu {nullptr}; + DDropdownMenu *m_pHighlightMenu {nullptr}; + QString m_rowStr {QString()}; + QString m_columnStr {QString()}; + QString m_chrCountStr {QString()}; + bool m_bIsFindOrReplace {false}; + DLabel* m_scaleLabel = nullptr; + DLabel* m_progressLabel = nullptr; + DProgressBar* m_progressBar = nullptr; + DDropdownMenu *m_formatMenu = nullptr; + EndlineFormat m_endlineFormat = EndlineFormat::Unix; + QAction* m_unixAction = nullptr; + QAction* m_windowsAction = nullptr; + + +public slots: + //编码按钮/文本类型按钮失去焦点后,设置光标回到文本框里 + void slotSetTextEditFocus(); +}; + +#endif diff --git a/src/widgets/ddropdownmenu.cpp b/src/widgets/ddropdownmenu.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1e12abe981f65321d737186de23ccbafc5fa5109 --- /dev/null +++ b/src/widgets/ddropdownmenu.cpp @@ -0,0 +1,497 @@ +// SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../common/utils.h" +#include "../common/settings.h" +#include "ddropdownmenu.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Dtk::Core; + +DDropdownMenu::DDropdownMenu(QWidget *parent) + : QFrame(parent) + , m_pToolButton(new DToolButton(this)) + , m_menu(new DMenu) +{ + //设置toobutton属性 + m_pToolButton->setFocusPolicy(Qt::StrongFocus); + m_pToolButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + m_pToolButton->setArrowType(Qt::NoArrow); + m_pToolButton->setFixedHeight(28); + m_pToolButton->installEventFilter(this); + //this->installEventFilter(this); + //设置图标 + QString theme = (DGuiApplicationHelper::instance()->applicationPalette().color(QPalette::Background).lightness() < 128) ? "dark" : "light"; + QString arrowSvgPath = QString(":/images/dropdown_arrow_%1.svg").arg(theme); + //装换图片 + int scaled =qApp->devicePixelRatio() == 1.25 ? 2 : 1; + QSvgRenderer svg_render(arrowSvgPath); + QPixmap pixmap(QSize(8,5)*scaled); + pixmap.fill(Qt::transparent); + pixmap.setDevicePixelRatio(scaled); + QPainter painter(&pixmap); + svg_render.render(&painter,QRect(0,0,8,5)); + m_arrowPixmap = pixmap; + m_pToolButton->setIcon(createIcon()); + + //设置字体 + int fontsize =DFontSizeManager::instance()->fontPixelSize(DFontSizeManager::T9); + m_font.setPixelSize(fontsize); + + //添加布局 + QHBoxLayout *layout = new QHBoxLayout(); + layout->addWidget(m_pToolButton); + layout->setContentsMargins(0,0,0,0); + this->setLayout(layout); + + connect(this, &DDropdownMenu::requestContextMenu, this, &DDropdownMenu::slotRequestMenu); + + //设置字体自适应大小 + //设置界面大小根据内容大小自适应 梁卫东 2020.7.7 + connect(qApp,&DApplication::fontChanged,this,&DDropdownMenu::OnFontChangedSlot); +} + +DDropdownMenu::~DDropdownMenu() +{ + deleteMenuActionGroup(); + deleteMenu(); +} + +void DDropdownMenu::setFontEx(const QFont& font) +{ + m_pToolButton->setFont(font); + m_font = font; +} + +void DDropdownMenu::setCurrentAction(QAction *pAct) +{ + if(pAct){ + QList menuList = m_menu->actions(); + pAct->setChecked(true); + for (int i = 0; i < menuList.size(); i++) { + QList acts = menuList[i]->menu()->actions(); + for (int j = 0; j < acts.size(); j++) { + if(acts[j] != pAct) acts[j]->setChecked(false); + } + } + setText(pAct->text()); + } +} + +void DDropdownMenu::setCurrentTextOnly(const QString &name) +{ + // QList menuList = m_menu->actions(); + +// for (int i = 0; i < menuList.size(); i++) { +// if(menuList[i]->menu()){ +// QList acts = menuList[i]->menu()->actions(); +// if(acts.size() == 0) continue; +// for (int j = 0; j < acts.size(); j++) { +// if(acts[j]->text() != name){ +// acts[j]->setCheckable(false); +// acts[j]->setChecked(false); +// } +// else{ +// acts[j]->setCheckable(true); +// acts[j]->setChecked(true); +// } +// } +// } +// } + for(auto ac:m_menu->actions()){ + setCheckedExclusive(ac,name); + } + + setText(name); +} + + +void DDropdownMenu::setCheckedExclusive(QAction* action,const QString& name) +{ + if(nullptr == action){ + return; + } + + if(action->menu()){ + for(auto ac:action->menu()->actions()){ + setCheckedExclusive(ac,name); + } + } + else { + if(action->text() != name){ + action->setCheckable(false); + action->setChecked(false); + } + else{ + action->setCheckable(true); + action->setChecked(true); + } + } +} + +void DDropdownMenu::slotRequestMenu(bool request) +{ + if (request) { + //如果鼠标点击清除focus + m_pToolButton->clearFocus(); + } + QPoint center = this->mapToGlobal(this->rect().center()); + int menuHeight = m_menu->sizeHint().height(); + int menuWidth = m_menu->sizeHint().width(); + center.setY(center.y() - menuHeight - this->rect().height() / 2); + center.setX(center.x() - menuWidth / 2); + m_menu->move(center); + m_menu->exec(); + //清除focus + m_pToolButton->clearFocus(); + QEvent event(QEvent::HoverLeave); + QApplication::sendEvent(m_pToolButton, &event); + emit sigSetTextEditFocus(); +} + +void DDropdownMenu::setText(const QString &text) +{ + m_text = text; + //重新绘制icon 设置宽度 + m_pToolButton->setIcon(createIcon()); +} + +void DDropdownMenu::setMenu(DMenu *menu) +{ + deleteMenu(); + m_menu = menu; +} + +void DDropdownMenu::deleteMenu() +{ + if (m_menu != nullptr) { + delete m_menu; + m_menu = nullptr; + } +} + +void DDropdownMenu::setMenuActionGroup(QActionGroup *actionGroup) +{ + deleteMenuActionGroup(); + m_actionGroup = actionGroup; +} + +void DDropdownMenu::deleteMenuActionGroup() +{ + if (m_actionGroup != nullptr) { + delete m_actionGroup; + m_actionGroup = nullptr; + } +} + +void DDropdownMenu::setTheme(const QString &theme) +{ + QString arrowSvgPath = QString(":/images/dropdown_arrow_%1.svg").arg(theme); + //装换图片 + int scaled =qApp->devicePixelRatio() == 1.25 ? 2 : 1; + QSvgRenderer svg_render(arrowSvgPath); + + QPixmap pixmap(QSize(8,5)*scaled); + pixmap.fill(Qt::transparent); + pixmap.setDevicePixelRatio(scaled); + + QPainter painter(&pixmap); + svg_render.render(&painter,QRect(0,0,8,5)); + + m_arrowPixmap = pixmap; + m_pToolButton->setIcon(createIcon()); +} + +void DDropdownMenu::setChildrenFocus(bool ok) +{ + if(ok) m_pToolButton->setFocusPolicy(Qt::StrongFocus); + else { + m_pToolButton->clearFocus(); + m_pToolButton->setFocusPolicy(Qt::NoFocus); + } +} + +void DDropdownMenu::setRequestMenu(bool request) +{ + isRequest = request; +} + +DToolButton *DDropdownMenu::getButton() +{ + return m_pToolButton; +} + +QString DDropdownMenu::getCurrentText() const +{ + return m_text; +} + +DDropdownMenu *DDropdownMenu::createEncodeMenu() +{ + DDropdownMenu *m_pEncodeMenu = new DDropdownMenu(); + DMenu* m_pMenu = new DMenu(); + + auto groupEncodeVec = Utils::getSupportEncoding(); + if (!groupEncodeVec.isEmpty()) { + int cnt = groupEncodeVec.size(); + for (int i = 0; i < cnt;i++) { + QMenu* groupMenu = new QMenu(QObject::tr(groupEncodeVec[i].first.toLocal8Bit().data())); + foreach(QString var, groupEncodeVec[i].second) + { + QAction *act= groupMenu->addAction(QObject::tr(var.toLocal8Bit().data())); + if(act->text() == "UTF-8") { + m_pEncodeMenu->m_pActUtf8 = act; + act->setCheckable(true); + act->setChecked(true); + }else { + act->setCheckable(false); + } + } + + m_pMenu->addMenu(groupMenu); + } + } + + connect(m_pMenu, &DMenu::triggered, m_pEncodeMenu,[m_pEncodeMenu](QAction *action) { + //编码内容改变触发内容改变和信号发射 梁卫东 2020.7.7 + if (m_pEncodeMenu->m_text != action->text()) { + emit m_pEncodeMenu->currentActionChanged(action); + } + }); + + m_pEncodeMenu->setText("UTF-8"); + m_pEncodeMenu->setMenu(m_pMenu); + + return m_pEncodeMenu; +} + +DDropdownMenu *DDropdownMenu::createHighLightMenu() +{ + DDropdownMenu *m_pHighLightMenu = new DDropdownMenu(); + DMenu *m_pMenu = new DMenu; + QAction *noHlAction = m_pMenu->addAction(tr("None")); + noHlAction->setCheckable(true); + + QActionGroup* m_pActionGroup = new QActionGroup(m_pMenu); + m_pActionGroup->setExclusive(true); + m_pActionGroup->addAction(noHlAction); + + DMenu *pSubMenu = nullptr; + QString currentGroup; + + bool intel = true; + for (KSyntaxHighlighting::Definition def : m_pHighLightMenu->m_Repository.definitions()) { + + if(def.translatedName()=="Intel x86 (NASM)"&&intel) + { + intel = false; + continue; + } + if (def.isHidden()) { + continue; + } + + if (currentGroup != def.section()) { + currentGroup = def.section(); + pSubMenu = m_pMenu->addMenu(def.translatedSection()); + } + + if (!pSubMenu) { + continue; + } + + QAction* action = pSubMenu->addAction(def.translatedName()); + action->setCheckable(true); + action->setText(def.name()); + m_pActionGroup->addAction(action); + } + + // 转发选中“None“无高亮选项的信号 + connect(noHlAction, &QAction::triggered, m_pHighLightMenu, [noHlAction, m_pHighLightMenu] (bool checked) { + if (checked) { + emit m_pHighLightMenu->currentActionChanged(noHlAction); + } + }); + + connect(m_pActionGroup, &QActionGroup::triggered, m_pHighLightMenu, [m_pHighLightMenu] (QAction *action) { + const auto defName = action->text(); + const auto def = m_pHighLightMenu->m_Repository.definitionForName(defName); + if (def.isValid() && m_pHighLightMenu->m_text != action->text()) { + emit m_pHighLightMenu->currentActionChanged(action); + } + else { + m_pHighLightMenu->setText(tr("None")); + } + + }); + + m_pHighLightMenu->setText(tr("None")); + m_pHighLightMenu->setMenu(m_pMenu); + m_pHighLightMenu->setMenuActionGroup(m_pActionGroup); + + return m_pHighLightMenu; +} + +QIcon DDropdownMenu::createIcon() +{ + + DPalette dpalette = DApplicationHelper::instance()->palette(m_pToolButton); + QColor textColor; + + QPixmap arrowPixmap; + + if(m_bPressed){ + textColor = dpalette.color(DPalette::Highlight); + QString color = textColor.name(QColor::HexRgb); + arrowPixmap = setSvgColor(color); + }else { + textColor = dpalette.color(DPalette::WindowText); + arrowPixmap = m_arrowPixmap; + } + + // 根据字体大小设置icon大小,按计算的字体高度,而非从字体文件中读取的高度(部分字体中英文高度不同) + QFontMetrics metrics(m_font); + int fontWidth = metrics.width(m_text) + 20; + int fontHeight = metrics.size(Qt::TextSingleLine, m_text).height(); + int iconW = 8; + int iconH = 5; + + int totalWidth = fontWidth + iconW + 20; + int totalHeigth = 28; + m_pToolButton->setFixedSize(totalWidth,totalHeigth); + m_pToolButton->setIconSize(QSize(totalWidth,totalHeigth)); + + qreal rate = this->devicePixelRatioF(); + QPixmap icon(QSize(totalWidth,totalHeigth)*rate); + icon.setDevicePixelRatio(rate); + icon.fill(Qt::transparent); + + QPainter painter(&icon); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHints(QPainter::SmoothPixmapTransform); + + painter.save(); + painter.setFont(m_font); + painter.setPen(textColor); + painter.drawText(QRectF(10,(totalHeigth-fontHeight)/2,fontWidth,fontHeight),m_text); + painter.restore(); + + //arrowPixmap=arrowPixmap.scaled(iconW,iconH,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); + + //qDebug()<<"==================="<fontPixelSize(DFontSizeManager::T8); + m_font.setPixelSize(fontsize); + m_pToolButton->setIcon(createIcon()); +} + + +bool DDropdownMenu::eventFilter(QObject *object, QEvent *event) +{ + if(object == m_pToolButton){ + if(event->type() == QEvent::KeyPress){ + QKeyEvent *keyEvent = static_cast(event); + //QString key = Utils::getKeyshortcut(keyEvent); + if(keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Space) //按下enter展开列表 + { + //if(isRequest){ + Q_EMIT requestContextMenu(false); + //} + return true; + } + return false; + } + + if(event->type() == QEvent::MouseButtonPress){ + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton){ + m_bPressed = true; + //if (isRequest) { + //重新绘制icon 点击改变前景色 + m_pToolButton->setIcon(createIcon()); + //} + return true; + } + + if(mouseEvent->button() == Qt::RightButton){ + return true; + } + } + + if(event->type() == QEvent::MouseButtonRelease){ + QMouseEvent *mouseEvent = static_cast(event); + if(mouseEvent->button() == Qt::LeftButton){ + m_bPressed = false; + m_pToolButton->setIcon(createIcon()); + if (isEnabled()) { + Q_EMIT requestContextMenu(true); + } + m_pToolButton->clearFocus(); + } + return true; + } + } + return QFrame::eventFilter(object,event); +} + +QPixmap DDropdownMenu::setSvgColor(QString color) +{ + //设置图标颜色 + QString path = QString(":/images/arrow_dark.svg"); + QFile file(path); + file.open(QIODevice::ReadOnly); + QByteArray data = file.readAll(); + QDomDocument doc; + doc.setContent(data); + file.close(); + QDomElement elem = doc.documentElement(); + SetSVGBackColor(elem, "fill", color); + + //装换图片 + //int scaled =qApp->devicePixelRatio() == 1.25 ? 2 : 1; + qreal scaled = this->devicePixelRatioF(); + QSvgRenderer svg_render(doc.toByteArray()); + + QPixmap pixmap(QSize(8,5)*scaled); + pixmap.fill(Qt::transparent); + pixmap.setDevicePixelRatio(scaled); + + QPainter painter(&pixmap); + svg_render.render(&painter,QRect(0,0,8,5)); + + return pixmap; +} + +void DDropdownMenu::SetSVGBackColor(QDomElement &elem, QString strattr, QString strattrval) +{ + + if (elem.tagName().compare("g") == 0 && elem.attribute("id").compare("color") == 0) + { + QString before_color = elem.attribute(strattr); + elem.setAttribute(strattr, strattrval); + } + for (int i = 0; i < elem.childNodes().count(); i++) + { + if (!elem.childNodes().at(i).isElement()) continue; + QDomElement element = elem.childNodes().at(i).toElement(); + SetSVGBackColor(element, strattr, strattrval); + } +} diff --git a/src/widgets/ddropdownmenu.h b/src/widgets/ddropdownmenu.h new file mode 100644 index 0000000000000000000000000000000000000000..e516ebbd5adeaefa5a339f431e5b053c0110b519 --- /dev/null +++ b/src/widgets/ddropdownmenu.h @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef DDROPDOWNMENU_H +#define DDROPDOWNMENU_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +DWIDGET_USE_NAMESPACE + +class DDropdownMenu : public QFrame +{ + Q_OBJECT + +public: + explicit DDropdownMenu(QWidget *parent = nullptr); + ~DDropdownMenu(); + void setFontEx(const QFont& font); + + void setMenu(DMenu *menu); + void deleteMenu(); + void setMenuActionGroup(QActionGroup *actionGroup); + void deleteMenuActionGroup(); + void setTheme(const QString &theme); + + void setChildrenFocus(bool ok); + void setRequestMenu(bool request); + DToolButton* getButton(); + QString getCurrentText() const; + +public slots: + void setCurrentAction(QAction*); + void setCurrentTextOnly(const QString& name); + void slotRequestMenu(bool request); + void setCheckedExclusive(QAction* action,const QString& name); + +public: + //创建编码菜单 + static DDropdownMenu* createEncodeMenu(); + //创建文件类型菜单 + static DDropdownMenu* createHighLightMenu(); + +signals: + void requestContextMenu(bool bClicked = false); + void currentTextChanged(const QString &text); + void currentActionChanged(QAction*); + void sigSetTextEditFocus(); + +private: + //创建文字ICON + QIcon createIcon(); + void setText(const QString &text); +private slots: + //字体大小跟随系统变化 + void OnFontChangedSlot(const QFont &font); +protected: + //按键事件 鼠标释放弹出菜单 + bool eventFilter(QObject *object, QEvent *event); +private: + QPixmap setSvgColor(QString color); + void SetSVGBackColor(QDomElement &elem, QString strattr, QString strattrval); +private: + DToolButton *m_pToolButton = nullptr; + DMenu *m_menu = nullptr; + QActionGroup *m_actionGroup = nullptr; + QPixmap m_arrowPixmap; + QString m_text = "UTF-8"; + QAction* m_pActUtf8 = nullptr; + QFont m_font; + bool m_bPressed =false; + bool isRequest = false; + KSyntaxHighlighting::Repository m_Repository; +}; + +#endif diff --git a/src/widgets/pathsettintwgt.cpp b/src/widgets/pathsettintwgt.cpp new file mode 100644 index 0000000000000000000000000000000000000000..57679ef4927ca51611e0522bd7b22029976d6ae1 --- /dev/null +++ b/src/widgets/pathsettintwgt.cpp @@ -0,0 +1,149 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "pathsettintwgt.h" +#include "../common/settings.h" + +#include + +#include +#include +#include +#include + +PathSettingWgt::PathSettingWgt(QWidget* parent):DWidget(parent) +{ + init(); + onSaveIdChanged(Settings::instance()->getSavePathId()); +} +PathSettingWgt::~PathSettingWgt() +{ + +} +void PathSettingWgt::onSaveIdChanged(int id) +{ + switch (id) { + case CurFileBox:{ + m_curFileBox->setChecked(true); + m_customBtn->setEnabled(false); + break; + } + case LastOptBox:{ + m_lastOptBox->setChecked(true); + m_customBtn->setEnabled(false); + break; + } + case CustomBox:{ + m_customBox->setChecked(true); + m_customBtn->setEnabled(true); + setEditText(Settings::instance()->getSavePath(CustomBox)); + break; + } + default: + break; + } +} + +void PathSettingWgt::init() +{ + QVBoxLayout* layout = new QVBoxLayout(this); + m_group = new QButtonGroup(this); + layout->setContentsMargins(0,0,0,0); + m_curFileBox = new DCheckBox(this); + m_lastOptBox = new DCheckBox(this); + m_customBox = new DCheckBox(this); + m_customEdit = new DLineEdit(this); + m_customBtn = new DSuggestButton(this); + // 获取DTK提供的选取按钮,保持和 DFileChooserEdit 相同的设置 + m_customBtn->setFixedSize(36, 36); + m_customBtn->setIconSize(QSize(24, 24)); + m_customBtn->setIcon(DStyleHelper(style()).standardIcon(DStyle::SP_SelectElement, nullptr)); + + m_group->addButton(m_lastOptBox,LastOptBox); + m_group->addButton(m_curFileBox,CurFileBox); + m_group->addButton(m_customBox,CustomBox); + + m_lastOptBox->setText(tr("Remember the last used path")); + m_curFileBox->setText(tr("Same path as the current file")); + m_customBox->setText(tr("Customize the default path")); + m_customBtn->setEnabled(false); + m_customEdit->setDisabled(true); + m_customEdit->setClearButtonEnabled(false); + + QHBoxLayout* hlayout = new QHBoxLayout; + hlayout->addWidget(m_customBox); + hlayout->addWidget(m_customEdit); + hlayout->addWidget(m_customBtn); + + layout->addWidget(m_lastOptBox); + layout->addWidget(m_curFileBox); + layout->addLayout(hlayout); + + connections(); + +} + +void PathSettingWgt::connections() +{ + connect(m_group,static_cast(&QButtonGroup::buttonClicked),this,&PathSettingWgt::onBoxClicked); + connect(m_customBtn, &QPushButton::clicked, this, &PathSettingWgt::onBtnClicked); +} + +void PathSettingWgt::setEditText(const QString& text) +{ + QFontMetrics metrics(m_customEdit->font()); + Qt::TextElideMode em = Qt::TextElideMode::ElideMiddle; + m_customEdit->setText(metrics.elidedText(text, em, 175)); +} + +void PathSettingWgt::onBoxClicked(int id) +{ + switch (id) { + case CurFileBox:{ + Settings::instance()->setSavePathId(CurFileBox); + m_customBtn->setEnabled(false); + break; + } + case LastOptBox:{ + Settings::instance()->setSavePathId(LastOptBox); + m_customBtn->setEnabled(false); + break; + } + case CustomBox:{ + Settings::instance()->setSavePathId(CustomBox); +// auto path = Settings::instance()->getSavePath(CustomBox); +// if(path.isEmpty()){ +// path = QDir::homePath() + "/Documents"; +// Settings::instance()->setSavePath(CustomBox,path); +// Settings::instance()->setSavePath(LastOptBox,path); +// Settings::instance()->setSavePath(CurFileBox,path); +// } + setEditText(Settings::instance()->getSavePath(CustomBox)); + m_customBtn->setEnabled(true); + break; + } + default: + break; + } +} + +void PathSettingWgt::onBtnClicked() +{ + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::DirectoryOnly); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + QString path = Settings::instance()->getSavePath(PathSettingWgt::CustomBox); + if(!QDir(path).exists() || path.isEmpty()){ + path = QDir::homePath() + "/Documents"; + } + dialog.setDirectory(path); + const int mode = dialog.exec(); + if (mode != QDialog::Accepted) { + return; + } + + path = dialog.selectedFiles().at(0); + setEditText(path); + Settings::instance()->setSavePath(PathSettingWgt::CustomBox,path); +} diff --git a/src/widgets/pathsettintwgt.h b/src/widgets/pathsettintwgt.h new file mode 100644 index 0000000000000000000000000000000000000000..2419cfdc14252acd627506d2b3b2a4b0db1561b8 --- /dev/null +++ b/src/widgets/pathsettintwgt.h @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef PATHSETTINTWGT_H +#define PATHSETTINTWGT_H + +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE +class PathSettingWgt : public DWidget +{ + Q_OBJECT +public: + enum CheckBoxType{ + LastOptBox, + CurFileBox, + CustomBox + }; + +public: + PathSettingWgt(QWidget* parent = nullptr); + virtual ~PathSettingWgt(); +public slots: + void onSaveIdChanged(int id); + void setEditText(const QString& text); + +private: + void init(); + void connections(); + +signals: + void savingPathChanged(CheckBoxType id,const QString& path); + +private slots: + void onBoxClicked(int); + void onBtnClicked(); + +private: + DCheckBox* m_curFileBox = nullptr; + DCheckBox* m_lastOptBox = nullptr; + DCheckBox* m_customBox = nullptr; + DLineEdit* m_customEdit = nullptr; + DSuggestButton* m_customBtn = nullptr; + QButtonGroup* m_group = nullptr; +}; + +#endif diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp new file mode 100644 index 0000000000000000000000000000000000000000..362c6b136df5960b31a9b22562f844fd3c1dc860 --- /dev/null +++ b/src/widgets/window.cpp @@ -0,0 +1,3556 @@ +// SPDX-FileCopyrightText: 2011 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "window.h" +#include "pathsettintwgt.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DTKWIDGET_CLASS_DFileDialog + +#include +#else +#include +#endif + +#define PRINT_FLAG 2 +#define PRINT_ACTION 8 +#define PRINT_FORMAT_MARGIN 10 +#define FLOATTIP_MARGIN 95 + +/** + * @brief 根据传入的源文档 \a doc 创建新的文档 + * @param doc 源文档指针 + * @return 创建的新文档,用于拷贝数据 + */ +static QTextDocument *createNewDocument(QTextDocument *doc) +{ + QTextDocument *createDoc = new QTextDocument(doc); + // 不记录撤销信息 + createDoc->setUndoRedoEnabled(false); + createDoc->setMetaInformation(QTextDocument::DocumentTitle, + doc->metaInformation(QTextDocument::DocumentTitle)); + createDoc->setMetaInformation(QTextDocument::DocumentUrl, + doc->metaInformation(QTextDocument::DocumentUrl)); + createDoc->setDefaultFont(doc->defaultFont()); + createDoc->setDefaultStyleSheet(doc->defaultStyleSheet()); + createDoc->setIndentWidth(doc->indentWidth()); + + // 设置固定为从左向右布局,降低后续高亮等操作导致更新计算布局方向 + auto textOption = createDoc->defaultTextOption(); + textOption.setTextDirection(Qt::LeftToRight); + textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + createDoc->setDefaultTextOption(textOption); + + return createDoc; +} + +/*! + * \~chinese \brief printPage 绘制每一页文本纸张到打印机 + * \~chinese \param index 纸张索引 + * \~chinese \param doc 文本文件 + * \~chinese \param body 范围大小 + * \~chinese \param pageCountBox 绘制页码的范围 + */ +void Window::printPage(int index, QPainter *painter, const QTextDocument *doc, + const QRectF &body, const QRectF &pageCountBox) +{ + painter->save(); + + painter->translate(body.left(), body.top() - (index - 1) * body.height()); + const QRectF view(0, (index - 1) * body.height(), body.width(), body.height()); + + QAbstractTextDocumentLayout *layout = doc->documentLayout(); + QAbstractTextDocumentLayout::PaintContext ctx; + + painter->setFont(QFont(doc->defaultFont())); + const QRectF box = pageCountBox.translated(0, view.top()); + const QString pageString = QString::number(index); + painter->drawText(box, Qt::AlignRight, pageString); + + painter->setClipRect(view); + ctx.clip = view; + ctx.palette.setColor(QPalette::Text, Qt::black); + + layout->draw(painter, ctx); + + painter->restore(); +} + +/** + * @brief 使用多组文档打印,用于超大文档的情况 + * @param index 纸张索引 + * @param painter 打印指针 + * @param printInfo 多组文档信息 + * @param body 范围大小 + * @param pageCountBox 绘制页码的范围 + */ +void Window::printPageWithMultiDoc( + int index, QPainter *painter, const QVector &printInfo, const QRectF &body, const QRectF &pageCountBox) +{ + painter->save(); + + int docIndex = index; + for (auto info : printInfo) { + if (docIndex <= info.doc->pageCount()) { + // 调整绘制工具坐标到当前页面顶部 + painter->translate(body.left(), body.top() - (docIndex - 1) * body.height()); + + // 绘制页码 + painter->setFont(QFont(info.doc->defaultFont())); + const QRectF box = pageCountBox.translated(0, (docIndex - 1) * body.height()); + const QString pageString = QString::number(index); + painter->drawText(box, Qt::AlignRight, pageString); + + // 设置文档裁剪区域 + const QRectF docView(0, (docIndex - 1) * body.height(), body.width(), body.height()); + QAbstractTextDocumentLayout *layout = info.doc->documentLayout(); + + // 大文本的高亮单独处理 + if (info.highlighter) { + // 提前两页拷贝数据,用于处理高亮计算时连续处理 + qreal offsetHeight = qMax(0, (qMin(2, docIndex - 1) * body.height())); + QPointF point = docView.topLeft() - QPointF(0, offsetHeight); + int pos = layout->hitTest(point, Qt::FuzzyHit); + QTextCursor cursor(info.doc); + cursor.setPosition(pos); + // 选取后续内容 + int endPos = layout->hitTest(docView.bottomLeft(), Qt::FuzzyHit); + endPos = qMin(endPos + 1000, info.doc->characterCount() - 1); + cursor.setPosition(endPos, QTextCursor::KeepAnchor); + cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); + + // 创建临时文档 + QTextDocument *tmpDoc = createNewDocument(info.doc); + QTextCursor insertCursor(tmpDoc); + insertCursor.beginEditBlock(); + insertCursor.insertFragment(QTextDocumentFragment(cursor)); + insertCursor.endEditBlock(); + + auto margin = info.doc->rootFrame()->frameFormat().margin(); + auto fmt = tmpDoc->rootFrame()->frameFormat(); + fmt.setMargin(margin); + tmpDoc->rootFrame()->setFrameFormat(fmt); + + tmpDoc->setPageSize(body.size()); + // 重新高亮文本 + auto newHighlighter = new CSyntaxHighlighter(tmpDoc); + newHighlighter->setDefinition(info.highlighter->definition()); + newHighlighter->setTheme(info.highlighter->theme()); + rehighlightPrintDoc(tmpDoc, newHighlighter); + + // 确保布局完成 + tmpDoc->pageCount(); + + // 调整显示位置 + painter->resetTransform(); + painter->translate(body.left(), body.top() - offsetHeight); + QAbstractTextDocumentLayout::PaintContext ctx; + ctx.clip = QRectF(0, offsetHeight, body.width(), body.height()); + ctx.palette.setColor(QPalette::Text, Qt::black); + tmpDoc->documentLayout()->setPaintDevice(painter->device()); + tmpDoc->documentLayout()->draw(painter, ctx); + + delete newHighlighter; + delete tmpDoc; + } else { + QAbstractTextDocumentLayout::PaintContext ctx; + ctx.clip = docView; + ctx.palette.setColor(QPalette::Text, Qt::black); + // 绘制文档 + layout->draw(painter, ctx); + } + + break; + } + docIndex -= info.doc->pageCount(); + } + + painter->restore(); +} + +Window::Window(DMainWindow *parent) + : DMainWindow(parent), + m_centralWidget(new QWidget), + m_editorWidget(new QStackedWidget), + m_centralLayout(new QVBoxLayout(m_centralWidget)), + m_tabbar(new Tabbar), + m_jumpLineBar(new JumpLineBar()), + m_replaceBar(new ReplaceBar(this)), + m_themePanel(new ThemePanel(this)), + m_findBar(new FindBar(this)), + m_menu(new DMenu), + m_blankFileDir(QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("blank-files")), + m_backupDir(QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("backup-files")), + m_autoBackupDir(QDir(Utils::cleanPath(QStandardPaths::standardLocations(QStandardPaths::DataLocation)).first()).filePath("autoBackup-files")), + m_titlebarStyleSheet(titlebar()->styleSheet()), + m_themePath(Settings::instance()->settings->option("advance.editor.theme")->value().toString()) +{ + qRegisterMetaType("TextEdit"); + m_rootSaveDBus = new DBusDaemon::dbus("com.deepin.editor.daemon", "/", QDBusConnection::systemBus(), this); + m_settings = Settings::instance(); + + // Init. + setAcceptDrops(true); + loadTheme(m_themePath); + + DGuiApplicationHelper *guiAppHelp = DGuiApplicationHelper::instance(); + slotLoadContentTheme(guiAppHelp->themeType()); + + //关闭 替换 查找 跳行bar + connect(this, &Window::pressEsc, m_replaceBar, &ReplaceBar::pressEsc, Qt::QueuedConnection); + connect(this, &Window::pressEsc, m_findBar, &FindBar::pressEsc, Qt::QueuedConnection); + connect(this, &Window::pressEsc, m_jumpLineBar, &JumpLineBar::pressEsc, Qt::QueuedConnection); + + // Init settings. + connect(m_settings, &Settings::sigAdjustFont, this, &Window::slotSigAdjustFont); + connect(m_settings, &Settings::sigAdjustFontSize, this, &Window::slotSigAdjustFontSize); + connect(m_settings, &Settings::sigAdjustTabSpaceNumber, this, &Window::slotSigAdjustTabSpaceNumber); + connect(m_settings, &Settings::sigThemeChanged, this, &Window::slotSigThemeChanged); + connect(m_settings, &Settings::sigAdjustWordWrap, this, &Window::slotSigAdjustWordWrap); + connect(m_settings, &Settings::sigSetLineNumberShow, this, &Window::slotSigSetLineNumberShow); + connect(m_settings, &Settings::sigAdjustBookmark, this, &Window::slotSigAdjustBookmark); + connect(m_settings, &Settings::sigShowBlankCharacter, this, &Window::slotSigShowBlankCharacter); + connect(m_settings, &Settings::sigHightLightCurrentLine, this, &Window::slotSigHightLightCurrentLine); + connect(m_settings, &Settings::sigShowCodeFlodFlag, this, &Window::slotSigShowCodeFlodFlag); + /* 设置页面里窗口模式的设置是针对新创建窗口的设置,本窗口不需要实时响应,暂且屏蔽此信号的绑定 */ + //connect(m_settings, &Settings::sigChangeWindowSize, this, &Window::slotSigChangeWindowSize); + + // Init layout and editor. + m_centralLayout->setMargin(0); + m_centralLayout->setSpacing(0); + + m_centralLayout->addWidget(m_editorWidget); + setWindowIcon(QIcon::fromTheme("deepin-editor")); + setCentralWidget(m_centralWidget); + + // Init titlebar. + if (titlebar()) { + initTitlebar(); + } + + // window minimum size. + setMinimumSize(680, 300); + // resize window size. + int window_width = Settings::instance()->settings->option("advance.window.window_width")->value().toInt(); + int window_height = Settings::instance()->settings->option("advance.window.window_height")->value().toInt(); + window_height == 1 ? window_height = 600 : window_height; + window_width == 1 ? window_width = 1000 : window_width; + resize(window_width, window_height); + + //设置函数最大化或者正常窗口的初始化 2021.4.26 ut002764 lxp fix bug:74774 + showCenterWindow(true); + //检测语音助手服务是否被注册 + detectionIflytekaiassistant(); + + // Init find bar. + connect(m_findBar, &FindBar::findNext, this, &Window::handleFindNextSearchKeyword, Qt::QueuedConnection); + connect(m_findBar, &FindBar::findPrev, this, &Window::handleFindPrevSearchKeyword, Qt::QueuedConnection); + connect(m_findBar, &FindBar::removeSearchKeyword, this, &Window::handleRemoveSearchKeyword, Qt::QueuedConnection); + connect(m_findBar, &FindBar::updateSearchKeyword, this, [ = ](QString file, QString keyword) { + handleUpdateSearchKeyword(m_findBar, file, keyword); + }); + connect(m_findBar, &FindBar::sigFindbarClose, this, &Window::slotFindbarClose, Qt::QueuedConnection); + + // Init replace bar. + //connect(m_replaceBar, &ReplaceBar::removeSearchKeyword, this, &Window::handleRemoveSearchKeyword, Qt::QueuedConnection); + + connect(m_replaceBar, &ReplaceBar::beforeReplace, this, &Window::slot_beforeReplace, Qt::QueuedConnection); + connect(m_replaceBar, &ReplaceBar::replaceAll, this, &Window::handleReplaceAll, Qt::QueuedConnection); + connect(m_replaceBar, &ReplaceBar::replaceNext, this, &Window::handleReplaceNext, Qt::QueuedConnection); + connect(m_replaceBar, &ReplaceBar::replaceRest, this, &Window::handleReplaceRest, Qt::QueuedConnection); + connect(m_replaceBar, &ReplaceBar::replaceSkip, this, &Window::handleReplaceSkip, Qt::QueuedConnection); + connect(m_replaceBar, &ReplaceBar::updateSearchKeyword, this, [ = ](QString file, QString keyword) { + handleUpdateSearchKeyword(m_replaceBar, file, keyword); + }); + connect(m_replaceBar, &ReplaceBar::sigReplacebarClose, this, &Window::slotReplacebarClose, Qt::QueuedConnection); + + // Init jump line bar. + //QTimer::singleShot(0, m_jumpLineBar, SLOT(hide())); + m_jumpLineBar->hide(); + m_jumpLineBar->setParent(this); + + connect(m_jumpLineBar, &JumpLineBar::jumpToLine, this, &Window::handleJumpLineBarJumpToLine, Qt::QueuedConnection); + connect(m_jumpLineBar, &JumpLineBar::backToPosition, this, &Window::handleBackToPosition, Qt::QueuedConnection); + connect(m_jumpLineBar, &JumpLineBar::lostFocusExit, this, &Window::handleJumpLineBarExit, Qt::QueuedConnection); + + // Make jump line bar pop at top-right of editor. + //DAnchorsBase::setAnchor(m_jumpLineBar, Qt::AnchorTop, m_centralWidget, Qt::AnchorTop); + //DAnchorsBase::setAnchor(m_jumpLineBar, Qt::AnchorRight, m_centralWidget, Qt::AnchorRight); + + DAnchors anchors_jumpLineBar(m_jumpLineBar); + anchors_jumpLineBar.setAnchor(Qt::AnchorTop, m_centralWidget, Qt::AnchorTop); + anchors_jumpLineBar.setAnchor(Qt::AnchorRight, m_centralWidget, Qt::AnchorRight); + anchors_jumpLineBar.setTopMargin(5); + anchors_jumpLineBar.setRightMargin(5); + m_jumpLineBar->raise(); + + // Init findbar panel. + static DAnchors anchors_findbar(m_findBar); + anchors_findbar.setAnchor(Qt::AnchorBottom, m_centralWidget, Qt::AnchorBottom); + anchors_findbar.setAnchor(Qt::AnchorHorizontalCenter, m_centralWidget, Qt::AnchorHorizontalCenter); + anchors_findbar.setBottomMargin(1); + //m_findBar->move(QPoint(10, height() - 5)); + m_findBar->raise(); + + // Init replaceBar panel. + DAnchors anchors_replaceBar(m_replaceBar); + anchors_replaceBar.setAnchor(Qt::AnchorBottom, m_centralWidget, Qt::AnchorBottom); + anchors_replaceBar.setAnchor(Qt::AnchorHorizontalCenter, m_centralWidget, Qt::AnchorHorizontalCenter); + anchors_replaceBar.setBottomMargin(1); + //m_replaceBar->move(QPoint(10, height() - 57)); + m_replaceBar->raise(); + + // Init theme panel. + DAnchorsBase::setAnchor(m_themePanel, Qt::AnchorTop, m_centralWidget, Qt::AnchorTop); + DAnchorsBase::setAnchor(m_themePanel, Qt::AnchorBottom, m_centralWidget, Qt::AnchorBottom); + DAnchorsBase::setAnchor(m_themePanel, Qt::AnchorRight, m_centralWidget, Qt::AnchorRight); + + // for the first time open the need be init. + m_themePanel->setSelectionTheme(m_themePath); + + connect(m_themePanel, &ThemePanel::themeChanged, this, &Window::themeChanged); + connect(this, &Window::requestDragEnterEvent, this, &Window::dragEnterEvent); + connect(this, &Window::requestDropEvent, this, &Window::dropEvent); + + connect(qApp, &QGuiApplication::focusWindowChanged, this, &Window::handleFocusWindowChanged); + connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, &Window::slotLoadContentTheme); + + //setChildrenFocus(false); + Utils::clearChildrenFocus(m_tabbar);//使用此函数把tabbar的组件焦点去掉(左右箭头不能focus) + +} + +Window::~Window() +{ + // We don't need clean pointers because application has exit here. + if (nullptr != m_shortcutViewProcess) { + delete (m_shortcutViewProcess); + m_shortcutViewProcess = nullptr; + } + + clearPrintTextDocument(); +} + +void Window::detectionIflytekaiassistant() +{ + IflytekAiassistantThread *pIflyThread = new IflytekAiassistantThread(this); + connect(pIflyThread, &IflytekAiassistantThread::sigIsRegisteredIflytekAiassistant, + this, &Window::slotIsRegisteredIflytekAiassistant); + connect(pIflyThread, &IflytekAiassistantThread::finished, pIflyThread, &IflytekAiassistantThread::deleteLater); + pIflyThread->start(); +} + +bool Window::getIsRegistIflytekAiassistant() +{ + return m_bIsRegistIflytekAiassistant; +} + +void Window::loadIflytekaiassistantConfig() +{ + QString configPath = QString("%1/%2") + .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) + .arg("iflytek"); + + QDir dir(configPath); + if (!dir.exists()) { + return; + } + QString key = "base/enable"; + dir.setFilter(QDir::Files); + QStringList nameList = dir.entryList(); + for (auto name : nameList) { + if (name.contains("-iat") || name.contains("-tts") || name.contains("-trans")) { + QString filename = configPath + "/" + name; + QSettings file(filename, QSettings::IniFormat); + m_IflytekAiassistantState[name.split(".").first()] = file.value(key).toBool(); + } + } +} + +bool Window::getIflytekaiassistantConfig(const QString &mode_name) +{ + if (m_IflytekAiassistantState.contains(mode_name)) { + return m_IflytekAiassistantState[mode_name]; + } else { + qWarning() << "mode_name is not valid"; + return false; + } +} + +void Window::updateModifyStatus(const QString &path, bool isModified) +{ + int tabIndex = m_tabbar->indexOf(path); + if (tabIndex == -1) { + return; + } + + QString tabName; + QString filePath = m_tabbar->truePathAt(tabIndex); + if (filePath.isNull() || filePath.length() <= 0 || Utils::isDraftFile(filePath)) { + tabName = m_tabbar->textAt(tabIndex); + if (isModified) { + if (!tabName.contains('*')) { + tabName.prepend('*'); + } + } else { + QRegularExpression reg("[^*](.+)"); + QRegularExpressionMatch match = reg.match(tabName); + if (match.hasMatch()) { + tabName = match.captured(0); + } + } + } else { + QFileInfo fileInfo(filePath); + tabName = fileInfo.fileName(); + if (isModified) { + tabName.prepend('*'); + } + } + + m_tabbar->setTabText(tabIndex, tabName); + //判断是否需要阻塞系统关机 + emit sigJudgeBlockShutdown(); +} + +void Window::updateSaveAsFileName(QString strOldFilePath, QString strNewFilePath) +{ + int tabIndex = m_tabbar->indexOf(strOldFilePath); + EditWrapper *wrapper = m_wrappers.value(strOldFilePath); + m_tabbar->updateTab(tabIndex, strNewFilePath, QFileInfo(strNewFilePath).fileName()); + wrapper->updatePath(strNewFilePath); + + //tabbar中存在和strNewFilePath同名的tab + if (m_wrappers.contains(strNewFilePath)) { + closeTab(strNewFilePath); + } + + m_wrappers.remove(strOldFilePath); + m_wrappers.insert(strNewFilePath, wrapper); +} + +void Window::updateSabeAsFileNameTemp(QString strOldFilePath, QString strNewFilePath) +{ + int tabIndex = m_tabbar->indexOf(strOldFilePath); + EditWrapper *wrapper = m_wrappers.value(strOldFilePath); + m_tabbar->updateTab(tabIndex, strNewFilePath, QFileInfo(strNewFilePath).fileName()); + wrapper->updatePath(strNewFilePath); + m_wrappers.remove(strOldFilePath); + m_wrappers.insert(strNewFilePath, wrapper); +} + +void Window::showCenterWindow(bool bIsCenter) +{ + // Init window state with config. + // Below code must before this->titlebar()->setMenu, otherwise main menu can't display pre-build-in menu items by dtk. + QString windowState = Settings::instance()->settings->option("advance.window.windowstate")->value().toString(); + + if (bIsCenter) { + Dtk::Widget::moveToCenter(this); + } + // init window state. + if (windowState == "window_maximum") { + showMaximized(); + m_needMoveToCenter = true; + } else if (windowState == "fullscreen") { + showFullScreen(); + m_needMoveToCenter = true; + } else { + showNormal(); + } +} + +void Window::initTitlebar() +{ + QAction *newWindowAction(new QAction(tr("New window"), this)); + QAction *newTabAction(new QAction(tr("New tab"), this)); + QAction *openFileAction(new QAction(tr("Open file"), this)); + QAction *saveAction(new QAction(tr("Save"), this)); + QAction *saveAsAction(new QAction(tr("Save as"), this)); + QAction *printAction(new QAction(tr("Print"), this)); + QAction *switchThemeAction(new QAction(tr("Switch theme"), this)); + QAction *settingAction(new QAction(tr("Settings"), this)); + QAction *findAction(new QAction(QApplication::translate("TextEdit", "Find"), this)); + QAction *replaceAction(new QAction(QApplication::translate("TextEdit", "Replace"), this)); + + m_menu->addAction(newWindowAction); + m_menu->addAction(newTabAction); + m_menu->addAction(openFileAction); + m_menu->addSeparator(); + m_menu->addAction(findAction); + m_menu->addAction(replaceAction); + m_menu->addAction(saveAction); + m_menu->addAction(saveAsAction); + m_menu->addAction(printAction); + //此接口不可删除,预留的编辑器内部主题选择接口 + //m_menu->addAction(switchThemeAction); + m_menu->addSeparator(); + m_menu->addAction(settingAction); + + m_menu->setMinimumWidth(150); + + titlebar()->addWidget(m_tabbar); + + titlebar()->setCustomWidget(m_tabbar, false); + titlebar()->setSeparatorVisible(false); + titlebar()->setMenu(m_menu); + titlebar()->setIcon(QIcon::fromTheme("deepin-editor")); + titlebar()->setFocusPolicy(Qt::NoFocus); //设置titlebar无焦点,点击titlebar时光标不移动 + + DIconButton *addButton = m_tabbar->findChild("AddButton"); + addButton->setFocusPolicy(Qt::NoFocus); + DIconButton *optionBtn = titlebar()->findChild("DTitlebarDWindowOptionButton"); + optionBtn->setFocusPolicy(Qt::NoFocus); + DIconButton *minBtn = titlebar()->findChild("DTitlebarDWindowMinButton"); + minBtn->setFocusPolicy(Qt::NoFocus); + DIconButton *quitFullBtn = titlebar()->findChild("DTitlebarDWindowQuitFullscreenButton"); + quitFullBtn->setFocusPolicy(Qt::NoFocus); + DIconButton *maxBtn = titlebar()->findChild("DTitlebarDWindowMaxButton"); + maxBtn->setFocusPolicy(Qt::NoFocus); + DIconButton *closeBtn = titlebar()->findChild("DTitlebarDWindowCloseButton"); + closeBtn->setFocusPolicy(Qt::NoFocus); + + connect(m_tabbar, &DTabBar::tabBarDoubleClicked, titlebar(), &DTitlebar::doubleClicked, Qt::QueuedConnection); + + connect(m_tabbar, &Tabbar::closeTabs, this, &Window::handleTabsClosed, Qt::QueuedConnection); + connect(m_tabbar, &Tabbar::requestHistorySaved, this, [ = ](const QString & filePath) { + if (QFileInfo(filePath).dir().absolutePath() == m_blankFileDir) { + return; + } + + if (!m_closeFileHistory.contains(filePath)) { + m_closeFileHistory << filePath; + } + }); + + connect(m_tabbar, &DTabBar::tabCloseRequested, this, &Window::handleTabCloseRequested, Qt::QueuedConnection); + connect(m_tabbar, &DTabBar::tabAddRequested, this, static_cast(&Window::addBlankTab), Qt::QueuedConnection); + connect(m_tabbar, &DTabBar::currentChanged, this, &Window::handleCurrentChanged, Qt::QueuedConnection); + // 当标签页新增、删除时触发变更信号(用于备份当前打开文件信息) + connect(m_tabbar, &DTabBar::tabIsInserted, this, &Window::tabChanged, Qt::QueuedConnection); + connect(m_tabbar, &DTabBar::tabIsRemoved, this, &Window::tabChanged, Qt::QueuedConnection); + + connect(newWindowAction, &QAction::triggered, this, &Window::newWindow); + connect(newTabAction, &QAction::triggered, this, static_cast(&Window::addBlankTab)); + connect(openFileAction, &QAction::triggered, this, &Window::openFile); + connect(findAction, &QAction::triggered, this, &Window::popupFindBar); + connect(replaceAction, &QAction::triggered, this, &Window::popupReplaceBar); + connect(saveAction, &QAction::triggered, this, &Window::saveFile); + connect(saveAsAction, &QAction::triggered, this, &Window::saveAsFile); + connect(printAction, &QAction::triggered, this, &Window::popupPrintDialog); + connect(settingAction, &QAction::triggered, this, &Window::popupSettingsDialog); + connect(switchThemeAction, &QAction::triggered, this, &Window::popupThemePanel); +} + +bool Window::checkBlockShutdown() +{ + //判断是否有未保存的tab项 + for (int i = 0; i < m_tabbar->count(); i++) { + if (m_tabbar->textAt(i).isNull()) { + return false; + } + //如果有未保存的tab项,return true阻塞系统关机 + if (m_tabbar->textAt(i).at(0) == '*') { + return true; + } + } + + return false; +} + +int Window::getTabIndex(const QString &file) +{ + return m_tabbar->indexOf(file); +} + +void Window::activeTab(int index) +{ + DMainWindow::activateWindow(); + m_tabbar->setCurrentIndex(index); +} + +Tabbar *Window::getTabbar() +{ + return m_tabbar; +} + +void Window::addTab(const QString &filepath, bool activeTab) +{ + // check whether it is an editable file thround mimeType. + if (Utils::isMimeTypeSupport(filepath)) { + const QFileInfo fileInfo(filepath); + QString tabName = fileInfo.fileName(); + EditWrapper *curWrapper = currentWrapper(); + + if (!fileInfo.isWritable() && fileInfo.isReadable()) { + tabName += QString(" (%1)").arg(tr("Read-Only")); + } + + if (curWrapper) { + // if the current page is a draft file and is empty + if (m_tabbar->indexOf(filepath) != -1) { + m_tabbar->setCurrentIndex(m_tabbar->indexOf(filepath)); + } + } + + // check if have permission to read the file. + QFile file(filepath); + QFile::Permissions permissions = file.permissions(); + bool bIsRead = (permissions & QFile::ReadUser || permissions & QFile::ReadOwner || permissions & QFile::ReadOther); + if (fileInfo.exists() && !bIsRead) { + DMessageManager::instance()->sendMessage(m_editorWidget->currentWidget(), QIcon(":/images/warning.svg") + , QString(tr("You do not have permission to open %1")).arg(filepath)); + return; + } + + if (StartManager::instance()->checkPath(filepath)) { + + m_tabbar->addTab(filepath, tabName, filepath); + + if (!m_wrappers.contains(filepath)) { + EditWrapper *wrapper = createEditor(); + showNewEditor(wrapper); + m_wrappers[filepath] = wrapper; + + if (!fileInfo.isWritable() && fileInfo.isReadable()) { + wrapper->textEditor()->setReadOnlyPermission(true); + } + + wrapper->openFile(filepath, filepath); + + // 查找文件是否存在书签 + auto bookmarkInfo = StartManager::instance()->findBookmark(filepath); + wrapper->textEditor()->setBookMarkList(bookmarkInfo); + } + // Activate window. + activateWindow(); + } + + // Active tab if activeTab is true. + if (activeTab) { + int tabIndex = m_tabbar->indexOf(filepath); + if (tabIndex != -1) { + m_tabbar->setCurrentIndex(tabIndex); + } + } + } else { + if (currentWrapper() == nullptr) { + this->addBlankTab(); + } + + QString strFileName = QFileInfo(filepath).fileName(); + strFileName = tr("Invalid file: %1").arg(strFileName); + strFileName = Utils::lineFeed(strFileName, m_editorWidget->currentWidget()->width() - FLOATTIP_MARGIN, m_editorWidget->currentWidget()->font(), 2); + DMessageManager::instance()->sendMessage(m_editorWidget->currentWidget(), QIcon(":/images/warning.svg"), strFileName); + } +} + +void Window::addTabWithWrapper(EditWrapper *wrapper, const QString &filepath, const QString &qstrTruePath, const QString &tabName, int index) +{ + if (index == -1) { + index = m_tabbar->currentIndex() + 1; + } + + //这里会重复连接信号和槽,先全部取消 + QDBusConnection dbus = QDBusConnection::sessionBus(); + switch (Utils::getSystemVersion()) { + case Utils::V23: + dbus.systemBus().disconnect("org.deepin.dde.Gesture1", + "/org/deepin/dde/Gesture1", "org.deepin.dde.Gesture1", + "Event", + wrapper->textEditor(), SLOT(fingerZoom(QString, QString, int))); + break; + default: + dbus.systemBus().disconnect("com.deepin.daemon.Gesture", + "/com/deepin/daemon/Gesture", "com.deepin.daemon.Gesture", + "Event", + wrapper->textEditor(), SLOT(fingerZoom(QString, QString, int))); + break; + } + wrapper->textEditor()->disconnect(); + connect(wrapper->textEditor(), &TextEdit::cursorModeChanged, wrapper, &EditWrapper::handleCursorModeChanged); + connect(wrapper->textEditor(), &TextEdit::clickFindAction, this, &Window::popupFindBar, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickReplaceAction, this, &Window::popupReplaceBar, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickJumpLineAction, this, &Window::popupJumpLineBar, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickFullscreenAction, this, &Window::toggleFullscreen, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::popupNotify, this, &Window::showNotify, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::signal_setTitleFocus, this, &Window::slot_setTitleFocus, Qt::QueuedConnection); + + switch (Utils::getSystemVersion()) { + case Utils::V23: + dbus.systemBus().connect("org.deepin.dde.Gesture1", + "/org/deepin/dde/Gesture1", "org.deepin.dde.Gesture1", + "Event", + wrapper->textEditor(), SLOT(fingerZoom(QString, QString, int))); + break; + default: + dbus.systemBus().connect("com.deepin.daemon.Gesture", + "/com/deepin/daemon/Gesture", "com.deepin.daemon.Gesture", + "Event", + wrapper->textEditor(), SLOT(fingerZoom(QString, QString, int))); + break; + } + connect(wrapper->textEditor(), &QPlainTextEdit::cursorPositionChanged, wrapper->textEditor(), &TextEdit::cursorPositionChanged); + + connect(wrapper->textEditor(), &QPlainTextEdit::textChanged, wrapper->textEditor(), [ = ]() { + wrapper->UpdateBottomBarWordCnt(wrapper->textEditor()->characterCount()); + }); + + + // add wrapper to this window. + m_tabbar->addTabWithIndex(index, filepath, tabName, qstrTruePath); + m_wrappers[filepath] = wrapper; + wrapper->updatePath(filepath, qstrTruePath); + + showNewEditor(wrapper); + wrapper->OnThemeChangeSlot(m_themePath); +} + +/** + * @return 关闭当前焦点的标签页并返回是否成功关闭。 + */ +bool Window::closeTab() +{ + const QString &filePath = m_tabbar->currentPath(); + // 避免异常情况重入时当前已无标签页的情况 + if (filePath.isEmpty()) { + return false; + } + return closeTab(filePath); +} + +bool Window::closeTab(const QString &filePath) +{ + EditWrapper *wrapper = m_wrappers.value(filePath); + if (!wrapper) { + return false; + } + + if (!currentWrapper()) { + return false; + } + + if (m_reading_list.contains(currentWrapper()->textEditor())) { + if (m_settings->settings) { + m_settings->settings->sync(); + } + + QProcess process; + process.start("dbus-send --print-reply --dest=com.iflytek.aiassistant /aiassistant/tts com.iflytek.aiassistant.tts.stopTTSDirectly"); + if (!process.waitForFinished(10)) { + process.terminate(); + } + } + + // 当前窗口为打印文本窗口 + if (wrapper == m_printWrapper) { + // 退出打印 + m_bPrintProcessing = false; + } + + disconnect(wrapper, nullptr); + disconnect(wrapper->textEditor(), &TextEdit::textChanged, nullptr, nullptr); + + // this property holds whether the document has been modified by the user + bool isModified = wrapper->isModified(); + bool isDraftFile = wrapper->isDraftFile(); + bool bIsBackupFile = false; + + if (wrapper->isTemFile()) { + bIsBackupFile = true; + } + + if (wrapper->getFileLoading()) { + isModified = false; + } + + // 关闭标签页前,记录全局的书签信息 + QList bookmarkInfo = wrapper->textEditor()->getBookmarkInfo(); + if (!bookmarkInfo.isEmpty()) { + QString localPath = wrapper->textEditor()->getTruePath(); + StartManager::instance()->recordBookmark(localPath, bookmarkInfo); + } + + if (isDraftFile) { + if (isModified) { + DDialog *dialog = createDialog(tr("Do you want to save this file?"), ""); + int res = dialog->exec(); + + //取消或关闭弹窗不做任务操作 + if (res == 0 || res == -1) { + return false; + } + + //不保存 + if (res == 1) { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + QFile(filePath).remove(); + return true; + } + + //保存 + if (res == 2) { + QFileInfo fileInfo(filePath); + QString newFilePath; + + if (wrapper->saveDraftFile(newFilePath)) { + removeWrapper(filePath, true); + // 保存临时文件后已更新tab页的文件路径,使用新的文件路径删除窗口 + m_tabbar->closeCurrentTab(newFilePath); + QFile(filePath).remove(); + } else { + // 保存不成功时不关闭窗口 + return false; + } + } + } else { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + QFile(filePath).remove(); + } + } + // document has been modified or unsaved draft document. + // need to prompt whether to save. + else { + QFileInfo fileInfo(filePath); + isModified = false; + if (m_tabbar->textAt(m_tabbar->currentIndex()).front() == "*") { + isModified = true; + } + if (isModified) { + DDialog *dialog = createDialog(tr("Do you want to save this file?"), ""); + int res = dialog->exec(); + + //取消或关闭弹窗不做任务操作 + if (res == 0 || res == -1) { + return false; + } + + //不保存 + if (res == 1) { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + + //删除备份文件 + if (bIsBackupFile) { + QFile(filePath).remove(); + } + + //删除自动备份文件 + if (QFileInfo(m_autoBackupDir).exists()) { + fileInfo.setFile(wrapper->textEditor()->getTruePath()); + QString name = fileInfo.absolutePath().replace("/", "_"); + QDir(m_autoBackupDir).remove(fileInfo.baseName() + "." + name + "." + fileInfo.suffix()); + } + + return true; + } + + //保存 + if (res == 2) { + if (bIsBackupFile) { + if (wrapper->saveFile()) { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + QFile(filePath).remove(); + } else { + saveAsFile(); + } + } else { + if (wrapper->saveFile()) { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + } else { + saveAsFile(); + } + } + } + } else { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + } + + //删除自动备份文件 + if (QFileInfo(m_autoBackupDir).exists()) { + fileInfo.setFile(wrapper->textEditor()->getTruePath()); + QString name = fileInfo.absolutePath().replace("/", "_"); + QDir(m_autoBackupDir).remove(fileInfo.baseName() + "." + name + "." + fileInfo.suffix()); + } + } + + return true; +} + +void Window::restoreTab() +{ + if (m_closeFileHistory.size() > 0) { + addTab(m_closeFileHistory.takeLast()); + } +} + +EditWrapper *Window::createEditor() +{ + EditWrapper *wrapper = new EditWrapper(this); + connect(wrapper, &EditWrapper::sigClearDoubleCharaterEncode, this, &Window::slotClearDoubleCharaterEncode); + connect(wrapper->textEditor(), &TextEdit::signal_readingPath, this, &Window::slot_saveReadingPath, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::signal_setTitleFocus, this, &Window::slot_setTitleFocus, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickFindAction, this, &Window::popupFindBar, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickReplaceAction, this, &Window::popupReplaceBar, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickJumpLineAction, this, &Window::popupJumpLineBar, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::clickFullscreenAction, this, &Window::toggleFullscreen, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::popupNotify, this, &Window::showNotify, Qt::QueuedConnection); + connect(wrapper->textEditor(), &TextEdit::textChanged, this, [ = ]() { + updateJumpLineBar(wrapper->textEditor()); + }, Qt::QueuedConnection); + + bool wordWrap = m_settings->settings->option("base.font.wordwrap")->value().toBool(); + wrapper->textEditor()->m_pIsShowCodeFoldArea = m_settings->settings->option("base.font.codeflod")->value().toBool(); + wrapper->OnThemeChangeSlot(m_themePath); + wrapper->textEditor()->setSettings(m_settings); + wrapper->textEditor()->setTabSpaceNumber(m_settings->settings->option("advance.editor.tabspacenumber")->value().toInt()); + wrapper->textEditor()->setFontFamily(m_settings->settings->option("base.font.family")->value().toString()); + wrapper->textEditor()->setLineWrapMode(wordWrap); + setFontSizeWithConfig(wrapper); + + //设置显示空白符 梁卫东 + wrapper->setShowBlankCharacter(m_settings->settings->option("base.font.showblankcharacter")->value().toBool()); + //yanyuhan 设置行号显示 + wrapper->setLineNumberShow(m_settings->settings->option("base.font.showlinenumber")->value().toBool(), true); + wrapper->textEditor()->setHighLineCurrentLine(m_settings->settings->option("base.font.hightlightcurrentline")->value().toBool()); + wrapper->textEditor()->setBookmarkFlagVisable(m_settings->settings->option("base.font.showbookmark")->value().toBool(), true); + wrapper->textEditor()->setCodeFlodFlagVisable(m_settings->settings->option("base.font.codeflod")->value().toBool(), true); + wrapper->textEditor()->updateLeftAreaWidget(); + + return wrapper; +} + +EditWrapper *Window::currentWrapper() +{ + if (m_wrappers.contains(m_tabbar->currentPath())) { + return m_wrappers.value(m_tabbar->currentPath()); + } else { + return nullptr; + } +} + +EditWrapper *Window::wrapper(const QString &filePath) +{ + if (m_wrappers.contains(filePath)) { + return m_wrappers.value(filePath); + } else { + for (auto wrapper : m_wrappers) { + QString truePath = wrapper->textEditor()->getTruePath(); + if (truePath == filePath) { + return m_wrappers.value(wrapper->textEditor()->getFilePath()); + } + } + + return nullptr; + } +} + +TextEdit *Window::getTextEditor(const QString &filepath) +{ + if (m_wrappers.contains(filepath)) { + return m_wrappers.value(filepath)->textEditor(); + } else { + return nullptr; + } +} + +void Window::focusActiveEditor() +{ + if (m_tabbar->count() > 0) { + if (currentWrapper() == nullptr) { + return; + } + currentWrapper()->textEditor()->setFocus(); + } +} + +void Window::removeWrapper(const QString &filePath, bool isDelete) +{ + EditWrapper *wrapper = m_wrappers.value(filePath); + + if (wrapper) { + qInfo() << "begin removeWrapper"; + if (nullptr == m_editorWidget) { + return; + } + m_editorWidget->removeWidget(wrapper); + m_wrappers.remove(filePath); + if (isDelete) { + disconnect(wrapper->textEditor(), nullptr); + disconnect(wrapper, nullptr); + wrapper->setQuitFlag(); + wrapper->deleteLater(); + qInfo() << "after delete wrapper"; + } + } + + // Exit window after close all tabs. + if (m_wrappers.isEmpty()) { + close(); + qInfo() << "after close"; + } + + qInfo() << "end removeWrapper"; +} + +void Window::openFile() +{ + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::ExistingFiles); + dialog.setAcceptMode(QFileDialog::AcceptOpen); + + // read history directory. + QString historyDirStr = m_settings->settings->option("advance.editor.file_dialog_dir")->value().toString(); + if (historyDirStr.isEmpty() || !QDir(historyDirStr).exists() || !QFileInfo(historyDirStr).isWritable() || !QDir(historyDirStr).isReadable()) { + historyDirStr = QDir::homePath() + "/Documents"; + } + dialog.setDirectory(historyDirStr); + + QDir historyDir(historyDirStr); + + if (historyDir.exists()) { + dialog.setDirectory(historyDir); + } else { + qDebug() << "historyDir or default path not existed:" << historyDir; + } + + QString path = m_settings->getSavePath(m_settings->getSavePathId()); + // 使用当前文件路径时,打开当前文件的目录,新建文档为系统-文档目录 + if (PathSettingWgt::CurFileBox == m_settings->getSavePathId()) { + path = getCurrentOpenFilePath(); + } + if (path.isEmpty() || !QDir(path).exists() || !QFileInfo(path).isWritable() || !QDir(path).isReadable()) { + path = QDir::homePath() + "/Documents"; + } + dialog.setDirectory(path); + + const int mode = dialog.exec(); + + PerformanceMonitor::openFileStart(); + // save the directory string. + m_settings->settings->option("advance.editor.file_dialog_dir")->setValue(dialog.directoryUrl().toLocalFile()); + + if (mode != QDialog::Accepted) { + return; + } + + QStringList supportfileNames; + QStringList otherfiles; + for (const QString &file : dialog.selectedFiles()) { + + if (Utils::isMimeTypeSupport(file)) { + supportfileNames.append(file); + } else { + otherfiles.append(file); + } + + //先添加支持的文件 + } + foreach (QString var, supportfileNames) { + addTab(var, true); + } + + //后添加不支持文件 在最后编辑页面显示 + foreach (QString var, otherfiles) { + addTab(var, true); + } +} + +bool Window::saveFile() +{ + EditWrapper *wrapperEdit = currentWrapper(); + + //大文本加载过程不允许保存 + if (!wrapperEdit || wrapperEdit->getFileLoading()) return false; + + bool isDraftFile = wrapperEdit->isDraftFile(); + //bool isEmpty = wrapperEdit->isPlainTextEmpty(); + QString filePath = wrapperEdit->textEditor()->getTruePath(); + + // save blank file. + if (isDraftFile) { + return saveAsFile(); + } + + QFileInfo info(filePath); + if (info.exists()) { + //判断文件是否有写的权限 + QFile temporaryBuffer(filePath); + QFile::Permissions pers = temporaryBuffer.permissions(); + bool isWrite = ((pers & QFile::WriteUser) || (pers & QFile::WriteOwner) || (pers & QFile::WriteOther)); + if (!isWrite) { + DMessageManager::instance()->sendMessage(m_editorWidget->currentWidget(), QIcon(":/images/warning.svg") + , QString(tr("You do not have permission to save %1")).arg(info.fileName())); + return false; + } + } + + // save normal file. + QString temPath = ""; + + if (wrapperEdit->isTemFile()) { + temPath = wrapperEdit->textEditor()->getFilePath(); + } else { + temPath = filePath; + } + bool success = wrapperEdit->saveFile(); + + if (success) { + updateSabeAsFileNameTemp(temPath, filePath); + if (currentWrapper()) { + currentWrapper()->hideWarningNotices(); + } + showNotify(tr("Saved successfully")); + + //删除备份文件 + if (temPath != filePath) { + QFile(temPath).remove(); + } + + //删除自动备份文件 + if (QFileInfo(m_autoBackupDir).exists()) { + QFileInfo fileInfo(filePath); + QString name = fileInfo.absolutePath().replace("/", "_"); + QDir(m_autoBackupDir).remove(fileInfo.baseName() + "." + name + "." + fileInfo.suffix()); + } + + return true; + } + + return false; +} + +bool Window::saveAsFile() +{ + return !saveAsFileToDisk().isEmpty(); +} + +QString Window::saveAsFileToDisk() +{ + EditWrapper *wrapper = currentWrapper(); + //大文本加载过程不允许保存 梁卫东 + if (!wrapper || wrapper->getFileLoading()) { + return QString(); + } + + bool isDraft = wrapper->isDraftFile(); + QFileInfo fileInfo(wrapper->textEditor()->getTruePath()); + + DFileDialog dialog(this, tr("Save File")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.setDirectory(QDir::homePath()); + // 允许选取保存的编码格式 + DFileDialog::DComboBoxOptions encodingOptions; + encodingOptions.editable = false; + encodingOptions.defaultValue = wrapper->getTextEncode(); + encodingOptions.data = Utils::getSupportEncodingList(); + dialog.addComboBox(QObject::tr("Encoding"), encodingOptions); + + QString path = m_settings->getSavePath(m_settings->getSavePathId()); + // 使用当前文件路径时,打开当前文件的目录,新建文档为系统-文档目录 + if (PathSettingWgt::CurFileBox == m_settings->getSavePathId()) { + path = getCurrentOpenFilePath(); + } + if (path.isEmpty() || !QDir(path).exists() || !QFileInfo(path).isWritable() || !QDir(path).isReadable()) { + path = QDir::homePath() + "/Documents"; + } + dialog.setDirectory(path); + + if (isDraft) { + QRegularExpression reg("[^*](.+)"); + QRegularExpressionMatch match = reg.match(m_tabbar->currentName()); + dialog.selectFile(match.captured(0) + ".txt"); + } else { + dialog.setDirectory(fileInfo.dir()); + dialog.selectFile(fileInfo.fileName()); + } + + int mode = dialog.exec(); + if (mode == QDialog::Accepted) { + const QByteArray encode = dialog.getComboBoxValue(QObject::tr("Encoding")).toUtf8(); + const QString newFilePath = dialog.selectedFiles().value(0); + Settings::instance()->setSavePath(PathSettingWgt::LastOptBox, QFileInfo(newFilePath).absolutePath()); + Settings::instance()->setSavePath(PathSettingWgt::CurFileBox, QFileInfo(newFilePath).absolutePath()); + + wrapper->updatePath(wrapper->filePath(), newFilePath); + + bool needChangeEncode = (encode != wrapper->getTextEncode().toUtf8()); + bool saveSucc = false; + if (QFileInfo(wrapper->filePath()).absoluteFilePath() + == QFileInfo(newFilePath).absoluteFilePath()) { + // 相同路径,直接保存文件 + saveSucc = wrapper->saveFile(encode); + } else { + saveSucc = wrapper->saveAsFile(newFilePath, encode); + } + + if (!saveSucc) { + /* 如果保存未成功,无需记录更新新文件路径 */ + wrapper->updatePath(wrapper->filePath(), QString()); + return QString(); + } else { + // 更新文件编码 + wrapper->bottomBar()->setEncodeName(encode); + + // 若编码变更,保存完成后,重新加载文件 + if (needChangeEncode) { + wrapper->readFile(encode); + } + } + + if (wrapper->filePath().contains(m_backupDir) || wrapper->filePath().contains(m_blankFileDir)) { + QFile(wrapper->filePath()).remove(); + } + + //删除自动备份文件 + if (QFileInfo(m_autoBackupDir).exists()) { + QString truePath = wrapper->textEditor()->getTruePath(); + fileInfo.setFile(truePath); + QString name = fileInfo.absolutePath().replace("/", "_"); + QDir(m_autoBackupDir).remove(fileInfo.baseName() + "." + name + "." + fileInfo.suffix()); + } + + /* 如果另存为的文件名+路径与当前tab项对应的文件名+路径是一致,则直接做保存操作即可 */ + if (!wrapper->filePath().compare(newFilePath)) { + if (saveFile()) { + return newFilePath; + } + } + + updateSaveAsFileName(wrapper->filePath(), newFilePath); + return newFilePath; + } + + return QString(); +} + +QString Window::saveBlankFileToDisk() +{ + QString filePath = m_tabbar->currentPath(); + EditWrapper *wrapper = m_wrappers.value(filePath); + bool isDraft = Utils::isDraftFile(filePath); + QFileInfo fileInfo(filePath); + + if (!wrapper) + //return false; + return QString(); + + DFileDialog dialog(this, tr("Save File")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.addComboBox(tr("Encoding"), QStringList() << wrapper->getTextEncode()); + dialog.setDirectory(QDir::homePath()); + + if (isDraft) { + QRegularExpression reg("[^*](.+)"); + QRegularExpressionMatch match = reg.match(m_tabbar->currentName()); + dialog.selectFile(match.captured(0) + ".txt"); + } else { + dialog.setDirectory(fileInfo.dir()); + dialog.selectFile(fileInfo.fileName()); + } + + int mode = dialog.exec(); + if (mode == QDialog::Accepted) { + const QString newFilePath = dialog.selectedFiles().value(0); + wrapper->updatePath(newFilePath); + wrapper->saveFile(); + + m_wrappers.remove(filePath); + m_wrappers.insert(newFilePath, wrapper); + + // wrapper->textEditor()->loadHighlighter(); + return newFilePath; + } + + return QString(); +} + +bool Window::saveAsOtherTabFile(EditWrapper *wrapper) +{ + QString filePath = wrapper->textEditor()->getFilePath(); + bool isDraft = Utils::isDraftFile(filePath); + QFileInfo fileInfo(filePath); + int index = m_tabbar->indexOf(filePath); + QString strTabText = m_tabbar->tabText(index); + + if (!wrapper) + return false; + + DFileDialog dialog(this, tr("Save File")); + dialog.setAcceptMode(QFileDialog::AcceptSave); + dialog.addComboBox(QObject::tr("Encoding"), Utils::getEncodeList()); + dialog.addComboBox(QObject::tr("Line Endings"), QStringList() << "Linux" << "Windows" << "Mac OS"); + dialog.setDirectory(QDir::homePath()); + + if (isDraft) { + QRegularExpression reg("[^*](.+)"); + QRegularExpressionMatch match = reg.match(strTabText); + dialog.selectFile(match.captured(0) + ".txt"); + } else { + dialog.setDirectory(fileInfo.dir()); + dialog.selectFile(fileInfo.fileName()); + } + + int mode = dialog.exec(); + if (mode == QDialog::Accepted) { + const QByteArray encode = dialog.getComboBoxValue(QObject::tr("Encoding")).toUtf8(); + const QString endOfLine = dialog.getComboBoxValue(QObject::tr("Line Endings")); + const QString newFilePath = dialog.selectedFiles().value(0); + const QFileInfo newFileInfo(newFilePath); +// EditWrapper::EndOfLineMode eol = EditWrapper::eolUnix; + +// if (endOfLine == "Windows") { +// eol = EditWrapper::eolDos; +// } else if (endOfLine == "Mac OS") { +// eol = EditWrapper::eolMac; +// } + + if (isDraft) { + QFile(filePath).remove(); + } + + //m_tabbar->updateTab(m_tabbar->currentIndex(), newFilePath, newFileInfo.fileName()); + + // wrapper->setTextCodec(encode); + wrapper->updatePath(newFilePath); + //wrapper->setEndOfLineMode(eol); + wrapper->saveFile(); + + // wrapper->textEditor()->loadHighlighter(); + } else { + return false; + } + + return true; +} + +void Window::changeSettingDialogComboxFontNumber(int fontNumber) +{ + m_settings->settings->option("base.font.size")->setValue(fontNumber); +} + +/** + * @brief 根据传入的字体大小计算字体的比例,字体大小范围在 8 ~ 500,比例范围在 10% ~ 500%, + * 默认字体大小为12。因此在 8~12 和 12~50 两组范围字体的缩放间隔不同。 + * @param fontSize 字体大小 + * @return 字体缩放比例,范围 10 ~ 500 + */ +qreal Window::calcFontScale(qreal fontSize) +{ + if (qFuzzyCompare(fontSize, m_settings->m_iDefaultFontSize)) { + return 100.0; + } else if (fontSize > m_settings->m_iDefaultFontSize) { + static const qreal delta = (500 - 100) * 1.0 / (m_settings->m_iMaxFontSize - m_settings->m_iDefaultFontSize); + qreal fontScale = 100 + delta * (fontSize - m_settings->m_iDefaultFontSize); + return qMin(fontScale, 500.0); + } else { + static const qreal delta = (100 - 10) * 1.0 / (m_settings->m_iDefaultFontSize - m_settings->m_iMinFontSize); + qreal fontScale = 100 + delta * (fontSize - m_settings->m_iDefaultFontSize); + return qMax(fontScale, 10.0); + } +} + +/** + * @brief 根据字体缩放比例返回字体大小 + * @param fontScale 字体缩放比例 + * @return 字体大小,范围 8~50 + */ +qreal Window::calcFontSizeFromScale(qreal fontScale) +{ + if (qFuzzyCompare(fontScale, 100.0)) { + return m_settings->m_iDefaultFontSize; + } else if (fontScale > 100.0) { + static const qreal delta = (m_settings->m_iMaxFontSize - m_settings->m_iDefaultFontSize) * 1.0 / (500 - 100); + qreal fontSize = m_settings->m_iDefaultFontSize + delta * ((fontScale) - 100); + return qMin(fontSize, m_settings->m_iMaxFontSize); + } else { + static const qreal delta = (m_settings->m_iDefaultFontSize - m_settings->m_iMinFontSize) * 1.0 / (100 - 10) ; + qreal fontSize = m_settings->m_iMinFontSize + delta * (fontScale - 10); + return qMax(fontSize, m_settings->m_iMinFontSize); + } +} + +void Window::decrementFontSize() +{ + qreal fontScale = calcFontScale(m_fontSize); + // 减少10% + fontScale -= 10; + m_fontSize = calcFontSizeFromScale(fontScale); + + qreal size = qMax(m_fontSize, m_settings->m_iMinFontSize); + m_settings->settings->option("base.font.size")->setValue(size); +} + +void Window::incrementFontSize() +{ + qreal fontScale = calcFontScale(m_fontSize); + // 增加10% + fontScale += 10; + m_fontSize = calcFontSizeFromScale(fontScale); + + qreal size = qMin(m_fontSize, m_settings->m_iMaxFontSize); + m_settings->settings->option("base.font.size")->setValue(size); +} + +void Window::resetFontSize() +{ + m_settings->settings->option("base.font.size")->setValue(m_settings->m_iDefaultFontSize); +} + +void Window::setFontSizeWithConfig(EditWrapper *wrapper) +{ + qreal size = m_settings->settings->option("base.font.size")->value().toReal(); + wrapper->textEditor()->setFontSize(size); + wrapper->bottomBar()->setScaleLabelText(size); + + m_fontSize = size; +} + +void Window::popupFindBar() +{ +#if 0 + if (m_findBar->isVisible()) { + m_findBar->move(QPoint(10, height() - 59)); + if (m_findBar->isFocus()) { + m_wrappers.value(m_tabbar->currentPath())->textEditor()->setFocus(); + } else { + m_findBar->focus(); + } + } else { + addBottomWidget(m_findBar); + } +#endif + + m_findBar->setSearched(false); + QString tabPath = m_tabbar->currentPath(); + EditWrapper *wrapper = currentWrapper(); + + if (currentWrapper() == nullptr) { + return; + } + + if (wrapper->textEditor()->document()->isEmpty()) { + return; + } + + currentWrapper()->bottomBar()->updateSize(m_findBar->height() + 8, true); + + if (m_replaceBar->isVisible()) { + m_replaceBar->hide(); + } + m_findBar->raise(); + m_findBar->show(); + m_findBar->move(QPoint(4, height() - m_findBar->height() - 4)); + + //QString text = wrapper->textEditor()->textCursor().selectedText(); + QString text = wrapper->textEditor()->selectedText(); + int row = wrapper->textEditor()->getCurrentLine(); + int column = wrapper->textEditor()->getCurrentColumn(); + int scrollOffset = wrapper->textEditor()->getScrollOffset(); + + m_findBar->activeInput(text, tabPath, row, column, scrollOffset); + // highlight keyword when findbar show + wrapper->textEditor()->highlightKeywordInView(text); + // set keywords + m_keywordForSearchAll = m_keywordForSearch = text; + + QTimer::singleShot(10, this, [ = ] { m_findBar->focus(); }); +} + +void Window::popupReplaceBar() +{ + if (currentWrapper() == nullptr) { + return; + } + + if (currentWrapper()->textEditor()->document()->isEmpty()) { + return; + } + + if (currentWrapper() && currentWrapper()->getFileLoading()) { + return; + } + + QTextCursor cursor = currentWrapper()->textEditor()->textCursor(); + + m_replaceBar->setsearched(false); + EditWrapper *curWrapper = currentWrapper(); + bool bIsReadOnly = curWrapper->textEditor()->getReadOnlyMode(); + + if (cursor.hasSelection()) { + currentWrapper()->textEditor()->setCursorStart(cursor.selectionStart()); + } + + if (bIsReadOnly) { + showNotify(tr("Read-Only mode is on")); + return; + } + + currentWrapper()->bottomBar()->updateSize(m_replaceBar->height() + 8, true); + + EditWrapper *wrapper = currentWrapper(); + if (m_findBar->isVisible()) { + m_findBar->hide(); + } + m_replaceBar->raise(); + m_replaceBar->show(); + m_replaceBar->move(QPoint(4, height() - m_replaceBar->height() - 4)); + //addBottomWidget(m_replaceBar); + + QString tabPath = m_tabbar->currentPath(); + // QString text = wrapper->textEditor()->textCursor().selectedText(); + QString text = wrapper->textEditor()->selectedText(); + int row = wrapper->textEditor()->getCurrentLine(); + int column = wrapper->textEditor()->getCurrentColumn(); + int scrollOffset = wrapper->textEditor()->getScrollOffset(); + + m_replaceBar->activeInput(text, tabPath, row, column, scrollOffset); + + QTimer::singleShot(10, this, [ = ] { m_replaceBar->focus(); }); +} + +void Window::popupJumpLineBar() +{ + EditWrapper *curWrapper = currentWrapper(); + + if (curWrapper == nullptr) { + return; + } + + if (curWrapper->textEditor()->document()->isEmpty()) { + return; + } + + if (m_jumpLineBar->isVisible()) { + m_jumpLineBar->hide(); + return; + } + + if (m_jumpLineBar->isVisible()) { + if (m_jumpLineBar->isFocus()) { + //QTimer::singleShot(0, m_wrappers.value(m_tabbar->currentPath())->textEditor(), SLOT(setFocus())); + } else { + m_jumpLineBar->focus(); + } + } else { + QString tabPath = m_tabbar->currentPath(); + EditWrapper *wrapper = currentWrapper(); + QString text = wrapper->textEditor()->textCursor().selectedText(); + int row = wrapper->textEditor()->getCurrentLine(); + int column = wrapper->textEditor()->getCurrentColumn(); + int count = wrapper->textEditor()->blockCount(); + int scrollOffset = wrapper->textEditor()->getScrollOffset(); + + m_jumpLineBar->activeInput(tabPath, row, column, count, scrollOffset); + m_jumpLineBar->show(); + m_jumpLineBar->focus(); + } +} + +void Window::updateJumpLineBar(TextEdit *editor) +{ + // 文本块内容未新增行不更新跳转行号 + if (m_jumpLineBar->isVisible() && editor->blockCount() != m_jumpLineBar->getLineCount()) { + QString tabPath = m_tabbar->currentPath(); + QString text = editor->textCursor().selectedText(); + int row = editor->getCurrentLine(); + int column = editor->getCurrentColumn(); + int count = editor->blockCount(); + int scrollOffset = editor->getScrollOffset(); + m_jumpLineBar->activeInput(tabPath, row, column, count, scrollOffset); + } + if (editor && !editor->ifHasHighlight()) { + m_findBar->setSearched(false); + m_replaceBar->setsearched(false); + } +} + +void Window::popupSettingsDialog() +{ + DSettingsDialog *dialog = new DSettingsDialog(this); + dialog->widgetFactory()->registerWidget("fontcombobox", Settings::createFontComBoBoxHandle); + dialog->widgetFactory()->registerWidget("keySequenceEdit", Settings::createKeySequenceEditHandle); + dialog->widgetFactory()->registerWidget("savingpathwgt", Settings::createSavingPathWgt); + dialog->resize(680, 300); + dialog->setMinimumSize(680, 300); + m_settings->setSettingDialog(dialog); + + dialog->updateSettings(m_settings->settings); + + dialog->exec(); + + delete dialog; + m_settings->settings->sync(); +} + +/** + * @brief 清空打印文档信息,用于关闭打印对话框或中止打印时释放构造的临时文档 + */ +void Window::clearPrintTextDocument() +{ + if (m_printDoc != nullptr) { + if (!m_printDoc->isEmpty()) { + m_printDoc->clear(); + } + m_printDoc = nullptr; + } + + // 清空打印对象列表 + if (!m_printDocList.isEmpty()) { + for (auto &info : m_printDocList) { + if (info.highlighter) { + delete info.highlighter; + } + + if (info.doc) { + info.doc->clear(); + delete info.doc; + } + } + + m_printDocList.clear(); + } +} + +void Window::setWindowTitleInfo() +{ + if (m_tabbar) { + qDebug() << __FUNCTION__ << "--" << m_tabbar->truePathAt(m_tabbar->currentIndex()); + if (m_tabbar->truePathAt(m_tabbar->currentIndex()) != "") { + setWindowTitle(m_tabbar->truePathAt(m_tabbar->currentIndex())); + } else { + setWindowTitle(m_tabbar->currentName()); + } + } +} + +/** + * @brief 取得当前文件打开文档目录,新建文档为"系统-文档"目录(~/Documents) + * @return 当前文件打开文档目录 + */ +QString Window::getCurrentOpenFilePath() +{ + QString path; + EditWrapper *wrapper = currentWrapper(); + if (wrapper) { + QString curFilePath = wrapper->textEditor() ? wrapper->textEditor()->getTruePath() + : wrapper->filePath(); + // 临时文件或备份文件,均返回"文档"目录 + if (Utils::isDraftFile(curFilePath) || Utils::isBackupFile(curFilePath)) { + path = QDir::homePath() + "/Documents"; + } else { + path = QFileInfo(curFilePath).absolutePath(); + } + } + + return path; +} + +/** + * @brief 克隆文本数据,不同于 QTextDocument::clone(), 主要用于大文本的拷贝,拷贝过程通过 + * QApplication::processEvents() 执行其它事件 + * @param editWrapper 文本编辑处理,提供文本编辑器和高亮信息 + * @return 是否克隆数据成功 + * + * @note Qt自带的布局算法在超长文本时存在计算越界的问题,计算长度将返回溢出值,导致显示异常, + 调整为拆分的文档结构 + */ +bool Window::cloneLargeDocument(EditWrapper *editWrapper) +{ + if (!editWrapper) { + return false; + } + + // 获取源文本 + QTextDocument *srcDoc = editWrapper->textEditor()->document(); + // 是否需要高亮 + bool needHighlighter = editWrapper->getSyntaxHighlighter() + && editWrapper->getSyntaxHighlighter()->definition().isValid(); + // 创建新的打印信息 + auto createPrintInfo = [ = ]()->PrintInfo { + PrintInfo info; + info.doc = createNewDocument(srcDoc); + if (needHighlighter) + { + // 构造高亮处理 + info.highlighter = new CSyntaxHighlighter(info.doc); + info.highlighter->setDefinition(editWrapper->getSyntaxHighlighter()->definition()); + info.highlighter->setTheme(editWrapper->getSyntaxHighlighter()->theme()); + } + return info; + }; + + // 每次拷贝约100kb数据 + static const int s_StepCopyCharCount = 1024 * 100; + // 单个文档字符不超过50MB, 防止布局失败 + static const int s_MaxDocCharCount = 1024 * 1024 * 50; + // 单个文档文本块数不超过10万行 + static const int s_MaxDocBlockCount = 100000; + + // 创建首个拷贝文本对象 + PrintInfo info = createPrintInfo(); + QTextDocument *copyDoc = info.doc; + m_printDocList.append(info); + + try { + // 此次拷贝到字符数统计 + int currentCopyCharCount = 0; + // 此次拷贝勾选的文本块数 + int currentSelectBlock = 0; + // 已读取的源文件偏移量 + int srcOffset = 0; + + // 标记开始处理 + m_bPrintProcessing = true; + QPointer checkPtr(this); + + QTextCursor copyCursor(copyDoc); + QTextCursor srcCursor(srcDoc); + + for (QTextBlock srcBlock = srcDoc->firstBlock(); srcBlock.isValid(); srcBlock = srcBlock.next()) { + currentSelectBlock++; + currentCopyCharCount += srcBlock.length(); + + if (currentCopyCharCount >= s_StepCopyCharCount) { + // 判断是否超过单个文档允许的最大范围 + if ((copyDoc->characterCount() + currentCopyCharCount) > s_MaxDocCharCount || + (copyDoc->blockCount() + currentSelectBlock) > s_MaxDocBlockCount) { + // 创建新的打印文档 + m_printDocList.append(createPrintInfo()); + copyDoc = m_printDocList.last().doc; + // 创建新的插入光标 + copyCursor = QTextCursor(copyDoc); + } + + srcCursor.setPosition(srcOffset); + srcCursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, currentSelectBlock); + copyCursor.insertFragment(QTextDocumentFragment(srcCursor)); + + srcOffset += currentCopyCharCount; + currentSelectBlock = 0; + currentCopyCharCount = 0; + } + + // 处理其它事件 + qApp->processEvents(); + if (!checkPtr || !m_bPrintProcessing) { + qWarning() << "Abort print copy!"; + clearPrintTextDocument(); + return false; + } + } + + // 补充保存最后的信息 + srcCursor.setPosition(srcOffset); + srcCursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, currentSelectBlock); + // 保证拷贝到文档末尾 + srcCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor, 1); + copyCursor.insertFragment(QTextDocumentFragment(srcCursor)); + + m_bPrintProcessing = false; + } catch (const std::exception &e) { + qWarning() << "Print copy doc error!" << e.what(); + // 清理数据 + m_bPrintProcessing = false; + clearPrintTextDocument(); + return false; + } + + return true; +} + +/** + @brief 使用 \a highlighter 重新高亮传入的文本 \a doc ,此函数用于大文本打印时对临时文本的处理 + */ +void Window::rehighlightPrintDoc(QTextDocument *doc, CSyntaxHighlighter *highlighter) +{ + if (!doc || !highlighter) { + return; + } + + QColor background = m_printWrapper->textEditor()->palette().color(QPalette::Base); + bool backgroundIsDark = background.value() < 128; + + highlighter->setEnableHighlight(true); + if (backgroundIsDark) { + for (QTextBlock block = doc->firstBlock(); block.isValid(); block = block.next()) { + highlighter->rehighlightBlock(block); + + QVector formatList = block.layout()->formats(); + // adjust syntax highlighting colors for better contrast + for (int i = formatList.count() - 1; i >= 0; --i) { + QTextCharFormat &format = formatList[i].format; + if (format.background().color() == background) { + QBrush brush = format.foreground(); + QColor color = brush.color(); + int h, s, v, a; + color.getHsv(&h, &s, &v, &a); + color.setHsv(h, s, qMin(128, v), a); + brush.setColor(color); + format.setForeground(brush); + } + format.setBackground(Qt::white); + } + + block.layout()->setFormats(formatList); + } + } else { + highlighter->rehighlight(); + } + highlighter->setEnableHighlight(false); +} + +void Window::popupPrintDialog() +{ + //大文本加载过程不允许打印操作 + if (currentWrapper() && currentWrapper()->getFileLoading()) return; + + // 已有处理的打印事件,不继续进入 + if (m_bPrintProcessing) { + return; + } + + const QString &filePath = currentWrapper()->textEditor()->getFilePath(); + const QString &fileDir = QFileInfo(filePath).dir().absolutePath(); + + qInfo() << qPrintable("Start print doc"); + + //适配打印接口2.0,dtk版本大于或等于5.4.10才放开最新的2.0打印预览接口 +#if (DTK_VERSION_MAJOR > 5 \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR > 4) \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR == 4 && DTK_VERSION_PATCH >= 10)) + + QTextDocument *doc = currentWrapper()->textEditor()->document(); + m_bLargePrint = false; + m_bPrintProcessing = false; + m_printWrapper = currentWrapper(); + m_multiDocPageCount = 0; + + if (doc != nullptr && !doc->isEmpty()) { + static const int s_maxDirectReadLen = 1024 * 1024 * 10; + static const int s_maxHighlighterDirectReadLen = 1024 * 1024 * 5; + // 判断是否需要文本高亮,文本数据量大小,不同数据量使用不同分支。 + bool needHighlighter = currentWrapper()->getSyntaxHighlighter() + && currentWrapper()->getSyntaxHighlighter()->definition().isValid(); + + if (needHighlighter + && doc->characterCount() > s_maxHighlighterDirectReadLen) { + // 需要高亮且数据量超过 5MB + m_bLargePrint = true; + } else if (!needHighlighter + && doc->characterCount() > s_maxDirectReadLen) { + // 无需高亮且数据量超过 10MB + m_bLargePrint = true; + } else { + currentWrapper()->updateHighlighterAll(); + m_printDoc = doc->clone(doc); + } + + // 大文件处理 + if (m_bLargePrint) { + qInfo() << qPrintable("Clone large print document"); + // 克隆大文本数据 + if (!cloneLargeDocument(currentWrapper())) { + return; + } + } + } + + if ((!m_bLargePrint && nullptr == m_printDoc) + || (m_bLargePrint && m_printDocList.isEmpty())) { + qWarning() << "The print document is not valid!"; + return; + } + + DPrinter printer(QPrinter::HighResolution); + m_isNewPrint = true; + m_pPreview = new DPrintPreviewDialog(this); + m_pPreview->setAttribute(Qt::WA_DeleteOnClose); + + // 设置 QPrinter 的文档名称,保留绝对路径和文件后缀(在cups的page_log中保留完整的job-name) + // 注意和文件的输出文件路径进行区分 + if (fileDir == m_blankFileDir) { + m_pPreview->setDocName(filePath); + } else { + QString path = currentWrapper()->textEditor()->getTruePath(); + m_pPreview->setDocName(path); + } + + // 后续布局计算后再更新打印页数 + m_pPreview->setAsynPreview(PRINT_FLAG); + + connect(m_pPreview, &DPrintPreviewDialog::finished, this, [ = ] { + m_bPrintProcessing = false; + clearPrintTextDocument(); + }); + connect(m_pPreview, &DPrintPreviewDialog::rejected, this, [ = ] { + m_bPrintProcessing = false; + clearPrintTextDocument(); + }); + + connect(m_pPreview, QOverload &>::of(&DPrintPreviewDialog::paintRequested), + this, [ = ](DPrinter * _printer, const QVector &pageRange) { + if (m_bLargePrint) { + this->doPrintWithLargeDoc(_printer, pageRange); + } else { + this->doPrint(_printer, pageRange); + } + }); + + m_pPreview->exec(); + +#else + DPrintPreviewDialog preview(this); + + connect(&preview, QOverload::of(&DPrintPreviewDialog::paintRequested), + this, [ & ](DPrinter * printer) { + if (fileDir == m_blankFileDir) { + printer->setDocName(QString(m_tabbar->currentName())); + } else { + printer->setDocName(QString(QFileInfo(filePath).baseName())); + } + currentWrapper()->textEditor()->print(printer); + }); + + currentWrapper()->updateHighlighterAll(); + + preview.exec(); +#endif +} + +void Window::popupThemePanel() +{ + updateThemePanelGeomerty(); + m_themePanel->setSelectionTheme(m_themePath); + m_themePanel->popup(); +} + +void Window::toggleFullscreen() +{ + if (!window()->windowState().testFlag(Qt::WindowFullScreen)) { + window()->setWindowState(windowState() | Qt::WindowFullScreen); + } else { + window()->setWindowState(windowState() & ~Qt::WindowFullScreen); + } +} + +void Window::remberPositionSave() +{ + EditWrapper *wrapper = currentWrapper(); + + m_remberPositionFilePath = m_tabbar->currentPath(); + m_remberPositionRow = wrapper->textEditor()->getCurrentLine(); + m_remberPositionColumn = wrapper->textEditor()->getCurrentColumn(); + m_remberPositionScrollOffset = wrapper->textEditor()->getScrollOffset(); + + currentWrapper()->showNotify(tr("Current location remembered")); +} + +void Window::remberPositionRestore() +{ + if (m_remberPositionFilePath.isEmpty()) { + return; + } + + if (m_wrappers.contains(m_remberPositionFilePath)) { + const QString &filePath = m_remberPositionFilePath; + const int &scrollOffset = m_remberPositionScrollOffset; + const int &row = m_remberPositionRow; + const int &column = m_remberPositionColumn; + + activeTab(m_tabbar->indexOf(m_remberPositionFilePath)); + m_wrappers.value(filePath)->textEditor()->scrollToLine(scrollOffset, row, column); + } +} + + +void Window::displayShortcuts() +{ + QRect rect = window()->geometry(); + QPoint pos(rect.x() + rect.width() / 2, + rect.y() + rect.height() / 2); + + //窗体快捷键 + QStringList windowKeymaps; + windowKeymaps << "addblanktab" << "newwindow" << "savefile" + << "saveasfile" << "selectnexttab" << "selectprevtab" + << "closetab" << "closeothertabs" << "restoretab" + << "openfile" << "incrementfontsize" << "decrementfontsize" + << "resetfontsize" << "togglefullscreen" << "find" << "replace" + << "jumptoline" << "saveposition" << "restoreposition" + << "escape" << "print"; + + QJsonObject shortcutObj; + QJsonArray jsonGroups; + + QJsonObject windowJsonGroup; + windowJsonGroup.insert("groupName", QObject::tr("Window")); + QJsonArray windowJsonItems; + + for (const QString &keymap : windowKeymaps) { + auto option = m_settings->settings->group("shortcuts.window")->option(QString("shortcuts.window.%1").arg(keymap)); + QJsonObject jsonItem; + jsonItem.insert("name", QObject::tr(option->name().toUtf8().data())); + if (keymap != "incrementfontsize" && keymap != "decrementfontsize") { + jsonItem.insert("value", option->value().toString().replace("Meta", "Super")); + } else if (keymap == "incrementfontsize") { + QString strIncrementfontValue = QString(tr("Ctrl+'='")); + jsonItem.insert("value", strIncrementfontValue.replace("Meta", "Super")); + } else if (keymap == "decrementfontsize" && option->value().toString() == "Ctrl+-") { + QString strDecrementfontValue = QString(tr("Ctrl+'-'")); + jsonItem.insert("value", strDecrementfontValue.replace("Meta", "Super")); + } + + windowJsonItems.append(jsonItem); + } + + windowJsonGroup.insert("groupItems", windowJsonItems); + jsonGroups.append(windowJsonGroup); + + //编辑快捷键 + QStringList editorKeymaps; + editorKeymaps << "indentline" << "backindentline" << "forwardchar" + << "backwardchar" << "forwardword" << "backwardword" + << "nextline" << "prevline" << "newline" << "opennewlineabove" + << "opennewlinebelow" << "duplicateline" << "killline" + << "killcurrentline" << "swaplineup" << "swaplinedown" + << "scrolllineup" << "scrolllinedown" << "scrollup" + << "scrolldown" << "movetoendofline" << "movetostartofline" + << "movetoend" << "movetostart" << "movetolineindentation" + << "upcaseword" << "downcaseword" << "capitalizeword" + << "killbackwardword" << "killforwardword" << "forwardpair" + << "backwardpair" << "selectall" << "copy" << "cut" + << "paste" << "transposechar" << "setmark" << "exchangemark" + << "copylines" << "cutlines" << "joinlines" << "togglereadonlymode" + << "togglecomment" << "removecomment" << "undo" << "redo" << "switchbookmark" << "movetoprebookmark" + << "movetonextbookmark" << "mark"; + + QJsonObject editorJsonGroup; + editorJsonGroup.insert("groupName", tr("Editor")); + QJsonArray editorJsonItems; + + for (const QString &keymap : editorKeymaps) { + auto option = m_settings->settings->group("shortcuts.editor")->option(QString("shortcuts.editor.%1").arg(keymap)); + QJsonObject jsonItem; + jsonItem.insert("name", QObject::tr(option->name().toUtf8().data())); + jsonItem.insert("value", option->value().toString().replace("Meta", "Super")); + editorJsonItems.append(jsonItem); + } + editorJsonGroup.insert("groupItems", editorJsonItems); + jsonGroups.append(editorJsonGroup); + + //设置快捷键 + QStringList setupKeymaps; + setupKeymaps << "help" << "displayshortcuts"; + + QJsonObject setupJsonGroup; + setupJsonGroup.insert("groupName", tr("Settings")); + QJsonArray setupJsonItems; + + for (const QString &keymap : setupKeymaps) { + auto option = m_settings->settings->group("shortcuts.window")->option(QString("shortcuts.window.%1").arg(keymap)); + QJsonObject jsonItem; + jsonItem.insert("name", QObject::tr(option->name().toUtf8().data())); + jsonItem.insert("value", option->value().toString().replace("Meta", "Super")); + setupJsonItems.append(jsonItem); + } + setupJsonGroup.insert("groupItems", setupJsonItems); + jsonGroups.append(setupJsonGroup); + + shortcutObj.insert("shortcut", jsonGroups); + + QJsonDocument doc(shortcutObj); + + QStringList shortcutString; + QString param1 = "-j=" + QString(doc.toJson().data()); + QString param2 = "-p=" + QString::number(pos.x()) + "," + QString::number(pos.y()); + shortcutString << param1 << param2; + + m_shortcutViewProcess = new QProcess(); + m_shortcutViewProcess->startDetached("deepin-shortcut-viewer", shortcutString); + + connect(m_shortcutViewProcess, SIGNAL(finished(int)), m_shortcutViewProcess, SLOT(deleteLater())); +} + +/*! + * \~chinese \brief Window::doPrint 调用打印预览,将文本分块输出给打印机 + * \~chinese \param pageRange 打印预览请求的页码列表 + */ +#if (DTK_VERSION_MAJOR > 5 \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR > 4) \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR == 4 && DTK_VERSION_PATCH >= 10)) +void Window::doPrint(DPrinter *printer, const QVector &pageRange) +{ + if (nullptr == m_printDoc) { + return; + } + + //如果打印预览请求的页码为空,则直接返回 + if (pageRange.isEmpty()) { + return; + } + + QPainter p(printer); + if (!p.isActive()) + return; + + if (m_lastLayout.isValid() && !m_isNewPrint) { + if (m_lastLayout == printer->pageLayout()) { + // 如果打印属性没发生变化,直接加载已生成的资源,提高切换速度 + asynPrint(p, printer, pageRange); + return; + } + } + + //保留print的打印布局 + m_lastLayout = printer->pageLayout(); + m_isNewPrint = false; + + QTextOption opt = m_printDoc->defaultTextOption(); + opt.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + m_printDoc->setDefaultTextOption(opt); + + (void)m_printDoc->documentLayout(); // make sure that there is a layout + + if (currentWrapper() == nullptr) { + return; + } + QColor background = currentWrapper()->textEditor()->palette().color(QPalette::Base); + bool backgroundIsDark = background.value() < 128; + //对文本进行分页处理 + for (QTextBlock srcBlock = currentWrapper()->textEditor()->document()->firstBlock(), dstBlock = m_printDoc->firstBlock(); + srcBlock.isValid() && dstBlock.isValid(); + srcBlock = srcBlock.next(), dstBlock = dstBlock.next()) { + QVector formatList = srcBlock.layout()->formats(); + if (backgroundIsDark) { + // adjust syntax highlighting colors for better contrast + for (int i = formatList.count() - 1; i >= 0; --i) { + QTextCharFormat &format = formatList[i].format; + if (format.background().color() == background) { + QBrush brush = format.foreground(); + QColor color = brush.color(); + int h, s, v, a; + color.getHsv(&h, &s, &v, &a); + color.setHsv(h, s, qMin(128, v), a); + brush.setColor(color); + format.setForeground(brush); + } + format.setBackground(Qt::white); + } + } + + dstBlock.layout()->setFormats(formatList); + } + + QAbstractTextDocumentLayout *layout = m_printDoc->documentLayout(); + layout->setPaintDevice(p.device()); + + int dpiy = p.device()->logicalDpiY(); + int margin = static_cast((2 / 2.54) * dpiy); // 2 cm margins + + auto fmt = m_printDoc->rootFrame()->frameFormat(); + fmt.setMargin(margin); + m_printDoc->rootFrame()->setFrameFormat(fmt); + + QRectF pageRect(printer->pageRect()); + QRectF body = QRectF(0, 0, pageRect.width(), pageRect.height()); + QFontMetrics fontMetrics(m_printDoc->defaultFont(), p.device()); + QRectF titleBox(margin, + body.bottom() - margin + + fontMetrics.height() + - 6 * dpiy / 72.0, + body.width() - 2 * margin, + fontMetrics.height()); + m_printDoc->setPageSize(body.size()); + //输出总页码给到打印预览 + m_pPreview->setAsynPreview(m_printDoc->pageCount()); + + //渲染第一页文本 + for (int i = 0; i < pageRange.count(); ++i) { + if (pageRange[i] > m_printDoc->pageCount()) + continue; + Window::printPage(pageRange[i], &p, m_printDoc, body, titleBox); + if (i != pageRange.count() - 1) + printer->newPage(); + } +} + +/** + * @brief 用于较大的文本文件进行打印计算和绘制,使用 processEvents 规避打印输入 + * @param printer 打印指针 + * @param pageRange 打印范围 + */ +void Window::doPrintWithLargeDoc(DPrinter *printer, const QVector &pageRange) +{ + if (m_bPrintProcessing) { + return; + } + + if (m_printDocList.isEmpty()) { + return; + } + + //如果打印预览请求的页码为空,则直接返回 + if (pageRange.isEmpty()) { + return; + } + + QPainter p(printer); + if (!p.isActive()) + return; + + if (m_lastLayout.isValid() && !m_isNewPrint) { + if (m_lastLayout == printer->pageLayout()) { + // 如果打印属性没发生变化,直接加载已生成的资源,提高切换速度 + asynPrint(p, printer, pageRange); + return; + } + } + + //保留print的打印布局 + m_lastLayout = printer->pageLayout(); + m_isNewPrint = false; + + if (currentWrapper() == nullptr) { + return; + } + + qInfo() << qPrintable("Calc print large doc!"); + + // 执行处理时屏蔽其它输入 + DPrintPreviewWidget *prieviewWidget = m_pPreview->findChild(); + QStringList findWidgetList {"leftWidget", "rightWidget"}; + QWidgetList widList; + if (prieviewWidget) { + // 通过设置刷新标识,防止频繁的触发刷新 + prieviewWidget->refreshBegin(); + + for (QString widStr : findWidgetList) { + QWidget *wid = m_pPreview->findChild(widStr); + if (wid) { + wid->setEnabled(false); + widList.append(wid); + } else { + qWarning() << "not find widget"; + } + } + + QApplication::processEvents(); + } + + m_bPrintProcessing = true; + QPointer checkPtr(this); + + int dpiy = p.device()->logicalDpiY(); + int margin = static_cast((2 / 2.54) * dpiy); // 2 cm margins + + QRectF pageRect(printer->pageRect()); + QRectF body = QRectF(0, 0, pageRect.width(), pageRect.height()); + // 使用首个文档信息即可 + QFontMetrics fontMetrics(m_printDocList.first().doc->defaultFont(), p.device()); + QRectF titleBox(margin, + body.bottom() - margin + + fontMetrics.height() + - 6 * dpiy / 72.0, + body.width() - 2 * margin, + fontMetrics.height()); + + // Note:大文本打印的高亮处理被延迟到实际打印时计算 + m_multiDocPageCount = 0; + for (auto &info : m_printDocList) { + QTextDocument *printDoc = info.doc; + + QAbstractTextDocumentLayout *lay = info.doc->documentLayout(); + lay->setPaintDevice(p.device()); + + auto fmt = printDoc->rootFrame()->frameFormat(); + fmt.setMargin(margin); + printDoc->rootFrame()->setFrameFormat(fmt); + + // 设置打印大小 + printDoc->setPageSize(body.size()); + + for (QTextBlock block = printDoc->firstBlock(); block.isValid(); block = block.next()) { + // 通过对单个文本块进行布局,拆分布局总时间,防止布局时间过长 + lay->blockBoundingRect(block); + // 处理其它事件 + qApp->processEvents(QEventLoop::AllEvents | QEventLoop::DialogExec); + // 判断当前窗口是否关闭,退出打印状态 + if (!checkPtr || !m_bPrintProcessing) { + qWarning() << "Abort print layout!"; + + // 手动清理数据 + QObject::disconnect(m_pPreview, nullptr, this, nullptr); + clearPrintTextDocument(); + + // 异常退出、中断打印时需要关闭窗口 + QMetaObject::invokeMethod(m_pPreview, "reject", Qt::QueuedConnection); + return; + } + } + + // 更新文件总打印页数 + m_multiDocPageCount += printDoc->pageCount(); + } + + if (prieviewWidget) { + prieviewWidget->refreshEnd(); + } + + m_bPrintProcessing = false; + for (auto wid : widList) { + wid->setEnabled(true); + } + + //输出总页码给到打印预览 + m_pPreview->setAsynPreview(m_multiDocPageCount); + + if (!m_printDocList.isEmpty()) { + //渲染第一页文本 + for (int i = 0; i < pageRange.count(); ++i) { + if (pageRange[i] > m_multiDocPageCount) + continue; + printPageWithMultiDoc(pageRange[i], &p, m_printDocList, body, titleBox); + if (i != pageRange.count() - 1) + printer->newPage(); + } + } + + qInfo() << qPrintable("Calc print large doc finised!"); +} +#endif + +/*! + * \~chinese \brief Window::asynPrint 进行翻页预览打印 + * \~chinese \param pageRange 打印预览请求的页码列表 + */ +void Window::asynPrint(QPainter &p, DPrinter *printer, const QVector &pageRange) +{ + if ((!m_bLargePrint && nullptr == m_printDoc) + || (m_bLargePrint && m_printDocList.isEmpty())) { + qWarning() << "The print document is not valid!"; + return; + } + + QRectF pageRect(printer->pageRect()); + int dpiy = p.device()->logicalDpiY(); + int margin = static_cast((2 / 2.54) * dpiy); // 2 cm margins + QRectF body = QRectF(0, 0, pageRect.width(), pageRect.height()); + + QTextDocument *curDoc = m_bLargePrint ? m_printDocList.first().doc : m_printDoc; + QFontMetrics fontMetrics(curDoc->defaultFont(), p.device()); + QRectF titleBox(margin, + body.bottom() - margin + + fontMetrics.height() + - 6 * dpiy / 72.0, + body.width() - 2 * margin, + fontMetrics.height()); + + if (m_bLargePrint + && !m_printDocList.isEmpty()) { + // 大文本打印 + for (int i = 0; i < pageRange.count(); ++i) { + if (pageRange[i] > m_multiDocPageCount) + continue; + printPageWithMultiDoc(pageRange[i], &p, m_printDocList, body, titleBox); + if (i != pageRange.count() - 1) + printer->newPage(); + } + } else { + for (int i = 0; i < pageRange.count(); ++i) { + if (pageRange[i] > m_printDoc->pageCount()) + continue; + Window::printPage(pageRange[i], &p, m_printDoc, body, titleBox); + if (i != pageRange.count() - 1) + printer->newPage(); + } + } +} + +void Window::backupFile() +{ + if (!QFileInfo(m_backupDir).exists()) { + QDir().mkpath(m_backupDir); + } + + QMap wrappers = m_wrappers; + QStringList listBackupInfo; + QString filePath, localPath, curPos; + QFileInfo fileInfo; + m_qlistTemFile.clear(); + m_qlistTemFile = wrappers.keys(); + + for (EditWrapper *wrapper : wrappers) { + if (nullptr == wrapper) { + continue; + } + if (wrapper->getFileLoading()) continue; + + if (nullptr == wrapper->textEditor()) { + continue; + } + + filePath = wrapper->textEditor()->getFilePath(); + localPath = wrapper->textEditor()->getTruePath(); + + if (localPath.isEmpty()) { + localPath = wrapper->textEditor()->getFilePath(); + } + + qInfo() << "begin backupFile()"; + StartManager::FileTabInfo tabInfo = StartManager::instance()->getFileTabInfo(filePath); + curPos = QString::number(wrapper->textEditor()->textCursor().position()); + fileInfo.setFile(localPath); + + QJsonObject jsonObject; + QJsonDocument document; + jsonObject.insert("localPath", localPath); + jsonObject.insert("cursorPosition", QString::number(wrapper->textEditor()->textCursor().position())); + jsonObject.insert("modify", wrapper->isModified()); + jsonObject.insert("lastModifiedTime", wrapper->getLastModifiedTime().toString()); + QList bookmarkList = wrapper->textEditor()->getBookmarkInfo(); + if (!bookmarkList.isEmpty()) { + QString bookmarkInfo; + + //记录书签 + for (int i = 0; i < bookmarkList.count(); i++) { + if (i == bookmarkList.count() - 1) { + bookmarkInfo.append(QString::number(bookmarkList.value(i))); + } else { + bookmarkInfo.append(QString::number(bookmarkList.value(i)) + ","); + } + } + + jsonObject.insert("bookMark", bookmarkInfo); + } + + //记录活动页 + if (filePath == m_tabbar->currentPath()) { + jsonObject.insert("focus", true); + } + + //保存备份文件 + if (Utils::isDraftFile(filePath)) { + wrapper->saveTemFile(filePath); + } else { + if (wrapper->isModified()) { + QString name = fileInfo.absolutePath().replace("/", "_"); + QString qstrFilePath = m_backupDir + "/" + Utils::getStringMD5Hash(fileInfo.baseName()) + "." + name + "." + fileInfo.suffix(); + jsonObject.insert("temFilePath", qstrFilePath); + wrapper->saveTemFile(qstrFilePath); + } + } + + qInfo() << "after call wrapper->saveTemFile()"; + + //使用json串形式保存 + document.setObject(jsonObject); + QByteArray byteArray = document.toJson(QJsonDocument::Compact); + m_qlistTemFile.replace(tabInfo.tabIndex, byteArray); + } + + //将json串列表写入配置文件 + m_settings->settings->option("advance.editor.browsing_history_temfile")->setValue(m_qlistTemFile); + + //删除自动备份文件 + if (QFileInfo(m_autoBackupDir).exists()) { + QDir(m_autoBackupDir).removeRecursively(); + } + + qInfo() << "end backupFile()"; +} + +bool Window::closeAllFiles() +{ + qInfo() << "begin closeAllFiles()"; + QMap wrappers = m_wrappers; + + // 被删除的窗口索引已变更,需要计算其范围 + int closedTabCount = 0; + //关闭所有文件 + for (int i = 0; i < wrappers.count(); i++) { + // 窗口索引 - 已删除窗口索引 + m_tabbar->setCurrentIndex(i - closedTabCount); + + if (!closeTab()) { + // 取消操作时,停留在当前标签页 + return false; + } else { + // 窗口已删除,调整索引 + ++closedTabCount; + } + } + qInfo() << "end closeAllFiles()"; + return true; +} + +/** + * @brief addTemFileTab 恢复备份文件标签页 + * @param qstrPath 打开文件路径 + * @param qstrName 真实文件名 + * @param qstrTruePath 真实文件路径 + * @param qstrTruePath 最后一次修改时间 + * @param bIsTemFile 是否修改 + */ +void Window::addTemFileTab(const QString &qstrPath, const QString &qstrName, const QString &qstrTruePath, const QString &lastModifiedTime, bool bIsTemFile) +{ + if (qstrPath.isEmpty() || !Utils::fileExists(qstrPath)) { + return; + } + + // 若为MIMETYPE不支持的文件,给出无效文件提示 修复bug:https://pms.uniontech.com/bug-view-132653.html + if (!Utils::isMimeTypeSupport(qstrPath)) { + if (currentWrapper() == nullptr) { + this->addBlankTab(); + } + + QString strFileName = QFileInfo(qstrPath).fileName(); + strFileName = tr("Invalid file: %1").arg(strFileName); + strFileName = Utils::lineFeed(strFileName, m_editorWidget->currentWidget()->width() - FLOATTIP_MARGIN, m_editorWidget->currentWidget()->font(), 2); + DMessageManager::instance()->sendMessage(m_editorWidget->currentWidget(), QIcon(":/images/warning.svg"), strFileName); + + return; + } + + EditWrapper *wrapper = createEditor(); + m_tabbar->addTab(qstrPath, qstrName, qstrTruePath); + wrapper->openFile(qstrPath, qstrTruePath, bIsTemFile); + + // 查找文件是否存在书签,临时文件同样可标记书签 + auto bookmarkInfo = StartManager::instance()->findBookmark(qstrTruePath); + wrapper->textEditor()->setBookMarkList(bookmarkInfo); + + //set m_tModifiedDateTime in wrapper again. + if (bIsTemFile && !lastModifiedTime.isEmpty()) { + wrapper->setLastModifiedTime(lastModifiedTime); + } + m_wrappers[qstrPath] = wrapper; + showNewEditor(wrapper); +} + +QMap Window::getWrappers() +{ + return m_wrappers; +} + +void Window::setChildrenFocus(bool ok) +{ + if (ok) { + DIconButton *addButton = m_tabbar->findChild("AddButton"); + DIconButton *optionBtn = titlebar()->findChild("DTitlebarDWindowOptionButton"); + DIconButton *minBtn = titlebar()->findChild("DTitlebarDWindowMinButton"); + DIconButton *quitFullBtn = titlebar()->findChild("DTitlebarDWindowQuitFullscreenButton"); + DIconButton *maxBtn = titlebar()->findChild("DTitlebarDWindowMaxButton"); + DIconButton *closeBtn = titlebar()->findChild("DTitlebarDWindowCloseButton"); + + titlebar()->setFocusPolicy(Qt::TabFocus); + if (addButton) addButton->setFocusPolicy(Qt::TabFocus); + if (optionBtn) optionBtn->setFocusPolicy(Qt::TabFocus); + if (minBtn) minBtn->setFocusPolicy(Qt::TabFocus); + if (quitFullBtn) quitFullBtn->setFocusPolicy(Qt::TabFocus); + if (maxBtn) maxBtn->setFocusPolicy(Qt::TabFocus); + if (closeBtn) closeBtn->setFocusPolicy(Qt::TabFocus); + + setTabOrder(addButton, optionBtn); + setTabOrder(optionBtn, minBtn); + setTabOrder(minBtn, quitFullBtn); + setTabOrder(quitFullBtn, maxBtn); + setTabOrder(maxBtn, closeBtn); + } else { + DIconButton *addButton = m_tabbar->findChild("AddButton"); + DIconButton *optionBtn = titlebar()->findChild("DTitlebarDWindowOptionButton"); + DIconButton *minBtn = titlebar()->findChild("DTitlebarDWindowMinButton"); + DIconButton *quitFullBtn = titlebar()->findChild("DTitlebarDWindowQuitFullscreenButton"); + DIconButton *maxBtn = titlebar()->findChild("DTitlebarDWindowMaxButton"); + DIconButton *closeBtn = titlebar()->findChild("DTitlebarDWindowCloseButton"); + + titlebar()->setFocusPolicy(Qt::NoFocus); + if (addButton) addButton->setFocusPolicy(Qt::NoFocus); + if (optionBtn) optionBtn->setFocusPolicy(Qt::NoFocus); + if (minBtn) minBtn->setFocusPolicy(Qt::NoFocus); + if (quitFullBtn) quitFullBtn->setFocusPolicy(Qt::NoFocus); + if (maxBtn) maxBtn->setFocusPolicy(Qt::NoFocus); + if (closeBtn) closeBtn->setFocusPolicy(Qt::NoFocus); + } +} + +void Window::addBlankTab() +{ + addBlankTab(""); +} + +void Window::addBlankTab(const QString &blankFile) +{ + QString blankTabPath; + + if (blankFile.isEmpty()) { + const QString &fileName = QString("blank_file_%1").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss-zzz")); + blankTabPath = QDir(m_blankFileDir).filePath(fileName); + + if (!Utils::fileExists(blankTabPath)) { + QDir().mkpath(m_blankFileDir); + } + } else { + blankTabPath = blankFile; + } + + int blankFileIndex = getBlankFileIndex(); + m_tabbar->addTab(blankTabPath, tr("Untitled %1").arg(blankFileIndex)); + EditWrapper *wrapper = createEditor(); + wrapper->updatePath(blankTabPath); + + if (!blankFile.isEmpty() && Utils::fileExists(blankFile)) { + wrapper->openFile(blankTabPath, blankTabPath); + } + + m_wrappers[blankTabPath] = wrapper; + showNewEditor(wrapper); +} + +/** + * @brief 标签页关闭请求处理 + * @param index 标签页索引 + * + * @note 由于使用 Qt::QueuedConnection 模式,在界面被其它任务阻塞时,可能触发多次关闭事件, + * 导致队列中存在多个请求关闭任务,阻塞结束后,重复触发,删除所有的标签页,导致窗口关闭。 + */ +void Window::handleTabCloseRequested(int index) +{ + // 延迟执行关闭标签页 + if (!m_delayCloseTabTimer.isActive()) { + // 记录关闭标签索引 + m_requestCloseTabIndex = index; + + // 延迟10ms + static const int s_nDelayTime = 10; + m_delayCloseTabTimer.start(s_nDelayTime, this); + } +} + +void Window::handleTabsClosed(QStringList tabList) +{ + if (tabList.isEmpty()) { + return; + } + + for (const QString &path : tabList) { + int index = m_tabbar->indexOf(path); + m_tabbar->setCurrentIndex(index); + closeTab(); + } +} + +void Window::handleCurrentChanged(const int &index) +{ + if (m_findBar->isVisible()) { + m_findBar->hide(); + } + + if (m_replaceBar->isVisible()) { + m_replaceBar->hide(); + } + + if (m_jumpLineBar->isVisible()) { + m_jumpLineBar->hide(); + } + + for (auto wrapper : m_wrappers.values()) { + wrapper->textEditor()->removeKeywords(); + } + + if (currentWrapper()) { + currentWrapper()->checkForReload(); + checkTabbarForReload(); + } + + const QString &filepath = m_tabbar->fileAt(index); + + if (m_wrappers.contains(filepath)) { + bool bIsContains = false; + EditWrapper *wrapper = m_wrappers.value(filepath); + wrapper->textEditor()->setFocus(); + for (int i = 0; i < m_editorWidget->count(); i++) { + if (m_editorWidget->widget(i) == wrapper) { + bIsContains = true; + } + } + + if (!bIsContains) { + m_editorWidget->addWidget(wrapper); + } + + m_editorWidget->setCurrentWidget(wrapper); + } + + if (currentWrapper() != nullptr) { + currentWrapper()->bottomBar()->show(); + currentWrapper()->bottomBar()->updateSize(32, false); + } +} + +void Window::handleJumpLineBarExit() +{ + if (currentWrapper() != nullptr) { + QTimer::singleShot(0, currentWrapper()->textEditor(), SLOT(setFocus())); + } +} + +void Window::handleJumpLineBarJumpToLine(const QString &filepath, int line, bool focusEditor) +{ + if (m_wrappers.contains(filepath)) { + getTextEditor(filepath)->jumpToLine(line, true); + + if (focusEditor) { + QTimer::singleShot(0, getTextEditor(filepath), SLOT(setFocus())); + } + } +} + +void Window::handleBackToPosition(const QString &file, int row, int column, int scrollOffset) +{ + if (m_wrappers.contains(file)) { + m_wrappers.value(file)->textEditor()->scrollToLine(scrollOffset, row, column); + } +} + +void Window::handleFindNextSearchKeyword(const QString &keyword) +{ + handleFindKeyword(keyword, true); +} + +void Window::handleFindPrevSearchKeyword(const QString &keyword) +{ + handleFindKeyword(keyword, false); +} + +void Window::handleFindKeyword(const QString &keyword, bool state) +{ + EditWrapper *wrapper = currentWrapper(); + m_keywordForSearch = keyword; + wrapper->textEditor()->saveMarkStatus(); + wrapper->textEditor()->updateCursorKeywordSelection(m_keywordForSearch, state); + if (QString::compare(m_keywordForSearch, m_keywordForSearchAll, Qt::CaseInsensitive) != 0) { + m_keywordForSearchAll.clear(); + wrapper->textEditor()->clearFindMatchSelections(); + } else { + wrapper->textEditor()->highlightKeywordInView(m_keywordForSearchAll); + } + + wrapper->textEditor()->markAllKeywordInView(); + + wrapper->textEditor()->renderAllSelections(); + wrapper->textEditor()->restoreMarkStatus(); + wrapper->textEditor()->updateLeftAreaWidget(); + + // 变更查询字符串位置后(可能滚屏),刷新当前界面的代码高亮效果 + wrapper->OnUpdateHighlighter(); +} + +void Window::slotFindbarClose() +{ + EditWrapper *wrapper = currentWrapper(); + + if (wrapper->bottomBar()->isHidden()) { + wrapper->bottomBar()->show(); + } + + wrapper->bottomBar()->updateSize(32, false); + currentWrapper()->textEditor()->setFocus(); + currentWrapper()->textEditor()->tellFindBarClose(); +} + +void Window::slotReplacebarClose() +{ + EditWrapper *wrapper = currentWrapper(); + + if (wrapper->bottomBar()->isHidden()) { + wrapper->bottomBar()->show(); + } + + wrapper->bottomBar()->updateSize(32, false); + currentWrapper()->textEditor()->setFocus(); + currentWrapper()->textEditor()->tellFindBarClose(); +} + +void Window::handleReplaceAll(const QString &replaceText, const QString &withText) +{ + EditWrapper *wrapper = currentWrapper(); + wrapper->textEditor()->replaceAll(replaceText, withText); +} + +void Window::handleReplaceNext(const QString &file, const QString &replaceText, const QString &withText) +{ + Q_UNUSED(file); + m_keywordForSearch = replaceText; + m_keywordForSearchAll = replaceText; + EditWrapper *wrapper = currentWrapper(); + wrapper->textEditor()->replaceNext(replaceText, withText); +} + +void Window::handleReplaceRest(const QString &replaceText, const QString &withText) +{ + EditWrapper *wrapper = currentWrapper(); + wrapper->textEditor()->replaceRest(replaceText, withText); +} + +void Window::handleReplaceSkip(QString file, QString keyword) +{ + EditWrapper *wrapper = currentWrapper(); + handleUpdateSearchKeyword(m_replaceBar, file, keyword); + if (QString::compare(m_keywordForSearch, m_keywordForSearchAll, Qt::CaseInsensitive) != 0) { + m_keywordForSearchAll.clear(); + wrapper->textEditor()->clearFindMatchSelections(); + } else { + wrapper->textEditor()->highlightKeywordInView(m_keywordForSearchAll); + } +#if 0 + EditWrapper *wrapper = currentWrapper(); + wrapper->textEditor()->updateCursorKeywordSelection(m_keywordForSearchAll, true); + wrapper->textEditor()->renderAllSelections(); +#endif +} + +void Window::handleRemoveSearchKeyword() +{ + if (currentWrapper() != nullptr) { + currentWrapper()->textEditor()->removeKeywords(); + } +} + +void Window::handleUpdateSearchKeyword(QWidget *widget, const QString &file, const QString &keyword) +{ + if (file == m_tabbar->currentPath() && m_wrappers.contains(file)) { + + // Update input widget warning status along with keyword match situation. + bool findKeyword = m_wrappers.value(file)->textEditor()->highlightKeyword(keyword, m_wrappers.value(file)->textEditor()->getPosition()); + m_keywordForSearchAll = keyword; + m_keywordForSearch = keyword; + // bool findKeyword = m_wrappers.value(file)->textEditor()->findKeywordForward(keyword); + bool emptyKeyword = keyword.trimmed().isEmpty(); + + auto *findBarWidget = qobject_cast(widget); + if (findBarWidget != nullptr) { + if (emptyKeyword) { + findBarWidget->setMismatchAlert(false); + } else { + findBarWidget->setMismatchAlert(!findKeyword); + } + } else { + auto *replaceBarWidget = qobject_cast(widget); + if (replaceBarWidget != nullptr) { + if (emptyKeyword) { + replaceBarWidget->setMismatchAlert(false); + } else { + replaceBarWidget->setMismatchAlert(false); + } + } + } + } + EditWrapper *wrapper = currentWrapper(); + wrapper->textEditor()->updateLeftAreaWidget(); + // 在设置查询字符串并跳转后,及时刷新代码高亮效果 + wrapper->OnUpdateHighlighter(); +} + +void Window::loadTheme(const QString &path) +{ + QFileInfo fileInfo(path); + if (!fileInfo.exists()) { + return; + } + + m_themePath = path; + + QVariantMap jsonMap = Utils::getThemeMapFromPath(path); + const QString &backgroundColor = jsonMap["editor-colors"].toMap()["background-color"].toString(); + const QString &tabbarStartColor = jsonMap["app-colors"].toMap()["tab-background-start-color"].toString(); + const QString &tabbarEndColor = jsonMap["app-colors"].toMap()["tab-background-end-color"].toString(); + + + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->OnThemeChangeSlot(m_themePath); + } + + m_themePanel->setBackground(backgroundColor); + m_tabbar->setBackground(tabbarStartColor, tabbarEndColor); + m_tabbar->setDNDColor(jsonMap["app-colors"].toMap()["tab-dnd-start"].toString(), jsonMap["app-colors"].toMap()["tab-dnd-end"].toString()); + + const QString &frameSelectedColor = jsonMap["app-colors"].toMap()["themebar-frame-selected"].toString(); + const QString &frameNormalColor = jsonMap["app-colors"].toMap()["themebar-frame-normal"].toString(); + m_themePanel->setFrameColor(frameSelectedColor, frameNormalColor); + m_settings->settings->option("advance.editor.theme")->setValue(path); +} + +void Window::showNewEditor(EditWrapper *wrapper) +{ + m_editorWidget->addWidget(wrapper); + m_editorWidget->setCurrentWidget(wrapper); +} + +void Window::showNotify(const QString &message) +{ + //DMainWindow::sendMessage(QIcon(":/images/ok.svg"), message); + //如果是第一次打开编辑器,需要创建一个空白编辑显示框窗体 + if (currentWrapper() == nullptr) { + this->addBlankTab(); + } + currentWrapper()->showNotify(message); +} + +int Window::getBlankFileIndex() +{ + // get blank tab index list. + QList tabIndexes; + + // tabFiles.size() + for (int i = 0; i < m_tabbar->count(); ++i) { + // find all the blank tab index number. + QFileInfo fileInfo(m_tabbar->fileAt(i)); + if (fileInfo.dir().absolutePath() == m_blankFileDir) { + const QString tabText = m_tabbar->textAt(i); + QRegularExpression reg("(\\d+)"); + QRegularExpressionMatch match = reg.match(tabText); + + tabIndexes << match.captured(1).toInt(); + } + } + std::sort(tabIndexes.begin(), tabIndexes.end()); + + // Return 1 if no blank file exists. + if (tabIndexes.size() == 0) { + return 1; + } + + // Return first mismatch index as new blank file index. + for (int j = 0; j < tabIndexes.size(); j++) { + if (tabIndexes[j] != j + 1) { + return j + 1; + } + } + + // Last, return biggest index as blank file index. + return tabIndexes.size() + 1; +} + +DDialog *Window::createDialog(const QString &title, const QString &content) +{ + DDialog *dialog = new DDialog(title, content, this); + //dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnBottomHint); + dialog->setWindowModality(Qt::ApplicationModal); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setIcon(QIcon::fromTheme("deepin-editor")); + dialog->addButton(QString(tr("Cancel")), false, DDialog::ButtonNormal); + dialog->addButton(QString(tr("Discard")), false, DDialog::ButtonNormal); + dialog->addButton(QString(tr("Save")), true, DDialog::ButtonRecommend); + + return dialog; +} + +void Window::slotLoadContentTheme(DGuiApplicationHelper::ColorType themeType) +{ + if (themeType == DGuiApplicationHelper::ColorType::LightType) { + loadTheme(DEEPIN_THEME); + if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::ColorType::UnknownType) { + DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::ColorType::UnknownType); + } + } else if (themeType == DGuiApplicationHelper::ColorType::DarkType) { + loadTheme(DEEPIN_DARK_THEME); + if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::ColorType::UnknownType) { + DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::ColorType::UnknownType); + } + } + + QString qstrColor = palette().color(QPalette::Active, QPalette::Text).name(); + + for (auto wrapper : m_wrappers) { + wrapper->textEditor()->setEditPalette(qstrColor, qstrColor); + wrapper->OnUpdateHighlighter(); + } + + qstrColor = palette().color(QPalette::Active, QPalette::ButtonText).name(); + QString qstrHighlightColor = palette().color(QPalette::Active, QPalette::HighlightedText).name(); + + m_tabbar->setTabPalette(qstrColor, qstrHighlightColor); +} + +void Window::slotSettingResetTheme(const QString &path) +{ + if (path == DEEPIN_THEME) { + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { + return; + } else { + DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::LightType); + } + } else if (path == DEEPIN_DARK_THEME) { + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType) { + return; + } else { + DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::DarkType); + } + } +} + +void Window::slot_saveReadingPath() +{ + m_reading_list.clear(); + m_reading_list.append(currentWrapper()->textEditor()); +} + +void Window::slot_beforeReplace(QString _) +{ + currentWrapper()->textEditor()->beforeReplace(_); +} + +void Window::slot_setTitleFocus() +{ + QMap::Iterator it = m_wrappers.begin(); + for (; it != m_wrappers.end(); it++) { + it.value()->bottomBar()->setChildrenFocus(true); + } + + titlebar()->setFocusPolicy(Qt::TabFocus); + titlebar()->setFocus(Qt::MouseFocusReason); + DIconButton *addButton = m_tabbar->findChild("AddButton"); + addButton->setFocusPolicy(Qt::TabFocus); + DIconButton *optionBtn = titlebar()->findChild("DTitlebarDWindowOptionButton"); + optionBtn->setFocusPolicy(Qt::TabFocus); + DIconButton *minBtn = titlebar()->findChild("DTitlebarDWindowMinButton"); + minBtn->setFocusPolicy(Qt::TabFocus); + + DIconButton *quitFullBtn = titlebar()->findChild("DTitlebarDWindowQuitFullscreenButton"); + quitFullBtn->setFocusPolicy(Qt::TabFocus); + DIconButton *maxBtn = titlebar()->findChild("DTitlebarDWindowMaxButton"); + maxBtn->setFocusPolicy(Qt::TabFocus); + DIconButton *closeBtn = titlebar()->findChild("DTitlebarDWindowCloseButton"); + closeBtn->setFocusPolicy(Qt::TabFocus); + QWidget::setTabOrder(addButton, optionBtn); + QWidget::setTabOrder(optionBtn, minBtn); + QWidget::setTabOrder(minBtn, quitFullBtn); + QWidget::setTabOrder(quitFullBtn, maxBtn); + QWidget::setTabOrder(maxBtn, closeBtn); + currentWrapper()->bottomBar()->setChildrenFocus(true, closeBtn); +} + +void Window::slotClearDoubleCharaterEncode() +{ + //赛迪方要求不能出现以下字符,但是编码库中存在,所以手动去掉 + QStringList shouldBeEmpty; + shouldBeEmpty << "\uE768" << "\uE769" << "\uE76A" << "\uE76B" << "\uE76D" << "\uE76E" << "\uE76F" << "\uE766" << "\uE767" << "\uE770" + << "\uE771" << "\uE777" << "\uE778" << "\uE779" << "\uE77A" << "\uE77B" << "\uE77C" << "\uE77D" << "\uE77E" << "\uE77F" << "\uE7FE" << "\uE7FF" + << "\uE801" << "\uE802" << "\uE803" << "\uE804" << "\uE805" << "\uE806" << "\uE807" << "\uE808" << "\uE809" << "\uE80A" << "\uE80B" << "\uE80C" << "\uE80D" << "\uE80E" + << "\uE80F" << "\uE800" << "\uE7D3" << "\uE7D4" << "\uE7D5" << "\uE7D6" << "\uE7D7" << "\uE7D8" << "\uE7D9" << "\uE7DA" << "\uE7DB" << "\uE7DC" << "\uE7DD" + << "\uE7DE" << "\uE7DF" << "\uE7E0" << "\uE7E1" << "\uE7CD" << "\uE7CE" << "\uE7CF" << "\uE7D0" << "\uE7D1" << "\uE7D2" << "\uE7AF" << "\uE7B0" << "\uE7B1" << "\uE7B2" + << "\uE7B3" << "\uE7B4" << "\uE7B5" << "\uE7B6" << "\uE7B7" << "\uE7B8" << "\uE7B9" << "\uE7BA" << "\uE7BB" << "\uE7A0" << "\uE7A1" << "\uE7A2" << "\uE7A3" << "\uE7A4" + << "\uE7A5" << "\uE7A6" << "\uE7A7" << "\uE7A8" << "\uE7A9" << "\uE7AA" << "\uE7AB" << "\uE7AC" << "\uE7AD" << "\uE7AE" << "\uE797" << "\uE798" << "\uE799" << "\uE79A" + << "\uE79B" << "\uE79C" << "\uE79D" << "\uE79E" << "\uE79F" << "\uE780" << "\uE781" << "\uE782" << "\uE783" << "\uE784" << "\uE772" << "\uE773" << "\uE774" << "\uE775" + << "\uE776" << "\uE78D" << "\uE78E" << "\uE78F" << "\uE790" << "\uE791" << "\uE792" << "\uE793" << "\uE796" + << "\uE7BC" << "\uE7BD" << "\uE7BE" << "\uE7BF" << "\uE7C0" << "\uE7C1" << "\uE7C2" << "\uE7C3" << "\uE7C4" + << "\uE7C5" << "\uE7C6" << "\uE7E3" << "\uE7E4" << "\uE7E5" << "\uE7E6" << "〾⿰⿱⿲⿳⿴⿵" << "\uE7F4" << "\uE7F5" << "\uE7F6" + << "\uE7F7" << "\uE7F8" << "\uE7F9" << "\uE7FA" << "\uE7FB" << "\uE7FC" << "⿶⿷⿸⿹⿺⿻" << "\uE7FD" + << "\u4DB6" << "\uE26C" << "\uE28F" << "\uE290" << "\uE291" << "\uE292" << "\uE293" << "\uE294" << "\uE295" << "\uE296" << "\uE297" << "\uE298" << "\uE299" + << "\uE29A" << "\uE29B" << "\uE29C" << "\uE29D" << "\uE29E" << "\uE29F" << "\uE26D" + << "\uE644" << "\uE645" << "\uE645" << "\uE646" << "\uE647" << "\uE648" << "\uE649" << "\uE64A" << "\uE64B" << "\uE64C" << "\uE64D" << "\uE64E" << "\uE64F" + << "\uE680" << "\uE681" << "\uE682" << "\uE683" << "\uE686" << "\uE688" << "\uE689" << "\uE68A" << "\uE68B" << "\uE68C" << "\uE68D" << "\uE6AC" << "\uE6AD" << "\uE6AE"; + + for (const QString &strTemp : shouldBeEmpty) { + handleReplaceAll(strTemp, " "); + } +} + +void Window::slotSigThemeChanged(const QString &path) +{ + if (path == DEEPIN_THEME) { + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { + return; + } else { + DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::LightType); + } + } else if (path == DEEPIN_DARK_THEME) { + if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType) { + return; + } else { + DGuiApplicationHelper::instance()->setPaletteType(DGuiApplicationHelper::DarkType); + } + } +} + +void Window::slotSigAdjustFont(QString fontName) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->textEditor()->setFontFamily(fontName); + } +} + +void Window::slotSigAdjustFontSize(qreal fontSize) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->textEditor()->setFontSize(fontSize); + wrapper->bottomBar()->setScaleLabelText(fontSize); + wrapper->OnUpdateHighlighter(); + } + + m_fontSize = fontSize; +} + +void Window::slotSigAdjustTabSpaceNumber(int number) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->textEditor()->setTabSpaceNumber(number); + } +} + +void Window::slotSigAdjustWordWrap(bool enable) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + TextEdit *textedit = wrapper->textEditor(); + textedit->setLineWrapMode(enable); + } +} + +void Window::slotSigSetLineNumberShow(bool bIsShow) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->setLineNumberShow(bIsShow); + } +} + +void Window::slotSigAdjustBookmark(bool bIsShow) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + TextEdit *textedit = wrapper->textEditor(); + textedit->setBookmarkFlagVisable(bIsShow); + } +} + +void Window::slotSigShowBlankCharacter(bool bIsShow) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->setShowBlankCharacter(bIsShow); + } +} + +void Window::slotSigHightLightCurrentLine(bool bIsShow) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->textEditor()->setHighLineCurrentLine(bIsShow); + } +} + +void Window::slotSigShowCodeFlodFlag(bool bIsShow) +{ + for (EditWrapper *wrapper : m_wrappers.values()) { + TextEdit *textedit = wrapper->textEditor(); + textedit->setCodeFlodFlagVisable(bIsShow); + } +} + +void Window::slotSigChangeWindowSize(QString mode) +{ + if (mode == "fullscreen") { + this->showFullScreen(); + } else if (mode == "window_maximum") { + this->showNormal(); + this->showMaximized(); + } else { + this->showNormal(); + } +} + +void Window::slotIsRegisteredIflytekAiassistant(bool bIsRegistIflytekAiassistant) +{ + m_bIsRegistIflytekAiassistant = bIsRegistIflytekAiassistant; +} + +void Window::handleFocusWindowChanged(QWindow *w) +{ + if (windowHandle() != w || !currentWrapper() || !isActiveWindow()) { + return; + } + + currentWrapper()->checkForReload(); + checkTabbarForReload(); +} + +void Window::updateThemePanelGeomerty() +{ + int yOffset = isFullScreen() ? 0 : titlebar()->height(); + QRect themePanelRect(0, yOffset, 250, height() - yOffset); + themePanelRect.moveRight(rect().right()); + m_themePanel->setGeometry(themePanelRect); +} + +void Window::checkTabbarForReload() +{ + /* 修复99423 bug暂且屏蔽;拖拽出只读tab文件项,只读字样消失 + int cur = m_tabbar->currentIndex(); + QFileInfo fi(m_tabbar->truePathAt(cur)); + */ + QFileInfo fi; + if (m_tabbar->currentPath().contains("backup-files")) { + fi.setFile(m_tabbar->truePathAt(m_tabbar->currentIndex())); + } else { + fi.setFile(m_tabbar->currentPath()); + } + + QString tabName = m_tabbar->currentName(); + QString readOnlyStr = QString(" (%1)").arg(tr("Read-Only")); + tabName.remove(readOnlyStr); + + EditWrapper *wrapper = m_wrappers.value(m_tabbar->currentPath()); + if (fi.exists() && !fi.isWritable()) { + tabName.append(readOnlyStr); + m_tabbar->setTabText(m_tabbar->currentIndex(), tabName); + wrapper->textEditor()->setReadOnlyPermission(true); + } else { + tabName.remove(readOnlyStr); + m_tabbar->setTabText(m_tabbar->currentIndex(), tabName); + wrapper->textEditor()->setReadOnlyPermission(false); + } + + setWindowTitleInfo(); + //m_tabbar->setTabText(m_tabbar->currentIndex(), tabName); + //判断是否需要阻塞系统关机 + emit sigJudgeBlockShutdown(); +} + +void Window::resizeEvent(QResizeEvent *e) +{ + if (m_themePanel->isVisible()) { + updateThemePanelGeomerty(); + } + + if (!isMaximized() && !isFullScreen()) { + m_settings->settings->option("advance.window.window_width")->setValue(rect().width()); + m_settings->settings->option("advance.window.window_height")->setValue(rect().height()); + if (m_needMoveToCenter) { + Dtk::Widget::moveToCenter(this); + m_needMoveToCenter = false; + } + } + + m_findBar->setGeometry(4, height() - m_findBar->height() - 4, width() - 8, m_findBar->height()); + m_replaceBar->setGeometry(4, height() - m_replaceBar->height() - 4, width() - 8, m_replaceBar->height()); + + for (EditWrapper *wrapper : m_wrappers.values()) { + wrapper->OnUpdateHighlighter(); + } + +#if 0 + if (!(m_tabbar->currentPath() == "")) { + EditWrapper *wrapper = m_wrappers.value(m_tabbar->currentPath()); + wrapper->textEditor()->hideRightMenu(); + } +#endif + + DMainWindow::resizeEvent(e); +} + +void Window::closeEvent(QCloseEvent *e) +{ + PerformanceMonitor::closeAppStart(); + + if (StartManager::instance()->isMultiWindow()) { + if (!closeAllFiles()) { + e->ignore(); + return; + } + } else { + bool save_tab_before_close = m_settings->settings->option("advance.startup.save_tab_before_close")->value().toBool(); + if (!save_tab_before_close) { + if (!closeAllFiles()) { + e->ignore(); + return; + } + } else { + backupFile(); + } + } + + // WARNING: 调用 QProcess::startDetached() 前同步配置,防止多线程对 qgetenv() 中的 environmentMutex 加锁 + // 导致创建进程 fork() 时保留了 environmentMutex 锁状态,使得父子进程陷入资源竞态,阻塞状态。 + if (m_settings->settings) { + m_settings->settings->sync(); + } + + // 退出打印状态 + m_bPrintProcessing = false; + + QProcess process; + process.start("dbus-send --print-reply --dest=com.iflytek.aiassistant /aiassistant/tts com.iflytek.aiassistant.tts.stopTTSDirectly"); + if (!process.waitForFinished(10)) { + process.terminate(); + } + + QList needSaveList; + QMap wrappers = m_wrappers; + + for (EditWrapper *wrapper : wrappers) { + if (nullptr == wrapper) { + continue; + } + m_wrappers.remove(wrapper->filePath()); + disconnect(wrapper->textEditor()); + wrapper->setQuitFlag(); + wrapper->deleteLater(); + } + + disconnect(m_settings, nullptr, this, nullptr); + //this->close(); + + + StartManager::instance()->closeAboutForWindow(this); + + emit closeWindow(); + + return DMainWindow::closeEvent(e); +} + +void Window::hideEvent(QHideEvent *event) +{ + if (this->isVisible()) { + if (currentWrapper() != nullptr) { + currentWrapper()->textEditor()->setFocus(); + } + } + //如果查找浮窗正显示着,则隐藏 + if (m_findBar->isVisible()) { + // m_findBar->hide(); + if (currentWrapper() != nullptr) { + currentWrapper()->bottomBar()->show(); + } + } + + //如果替换浮窗正显示着,则隐藏 +#if 0 + if (m_replaceBar->isVisible()) { + //m_replaceBar->hide(); + if (currentWrapper() != nullptr) { + currentWrapper()->m_bottomBar->show(); + } + } +#endif + DMainWindow::hideEvent(event); +} + +void Window::keyPressEvent(QKeyEvent *e) +{ + QString key = Utils::getKeyshortcut(e); + + if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "decrementfontsize") || + key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "incrementfontsize") || + key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "togglefullscreen")) { + currentWrapper()->textEditor()->setCodeFoldWidgetHide(true); + } + + if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "addblanktab")) { + addBlankTab(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "newwindow")) { + emit newWindow(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "savefile")) { + saveFile(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "saveasfile")) { + saveAsFile(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "selectnexttab")) { + m_tabbar->nextTab(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "selectprevtab")) { + m_tabbar->previousTab(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "closetab")) { + closeTab(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "restoretab")) { + restoreTab(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "closeothertabs")) { + m_tabbar->closeOtherTabs(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "openfile")) { + openFile(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "incrementfontsize")) { + incrementFontSize(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "decrementfontsize")) { + decrementFontSize(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "resetfontsize")) { + resetFontSize(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "togglefullscreen")) { + DIconButton *minBtn = titlebar()->findChild("DTitlebarDWindowMinButton"); + DIconButton *quitFullBtn = titlebar()->findChild("DTitlebarDWindowQuitFullscreenButton"); + quitFullBtn->setFocusPolicy(Qt::TabFocus); + DIconButton *maxBtn = titlebar()->findChild("DTitlebarDWindowMaxButton"); + if (minBtn->hasFocus() || maxBtn->hasFocus()) { + toggleFullscreen(); + quitFullBtn->setFocus(); + } else { + toggleFullscreen(); + } + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "find")) { + popupFindBar(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "findNext")) { + handleFindNextSearchKeyword(m_keywordForSearch); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "findPrev")) { + handleFindPrevSearchKeyword(m_keywordForSearch); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "replace")) { + popupReplaceBar(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "jumptoline")) { + popupJumpLineBar(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "saveposition")) { + remberPositionSave(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "restoreposition")) { + remberPositionRestore(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "escape")) { + emit pressEsc(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "displayshortcuts")) { + displayShortcuts(); + } else if (key == Utils::getKeyshortcutFromKeymap(m_settings, "window", "print")) { + popupPrintDialog(); + } else { + // Post event to window widget if match Alt+0 ~ Alt+9 + QRegularExpression re("^Alt\\+\\d"); + QRegularExpressionMatch match = re.match(key); + if (match.hasMatch()) { + auto tabIndex = key.replace("Alt+", "").toInt(); + if (tabIndex == 9) { + if (m_tabbar->count() > 1) { + activeTab(m_tabbar->count() - 1); + } + } else { + if (tabIndex <= m_tabbar->count()) { + activeTab(tabIndex - 1); + } + } + } + } +} + +void Window::keyReleaseEvent(QKeyEvent *keyEvent) +{ + if ((keyEvent->modifiers() | Qt::ShiftModifier) || (keyEvent->modifiers() | Qt::ControlModifier)) { +// if (nullptr != m_shortcutViewProcess) { +// int count = Utils::getProcessCountByName("deepin-shortcut-viewer"); +// if (count > 0) { +// Utils::killProcessByName("deepin-shortcut-viewer"); +// } +// delete (m_shortcutViewProcess); +// m_shortcutViewProcess = nullptr; +// } + } +} + + +void Window::dragEnterEvent(QDragEnterEvent *event) +{ + // Accept drag event if mime type is url. + event->accept(); +} + +void Window::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + + if (mimeData->hasUrls()) { + QStringList supportfileNames; + QStringList otherfiles; + for (auto url : mimeData->urls()) { + QString file = url.toLocalFile(); + if (Utils::isMimeTypeSupport(file)) { + supportfileNames.append(file); + } else { + otherfiles.append(file); + } + } + + //先添加支持的文件 + foreach (QString var, supportfileNames) { + addTab(var, true); + } + + //后添加不支持文件 在最后编辑页面显示 + foreach (QString var, otherfiles) { + addTab(var, true); + } + } +} + +/** + * @brief 处理定时事件 \a e , 主要处理延迟关闭标签事件,会在定时器结束后关闭标签页 + */ +void Window::timerEvent(QTimerEvent *e) +{ + // 处理延迟关闭标签事件 + if (e->timerId() == m_delayCloseTabTimer.timerId()) { + m_delayCloseTabTimer.stop(); + + // 判断当前处理的标签页是否合法 + if (0 <= m_requestCloseTabIndex && m_requestCloseTabIndex < m_tabbar->count()) { + activeTab(m_requestCloseTabIndex); + closeTab(); + } + } +} + +bool Window::findBarIsVisiable() +{ + if (m_findBar->isVisible()) { + return true; + } else { + return false; + } +} + +bool Window::replaceBarIsVisiable() +{ + return m_replaceBar == nullptr ? false : m_replaceBar->isVisible(); +} + +QString Window::getKeywordForSearchAll() +{ + return m_keywordForSearchAll; +} + +QString Window::getKeywordForSearch() +{ + return m_keywordForSearch; +} + +void Window::setPrintEnabled(bool enabled) +{ + for (int i = 0; i < m_menu->actions().count(); i++) { + if (!m_menu->actions().at(i)->text().compare(QString("Print"))) { + m_menu->actions().at(i)->setEnabled(enabled); + return; + } + } +} + +QStackedWidget *Window::getStackedWgt() +{ + return m_editorWidget; +} diff --git a/src/widgets/window.h b/src/widgets/window.h new file mode 100644 index 0000000000000000000000000000000000000000..9f67de33dcd1baca072466ea6674deceaa9b6f81 --- /dev/null +++ b/src/widgets/window.h @@ -0,0 +1,318 @@ +// SPDX-FileCopyrightText: 2011-2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef WINDOW_H +#define WINDOW_H + +//#include "../controls/toolbar.h" +#include "../common/utils.h" +#include "../startmanager.h" +#include "../common/performancemonitor.h" +#include "../editor/editwrapper.h" +#include "../controls/findbar.h" +#include "../controls/jumplinebar.h" +#include "../controls/replacebar.h" +#include "../common/settings.h" +#include "../controls/tabbar.h" +#include "../thememodule/themepanel.h" +#include "../common/performancemonitor.h" +#include "../common/dbusinterface.h" +#include "../common/iflytekaiassistantthread.h" +#include "../common/CSyntaxHighlighter.h" +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class Window : public DMainWindow +{ + Q_OBJECT + +public: + // 打印文档信息,用于超大文档的打印 + struct PrintInfo { + QTextDocument *doc = nullptr; // 打印的文本 + CSyntaxHighlighter *highlighter = nullptr; // 高亮处理 + }; + + explicit Window(DMainWindow *parent = nullptr); + ~Window() override; + + /** + * @brief detectionIflytekaiassistant 检测语音助手服务是否被注册 + * 通过dbus接口去检测语音助手服务会偶现应用卡死问题,开一个线程去检测规避应用卡死问题 + */ + void detectionIflytekaiassistant(); + bool getIsRegistIflytekAiassistant(); + /** + * @brief 加载语音助手配置文件 + */ + void loadIflytekaiassistantConfig(); + /** + * @brief 获取语音助手配置文件数据 + * @param mode_name 接口模块名称 + */ + bool getIflytekaiassistantConfig(const QString &mode_name); + //跟新文件修改状态 + void updateModifyStatus(const QString &path, bool isModified); + //跟新tab文件名称 + void updateSaveAsFileName(QString strOldFilePath, QString strNewFilePath); + void updateSabeAsFileNameTemp(QString strOldFilePath, QString strNewFilePath); + + void showCenterWindow(bool bIsCenter); + void initTitlebar(); + bool checkBlockShutdown(); + + int getTabIndex(const QString &file); + void activeTab(int index); + + Tabbar *getTabbar(); + + void addTab(const QString &filepath, bool activeTab = false); + void addTabWithWrapper(EditWrapper *wrapper, const QString &filepath, const QString &qstrTruePath, + const QString &tabName, int index = -1); + bool closeTab(); + bool closeTab(const QString &fileName); + void restoreTab(); + void clearBlack(); + + EditWrapper *createEditor(); + EditWrapper *currentWrapper(); + EditWrapper *wrapper(const QString &filePath); + TextEdit *getTextEditor(const QString &filepath); + void focusActiveEditor(); + void removeWrapper(const QString &filePath, bool isDelete = false); + + void openFile(); + bool saveFile(); + bool saveAsFile(); + QString saveAsFileToDisk(); + QString saveBlankFileToDisk(); + bool saveAsOtherTabFile(EditWrapper *wrapper); + + void changeSettingDialogComboxFontNumber(int fontNumber); + void decrementFontSize(); + void incrementFontSize(); + void resetFontSize(); + void setFontSizeWithConfig(EditWrapper *editor); + + void popupFindBar(); + void popupReplaceBar(); + void popupJumpLineBar(); + void updateJumpLineBar(TextEdit *editor); + void popupSettingsDialog(); + void popupPrintDialog(); + void popupThemePanel(); + + void toggleFullscreen(); + + void remberPositionSave(); + void remberPositionRestore(); + + void displayShortcuts(); + // 文本打印 + void doPrint(DPrinter *printer, const QVector &pageRange); + // 大文本打印 + void doPrintWithLargeDoc(DPrinter *printer, const QVector &pageRange); + // 翻页预览打印,无需重新布局 + void asynPrint(QPainter &p, DPrinter *printer, const QVector &pageRange); + + // 备份文件 + void backupFile(); + // 关闭当前窗口所有文件 + bool closeAllFiles(); + // 恢复备份文件标签页 + void addTemFileTab(const QString &qstrPath, const QString &qstrName, const QString &qstrTruePath, const QString &lastModifiedTime, bool bIsTemFile = false); + + QMap getWrappers(); + + //设置显示清除焦点 + void setChildrenFocus(bool ok); + + bool replaceBarIsVisiable(); + bool findBarIsVisiable(); + QString getKeywordForSearchAll(); + QString getKeywordForSearch(); + void setPrintEnabled(bool enabled); + QStackedWidget *getStackedWgt(); + + static void printPage(int index, QPainter *painter, const QTextDocument *doc, + const QRectF &body, const QRectF &pageCountBox); + +signals: + void themeChanged(const QString themeName); + void requestDragEnterEvent(QDragEnterEvent *); + void requestDropEvent(QDropEvent *); + void newWindow(); + void closeWindow(); + void sigJudgeBlockShutdown(); + void pressEsc(); + // 标签页出现变更信号,文件添加或删除时触发 + void tabChanged(); + +public slots: + void addBlankTab(); + void addBlankTab(const QString &blankFile); + void handleTabCloseRequested(int index); + void handleTabsClosed(QStringList tabList); + void handleCurrentChanged(const int &index); + + void handleJumpLineBarExit(); + void handleJumpLineBarJumpToLine(const QString &filepath, int line, bool focusEditor); + + void handleBackToPosition(const QString &file, int row, int column, int scrollOffset); + + void handleFindNextSearchKeyword(const QString &keyword); + void handleFindPrevSearchKeyword(const QString &keyword); + /** + * @brief handleFindKeyword + * @param keyword + * @author ut002764 lxp 2021.4.27 + */ + void handleFindKeyword(const QString &keyword, bool state); + + void slotFindbarClose(); + void slotReplacebarClose(); + + void handleReplaceAll(const QString &replaceText, const QString &withText); + void handleReplaceNext(const QString &file, const QString &replaceText, const QString &withText); + void handleReplaceRest(const QString &replaceText, const QString &withText); + void handleReplaceSkip(QString file, QString keyword); + + void handleRemoveSearchKeyword(); + void handleUpdateSearchKeyword(QWidget *widget, const QString &file, const QString &keyword); + + void loadTheme(const QString &path); + + void showNewEditor(EditWrapper *wrapper); + void showNotify(const QString &message); + int getBlankFileIndex(); + + DDialog *createDialog(const QString &title, const QString &content); + + void slotLoadContentTheme(DGuiApplicationHelper::ColorType themeType); + void slotSettingResetTheme(const QString &path); + + void slot_saveReadingPath(); + void slot_beforeReplace(QString _); + void slot_setTitleFocus(); + //清除不支持双字节字符集符号 + void slotClearDoubleCharaterEncode(); + void slotSigThemeChanged(const QString &path); + void slotSigAdjustFont(QString fontName); + void slotSigAdjustFontSize(qreal fontSize); + void slotSigAdjustTabSpaceNumber(int number); + void slotSigAdjustWordWrap(bool enable); + void slotSigSetLineNumberShow(bool bIsShow); + void slotSigAdjustBookmark(bool bIsShow); + void slotSigShowBlankCharacter(bool bIsShow); + void slotSigHightLightCurrentLine(bool bIsShow); + void slotSigShowCodeFlodFlag(bool bIsShow); + void slotSigChangeWindowSize(QString mode); + /** + * @brief slotIsRegisteredIflytekAiassistant 接收并设置注册标识位 + * @param bIsRegistIflytekAiassistant 是否注册布尔标识位 + */ + void slotIsRegisteredIflytekAiassistant(bool bIsRegistIflytekAiassistant); + +private: + void handleFocusWindowChanged(QWindow *w); + void updateThemePanelGeomerty(); + void checkTabbarForReload(); + void clearPrintTextDocument(); + void setWindowTitleInfo(); + // 取得当前文档打开路径(新建文档为"系统-文档"目录) + QString getCurrentOpenFilePath(); + // 计算字体大小的缩放比例 + qreal calcFontScale(qreal fontSize); + // 从字体缩放比例推算字体大小 + qreal calcFontSizeFromScale(qreal fontScale); + + // 克隆文本数据 + bool cloneLargeDocument(EditWrapper *editWrapper); + // 打印多文本数据 + void printPageWithMultiDoc(int index, QPainter *painter, const QVector &printInfo, + const QRectF &body, const QRectF &pageCountBox); + // 重新更新文本 + void rehighlightPrintDoc(QTextDocument *doc, CSyntaxHighlighter *highlighter); + +protected: + void resizeEvent(QResizeEvent *event) override; + void closeEvent(QCloseEvent *event) override; + void hideEvent(QHideEvent *event) override; + void keyPressEvent(QKeyEvent *keyEvent) override; + void keyReleaseEvent(QKeyEvent *keyEvent) override; + void dragEnterEvent(QDragEnterEvent *e) override; + void dropEvent(QDropEvent *event) override; + // 处理延迟处理等定时器事件 + void timerEvent(QTimerEvent *e) override; + +private: + DBusDaemon::dbus *m_rootSaveDBus {nullptr}; + + QWidget *m_centralWidget {nullptr}; + DStackedWidget *m_editorWidget {nullptr}; + QVBoxLayout *m_centralLayout {nullptr}; + Tabbar *m_tabbar {nullptr}; + + JumpLineBar *m_jumpLineBar {nullptr}; + ReplaceBar *m_replaceBar {nullptr}; + ThemePanel *m_themePanel {nullptr}; + FindBar *m_findBar {nullptr}; + Settings *m_settings {nullptr}; + + QMap m_wrappers; + + DMenu *m_menu {nullptr}; + + QStringList m_closeFileHistory; + + QString m_remberPositionFilePath; + int m_remberPositionRow; + int m_remberPositionColumn; + int m_remberPositionScrollOffset; + + QString m_blankFileDir; + QString m_backupDir; + QString m_autoBackupDir; + qreal m_fontSize = 0; + + QString m_titlebarStyleSheet; + + QString m_keywordForSearch; + QString m_keywordForSearchAll; + + QString m_themePath; + QString m_tabbarActiveColor; + QList m_reading_list; + QStringList m_qlistTemFile;///<临时文件列表 + + QProcess *m_shortcutViewProcess = nullptr; + bool m_needMoveToCenter = false; + DPrintPreviewDialog *m_pPreview {nullptr}; + + //打印文本 + QTextDocument *m_printDoc = nullptr; // 打印文档,用于普通文档打印 + QPageLayout m_lastLayout; // 打印布局 + bool m_isNewPrint = false; // 判断是否是新的打印文档 + bool m_bLargePrint = false; // 是否为大文件打印 + bool m_bPrintProcessing = false; // 文件打印计算中 + EditWrapper *m_printWrapper = nullptr; // 当前处理的编辑对象(关闭标签页时需要退出打印) + QTextDocument *printCopyDoc = nullptr; // 用于大文本打印时的拷贝文档 + CSyntaxHighlighter *printCopyHighlighter = nullptr; // 用于大文本打印时的高亮文档 + QVector m_printDocList; // 打印文档列表,用于超大文档打印 + int m_multiDocPageCount = 0; // 用于超大文档打印时单独记录多文档的打印页数 + + QBasicTimer m_delayCloseTabTimer; // 延迟关闭标签页定时器,防止异常情况多次触发关闭同一标签页的情况 + int m_requestCloseTabIndex = 0; // 请求关闭的标签页索引 + + //语音助手服务是否被注册 + bool m_bIsRegistIflytekAiassistant {false}; + //记录语音助手接口配置状态 + QMap m_IflytekAiassistantState; +}; + +#endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e29c970a6e95d925a9ccc5387fd084f8e1c0315f --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,153 @@ +# Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd. +# +# Author: zhangteng +# +# Maintainer: zhangteng +# +# 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 . +ADD_COMPILE_OPTIONS(-fno-access-control) +set(CMAKE_CXX_FLAGS "-g -fprofile-arcs -ftest-coverage") +set(APP_QRC "../src/deepin-editor.qrc") + +# Find the library +find_package(PkgConfig REQUIRED) +find_package(Qt5Widgets REQUIRED) +find_package(Qt5DBus REQUIRED) +find_package(Qt5Concurrent REQUIRED) +find_package(Qt5PrintSupport REQUIRED) +find_package(Qt5Gui REQUIRED) +find_package(DtkWidget REQUIRED) +find_package(DtkCore REQUIRED) +find_package(KF5SyntaxHighlighting) +find_package(KF5Codecs) +find_package(DFrameworkdbus REQUIRED) +find_package(Qt5Test REQUIRED) +find_package(GTest REQUIRED) +find_package(Qt5Xml REQUIRED) +find_package(Qt5Svg REQUIRED) +find_package(Qt5Test REQUIRED) +find_package(ICU COMPONENTS i18n uc REQUIRED) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) +include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) +include_directories(Qt5PrintSupport) +include_directories(${GTEST_INCLUDE_DIRS}) +include_directories(src) +link_libraries(uchardet) +link_libraries(chardet) + +pkg_check_modules(chardet REQUIRED chardet) +include_directories(${chardet_INCLUDE_DIRS}) +link_directories(${chardet_LIBRARY_DIRS}) + +set(PROJECT_NAME_TEST + ${PROJECT_NAME}-test) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-inline") + +#Include all app own subdirectorys + + +file(GLOB_RECURSE INTRODUCTION_SRC_TEST ${CMAKE_CURRENT_LIST_DIR}/../src/*.cpp) +#file(GLOB_RECURSE INTRODUCTION_SRC_TEST ${CMAKE_CURRENT_LIST_DIR}/../src/*.) +#file(GLOB_RECURSE INTRODUCTION_SRC_TEST1 ${CMAKE_CURRENT_LIST_DIR}/src/*.) +file(GLOB_RECURSE INTRODUCTION_SRC_TEST1 ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp *.theme) +#file(GLOB_RECURSE INTRODUCTION_SRC_TEST1 ${CMAKE_CURRENT_LIST_DIR}/src/*.theme) + +list(REMOVE_ITEM INTRODUCTION_SRC_TEST "${CMAKE_CURRENT_LIST_DIR}/../src/main.cpp") +list(REMOVE_ITEM INTRODUCTION_SRC_TEST "${CMAKE_CURRENT_LIST_DIR}/../src/dedit/main.cpp") +list(REMOVE_ITEM INTRODUCTION_SRC_TEST "${CMAKE_CURRENT_LIST_DIR}/../src/common/encoding.cpp") + + +# 生成测试可执行程序 +add_executable(${PROJECT_NAME_TEST} + ${INTRODUCTION_SRC_TEST} + ${INTRODUCTION_SRC_TEST1} + ${APP_QRC} + ) + +# 生成测试可执行程序的依赖库 +target_link_libraries(${PROJECT_NAME_TEST} + gmock gmock_main gtest gtest_main + ${DtkWidget_LIBRARIES} + ${DtkCore_LIBRARIES} + ${DFrameworkdbus_LIBRARIES} + ${GSTREAMER_LIBRARIES} + ${Qt5PrintSupport_LIBRARIES} + ${LIBDMR_LIBRARIES} + ${GTEST_LIBRARIES} + ${GTEST_MAIN_LIBRARIES} + ${Qt5Xml_LIBRARIES} + ${Qt5Svg_LIBRARIES} + Qt5::Core + Qt5::Gui + Qt5::Widgets + Qt5::DBus + Qt5::Test + ${Qt5Widgets_LIBRARIES} + ${Qt5DBus_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + ${chardet_LIBRARY_DIRS} + KF5::Codecs + KF5::SyntaxHighlighting + ICU::i18n + ICU::uc + -lpthread + -lm + uchardet + chardet +) + +target_include_directories(${PROJECT_NAME_TEST} PUBLIC ${DtkWidget_INCLUDE_DIRS} + ${DtkCore_INCLUDE_DIRS} + ${DtkGui_INCLUDE_DIRS}) +#以下注释 +add_custom_target(test +# #执行mkdir -p 创建 coverageResult +# COMMAND mkdir -p test/coverageResult +# WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +# +add_custom_command(TARGET test + COMMAND echo " =================== CREAT LCOV REPROT BEGIN ==================== " + + COMMAND ${CMAKE_BINARY_DIR}/tests/${PROJECT_NAME_TEST} + + COMMAND echo " =================== TEST END ==================== " +) + +##'make test'命令依赖与我们的测试程序f +add_dependencies(test ${PROJECT_NAME_TEST}) +# +## 设置添加gocv相关信息的输出 +#set(CMAKE_CXX_FLAGS "-g -fprofile-arcs -ftest-coverage") + +#ASAN安全性检测标志 +set(CMAKE_SAFETYTEST "${CMAKE_SAFETYTEST_ARG}") +if(CMAKE_SAFETYTEST STREQUAL "") + set(CMAKE_SAFETYTEST "CMAKE_SAFETYTEST_ARG_OFF") +endif() + +#代码覆盖率开关 +if(CMAKE_COVERAGE_ARG STREQUAL "CMAKE_COVERAGE_ARG_ON") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -fprofile-arcs -ftest-coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -fprofile-arcs -ftest-coverage") +endif() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${CMAKE_SAFETYTEST}") +if(CMAKE_SAFETYTEST STREQUAL "CMAKE_SAFETYTEST_ARG_ON") + #安全测试选项 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fsanitize=undefined,address -O2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=undefined,address -O2") +endif() diff --git a/tests/cmake-lcov-test.sh b/tests/cmake-lcov-test.sh new file mode 100644 index 0000000000000000000000000000000000000000..82ca18d60f60827bc9ea25eff25c0bd5d0ef257d --- /dev/null +++ b/tests/cmake-lcov-test.sh @@ -0,0 +1,23 @@ +utdir=build-ut +rm -r $utdir +rm -r ../$utdir +mkdir ../$utdir +cd ../$utdir + +cmake -DCMAKE_BUILD_TYPE=Debug .. +make -j16 + +workdir=$(cd ../$(dirname $0)/$utdir; pwd) + +./tests/deepin-editor-test --gtest_output=xml:./report/report.xml + +mkdir -p report +lcov -d $workdir -c -o ./report/coverage.info + +lcov --extract ./report/coverage.info '*/src/*' -o ./report/coverage.info + +lcov --remove ./report/coverage.info '*/tests/*' -o ./report/coverage.info + +genhtml -o ./report ./report/coverage.info + +exit 0 diff --git a/tests/src/common/ut_csyntaxhighlighter.cpp b/tests/src/common/ut_csyntaxhighlighter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e2ae37959c3487644cee4e681df64026cfa38bc --- /dev/null +++ b/tests/src/common/ut_csyntaxhighlighter.cpp @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_csyntaxhighlighter.h" + +test_CSyntaxHighlighter::test_CSyntaxHighlighter() +{ + +} + +TEST_F(test_CSyntaxHighlighter, setEnableHighlight) +{ + + TextEdit *m_pTextEdit = new TextEdit(); + bool bRet = true; + CSyntaxHighlighter *pCSyntaxHighlighter = new CSyntaxHighlighter(m_pTextEdit->document()); + pCSyntaxHighlighter->setEnableHighlight(bRet); + + EXPECT_EQ(pCSyntaxHighlighter->m_bHighlight,true); + + EXPECT_NE(m_pTextEdit,nullptr); + EXPECT_NE(pCSyntaxHighlighter,nullptr); + + pCSyntaxHighlighter->deleteLater(); + m_pTextEdit->deleteLater(); + + + +} + +TEST_F(test_CSyntaxHighlighter, setEnableHighlight2) +{ + + TextEdit *m_pTextEdit = new TextEdit(); + bool bRet = true; + CSyntaxHighlighter *pCSyntaxHighlighter = new CSyntaxHighlighter(this); + pCSyntaxHighlighter->setEnableHighlight(bRet); + + EXPECT_EQ(pCSyntaxHighlighter->m_bHighlight,true); + + EXPECT_NE(m_pTextEdit,nullptr); + EXPECT_NE(pCSyntaxHighlighter,nullptr); + + pCSyntaxHighlighter->deleteLater(); + m_pTextEdit->deleteLater(); + + +} + +TEST_F(test_CSyntaxHighlighter, highlightBlock) +{ + + TextEdit *m_pTextEdit = new TextEdit(); + bool bRet = true; + const QString strTest = "12345"; + CSyntaxHighlighter *pCSyntaxHighlighter = new CSyntaxHighlighter(m_pTextEdit->document()); + pCSyntaxHighlighter->m_bHighlight = false; + pCSyntaxHighlighter->highlightBlock(strTest); + + EXPECT_EQ(pCSyntaxHighlighter->m_bHighlight,false); + EXPECT_NE(m_pTextEdit,nullptr); + EXPECT_NE(pCSyntaxHighlighter,nullptr); + + pCSyntaxHighlighter->deleteLater(); + m_pTextEdit->deleteLater(); + + +} + +TEST_F(test_CSyntaxHighlighter, highlightBlock1) +{ + + TextEdit *m_pTextEdit = new TextEdit(); + bool bRet = true; + const QString strTest = "12345"; + CSyntaxHighlighter *pCSyntaxHighlighter = new CSyntaxHighlighter(m_pTextEdit->document()); + pCSyntaxHighlighter->m_bHighlight = true; + pCSyntaxHighlighter->highlightBlock(strTest); + + EXPECT_EQ(pCSyntaxHighlighter->m_bHighlight,true); + EXPECT_NE(m_pTextEdit,nullptr); + EXPECT_NE(pCSyntaxHighlighter,nullptr); + + pCSyntaxHighlighter->deleteLater(); + m_pTextEdit->deleteLater(); + + + +} + diff --git a/tests/src/common/ut_csyntaxhighlighter.h b/tests/src/common/ut_csyntaxhighlighter.h new file mode 100644 index 0000000000000000000000000000000000000000..210402d520a825335ea0e482946f35c885fb2128 --- /dev/null +++ b/tests/src/common/ut_csyntaxhighlighter.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_CSYNTAXHIGHLIGHTER_H +#define TEST_CSYNTAXHIGHLIGHTER_H + +#include "../../src/common/CSyntaxHighlighter.h" +#include "../../src/editor/dtextedit.h" + +#include "gtest/gtest.h" +#include + +class test_CSyntaxHighlighter: public QObject, public::testing::Test +{ +public: + test_CSyntaxHighlighter(); + + KSyntaxHighlighting::SyntaxHighlighter *m_highlighter = nullptr; +}; + +#endif // TEST_CSYNTAXHIGHLIGHTER_H \ No newline at end of file diff --git a/tests/src/common/ut_encoding.cpp b/tests/src/common/ut_encoding.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b5fe76a36830216001e68056d30a99e8bad7cf11 --- /dev/null +++ b/tests/src/common/ut_encoding.cpp @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +//#include "test_encoding.h" + +//test_encoding::test_encoding() +//{ + +//} + +//TEST_F(test_encoding, FileLoadThread) +//{ +// extern bool validateUTF8 (const QByteArray byteArray); +// char i = 'a'; +// QByteArray a(3,i); +// detectCharset(a); +// +//} + +//TEST_F(test_encoding, detectCharsetLatin) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detectCharsetLatin(text); +// +//} + +//TEST_F(test_encoding, detectCharsetCyrillic) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detectCharsetCyrillic(text); +// +//} + +//TEST_F(test_encoding, detectCharsetWinArabic) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detectCharsetWinArabic(text); +// +//} + +//TEST_F(test_encoding, detectCharsetChinese) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detectCharsetChinese(text); +// +//} + +//TEST_F(test_encoding, detectCharsetJapanese) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detectCharsetJapanese(text); +// +//} + +//TEST_F(test_encoding, detectCharsetKorean) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detectCharsetKorean(text); +// +//} + +//TEST_F(test_encoding, detect_noniso) +//{ +// const char *text = "dsfsdfsdf"; +// const std::string detect_noniso(text); +// +//} diff --git a/tests/src/common/ut_encoding.h b/tests/src/common/ut_encoding.h new file mode 100644 index 0000000000000000000000000000000000000000..ff17ef431ddc2b88e3afe2926c1f9a79b61320fa --- /dev/null +++ b/tests/src/common/ut_encoding.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +//#ifndef TEST_ENCODING_H +//#define TEST_ENCODING_H + +//#include"../../src/common/settings.h" +//#include"../../src/controls/tabbar.h" +//#include"../../src/editor/editwrapper.h" +//#include"../../src/widgets/window.h" +//#include"../../src/startmanager.h" +//#include"../../src/editor/dtextedit.h" +//#include"../../src/common/CSyntaxHighlighter.h" +//#include"../src/common/encoding.h" + +//#include "gtest/gtest.h" +//#include + +//class test_encoding: public QObject, public::testing::Test +//{ +//public: +// test_encoding(); +//}; + +//#endif // TEST_ENCODING_H diff --git a/tests/src/common/ut_fileloadthread.cpp b/tests/src/common/ut_fileloadthread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e102b810f4b53e6f0360dddeb1f6586f42abfba --- /dev/null +++ b/tests/src/common/ut_fileloadthread.cpp @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_fileloadthread.h" +#include "../../src/common/fileloadthread.h" +#include "stub.h" + +#include + +test_fileloadthread::test_fileloadthread() +{ +} + +void test_fileloadthread::SetUp() +{ + fthread = new FileLoadThread("aa"); + + EXPECT_NE(fthread, nullptr); + +} + +void test_fileloadthread::TearDown() +{ + delete fthread; + fthread = nullptr; +} + +//FileLoadThread(const QString &filepath, QObject *QObject = nullptr); +TEST_F(test_fileloadthread, FileLoadThread) +{ + FileLoadThread thread("aa"); + + EXPECT_EQ(thread.m_strFilePath, "aa"); +} + +//void run(); +TEST_F(test_fileloadthread, run) +{ + FileLoadThread *thread = new FileLoadThread("aa"); + thread->run(); + + EXPECT_NE(thread, nullptr); + thread->deleteLater(); +} + +//void setEncodeInfo(QStringList pathList,QStringList codeList); +TEST_F(test_fileloadthread, setEncodeInfo) +{ + QStringList pathList, codeList; + FileLoadThread *thread = new FileLoadThread("aa"); + //thread->setEncodeInfo(pathList,codeList); + + + EXPECT_NE(thread, nullptr); + thread->deleteLater(); +} + +//QString getCodec(); +TEST_F(test_fileloadthread, getCodec) +{ + FileLoadThread *thread = new FileLoadThread("aa"); + // thread->getCodec(); + + EXPECT_NE(thread, nullptr); + thread->deleteLater(); +} + +QByteArray readErrorFunc(qint64 maxlen) +{ + Q_UNUSED(maxlen); + throw std::bad_alloc(); + return QByteArray(); +} + +TEST_F(test_fileloadthread, readError) +{ + QString tmpFilePath("/tmp/test_fileloadthread.txt"); + QFile tmpFile(tmpFilePath); + if (tmpFile.open(QFile::WriteOnly)) { + tmpFile.write("local test data"); + tmpFile.close(); + } + ASSERT_TRUE(tmpFile.exists()); + + FileLoadThread *thread = new FileLoadThread(tmpFilePath); + Stub readErrorStub; + readErrorStub.set((QByteArray(QFile::*)(qint64))(ADDR(QFile, read)), readErrorFunc); + + bool readError = false; + connect(thread, &FileLoadThread::sigLoadFinished, [&](const QByteArray & encode, const QByteArray & content, bool error) { + Q_UNUSED(encode); + Q_UNUSED(content); + readError = error; + }); + + thread->run(); + + EXPECT_TRUE(readError); + EXPECT_NE(thread, nullptr); + thread->deleteLater(); + tmpFile.remove(); +} diff --git a/tests/src/common/ut_fileloadthread.h b/tests/src/common/ut_fileloadthread.h new file mode 100644 index 0000000000000000000000000000000000000000..54ea6c8697e9b211fe8eb660849a981c548eda6a --- /dev/null +++ b/tests/src/common/ut_fileloadthread.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_FILELOADTHREAD_H +#define TEST_FILELOADTHREAD_H +#include "gtest/gtest.h" +#include + +class FileLoadThread; +class test_fileloadthread : public QObject + , public ::testing::Test +{ +public: + test_fileloadthread(); + virtual void SetUp() override; + virtual void TearDown() override; + FileLoadThread *fthread; +}; + +#endif // TEST_FILELOADTHREAD_H diff --git a/tests/src/common/ut_performancemonitor.cpp b/tests/src/common/ut_performancemonitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45bb417bff304de78ba013bd759222bb8588735b --- /dev/null +++ b/tests/src/common/ut_performancemonitor.cpp @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_performancemonitor.h" +#include "../../src/common/performancemonitor.h" + +test_performanceMonitor::test_performanceMonitor() +{ + +} + +//explicit PerformanceMonitor(QObject *parent = nullptr); +TEST_F(test_performanceMonitor, PerformanceMonitor) +{ + PerformanceMonitor PerformanceMonitor; + +} + +//static void initializeAppStart(); +TEST_F(test_performanceMonitor, initializeAppStart) +{ + PerformanceMonitor p; + p.initializeAppStart(); + EXPECT_NE(p.initializeAppStartMs,0); + +} + +//static void initializAppFinish(); +TEST_F(test_performanceMonitor, initializAppFinish) +{ + PerformanceMonitor p; + p.initializAppFinish(); + + EXPECT_NE(p.inittalizeApoFinishMs,0); + +} + +//static void closeAppStart(); +TEST_F(test_performanceMonitor, closeAppStart) +{ + PerformanceMonitor p; + p.closeAppStart(); + + EXPECT_NE(p.closeAppStartMs,0); + +} + +//static void closeAPPFinish(); +TEST_F(test_performanceMonitor, closeAPPFinish) +{ + PerformanceMonitor p; + p.closeAPPFinish(); + + EXPECT_NE(p.closeAppFinishMs,0); + +} + +//static void openFileStart(); +TEST_F(test_performanceMonitor, openFileStart) +{ + PerformanceMonitor p; + p.openFileStart(); + + EXPECT_NE(p.openFileStartMs,0); +} + +//static void openFileFinish(const QString &strFileName, qint64 iFileSize); +TEST_F(test_performanceMonitor, openFileFinish) +{ + PerformanceMonitor p; + p.openFileFinish("aa",1); + + EXPECT_NE(p.openFileFinishMs,0); + +} diff --git a/tests/src/common/ut_performancemonitor.h b/tests/src/common/ut_performancemonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..7b15b9f4072814c5ded24f9f766a65a2004d3ac9 --- /dev/null +++ b/tests/src/common/ut_performancemonitor.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_PERFORMANCEMONITOR_H +#define TEST_PERFORMANCEMONITOR_H +#include "gtest/gtest.h" +#include + +class test_performanceMonitor : public QObject, public::testing::Test +{ +public: + test_performanceMonitor(); +}; + +#endif // TEST_PERFORMANCEMONITOR_H diff --git a/tests/src/common/ut_setting.cpp b/tests/src/common/ut_setting.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d496d2e5447b37bdba10df09b012d327de56bb6 --- /dev/null +++ b/tests/src/common/ut_setting.cpp @@ -0,0 +1,443 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_setting.h" +#include "../../src/common/settings.h" +#include +#include +#include +#include +#include +#include +#include +#include "src/stub.h" + +namespace settinsstub { + +KeySequenceEdit* keyvalue = nullptr; +KeySequenceEdit* KeySequenceEditstub() +{ + if(keyvalue==nullptr) + { + DTK_CORE_NAMESPACE::DSettingsOption o; + o.setValue("123.456"); + keyvalue = new KeySequenceEdit(&o); + } + return keyvalue; +} +} + +using namespace settinsstub; + +UT_Setting::UT_Setting() +{ + m_setting = new Settings(); +} + +void UT_Setting::SetUp() +{ + if (m_setting != nullptr) { + m_setting = new Settings(); + } + + EXPECT_NE(m_setting, nullptr); +} + +void UT_Setting::TearDown() +{ + delete m_setting; + m_setting=nullptr; +} + +QString retqstring() +{ + return "123.456"; +} + +TEST(UT_Setting_Settings, UT_Setting_Settings) +{ + Settings* m_setting = new Settings(); + QString figPath = QString("%1/%2/%3/config.conf") + .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) + .arg(qApp->organizationName()) + .arg(qApp->applicationName()); + QSettingBackend *m_backend = new QSettingBackend(figPath); + + + m_setting->settings = DSettings::fromJsonFile(":/resources/settings.json"); + m_setting->settings->setBackend(m_backend); + auto fontFamliy = m_setting->settings->option("base.font.family"); + // QVariant value; + // fontFamliy->valueChanged(value); + // sleep(500); + + QVariant retVal; + QMetaObject::invokeMethod(fontFamliy, "valueChanged", Qt::DirectConnection, + QGenericReturnArgument(), + Q_ARG(QVariant, "dsd")); + + + EXPECT_NE(m_backend,nullptr); + m_backend->deleteLater(); + m_setting->deleteLater(); +} + +TEST(UT_Setting_Settings, UT_Setting_Settings_002) +{ + Settings* m_setting = new Settings(); + QString figPath = QString("%1/%2/%3/config.conf") + .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) + .arg(qApp->organizationName()) + .arg(qApp->applicationName()); + QSettingBackend *m_backend = new QSettingBackend(figPath); + m_setting->~Settings(); + EXPECT_NE(m_backend,nullptr); + + if (m_backend != nullptr) { + m_backend->deleteLater(); + } + m_setting->deleteLater(); +} + +//static Settings* instance(); +TEST(UT_Setting_instance, UT_Setting_instance) +{ + EXPECT_NE(Settings::instance(),nullptr); + +} + +//void dtkThemeWorkaround(QWidget *parent, const QString &theme); +TEST(UT_Setting_dtkThemeWorkaround, UT_Setting_dtkThemeWorkaround) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + Settings *Settings = Settings::instance(); + Settings->dtkThemeWorkaround(pWindow, DEEPIN_THEME); + EXPECT_NE(pWindow, nullptr); + + Settings->deleteLater(); + pWindow->deleteLater(); +} + +//static QPair createFontComBoBoxHandle(QObject *obj); +TEST(UT_Setting_createFontComBoBoxHandle, UT_Setting_createFontComBoBoxHandle) +{ + Settings* m_setting = new Settings(); + + QWidget *widget = new QWidget(); + DSettingsDialog *dialog = new DSettingsDialog(widget); + dialog->widgetFactory()->registerWidget("fontcombobox", m_setting->createFontComBoBoxHandle); + + DTK_CORE_NAMESPACE::DSettingsOption o; + auto it = m_setting->createFontComBoBoxHandle(&o); + EXPECT_EQ(it.first,nullptr); + + EXPECT_NE(dialog,nullptr); + EXPECT_NE(widget,nullptr); + widget->deleteLater(); + dialog->deleteLater(); + m_setting->deleteLater(); +} + +//static QPair createKeySequenceEditHandle(QObject *obj); +TEST(UT_Setting_createKeySequenceEditHandle, UT_Setting_createKeySequenceEditHandle_001) +{ + Settings* m_setting = new Settings(); + QWidget *widget = new QWidget(); + DSettingsDialog *dialog = new DSettingsDialog(widget); + dialog->widgetFactory()->registerWidget("fontcombobox", Settings::createKeySequenceEditHandle); + + DTK_CORE_NAMESPACE::DSettingsOption o; + auto it = m_setting->createKeySequenceEditHandle(&o); + EXPECT_EQ(it.first,nullptr); + + EXPECT_NE(dialog,nullptr); + EXPECT_NE(widget,nullptr); + widget->deleteLater(); + dialog->deleteLater(); + m_setting->deleteLater(); +} + +//static Settings* instance(); + +//void setSettingDialog(DSettingsDialog *settingsDialog); +TEST(UT_Setting_setSettingDialog, UT_Setting_setSettingDialog) +{ + QWidget *widget = new QWidget(); + DSettingsDialog *dialog = new DSettingsDialog(widget); + Settings *pSettings = Settings::instance(); + pSettings->setSettingDialog(dialog); + + EXPECT_NE(Settings::instance()->m_pSettingsDialog, nullptr); + + EXPECT_NE(dialog,nullptr); + EXPECT_NE(widget,nullptr); + widget->deleteLater(); + dialog->deleteLater(); + pSettings->deleteLater(); +} + +//private: +//void updateAllKeysWithKeymap(QString keymap); +TEST(UT_Setting_updateAllKeysWithKeymap, UT_Setting_updateAllKeysWithKeymap) +{ + QString keymap = Settings::instance()->settings->option("shortcuts.keymap.keymap")->value().toString(); + Settings::instance()->updateAllKeysWithKeymap(keymap); + + EXPECT_NE(Settings::instance()->m_bUserChangeKey,true); +} + +//void copyCustomizeKeysFromKeymap(QString keymap); +TEST(UT_Setting_copyCustomizeKeysFromKeymap, UT_Setting_copyCustomizeKeysFromKeymap) +{ + QString keymap = Settings::instance()->settings->option("shortcuts.keymap.keymap")->value().toString(); + Settings::instance()->copyCustomizeKeysFromKeymap(keymap); + + EXPECT_NE(Settings::instance()->m_bUserChangeKey,true); +} + +//此函数代码调试中已经覆盖, html中显示未覆盖 +TEST(UT_Setting_checkShortcutValid, UT_Setting_checkShortcutValid) +{ + Settings* m_setting = new Settings(); + + bool ok; + QString reason = "reason"; + EXPECT_NE(m_setting->checkShortcutValid("shortcuts.keymap.keymap", "Enter", reason, ok),true); + m_setting->deleteLater(); +} + +TEST(UT_Setting_checkShortcutValid2, UT_Setting_checkShortcutValid2) +{ + Settings* m_setting = new Settings(); + bool ok; + QString reason = "reason"; + EXPECT_NE(m_setting->checkShortcutValid("shortcuts.keymap.keymap", "<", reason, ok),true); + + m_setting->deleteLater(); +} + +TEST(UT_Setting_checkShortcutValid3, UT_Setting_checkShortcutValid3) +{ + Settings* m_setting = new Settings(); + bool ok; + QString reason = "reason"; + EXPECT_NE(m_setting->checkShortcutValid("shortcuts.keymap.keymap<", "Num+", reason, ok),true); + + m_setting->deleteLater(); +} + +TEST(UT_Setting_isShortcutConflict, UT_Setting_isShortcutConflict) +{ + Settings* m_setting = new Settings(); + //Settings::instance()->isShortcutConflict("shortcuts.keymap.keymap", "Enter"); + // assert(1 == 1); + QStringList list; + list << "aa" + << "bb"; + EXPECT_NE(m_setting->isShortcutConflict("aa", "bb"), true); + + EXPECT_NE(m_setting->isShortcutConflict("aa", "bb"), true); + + QVariant value; + QString strValue("Ctrl+Z"); + const QString strKey("shortcuts.editor.undo"); + m_setting->m_bUserChangeKey = false; + m_setting->slotCustomshortcut(strKey, strValue); + + m_setting->slotsigAdjustFont(value); + + QVariant keymap2 = Settings::instance()->settings->option("base.font.size")->value(); + m_setting->slotsigAdjustFontSize(keymap2); + m_setting->slotsigAdjustWordWrap(value); + m_setting->slotsigSetLineNumberShow(value); + m_setting->slotsigAdjustBookmark(value); + m_setting->slotsigShowCodeFlodFlag(value); + m_setting->slotsigShowBlankCharacter(value); + m_setting->slotsigHightLightCurrentLine(value); + m_setting->slotsigAdjustTabSpaceNumber(value); + + QVariant keymap = Settings::instance()->settings->option("shortcuts.keymap.keymap")->value(); + m_setting->slotupdateAllKeysWithKeymap(keymap); + + m_setting->deleteLater(); +} + +TEST(UT_Setting_slotCustomshortcut, UT_Setting_slotCustomshortcut_001) +{ + QString strValue("Ctrl+Z"); + const QString strKey("shortcuts.editor.undo"); + Settings *pSettings = new Settings(); + pSettings->m_bUserChangeKey = false; + pSettings->slotCustomshortcut(strKey, strValue); + ASSERT_TRUE(pSettings->m_bUserChangeKey == false); + + pSettings->deleteLater(); +} + + +QVariant stub_dsettings_option() +{ + QVariant variant = QString("Hello word"); + return variant; +} + +TEST(UT_Setting_slotCustomshortcut, UT_Setting_slotCustomshortcut_002) +{ + QString strValue("Ctrl+Z"); + const QString strKey("shortcuts.editor.undo"); + Settings *pSettings = new Settings(); + pSettings->m_bUserChangeKey = false; + pSettings->slotCustomshortcut(strKey, strValue); + ASSERT_TRUE(pSettings->m_bUserChangeKey == false); + + pSettings->deleteLater(); +} + +TEST(UT_Setting_isShortcutConflict, UT_Setting_slotsigAdjustFontSize) +{ + Settings *pSettings = new Settings(); + pSettings->slotsigAdjustFont(15); + ASSERT_TRUE(pSettings->m_backend != nullptr); + + pSettings->deleteLater(); +} + +TEST(UT_Setting_createDialog, UT_Setting_createDialog_001) +{ + DSettingsDialog *pSettingsDialog = new DSettingsDialog; + Settings *pSettings = new Settings(); + pSettings->m_pSettingsDialog = pSettingsDialog; + DDialog *pDialog = pSettings->createDialog(QString("title"), QString("content"), true); + + ASSERT_TRUE(pDialog != nullptr); + + pSettingsDialog->deleteLater(); + pDialog->deleteLater(); + pSettings->deleteLater(); +} + +TEST(UT_Setting_createDialog, UT_Setting_createDialog_002) +{ + DSettingsDialog *pSettingsDialog = new DSettingsDialog; + Settings *pSettings = new Settings(); + pSettings->m_pSettingsDialog = pSettingsDialog; + DDialog *pDialog = pSettings->createDialog(QString("title"), QString("content"), false); + + ASSERT_TRUE(pDialog != nullptr); + + pSettingsDialog->deleteLater(); + pDialog->deleteLater(); + pSettings->deleteLater(); +} + +// +TEST(UT_Setting_KeySequenceEdit, UT_Setting_KeySequenceEdit1) +{ + QWidget *widget = new QWidget(); + DSettingsDialog *dialog = new DSettingsDialog(widget); + auto option = qobject_cast(dialog); + + KeySequenceEdit *shortCutLineEdit = new KeySequenceEdit(option); + QEvent *e = new QEvent(QEvent::KeyPress); + shortCutLineEdit->eventFilter(shortCutLineEdit,e); + + QVariant keymap = Settings::instance()->settings->option("shortcuts.keymap.keymap")->value(); + shortCutLineEdit->slotDSettingsOptionvalueChanged(keymap); + + EXPECT_NE(widget, nullptr); + EXPECT_NE(shortCutLineEdit, nullptr); + EXPECT_NE(e, nullptr); + widget->deleteLater(); + dialog->deleteLater(); + shortCutLineEdit->deleteLater(); + delete e ; + e=nullptr; +} + +TEST(UT_Setting_KeySequenceEdit, UT_KeySequenceEdit_KeySequenceEdit) +{ + DTK_CORE_NAMESPACE::DSettingsOption *opt = new DTK_CORE_NAMESPACE::DSettingsOption; + KeySequenceEdit *pKeySequenceEdit = new KeySequenceEdit(opt); + ASSERT_TRUE(pKeySequenceEdit->m_pOption != nullptr); + + opt->deleteLater(); + pKeySequenceEdit->deleteLater(); +} + +TEST(UT_Setting_KeySequenceEdit, UT_KeySequenceEdit_eventFilter_001) +{ + DTK_CORE_NAMESPACE::DSettingsOption *opt = new DTK_CORE_NAMESPACE::DSettingsOption; + KeySequenceEdit *pKeySequenceEdit = new KeySequenceEdit(opt); + Qt::KeyboardModifier modefiers[4] = {Qt::NoModifier, Qt::AltModifier, Qt::MetaModifier, Qt::NoModifier}; + QKeyEvent *pKeyEvent = new QKeyEvent(QEvent::KeyPress, Qt::Key_Return, modefiers[0], "\r"); + bool bRet = pKeySequenceEdit->eventFilter(pKeySequenceEdit, pKeyEvent); + + ASSERT_TRUE(bRet == true); + + opt->deleteLater(); + pKeySequenceEdit->deleteLater(); + delete pKeyEvent; + pKeyEvent = nullptr; +} + +TEST(UT_Setting_KeySequenceEdit, UT_KeySequenceEdit_eventFilter_002) +{ + DTK_CORE_NAMESPACE::DSettingsOption *opt = new DTK_CORE_NAMESPACE::DSettingsOption; + KeySequenceEdit *pKeySequenceEdit = new KeySequenceEdit(opt); + bool bRet = pKeySequenceEdit->eventFilter(nullptr, nullptr); + ASSERT_TRUE(bRet == false); + + opt->deleteLater(); + pKeySequenceEdit->deleteLater(); +} + +TEST(UT_Setting_KeySequenceEdit, UT_KeySequenceEdit_slotDSettingsOptionvalueChanged_001) +{ + DTK_CORE_NAMESPACE::DSettingsOption *opt = new DTK_CORE_NAMESPACE::DSettingsOption; + KeySequenceEdit *pKeySequenceEdit = new KeySequenceEdit(opt); + pKeySequenceEdit->slotDSettingsOptionvalueChanged(QString("")); + ASSERT_TRUE(pKeySequenceEdit->m_pOption != nullptr); + + opt->deleteLater(); + pKeySequenceEdit->deleteLater(); +} + +TEST(UT_Setting_KeySequenceEdit, UT_KeySequenceEdit_slotDSettingsOptionvalueChanged_002) +{ + DTK_CORE_NAMESPACE::DSettingsOption *opt = new DTK_CORE_NAMESPACE::DSettingsOption; + KeySequenceEdit *pKeySequenceEdit = new KeySequenceEdit(opt); + pKeySequenceEdit->slotDSettingsOptionvalueChanged(QString("Ctr+t")); + ASSERT_TRUE(pKeySequenceEdit->m_pOption != nullptr); + + opt->deleteLater(); + pKeySequenceEdit->deleteLater(); +} + +TEST(UT_Setting_KeySequenceEdit, UT_KeySequenceEdit_option) +{ + DTK_CORE_NAMESPACE::DSettingsOption *opt = new DTK_CORE_NAMESPACE::DSettingsOption; + KeySequenceEdit *pKeySequenceEdit = new KeySequenceEdit(opt); + DTK_CORE_NAMESPACE::DSettingsOption *pRet = pKeySequenceEdit->option(); + + ASSERT_TRUE(pRet == opt); + + opt->deleteLater(); + pKeySequenceEdit->deleteLater(); +} + +//以下两条CASE 脚本跑会造成程序崩,加两行debug后就不崩了 +//TEST(UT_Setting_createDialog2, UT_Setting_createDialog2) +//{ +// Settings set; +// set.createDialog("ba", "bb", false); +//} + +//TEST(UT_Setting_createDialog, UT_Setting_createDialog) +//{ +// Settings set; +// set.createDialog("ba", "bb", true); +//} diff --git a/tests/src/common/ut_setting.h b/tests/src/common/ut_setting.h new file mode 100644 index 0000000000000000000000000000000000000000..1b14e4d464ff55fbd2357374b2539c4416c47e39 --- /dev/null +++ b/tests/src/common/ut_setting.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_Setting_H +#define UT_Setting_H + +#include "gtest/gtest.h" +#include +#include +#include "../../src/widgets/window.h" +#include "../../src/common/utils.h" + +class Settings; +class KeySequenceEdit; +class UT_Setting : public QObject + , public ::testing::Test +{ + Q_OBJECT + +public: + UT_Setting(); + virtual void SetUp() override; + virtual void TearDown() override; + Settings *m_setting; +}; + +#endif // UT_Setting_H diff --git a/tests/src/common/ut_utils.cpp b/tests/src/common/ut_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..31fba3709af3d8ac7547023783f764686d8af609 --- /dev/null +++ b/tests/src/common/ut_utils.cpp @@ -0,0 +1,560 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_utils.h" + +#include "../../src/common/settings.h" +#include "../../src/controls/tabbar.h" +#include "../../src/editor/editwrapper.h" +#include "../../src/widgets/window.h" +#include "../../src/startmanager.h" +#include "../../src/editor/dtextedit.h" +#include "../../src/common/utils.h" +#include "stub.h" +#include +#include +#include +#include "qchar.h" +#include "QTextDecoder" +#include "qlocale.h" + + +namespace utilsstub { +QChar::Script scriptvalue = QChar::Script_Hiragana; +QChar::Script scriptstub() +{ + return scriptvalue; +} + +QLocale::Script scriptvalue2 = QLocale::ArabicScript; +QLocale::Script scriptstub2() +{ + return scriptvalue2; +} + +bool rettruestub() +{ + return true; +} + +bool retfalsestub() +{ + return false; +} + +ushort unicodestub() +{ + return 0x0000; +} + +QString namevalue; +QString namestub() +{ + return namevalue; +} + +int retintstub() +{ + return 2; +} + +} + +using namespace utilsstub; + +UT_Utils::UT_Utils() +{ +} + +void UT_Utils::SetUp() +{ + utils = new Utils; + EXPECT_NE(utils,nullptr); +} + +void UT_Utils::TearDown() +{ + delete utils; + utils=nullptr; +} + +//static QString getQrcPath(const QString &imageName); +TEST(UT_Utils_getQrcPath, UT_Utils_getQrcPath) +{ + EXPECT_NE(Utils::getQrcPath("aa").contains("aa"),false); + +} + +//static QString getQssPath(const QString &qssName); +TEST(UT_Utils_getQssPath, UT_Utils_getQssPath) +{ + EXPECT_NE(Utils::getQssPath("aa").contains("aa"),false); + +} + +//static QSize getRenderSize(int fontSize, const QString &string); +TEST(UT_Utils_getRenderSize, UT_Utils_getRenderSize) +{ + EXPECT_NE(Utils::getRenderSize(1, "aa").width(),0); + +} + +//static void setFontSize(QPainter &painter, int textSize); +TEST(UT_Utils_setFontSize, UT_Utils_setFontSize) +{ + QImage image(10, 10, QImage::Format_RGB888); + QPainter painter(&image); + Utils::setFontSize(painter, 1); + EXPECT_NE(painter.font().pixelSize(),0); + +} + +//static void applyQss(QWidget *widget, const QString &qssName); +TEST(UT_Utils_applyQss, UT_Utils_applyQss) +{ + QWidget *widget = new QWidget; + Utils::applyQss(widget, "1"); + + EXPECT_NE(widget,nullptr); + widget->deleteLater(); +} + +//static QString getKeyshortcut(QKeyEvent *keyEvent); +TEST(UT_Utils_getKeyshortcut, UT_Utils_getKeyshortcut) +{ + //QKeyEvent::Type + QKeyEvent *keyEvent = new QKeyEvent(QEvent::KeyPress, 1, Qt::NoModifier); + EXPECT_EQ(Utils::getKeyshortcut(keyEvent).contains("+"),false); + +} + +//static QString getKeyshortcutFromKeymap(Settings* settings, const QString &keyCategory, const QString &keyName); +TEST(UT_Utils_getKeyshortcutFromKeymap, UT_Utils_getKeyshortcutFromKeymap) +{ + EXPECT_NE(Utils::getKeyshortcutFromKeymap(Settings::instance(), "editor", "selectall")," "); + +} + +//static bool fileExists(const QString &path); +TEST(UT_Utils_fileExists, UT_Utils_fileExists) +{ + EXPECT_NE(Utils::fileExists("aa"),true); +} + +//static bool fileIsWritable(const QString &path); +TEST(UT_Utils_fileIsWritable, UT_Utils_fileIsWritable) +{ + EXPECT_NE(Utils::fileIsWritable("aa"),true); +} + +//static bool fileIsHome(const QString &path); +TEST(UT_Utils_fileIsHome, UT_Utils_fileIsHome) +{ + EXPECT_NE(Utils::fileIsHome("aa"),true); + +} + +//static void passInputEvent(int wid); + +//static QPixmap dropShadow(const QPixmap &source, qreal radius, const QColor &color, const QPoint &offset); +//static QImage dropShadow(const QPixmap &px, qreal radius, const QColor &color); +TEST(UT_Utils_dropShadow, UT_Utils_dropShadow) +{ + QImage image(10, 10, QImage::Format_RGB888); + EXPECT_NE(Utils::dropShadow(QPixmap::fromImage(image), 1.5, QColor("#000000"), QPoint(1, 1)).isNull(),true); + Utils::dropShadow(QPixmap::fromImage(image), 1.5, QColor("#000000")); + +} + +//static QByteArray detectEncode(const QByteArray &data, const QString &fileName = QString()); +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_001) +{ + EXPECT_NE(Utils::detectEncode("aa").size(),0); +} + +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_002) +{ + Utils* utils = new Utils; + QByteArray array; + array.clear(); + EXPECT_NE(utils->detectEncode(array).size(),0); + + delete utils; + utils = nullptr; + +} + +QTextCodec *stub_codecForUtfText(const QByteArray &ba, QTextCodec *defaultCodec) +{ + return nullptr; +} + +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_003) +{ +// Utils* utils = new Utils; + +// typedef QTextCodec *(*fptr)(const QByteArray &, QTextCodec *); +// fptr A_foo = (fptr)(&QTextCodec::codecForUtfText); + +// Stub st; +// st.set(A_foo, stub_codecForUtfText); +// QByteArray array("-"); +// EXPECT_NE(utils->detectEncode(array).size(),0); + +// delete utils; +// utils = nullptr; +} + +QMimeType stub_mimeTypeForData(const QByteArray &data) +{ + QMimeType type; + QMimeDatabase base; + type = base.mimeTypeForName("application/xml"); + return type; +} +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_004) +{ +// Utils* utils = new Utils; +// Stub st; +// st.set((QMimeType(QMimeDatabase::*)(const QByteArray &) const)ADDR(QMimeDatabase, mimeTypeForData), stub_mimeTypeForData); +// EXPECT_NE(utils->detectEncode("aa", nullptr).size(),0); + +// delete utils; +// utils = nullptr; +} + +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_005) +{ +// Utils* utils = new Utils; + +// typedef QTextCodec *(*fptr)(const QByteArray &, QTextCodec *); +// fptr A_foo = (fptr)(&QTextCodec::codecForUtfText); + +// Stub st; +// st.set(A_foo, stub_codecForUtfText); + +// Stub s1; +// s1.set(ADDR(QMimeType,name),namestub); +// namevalue = "text/x-python"; + +// QByteArray array("-"); +// EXPECT_NE(utils->detectEncode(array).size(),0); + +// delete utils; +// utils = nullptr; +} + +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_006) +{ +// Utils* utils = new Utils; + +// typedef QTextCodec *(*fptr)(const QByteArray &, QTextCodec *); +// fptr A_foo = (fptr)(&QTextCodec::codecForUtfText); + +// Stub st; +// st.set(A_foo, stub_codecForUtfText); + +// Stub s1; +// s1.set(ADDR(QMimeType,name),namestub); +// namevalue = "application/xml"; + +// Stub s2; +// s2.set(ADDR(QString,size),retintstub); + +// Stub s3; +// s3.set((QLocale::Script(QLocale::*)() const )ADDR(QLocale,script), scriptstub2); +// scriptvalue2 = QLocale::ArabicScript; + + +// QByteArray array("-"); +// EXPECT_NE(utils->detectEncode(array).size(),0); + +// delete utils; +// utils = nullptr; +} + +TEST(UT_Utils_detectEncode, UT_Utils_detectEncode_007) +{ + Utils* utils = new Utils; + + typedef QTextCodec *(*fptr)(const QByteArray &, QTextCodec *); + fptr A_foo = (fptr)(&QTextCodec::codecForUtfText); + + Stub st; + st.set(A_foo, stub_codecForUtfText); + + Stub s1; + s1.set(ADDR(QMimeType,name),namestub); + namevalue = "application/xml"; + + Stub s2; + s2.set(ADDR(QString,size),retintstub); + + Stub s3; + s3.set((QLocale::Script(QLocale::*)() const )ADDR(QLocale,script), scriptstub2); + scriptvalue2 = QLocale::SimplifiedChineseScript; + + QByteArray array("-"); + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::TraditionalChineseScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::CyrillicScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::GreekScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::HebrewScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::JapaneseScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::KoreanScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::ThaiScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + scriptvalue2 = QLocale::AvestanScript; + EXPECT_NE(utils->detectEncode(array).size(),0); + + + delete utils; + utils = nullptr; +} + +//static QByteArray getEncode(const QByteArray &data); +TEST(UT_Utils_getEncode, UT_Utils_getEncode) +{ + EXPECT_NE(Utils::getEncode("aa").isEmpty(),true); + +} + +//static qreal easeInOut(qreal x); +TEST(UT_Utils_easeInOut, UT_Utils_easeInOut) +{ + EXPECT_NE(Utils::easeInOut(0.1),0); +} + +//static qreal easeInQuad(qreal x); +TEST(UT_Utils_easeInQuad, UT_Utils_easeInQuad) +{ + EXPECT_NE(Utils::easeInQuad(0.1),0); +} + +//static qreal easeInQuint(qreal x); +TEST(UT_Utils_easeInQuint, UT_Utils_easeInQuint) +{ + EXPECT_NE(Utils::easeInQuint(0.1),0); +} + +//static qreal easeOutQuad(qreal x); +TEST(UT_Utils_easeOutQuad, UT_Utils_easeOutQuad) +{ + EXPECT_NE(Utils::easeOutQuad(0.1),0); +} + +//static qreal easeOutQuint(qreal x); +TEST(UT_Utils_easeOutQuint, UT_Utils_easeOutQuint) +{ + EXPECT_NE(Utils::easeOutQuint(0.1),0); +} + +//static QVariantMap getThemeMapFromPath(const QString &filepath); +TEST(UT_Utils_getThemeMapFromPath, UT_Utils_getThemeMapFromPath) +{ + EXPECT_NE(Utils::getThemeMapFromPath("aa").isEmpty(),false); +} + +//static bool isMimeTypeSupport(const QString &filepath); +TEST(UT_Utils_isMimeTypeSupport, UT_Utils_isMimeTypeSupport) +{ + EXPECT_NE(Utils::isMimeTypeSupport("aa"),false); +} + +//static bool isDraftFile(const QString &filepath); +TEST(UT_Utils_isDraftFile, UT_Utils_isDraftFile) +{ + EXPECT_NE(Utils::isDraftFile("aa"),true); +} + +//static const QStringList getEncodeList(); +TEST(UT_Utils_getEncodeList, UT_Utils_getEncodeList) +{ + Utils::getEncodeList(); + EXPECT_NE(Utils::renderSVG("", QSize(40, 40), false).isNull(),false); + +} + +TEST(UT_Utils_codecConfidenceForData, UT_Utils_codecConfidenceForData_001) +{ +// QByteArray data = "123"; +// QTextCodec *codec = QTextCodec::codecForName("KOI8-R"); +// QLocale::Country country= QLocale::China; + +// //Script script() const +// Stub s1; +// s1.set((QChar::Script(QChar::*)() const )ADDR(QChar,script), scriptstub); + +// scriptvalue = QChar::Script_Hiragana; +// Utils::codecConfidenceForData(codec,data,country); + +// scriptvalue = QChar::Script_Han; +// Utils::codecConfidenceForData(codec,data,country); + +// scriptvalue = QChar::Script_Hangul; +// Utils::codecConfidenceForData(codec,data,country); + +// scriptvalue = QChar::Script_Cyrillic; +// Utils::codecConfidenceForData(codec,data,country); + +// scriptvalue = QChar::Script_Devanagari; +// EXPECT_NE(Utils::codecConfidenceForData(codec,data,country),2.2); +} + +TEST(UT_Utils_codecConfidenceForData, UT_Utils_codecConfidenceForData_002) +{ +// QByteArray data = "123"; +// //QByteArray data(1,0xfffe); +// QTextCodec *codec = QTextCodec::codecForName("KOI8-R"); +// QLocale::Country country= QLocale::China; + +// //Script script() const +// Stub s1; +// s1.set((QChar::Script(QChar::*)() const )ADDR(QChar,script), scriptstub); +// Stub s2; +// s2.set((bool (QChar::*)() const )ADDR(QChar,isSurrogate), rettruestub); +// Stub s3; +// s3.set((bool (QChar::*)() const )ADDR(QChar,isHighSurrogate), rettruestub); +// Stub s4; +// s4.set((ushort (QChar::*)() const )ADDR(QChar,unicode), unicodestub); +// Stub s5; +// s5.set((ushort& (QChar::*)() )ADDR(QChar,unicode), unicodestub); + +// scriptvalue = QChar:: Script_Buhid; +// EXPECT_NE(Utils::codecConfidenceForData(codec,data,country),2.2); +} + + +TEST(UT_Utils_clearChildrenFoucusEx, clearChildrenFoucusEx) +{ + QWidget* wgt = new QWidget; + QPushButton* btn = new QPushButton(wgt); + + Utils::clearChildrenFoucusEx(wgt); + + EXPECT_NE(wgt,nullptr); + EXPECT_NE(btn,nullptr); + + wgt->deleteLater(); + btn->deleteLater(); + +} + +TEST(UT_Utils_setChildrenFocus, setChildrenFocus) +{ + QWidget* wgt = new QWidget; + QPushButton* btn = new QPushButton(wgt); + + Utils::setChildrenFocus(wgt,Qt::NoFocus); + + EXPECT_NE(wgt,nullptr); + EXPECT_NE(btn,nullptr); + + wgt->deleteLater(); + btn->deleteLater(); + +} + +TEST(UT_Utils_getProcessCountByName, getProcessCountByName) +{ + char a[10] = {"12345"}; + Utils::getProcessCountByName(a); + + EXPECT_NE(a[0],'2'); +} + +TEST(UT_Utils_killProcessByName, killProcessByName) +{ + char a[10] = {"12345"}; + Utils::killProcessByName(a); + + EXPECT_NE(a[0],'2'); +} + + +TEST(UT_Utils_isShareDirAndReadOnly, isShareDirAndReadOnly) +{ +// Stub s1; +// s1.set((bool(QDir::*)() const)ADDR(QDir,exists),rettruestub); + +// Stub s2; +// s2.set((bool(QDir::*)(const QString&) const)ADDR(QDir,exists),rettruestub); + + +// typedef bool (*fptr)(QFile*,QFile::OpenMode); +// fptr A_foo = (fptr)((bool(QFile::*)(QFile::OpenMode))&QFile::open); +// Stub s3; +// s3.set(A_foo,rettruestub); + +// EXPECT_NE(Utils::isShareDirAndReadOnly("1/2/3"),true); +} + +// static RegionIntersectType checkRegionIntersect(int x1, int y1, int x2, int y2); +TEST(UT_Utils_checkRegionIntersect, checkRegionIntersect) +{ + // 测试各边界判断 + Utils::RegionIntersectType type; + type = Utils::checkRegionIntersect(10, 20, 0, 9); + ASSERT_EQ(type, Utils::ELeft); + type = Utils::checkRegionIntersect(10, 20, 0, 10); + ASSERT_NE(type, Utils::ELeft); + + type = Utils::checkRegionIntersect(10, 20, 21, 30); + ASSERT_EQ(type, Utils::ERight); + type = Utils::checkRegionIntersect(10, 20, 20, 30); + ASSERT_NE(type, Utils::ERight); + + type = Utils::checkRegionIntersect(10, 20, 9, 15); + ASSERT_EQ(type, Utils::EIntersectLeft); + type = Utils::checkRegionIntersect(10, 20, 15, 21); + ASSERT_EQ(type, Utils::EIntersectRight); + type = Utils::checkRegionIntersect(10, 20, 9, 21); + ASSERT_EQ(type, Utils::EIntersectOutter); + type = Utils::checkRegionIntersect(10, 20, 10, 20); + ASSERT_EQ(type, Utils::EIntersectInner); +} + +QByteArray supportEncoding_readAll_stub() +{ + return QByteArray(); +} + +TEST(UT_Utils_getSupportEncoding, getSupportEncoding) +{ + auto encoding = Utils::getSupportEncoding(); + ASSERT_FALSE(encoding.isEmpty()); +} + +TEST(UT_Utils_getSupportEncoding, getSupportEncodingWithError) +{ + Stub stub1; + typedef QVector > VecType; + stub1.set(ADDR(VecType, isEmpty), supportEncoding_readAll_stub); + Stub stub2; + stub2.set(ADDR(QIODevice, readAll), supportEncoding_readAll_stub); + + auto encoding = Utils::getSupportEncoding(); + ASSERT_TRUE(encoding.isEmpty()); +} + +TEST(UT_Utils_getSupportEncodingList, getSupportEncodingList) +{ + QStringList encodingList = Utils::getSupportEncodingList(); + ASSERT_FALSE(encodingList.isEmpty()); + ASSERT_TRUE(encodingList.contains("UTF-8")); +} diff --git a/tests/src/common/ut_utils.h b/tests/src/common/ut_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..dc4b894488b31cc9fa2294a582cdfd7a137a4cd0 --- /dev/null +++ b/tests/src/common/ut_utils.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_Utils_H +#define UT_Utils_H + +#include "gtest/gtest.h" +#include + +class Utils; +class UT_Utils : public QObject + , public ::testing::Test +{ +public: + UT_Utils(); + virtual void SetUp() override; + virtual void TearDown() override; + Utils *utils; +}; + +#endif // UT_Utils_H diff --git a/tests/src/controls/ut_findbar.cpp b/tests/src/controls/ut_findbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad4dbd8a28c82bb501a9041fed2321e386574a17 --- /dev/null +++ b/tests/src/controls/ut_findbar.cpp @@ -0,0 +1,197 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_findbar.h" +#include "../../src/controls/findbar.h" +#include +#include + +test_findbar::test_findbar() +{ + +} + +TEST_F(test_findbar, FindBar) +{ + FindBar findBar(nullptr); + +} + +//bool isFocus(); +TEST_F(test_findbar, isFocus) +{ + FindBar *findBar = new FindBar(); + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->isFocus(),false); + + findBar->deleteLater(); + +} + +//void focus(); +TEST_F(test_findbar, focus) +{ + FindBar *findBar = new FindBar(); + findBar->focus(); + EXPECT_NE(findBar,nullptr); + + findBar->deleteLater(); + +} + +//void activeInput(QString text, QString file, int row, int column, int scrollOffset); +TEST_F(test_findbar, activeInput) +{ + FindBar *findBar = new FindBar(); + findBar->activeInput("aa","aa",1,1,1); + + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->m_editLine->lineEdit()->text(),"aa"); + + findBar->deleteLater(); + + +} + +//void setMismatchAlert(bool isAlert); +TEST_F(test_findbar, setMismatchAlert) +{ + FindBar *findBar = new FindBar(); + findBar->setMismatchAlert(true); + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->m_editLine->isAlert(),true); + findBar->deleteLater(); + +} + +//void receiveText(QString t); +TEST_F(test_findbar, receiveText) +{ + FindBar *findBar = new FindBar(); + findBar->receiveText("aa"); + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->m_receivedText,"aa"); + + findBar->deleteLater(); + +} + +//void setSearched(bool _); +TEST_F(test_findbar, setSearched) +{ + FindBar *findBar = new FindBar(); + findBar->setSearched(true); + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->searched,true); + findBar->deleteLater(); + +} + +//void findPreClicked(); +TEST_F(test_findbar, findPreClicked) +{ + FindBar *findBar = new FindBar(); + findBar->findPreClicked(); + + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->searched,true); + findBar->deleteLater(); +} + +//public slots: +//void findCancel(); +TEST_F(test_findbar, findCancel) +{ + FindBar *findBar = new FindBar(); + findBar->findCancel(); + + EXPECT_NE(findBar,nullptr); + EXPECT_EQ(findBar->isVisible(),false); + findBar->deleteLater(); + +} + +//void handleContentChanged(); +TEST_F(test_findbar, handleContentChanged) +{ + FindBar *findBar = new FindBar(); + findBar->handleContentChanged(); + findBar->handleFindPrev(); + findBar->handleFindNext(); + + EXPECT_NE(findBar,nullptr); + findBar->deleteLater(); + +} + +//void slot_ifClearSearchWord(); +//TEST_F(test_findbar, slot_ifClearSearchWord) +//{ +// FindBar *findBar = new FindBar(); +// findBar->slot_ifClearSearchWord(); +// +//} + +//protected: +//void hideEvent(QHideEvent *event) override; +TEST_F(test_findbar, hideEvent) +{ + QHideEvent *event = new QHideEvent(); + FindBar *findBar = new FindBar(); + findBar->hideEvent(event); + + EXPECT_NE(event,nullptr); + EXPECT_NE(findBar,nullptr); + findBar->deleteLater(); + delete event; + +} + +//bool focusNextPrevChild(bool next) override; +TEST_F(test_findbar, focusNextPrevChild) +{ + FindBar *findBar = new FindBar(); + + EXPECT_EQ(findBar->focusNextPrevChild(true),false); + EXPECT_NE(findBar,nullptr); + findBar->deleteLater(); + +} + +//void keyPressEvent(QKeyEvent *e) override; +TEST_F(test_findbar, keyPressEvent) +{ + FindBar *findBar = new FindBar(); + + QKeyEvent *e = new QKeyEvent(QEvent::KeyPress,Qt::Key_Tab,Qt::NoModifier); + findBar->m_closeButton->setFocus(); + findBar->keyPressEvent(e); + EXPECT_EQ(findBar->m_closeButton->hasFocus(),false); + + QKeyEvent *e1 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Escape,Qt::NoModifier); + findBar->keyPressEvent(e1); + + QKeyEvent *e2 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Enter,Qt::NoModifier); + findBar->m_findPrevButton->setFocus(); + findBar->m_findNextButton->setFocus(); + EXPECT_EQ(findBar->m_findPrevButton->hasFocus(),false); + + findBar->keyPressEvent(e2); + + + + EXPECT_NE(findBar,nullptr); + + + findBar->deleteLater(); + delete e; e = nullptr; + delete e1; e1 = nullptr; + delete e2; e2 = nullptr; +} diff --git a/tests/src/controls/ut_findbar.h b/tests/src/controls/ut_findbar.h new file mode 100644 index 0000000000000000000000000000000000000000..7908ca9576e6a8eddc7dd15f465601ca4ff1b268 --- /dev/null +++ b/tests/src/controls/ut_findbar.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_FINDBAR_H +#define TEST_FINDBAR_H +#include "gtest/gtest.h" +#include + +class test_findbar : public QObject, public::testing::Test +{ +public: + test_findbar(); +}; + +#endif // TEST_FINDBAR_H diff --git a/tests/src/controls/ut_fontitemdelegata.cpp b/tests/src/controls/ut_fontitemdelegata.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b477f84551d30c51f6c17d2d8313a3c480efe04d --- /dev/null +++ b/tests/src/controls/ut_fontitemdelegata.cpp @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_fontitemdelegata.h" +#include "../src/controls/fontitemdelegate.h" +#include +test_fontitemdelegata::test_fontitemdelegata() +{ + +} + +TEST_F(test_fontitemdelegata, FontItemDelegate) +{ + FontItemDelegate* delegate = new FontItemDelegate(); + + EXPECT_NE(delegate,nullptr); + + delete delegate;delegate=nullptr; +} + + +TEST_F(test_fontitemdelegata, paint) +{ + FontItemDelegate* delegate = new FontItemDelegate(); + QPainter* painter = new QPainter; + QStyleOptionViewItem option; + QModelIndex index; + option.state |= QStyle::State_Selected; + delegate->paint(painter,option,index); + + EXPECT_NE(delegate,nullptr); + EXPECT_NE(painter->pen().color(),Qt::white); + + delete painter;painter=nullptr; + delete delegate;delegate= nullptr; + +} + +TEST_F(test_fontitemdelegata, sizeHint) +{ + FontItemDelegate* delegate = new FontItemDelegate(); + QPainter* painter = new QPainter; + QStyleOptionViewItem option; + QModelIndex index; + option.state |= QStyle::State_Selected; + + EXPECT_EQ(delegate->sizeHint(option,index),QSize(-1, 30)); + EXPECT_NE(delegate,nullptr); + + delete painter;painter=nullptr; + delete delegate;delegate=nullptr; + +} diff --git a/tests/src/controls/ut_fontitemdelegata.h b/tests/src/controls/ut_fontitemdelegata.h new file mode 100644 index 0000000000000000000000000000000000000000..75bdb4dc2e7d1fcc570c7388761057e3cb2ca944 --- /dev/null +++ b/tests/src/controls/ut_fontitemdelegata.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_FONTITEMDELEGATA_H +#define TEST_FONTITEMDELEGATA_H + + +#include "gtest/gtest.h" +#include + +class test_fontitemdelegata : public QObject, public::testing::Test +{ +public: + test_fontitemdelegata(); +}; +#endif // TEST_FONTITEMDELEGATA_H diff --git a/tests/src/controls/ut_jumplinebar.cpp b/tests/src/controls/ut_jumplinebar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0df32f2dd288332c2053ec5afd7b77f3e4fe01a2 --- /dev/null +++ b/tests/src/controls/ut_jumplinebar.cpp @@ -0,0 +1,114 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_jumplinebar.h" +#include "../../src/controls/jumplinebar.h" + +test_jumplinebar::test_jumplinebar() +{ + +} + +TEST_F(test_jumplinebar, JumpLineBar) +{ + JumpLineBar jumpLineBar(nullptr); + +} + +//void focus(); +TEST_F(test_jumplinebar, focus) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->focus(); + + EXPECT_NE(jumpLineBar,nullptr); + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//bool isFocus(); +TEST_F(test_jumplinebar, isFocus) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->isFocus(); + + EXPECT_NE(jumpLineBar,nullptr); + EXPECT_NE(jumpLineBar->isFocus(),true); + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//void activeInput(QString file, int row, int column, int lineCount, int scrollOffset); +TEST_F(test_jumplinebar, activeInput) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->m_pSpinBoxInput->lineEdit()->setText("50"); + jumpLineBar->activeInput("aa",1,1,1,1); + + EXPECT_EQ(jumpLineBar->m_pSpinBoxInput->lineEdit()->text(),"1"); + EXPECT_NE(jumpLineBar,nullptr); + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//void handleFocusOut(); +TEST_F(test_jumplinebar, handleFocusOut) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->handleFocusOut(); + + + EXPECT_NE(jumpLineBar,nullptr); + EXPECT_EQ(jumpLineBar->isVisible(),false); + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//void handleLineChanged(); +TEST_F(test_jumplinebar, handleLineChanged) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->m_pSpinBoxInput->lineEdit()->setText("123"); + jumpLineBar->handleLineChanged(); + + EXPECT_NE(jumpLineBar,nullptr); + + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//void jumpCancel(); +TEST_F(test_jumplinebar, jumpCancel) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->jumpCancel(); + + EXPECT_NE(jumpLineBar,nullptr); + EXPECT_EQ(jumpLineBar->isVisible(),false); + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//void jumpConfirm(); +TEST_F(test_jumplinebar, jumpConfirm) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->jumpConfirm(); + jumpLineBar->m_pSpinBoxInput->lineEdit()->setText("123"); + + EXPECT_NE(jumpLineBar,nullptr); + + delete jumpLineBar;jumpLineBar=nullptr; +} + +//void slotFocusChanged(bool bFocus); +TEST_F(test_jumplinebar, slotFocusChanged) +{ + JumpLineBar *jumpLineBar = new JumpLineBar(); + jumpLineBar->slotFocusChanged(false); + + EXPECT_NE(jumpLineBar,nullptr); + + delete jumpLineBar;jumpLineBar=nullptr; +} diff --git a/tests/src/controls/ut_jumplinebar.h b/tests/src/controls/ut_jumplinebar.h new file mode 100644 index 0000000000000000000000000000000000000000..c3355499336665eee9dc2df603a84afa04f6ab66 --- /dev/null +++ b/tests/src/controls/ut_jumplinebar.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_JUMPLINEBAR_H +#define TEST_JUMPLINEBAR_H +#include "gtest/gtest.h" +#include + +class test_jumplinebar : public QObject, public::testing::Test +{ +public: + test_jumplinebar(); +}; + +#endif // TEST_JUMPLINEBAR_H diff --git a/tests/src/controls/ut_linebar.cpp b/tests/src/controls/ut_linebar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8c690e354ea52917ec0ffcf2ca534e0420eb739a --- /dev/null +++ b/tests/src/controls/ut_linebar.cpp @@ -0,0 +1,105 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_linebar.h" +#include "../../src/controls/linebar.h" +#include +#include + +test_linebar::test_linebar() +{ + +} + +TEST_F(test_linebar, LineBar) +{ + LineBar lineBar(nullptr); + +} + +//public slots: +// void handleTextChangeTimer(); +TEST_F(test_linebar, handleTextChangeTimer) +{ + LineBar *lineBar = new LineBar(); + lineBar->handleTextChangeTimer(); + + + EXPECT_NE(lineBar,nullptr); + + lineBar->deleteLater(); + +} + +// void handleTextChanged(); +TEST_F(test_linebar, handleTextChanged) +{ + LineBar *lineBar = new LineBar(); + lineBar->m_autoSaveTimer->start(); + + lineBar->handleTextChanged(); + + lineBar->m_autoSaveTimer->stop(); + + EXPECT_EQ(lineBar->m_autoSaveTimer->isActive(),false); + EXPECT_NE(lineBar,nullptr); + + lineBar->deleteLater(); +} + +// void sendText(QString t); +TEST_F(test_linebar, sendText) +{ + LineBar *lineBar = new LineBar(); + lineBar->sendText("aa"); + + EXPECT_NE(lineBar,nullptr); + + lineBar->deleteLater(); +} + +//protected: +// virtual void focusOutEvent(QFocusEvent *e); +TEST_F(test_linebar, focusOutEvent) +{ + LineBar *lineBar = new LineBar(); + QFocusEvent *e = new QFocusEvent(QEvent::FocusIn); + lineBar->focusOutEvent(e); + + + EXPECT_NE(lineBar,nullptr); + + lineBar->deleteLater(); + delete e;e=nullptr; + +} + +// virtual void keyPressEvent(QKeyEvent *e); +TEST_F(test_linebar, keyPressEvent) +{ + LineBar *lineBar = new LineBar(); + Qt::KeyboardModifier modefiers[4] = {Qt::ControlModifier,Qt::AltModifier,Qt::MetaModifier,Qt::NoModifier}; + + EXPECT_NE(lineBar,nullptr); + + QKeyEvent *e = new QKeyEvent(QEvent::KeyPress,1,modefiers[0],"\r"); + lineBar->keyPressEvent(e); + delete e;e=nullptr; + + + e = new QKeyEvent(QEvent::KeyPress,1,modefiers[1],"\r"); + lineBar->keyPressEvent(e); + delete e;e=nullptr; + + e = new QKeyEvent(QEvent::KeyPress,1,modefiers[2],"\r"); + lineBar->keyPressEvent(e); + delete e;e=nullptr; + + e = new QKeyEvent(QEvent::KeyPress,1,modefiers[3],"\r"); + lineBar->keyPressEvent(e); + delete e;e=nullptr; + + + lineBar->deleteLater(); +} diff --git a/tests/src/controls/ut_linebar.h b/tests/src/controls/ut_linebar.h new file mode 100644 index 0000000000000000000000000000000000000000..be23e31c84d068fcb8c1d47d33d93fc8fe9350f1 --- /dev/null +++ b/tests/src/controls/ut_linebar.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_LINEBAR_H +#define TEST_LINEBAR_H +#include "gtest/gtest.h" +#include + +class test_linebar : public QObject, public::testing::Test +{ +public: + test_linebar(); +}; + +#endif // TEST_LINEBAR_H diff --git a/tests/src/controls/ut_replacebar.cpp b/tests/src/controls/ut_replacebar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0d260bbcc99d791da840f8f70a8f3fd4a5f2ed0 --- /dev/null +++ b/tests/src/controls/ut_replacebar.cpp @@ -0,0 +1,201 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_replacebar.h" +#include +test_replacebar::test_replacebar() +{ + +} +//bool isFocus(); +TEST_F(test_replacebar, isFocus) +{ + ReplaceBar * rep = new ReplaceBar(); + EXPECT_EQ(rep->isFocus(),false); + rep->handleSkip(); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); +} +//void focus(); +TEST_F(test_replacebar, focus) +{ + ReplaceBar * rep = new ReplaceBar(); + EXPECT_EQ(rep->isFocus(),false); + rep->focus(); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} + +//void activeInput(QString text, QString file, int row, int column, int scrollOffset); +TEST_F(test_replacebar, activeInput) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->activeInput("aa","bb",2,2,2); + EXPECT_EQ(rep->isVisible(),true); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void setMismatchAlert(bool isAlert); +TEST_F(test_replacebar, setMismatchAlert) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->setMismatchAlert(true); + EXPECT_EQ(rep->m_replaceLine->isAlert(),true); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void setsearched(bool _); +TEST_F(test_replacebar, setsearched) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->setsearched(true); + EXPECT_EQ(rep->searched,true); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +// void change(); +TEST_F(test_replacebar, change) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->change(); + EXPECT_EQ(rep->searched,false); + + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void replaceClose(); +TEST_F(test_replacebar, replaceClose) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->replaceClose(); + EXPECT_EQ(rep->isVisible(),false); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void handleContentChanged(); +TEST_F(test_replacebar, handleContentChanged) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->handleContentChanged(); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void handleReplaceAll(); +TEST_F(test_replacebar, handleReplaceAll) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->handleReplaceAll(); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void handleReplaceNext(); +TEST_F(test_replacebar, handleReplaceNext) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->handleReplaceNext(); + EXPECT_EQ(rep->searched,true); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//void handleReplaceRest(); +TEST_F(test_replacebar, handleReplaceRest) +{ + ReplaceBar * rep = new ReplaceBar(); + rep->handleReplaceRest(); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} + +//protected: +//void hideEvent(QHideEvent *event); +TEST_F(test_replacebar, hideEvent) +{ + ReplaceBar * rep = new ReplaceBar(); + QHideEvent*e; + rep->hideEvent(e); + EXPECT_EQ(rep->searched,false); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} +//bool focusNextPrevChild(bool next); +//void keyPressEvent(QKeyEvent *e); + +TEST_F(test_replacebar, focusNextPrevChild) +{ + ReplaceBar * rep = new ReplaceBar(); + EXPECT_NE(rep->focusNextPrevChild(true),true); + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} + +TEST_F(test_replacebar, keyPressEvent) +{ + ReplaceBar * rep = new ReplaceBar(); + QKeyEvent * e3 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Excel,Qt::NoModifier); + rep->keyPressEvent(e3); + delete e3;e3=nullptr; + + QKeyEvent *e = new QKeyEvent(QEvent::KeyPress,Qt::Key_Tab,Qt::NoModifier); + rep->m_closeButton->setFocus(); + rep->keyPressEvent(e); + delete e;e=nullptr; + + QKeyEvent *e1 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Escape,Qt::NoModifier); + rep->keyPressEvent(e1); + EXPECT_EQ(rep->m_replaceLine->lineEdit()->hasFocus(),false); + delete e1;e1=nullptr; + + QKeyEvent *e2 = new QKeyEvent(QEvent::KeyPress,Qt::Key_Enter,Qt::NoModifier); + rep->m_replaceSkipButton->setFocus(); + rep->m_replaceButton->setFocus(); + rep->m_replaceAllButton->setFocus(); + rep->m_replaceRestButton->setFocus(); + rep->keyPressEvent(e2); + + EXPECT_EQ(rep->m_replaceRestButton->hasFocus(),false); + delete e2; e2=nullptr; + + + EXPECT_NE(rep,nullptr); + rep->deleteLater(); + + +} diff --git a/tests/src/controls/ut_replacebar.h b/tests/src/controls/ut_replacebar.h new file mode 100644 index 0000000000000000000000000000000000000000..e398e6a23631872f140eb19057989d4f348a804d --- /dev/null +++ b/tests/src/controls/ut_replacebar.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TES_REPLACEBAR_H +#define TES_REPLACEBAR_H +#include "gtest/gtest.h" +#include +#include "../../src/editor/editwrapper.h" +#include "../../src/widgets/window.h" +#include "../../src/startmanager.h" +#include "../../src/editor/dtextedit.h" +#include "../../src/controls/replacebar.h" +#include + +class test_replacebar: public QObject, public::testing::Test +{ +public: + test_replacebar(); +}; + +#endif // TES_REPLACEBAR_H diff --git a/tests/src/controls/ut_settingsdialog.cpp b/tests/src/controls/ut_settingsdialog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..351a01145d9279a7d84198c99f48636bb235abc4 --- /dev/null +++ b/tests/src/controls/ut_settingsdialog.cpp @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_settingsdialog.h" + +test_settingsdialog::test_settingsdialog() +{ + +} + + +extern void GenerateSettingTranslate(); +TEST_F(test_settingsdialog, GenerateSettingTranslate) +{ + + GenerateSettingTranslate(); + +} diff --git a/tests/src/controls/ut_settingsdialog.h b/tests/src/controls/ut_settingsdialog.h new file mode 100644 index 0000000000000000000000000000000000000000..bc323fa85e08c2f571dbcdf1261a907b40fb307c --- /dev/null +++ b/tests/src/controls/ut_settingsdialog.h @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_SETTINGSDIALOG_H +#define TEST_SETTINGSDIALOG_H + +#include "gtest/gtest.h" +#include + + +class test_settingsdialog: public QObject, public::testing::Test +{ +public: + test_settingsdialog(); +}; + +#endif // TEST_SETTINGSDIALOG_H diff --git a/tests/src/controls/ut_tabbar.cpp b/tests/src/controls/ut_tabbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f82b3853b86c2f1f08993baeacbbd400a530339 --- /dev/null +++ b/tests/src/controls/ut_tabbar.cpp @@ -0,0 +1,770 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_tabbar.h" +#include "QStyleOptionTab" +#include "../src/widgets/window.h" +#include "../src/editor/editwrapper.h" +#include +#include "src/stub.h" + + +namespace tabbarstub { + +int retintstub() +{ + return 1; +} + +} + +using namespace tabbarstub; + +UT_Tabbar::UT_Tabbar() +{ + +} + +TEST(UT_Tabbar_Tabbar, UT_Tabbar_Tabbar) +{ + Tabbar* tab = new Tabbar; + tab->m_moreWaysCloseMenu = new QMenu(tab); + tab->m_rightMenu = new QMenu(tab); + + EXPECT_NE(tab,nullptr); + EXPECT_NE(tab->m_moreWaysCloseMenu,nullptr); + EXPECT_NE(tab->m_rightMenu,nullptr); + + tab->deleteLater(); + + +} + +TEST(UT_Tabbar_openFilesInWindow, UT_Tabbar_openFilesInWindow) +{ +// Tabbar * tab = new Tabbar(); +// tab->addTab(".cache/deepin/deepin-editor","aabb"); + +// EXPECT_NE(tab,nullptr); +// EXPECT_EQ(tab->currentIndex(),0); + +// tab->deleteLater(); +} + +//addTabWithIndex +TEST(UT_Tabbar_addTabWithIndex, UT_Tabbar_addTabWithIndex) +{ +// Tabbar * tab = new Tabbar(); +// tab->addTabWithIndex(0,".cache/deepin/deepin-editor","aabb"); + +// EXPECT_NE(tab,nullptr); +// EXPECT_NE(tab->tabToolTip(0),"aabb"); + +// tab->deleteLater(); +} + +//closeTab +TEST(UT_Tabbar_closeTab, UT_Tabbar_closeTab) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->closeTab(index); + window->getTabbar()->closeTab(-1); + + + EXPECT_EQ(window->getTabbar()->count(),0); + EXPECT_NE(window->getTabbar(),nullptr); + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + +} +//void closeCurrentTab(); +TEST(UT_Tabbar_closeCurrentTab, UT_Tabbar_closeCurrentTab) +{ + Tabbar * tab = new Tabbar(); + tab->closeCurrentTab(); + + EXPECT_EQ(tab->count(),0); + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//void closeOtherTabs(); +TEST(UT_Tabbar_closeOtherTabs, UT_Tabbar_closeOtherTabs) +{ + Tabbar * tab = new Tabbar(); + tab->closeOtherTabs(); + + EXPECT_EQ(tab->count(),0); + EXPECT_NE(tab,nullptr); + + + tab->deleteLater(); + +} + +//void closeLeftTabs(const QString &filePath); +TEST(UT_Tabbar_closeLeftTabs, UT_Tabbar_closeLeftTabs) +{ + Tabbar * tab = new Tabbar(); + tab->m_tabPaths.push_back("aa"); + tab->closeLeftTabs("aa"); + tab->closeLeftTabs("bb"); + + + EXPECT_EQ(tab->count(),0); + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//void closeRightTabs(const QString &filePath); +TEST(UT_Tabbar_closeRightTabs, UT_Tabbar_closeRightTabs) +{ + Tabbar * tab = new Tabbar(); + tab->m_tabPaths.push_back("aa"); + tab->closeRightTabs("aa"); + tab->closeLeftTabs("bb"); + + EXPECT_EQ(tab->count(),0); + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} + +//void closeOtherTabsExceptFile(const QString &filePath); +TEST(UT_Tabbar_closeOtherTabsExceptFile, UT_Tabbar_closeOtherTabsExceptFile) +{ + Tabbar * tab = new Tabbar(); + tab->m_tabPaths.push_back("bb"); + tab->closeOtherTabsExceptFile("aa"); + + EXPECT_EQ(tab->count(),0); + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} + +//void updateTab(int index, const QString &filePath, const QString &tabName); +TEST(UT_Tabbar_updateTab, UT_Tabbar_updateTab) +{ +// Tabbar * tab = new Tabbar(); +// tab->addTab("/.cache/deepin/deepin-editor","aa"); +// EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + +// tab->updateTab(0,"/.cache/deepin/deepin-editor","aa"); + +// EXPECT_NE(tab,nullptr); +// tab->deleteLater(); +} + +//void previousTab(); +TEST(UT_Tabbar_previousTab, UT_Tabbar_previousTab) +{ +// Tabbar * tab = new Tabbar(); +// tab->addTab("/.cache/deepin/deepin-editor","aa"); +// EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); +// tab->previousTab(); + +// tab->addTab("/.cache/deepin/deepin-editor","bb"); +// tab->previousTab(); + +// EXPECT_NE(tab,nullptr); + +// tab->deleteLater(); + +} +//void nextTab(); +TEST(UT_Tabbar_nextTab, UT_Tabbar_nextTab) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + tab->nextTab(); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} + +//int indexOf(const QString &filePath); +TEST(UT_Tabbar_indexOf, UT_Tabbar_indexOf) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + EXPECT_NE(tab->indexOf("/.cache/deepin/deepin-editor"),2); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} + +//QString currentName() const; +TEST(UT_Tabbar_currentName, UT_Tabbar_currentName) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EXPECT_NE(tab->currentName(),""); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//QString currentPath() const; +TEST(UT_Tabbar_currentPath, UT_Tabbar_currentPath) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EXPECT_NE(tab->currentPath(),""); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//QString fileAt(int index) const; +TEST(UT_Tabbar_fileAt, UT_Tabbar_fileAt) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EXPECT_NE(tab->fileAt(0),""); + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//QString textAt(int index) const; +TEST(UT_Tabbar_textAt, UT_Tabbar_textAt) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + EXPECT_NE(tab->textAt(0),""); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} + +//void setTabPalette(const QString &activeColor, const QString &inactiveColor); +TEST(UT_Tabbar_setTabPalette, UT_Tabbar_setTabPalette) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + tab->setTabPalette("red","red"); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//void setBackground(const QString &startColor, const QString &endColor); +TEST(UT_Tabbar_setBackground, UT_Tabbar_setBackground) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + tab->setBackground("red","red"); + + EXPECT_EQ(tab->m_backgroundStartColor,"red"); + + tab->deleteLater(); + +} +//void setDNDColor(const QString &startColor, const QString &endColor); +TEST(UT_Tabbar_setDNDColor, UT_Tabbar_setDNDColor) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + tab->setDNDColor("red","red"); + + EXPECT_EQ(tab->m_dndStartColor,"red"); + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} +//bool canInsertFromMimeData(int index, const QMimeData *source) const; +//bool eventFilter(QObject *, QEvent *event); +TEST(UT_Tabbar_eventFilter, UT_Tabbar_eventFilter) +{ +// Window* window = new Window; +// EditWrapper* wrapper = new EditWrapper(window); +// TextEdit* edit = new TextEdit(wrapper); +// edit->m_wrapper = wrapper; +// window->m_wrappers["12"]=wrapper; +// Tabbar * tab = new Tabbar(window); + +// tab->addTab("/.cache/deepin/deepin-editor","aa"); +// EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + +// QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress,QPointF(76,29),Qt::RightButton,Qt::RightButton,Qt::NoModifier); + +// Stub s1; +// s1.set((QAction* (QMenu::*)(const QPoint& , QAction *))ADDR(QMenu,exec),retintstub); + +// tab->eventFilter(tab,e); + +// EXPECT_NE(tab,nullptr); + +// tab->deleteLater(); +// window->deleteLater(); +// wrapper->deleteLater(); +// edit->deleteLater(); +} + +//QSize minimumTabSizeHint(int index) const; +TEST(UT_Tabbar_minimumTabSizeHint, UT_Tabbar_minimumTabSizeHint) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + EXPECT_EQ(tab->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EXPECT_EQ(tab->minimumTabSizeHint(0),QSize(110, 40)); + + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + + +} +//QSize maximumTabSizeHint(int index) const; +TEST(UT_Tabbar_maximumTabSizeHint, UT_Tabbar_maximumTabSizeHint) +{ + Tabbar * tab = new Tabbar(); + tab->addTab("/.cache/deepin/deepin-editor","aa"); + + EXPECT_EQ(tab->maximumTabSizeHint(0),QSize(160, 40)); + + EXPECT_NE(tab,nullptr); + + tab->deleteLater(); + +} + +TEST(UT_Tabbar_createDragPixmapFromTab, UT_Tabbar_createDragPixmapFromTab) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->createDragPixmapFromTab(index,option,&p); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + + +TEST(UT_Tabbar_createMimeDataFromTab, UT_Tabbar_createMimeDataFromTab) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->createMimeDataFromTab(index,option); + + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_insertFromMimeDataOnDragEnter, UT_Tabbar_insertFromMimeDataOnDragEnter) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + QMimeData *mimeData = new QMimeData; + mimeData->setData("dedit/tabbar","test"); + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->insertFromMimeDataOnDragEnter(index,mimeData); + EXPECT_EQ(wrapper->getFileLoading(),false); + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + EXPECT_NE(mimeData,nullptr); + + delete mimeData;mimeData = nullptr; + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_insertFromMimeData, UT_Tabbar_insertFromMimeData) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + QMimeData *mimeData = new QMimeData; + mimeData->setData("dedit/tabbar","test"); + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->insertFromMimeData(index,mimeData); + EXPECT_NE(window->getTabbar()->count(),0); + + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + EXPECT_NE(mimeData,nullptr); + + delete mimeData;mimeData = nullptr; + window->deleteLater(); + wrapper->deleteLater(); + + +} + + +TEST(UT_Tabbar_canInsertFromMimeData, UT_Tabbar_canInsertFromMimeData) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + QMimeData *mimeData = new QMimeData; + mimeData->setData("dedit/tabbar","test"); + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + EXPECT_EQ(window->getTabbar()->canInsertFromMimeData(index,mimeData),true); + + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + EXPECT_NE(mimeData,nullptr); + + + delete mimeData;mimeData = nullptr; + window->deleteLater(); + wrapper->deleteLater(); + + +} + + +TEST(UT_Tabbar_handleDragActionChanged, UT_Tabbar_handleDragActionChanged) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + Qt::DropAction actions[2] = {Qt::IgnoreAction,Qt::MoveAction}; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->handleDragActionChanged(actions[0]); + window->getTabbar()->handleDragActionChanged(actions[1]); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_mousePressEvent, UT_Tabbar_mousePressEvent) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + QMouseEvent* event = new QMouseEvent(QEvent::None,QPoint(),Qt::MidButton,Qt::MidButton,Qt::NoModifier); + + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->mousePressEvent(event); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + delete event;event = nullptr; + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_dropEvent, UT_Tabbar_dropEvent) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + QMimeData *mimeData = new QMimeData; + mimeData->setData("dedit/tabbar","test"); + QDropEvent* event = new QDropEvent(QPointF(100,100),Qt::CopyAction,mimeData,Qt::LeftButton,Qt::NoModifier); + + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->dropEvent(event); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + EXPECT_NE(event,nullptr); + EXPECT_NE(mimeData,nullptr); + + delete mimeData;mimeData = nullptr; + delete event;event = nullptr; + window->deleteLater(); + wrapper->deleteLater(); + + + +} + +TEST(UT_Tabbar_tabSizeHint, UT_Tabbar_tabSizeHint) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + EXPECT_NE(window->getTabbar()->tabSizeHint(index),QSize(1,1)); + + + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_handleTabMoved, UT_Tabbar_handleTabMoved) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->handleTabMoved(index,index); + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_handleTabReleased, UT_Tabbar_handleTabReleased) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->m_listOldTabPath.push_back("/.cache/deepin/deepin-editor"); + EXPECT_EQ(window->getTabbar()->m_listOldTabPath.contains("/.cache/deepin/deepin-editor"),true); + window->getTabbar()->handleTabReleased(index); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_handleTabIsRemoved, UT_Tabbar_handleTabIsRemoved) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->handleTabIsRemoved(index); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_handleTabDroped, UT_Tabbar_handleTabDroped) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + Qt::DropAction actions[2] = {Qt::IgnoreAction,Qt::MoveAction}; + + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->handleTabDroped(index,actions[0],nullptr); + window->getTabbar()->handleTabDroped(index,actions[0],window->getTabbar()); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_onTabDrapStart, UT_Tabbar_onTabDrapStart) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + Qt::DropAction actions[2] = {Qt::IgnoreAction,Qt::MoveAction}; + + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->onTabDrapStart(); + EXPECT_EQ(window->isVisible(),true); + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + + window->deleteLater(); + wrapper->deleteLater(); + + +} + +TEST(UT_Tabbar_resizeEvent, UT_Tabbar_resizeEvent) +{ + int index = 0; + QStyleOptionTab option; + QPoint p; + Qt::DropAction actions[2] = {Qt::IgnoreAction,Qt::MoveAction}; + QResizeEvent* e = new QResizeEvent(QSize(),QSize()); + + + Window * window = new Window; + window->addTab("/.cache/deepin/deepin-editor",true); + EXPECT_EQ(window->m_tabbar->m_tabPaths.contains("/.cache/deepin/deepin-editor"),true); + + EditWrapper* wrapper = new EditWrapper(window); + window->getTabbar()->resizeEvent(e); + + + EXPECT_NE(window,nullptr); + EXPECT_NE(wrapper,nullptr); + EXPECT_NE(e,nullptr); + + + + delete e; e = nullptr; + window->deleteLater(); + wrapper->deleteLater(); + + +} + + diff --git a/tests/src/controls/ut_tabbar.h b/tests/src/controls/ut_tabbar.h new file mode 100644 index 0000000000000000000000000000000000000000..72e2564b3493112014426e39ae142809d977838e --- /dev/null +++ b/tests/src/controls/ut_tabbar.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_Tabbar_H +#define UT_Tabbar_H +#include "gtest/gtest.h" +#include +#include"../../src/controls/tabbar.h" + + +class UT_Tabbar: public QObject, public::testing::Test +{ + Q_OBJECT + +public: + UT_Tabbar(); +}; + +#endif // UT_Tabbar_H diff --git a/tests/src/controls/ut_toolbar.cpp b/tests/src/controls/ut_toolbar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d2c89241a56e38745a7ea5e57759a51ea25f58d --- /dev/null +++ b/tests/src/controls/ut_toolbar.cpp @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_toolbar.h" +#include "../src/controls/toolbar.h" +test_toolbar::test_toolbar() +{ + +} + +TEST_F(test_toolbar, ToolBar) +{ + ToolBar* tool = new ToolBar(); + + EXPECT_NE(tool,nullptr); + delete tool; + tool = nullptr; + +} + +TEST_F(test_toolbar, setTabbar) +{ + ToolBar* tool = new ToolBar(); + tool->setTabbar(nullptr); + + EXPECT_NE(tool->m_layout->count(),0); + + EXPECT_NE(tool,nullptr); + tool->deleteLater(); + +} diff --git a/tests/src/controls/ut_toolbar.h b/tests/src/controls/ut_toolbar.h new file mode 100644 index 0000000000000000000000000000000000000000..cb92bc181e41bdfabdce7899a8b3a5e693ee89c0 --- /dev/null +++ b/tests/src/controls/ut_toolbar.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_TOOLBAR_H +#define TEST_TOOLBAR_H + + +#include "gtest/gtest.h" +#include + +class test_toolbar : public QObject, public::testing::Test +{ +public: + test_toolbar(); +}; +#endif // TEST_TOOLBAR_H diff --git a/tests/src/controls/ut_warningnotices.cpp b/tests/src/controls/ut_warningnotices.cpp new file mode 100644 index 0000000000000000000000000000000000000000..def7d894f35019dd828376c01a3eb61e77dcf478 --- /dev/null +++ b/tests/src/controls/ut_warningnotices.cpp @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_warningnotices.h" +#include "../../src/controls/warningnotices.h" + +test_warningnotices::test_warningnotices() +{ + +} + +//explicit WarningNotices(MessageType notifyType = MessageType::ResidentType); +TEST_F(test_warningnotices, WarningNotices) +{ + WarningNotices notices(WarningNotices::ResidentType); + +} + +//void setReloadBtn(); +TEST_F(test_warningnotices, setReloadBtn) +{ + WarningNotices *notices = new WarningNotices(WarningNotices::ResidentType); + notices->m_reloadBtn->setVisible(false); + notices->setReloadBtn(); + + EXPECT_EQ(notices->m_reloadBtn->isVisible(),false); + + notices->setReloadBtn(); + notices->slotreloadBtnClicked(); + EXPECT_EQ(notices->isVisible(),false); + + + EXPECT_NE(notices,nullptr); + notices->deleteLater(); + +} + +//void setSaveAsBtn(); +TEST_F(test_warningnotices, setSaveAsBtn) +{ + WarningNotices *notices = new WarningNotices(WarningNotices::ResidentType); + notices->setSaveAsBtn(); + notices->slotsaveAsBtnClicked(); + + + EXPECT_EQ(notices->m_saveAsBtn->isVisible(),false); + + EXPECT_NE(notices,nullptr); + notices->deleteLater(); + +} + diff --git a/tests/src/controls/ut_warningnotices.h b/tests/src/controls/ut_warningnotices.h new file mode 100644 index 0000000000000000000000000000000000000000..7e71a2a25ef990e3d0b534ceff6c01bc75574e0a --- /dev/null +++ b/tests/src/controls/ut_warningnotices.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_WARNINGNOTICES_H +#define TEST_WARNINGNOTICES_H +#include "gtest/gtest.h" +#include + +class test_warningnotices : public QObject, public::testing::Test +{ +public: + test_warningnotices(); +}; + +#endif // TEST_WARNINGNOTICES_H diff --git a/tests/src/editor/ut_bookmarkwidget.cpp b/tests/src/editor/ut_bookmarkwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ede714b18a5e4f5130d528bf9f923fc2e626714 --- /dev/null +++ b/tests/src/editor/ut_bookmarkwidget.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_bookmarkwidget.h" + +test_bookmarkwidget::test_bookmarkwidget() +{ + +} + +TEST_F(test_bookmarkwidget, BookMarkWidget) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString("aabb")); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pBookMarkArea->m_leftAreaWidget != nullptr); + delete pWindow; + pWindow = nullptr; +} + +TEST_F(test_bookmarkwidget, paintEvent) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString("aabb")); + QPaintEvent *pEvent; + pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pBookMarkArea->paintEvent(pEvent); + + delete pWindow; + pWindow = nullptr; +} diff --git a/tests/src/editor/ut_bookmarkwidget.h b/tests/src/editor/ut_bookmarkwidget.h new file mode 100644 index 0000000000000000000000000000000000000000..60a5088ba085259ac31c2b1a1fdb1a4cf917aa33 --- /dev/null +++ b/tests/src/editor/ut_bookmarkwidget.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_BOOKMARKWIDGET_H +#define TEST_BOOKMARKWIDGET_H +#include"../../src/editor/bookmarkwidget.h" +#include "gtest/gtest.h" +#include"../../src/editor/editwrapper.h" +#include"../../src/widgets/window.h" +#include"../../src/startmanager.h" +#include"../../src/editor/dtextedit.h" +#include"../../src/editor/FlashTween.h" +#include"../stub.h" +#include +#include +#include + + +class test_bookmarkwidget: public QObject, public::testing::Test +{ +public: + test_bookmarkwidget(); +}; + +#endif // TEST_BOOKMARKWIDGET_H diff --git a/tests/src/editor/ut_codeflodarea.cpp b/tests/src/editor/ut_codeflodarea.cpp new file mode 100644 index 0000000000000000000000000000000000000000..56a6261c275a5a0beaa2a791b55d545c6c2d9c73 --- /dev/null +++ b/tests/src/editor/ut_codeflodarea.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_codeflodarea.h" +#include "QPaintEvent" +test_codeflodarea::test_codeflodarea() +{ + +} + +TEST_F(test_codeflodarea, CodeFlodArea) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString("abc")); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pFlodArea->m_pLeftAreaWidget != nullptr); + + delete pWindow; + pWindow = nullptr; +} + +TEST_F(test_codeflodarea, paintEvent) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString("abc")); + QPaintEvent *pEvent = new QPaintEvent(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pFlodArea->rect()); + pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pFlodArea->paintEvent(pEvent); + + delete pEvent; + pEvent = nullptr; + delete pWindow; + pWindow = nullptr; +} diff --git a/tests/src/editor/ut_codeflodarea.h b/tests/src/editor/ut_codeflodarea.h new file mode 100644 index 0000000000000000000000000000000000000000..89754ef87e808d4fc4e060cbf11feaf07af76e02 --- /dev/null +++ b/tests/src/editor/ut_codeflodarea.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_CODEFLODAREA_H +#define TEST_CODEFLODAREA_H +#include"../../src/editor/bookmarkwidget.h" +#include "gtest/gtest.h" +#include"../../src/editor/editwrapper.h" +#include"../../src/widgets/window.h" +#include"../../src/startmanager.h" +#include"../../src/editor/dtextedit.h" +#include"../../src/editor/FlashTween.h" +#include"../stub.h" +#include +#include +#include + + +class test_codeflodarea: public QObject, public::testing::Test +{ +public: + test_codeflodarea(); +}; + +#endif // TEST_CODEFLODAREA_H diff --git a/tests/src/editor/ut_deletebackcommond.cpp b/tests/src/editor/ut_deletebackcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..56452cd554eb0f4eb8ea38b22c93d2b810f828a5 --- /dev/null +++ b/tests/src/editor/ut_deletebackcommond.cpp @@ -0,0 +1,148 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_deletebackcommond.h" +#include "../src/editor/deletebackcommond.h" +#include"../../src/widgets/window.h" +#include "qplaintextedit.h" +#include "qtextcursor.h" +UT_Deletebackcommond::UT_Deletebackcommond() +{ + +} + +TEST(UT_Deletebackcommond_DeleteBackCommand, UT_Deletebackcommond_DeleteBackCommand) +{ + QTextCursor cursor; + QPlainTextEdit *pEdit = new QPlainTextEdit; + DeleteBackCommand *pCom = new DeleteBackCommand(cursor, pEdit); + ASSERT_TRUE(pCom->m_insertPos != 0); + + delete pCom; + pCom = nullptr; + delete pEdit; + pEdit = nullptr; +} + +TEST(UT_Deletebackcommond_redo, UT_Deletebackcommond_redo) +{ + QString text = "test"; + Window *pWindow = new Window; + pWindow->addBlankTab(QString()); + QTextCursor cursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertPlainText(QString("12345")); + cursor.setPosition(10, QTextCursor::MoveMode::KeepAnchor); + DeleteBackCommand *pCom = new DeleteBackCommand(cursor, pWindow->currentWrapper()->textEditor()); + pCom->m_delText = text; + pCom->redo(); + + ASSERT_EQ(cursor.position(), pWindow->currentWrapper()->textEditor()->textCursor().position()); + + delete pCom; + pCom = nullptr; + delete pWindow; + pWindow = nullptr; +} + +TEST(UT_Deletebackcommond_undo, UT_Deletebackcommond_undo) +{ + QString text = "test"; + Window *pWindow = new Window; + pWindow->addBlankTab(QString()); + QTextCursor cursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertPlainText(QString("12345")); + cursor.setPosition(10, QTextCursor::MoveMode::KeepAnchor); + DeleteBackCommand *pCom = new DeleteBackCommand(cursor, pWindow->currentWrapper()->textEditor()); + pCom->m_delText = text; + pCom->undo(); + + ASSERT_NE(cursor.position(), pWindow->currentWrapper()->textEditor()->textCursor().position()); + + delete pCom; + pCom = nullptr; + delete pWindow; + pWindow = nullptr; +} + + + +UT_Deletebackaltcommond::UT_Deletebackaltcommond() +{ + +} + +TEST(UT_Deletebackaltcommond_DeleteBackAltCommand, UT_Deletebackaltcommond_DeleteBackAltCommand) +{ + QString text = "test"; + QList list; + QTextEdit::ExtraSelection sel; + QTextCursor cursor; + cursor.insertText(text); + cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); + sel.cursor = cursor; + list.push_back(sel); + list.push_back(sel); + + QPlainTextEdit* edit = new QPlainTextEdit; + DeleteBackAltCommand* com = new DeleteBackAltCommand(list, edit); + + delete com; + com = nullptr; + delete edit; + edit = nullptr; +} + +TEST(UT_Deletebackaltcommond_redo, UT_Deletebackaltcommond_redo) +{ + + Window* window = new Window; + EditWrapper *wrapper = window->createEditor(); + TextEdit * edit = wrapper->textEditor(); + QString text = "test"; + QList list; + QTextEdit::ExtraSelection sel; + QTextCursor cursor; + cursor.insertText(text); + cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor); + sel.cursor = cursor; + list.push_back(sel); + list.push_back(sel); + DeleteBackAltCommand * commond = new DeleteBackAltCommand(list,edit); + commond->m_deletions = {{"123",1,1,1,cursor}}; + commond->redo(); + + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + + delete commond;commond=nullptr; +} + + +TEST(UT_Deletebackaltcommond_undo, UT_Deletebackaltcommond_undo) +{ + Window* window = new Window; + EditWrapper *wrapper = window->createEditor(); + TextEdit * edit = wrapper->textEditor(); + QString text = "test"; + QList list; + QTextEdit::ExtraSelection sel; + QTextCursor cursor; + cursor.insertText(text); + cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor); + sel.cursor = cursor; + list.push_back(sel); + list.push_back(sel); + + DeleteBackAltCommand* com = new DeleteBackAltCommand(list,edit); + com->m_deletions = {{"123",1,1,1,cursor}}; + com->undo(); + + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete com; + com = nullptr; + +} diff --git a/tests/src/editor/ut_deletebackcommond.h b/tests/src/editor/ut_deletebackcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..46718903612dac1af311a7b10c121dfe08623b00 --- /dev/null +++ b/tests/src/editor/ut_deletebackcommond.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_Deletebackcommond_H +#define UT_Deletebackcommond_H + + +#include "gtest/gtest.h" +#include + + +class UT_Deletebackcommond: public QObject, public::testing::Test +{ + Q_OBJECT +public: + UT_Deletebackcommond(); +}; + +class UT_Deletebackaltcommond: public QObject, public::testing::Test +{ + Q_OBJECT +public: + UT_Deletebackaltcommond(); +}; + + +#endif // UT_Deletebackcommond_H diff --git a/tests/src/editor/ut_deletetextundocommand.cpp b/tests/src/editor/ut_deletetextundocommand.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c252939a361c6826716cd1d7ea3803748ea0711 --- /dev/null +++ b/tests/src/editor/ut_deletetextundocommand.cpp @@ -0,0 +1,451 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_deletetextundocommand.h" +#include "src/stub.h" +#include + +namespace deletetextstub { + +int intvalue=1; +int retintstub() +{ + return intvalue; +} + +bool rettruestub() +{ + return true; +} +bool retfalsestub() +{ + return false; +} + +} + +using namespace deletetextstub; + + +UT_Deletetextundocommond::UT_Deletetextundocommond() +{ + +} + +TEST(UT_Deletetextundocommond_DeleteTextUndoCommand, UT_Deletetextundocommond_DeleteTextUndoCommand) +{ +#if 0 + Window* window = new Window; + EditWrapper *wrapper = window->createEditor(); + TextEdit * edit = wrapper->textEditor(); + edit->insertTextEx(edit->textCursor(),"123456"); + auto cursor1 = edit->textCursor(); + edit->selectAll(); + auto cursor2 = edit->textCursor(); + + + DeleteTextUndoCommand * commond1 = new DeleteTextUndoCommand(cursor1); + DeleteTextUndoCommand * commond2 = new DeleteTextUndoCommand(cursor2); + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + DeleteTextUndoCommand * commond3 = new DeleteTextUndoCommand(selections); + + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond1;commond1=nullptr; + delete commond2;commond2=nullptr; + delete commond3;commond3=nullptr; +#endif + +} + +TEST(UT_Deletetextundocommond_undo, UT_Deletetextundocommond_undo) +{ + QTextCursor cursor; + DeleteTextUndoCommand * commond1 = new DeleteTextUndoCommand(cursor, nullptr); + commond1->m_sInsertText = "ddd"; + + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor.clearSelection(); + extraSelections.append(selection); + DeleteTextUndoCommand * commond2 = new DeleteTextUndoCommand(extraSelections, nullptr); + + commond1->undo(); + commond2->undo(); + + int iRet = commond1->m_sInsertText.length(); + ASSERT_TRUE(iRet == QString("ddd").length()); + + delete commond1;commond1=nullptr; + delete commond2;commond2=nullptr; +} + +TEST(UT_Deletetextundocommond_undo, undo_withTextCursor_restoreCursor) +{ + // 撤销后恢复光标位置 + QPlainTextEdit *edit = new QPlainTextEdit; + edit->setPlainText("123456789"); + + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(3); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3); + EXPECT_EQ(QString("456"), cursor.selectedText()); + DeleteTextUndoCommand *command = new DeleteTextUndoCommand(cursor, edit); + cursor.deleteChar(); + command->undo(); + + EXPECT_EQ(command->m_textCursor.position(), edit->textCursor().position()); + + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = edit->textCursor(); + selection.cursor.setPosition(3); + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3); + extraSelections.append(selection); + DeleteTextUndoCommand *command2 = new DeleteTextUndoCommand(extraSelections, edit); + selection.cursor.deleteChar(); + command2->undo(); + + EXPECT_EQ(command2->m_ColumnEditSelections.last().cursor.position(), edit->textCursor().position()); + + delete command; + delete command2; + delete edit; +} + +TEST(UT_Deletetextundocommond_redo, UT_Deletetextundocommond_redo) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + QTextCursor cursor1 = pWindow->currentWrapper()->textEditor()->textCursor(); + auto cursor2 = pWindow->currentWrapper()->textEditor()->textCursor(); + DeleteTextUndoCommand * commond1 = new DeleteTextUndoCommand(cursor1, nullptr); + DeleteTextUndoCommand * commond2 = new DeleteTextUndoCommand(cursor2, nullptr); + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + DeleteTextUndoCommand * commond3 = new DeleteTextUndoCommand(selections, nullptr); + commond1->redo(); + commond2->redo(); + commond3->redo(); + + int iRet = commond1->m_sInsertText.length(); + ASSERT_TRUE(iRet == 1); + + delete commond1;commond1=nullptr; + delete commond2;commond2=nullptr; + delete commond3;commond3=nullptr; +} + +TEST(UT_Deletetextundocommond_rddo, redo_withTextCursor_changeCursor) +{ + // 重做后恢复光标位置 + QPlainTextEdit *edit = new QPlainTextEdit; + edit->setPlainText("123456789"); + + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(3); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3); + EXPECT_EQ(QString("456"), cursor.selectedText()); + DeleteTextUndoCommand *command = new DeleteTextUndoCommand(cursor, edit); + command->redo(); + + EXPECT_EQ(command->m_textCursor.position(), edit->textCursor().position()); + + edit->setPlainText("123456789"); + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = edit->textCursor(); + selection.cursor.setPosition(3); + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3); + extraSelections.append(selection); + DeleteTextUndoCommand *command2 = new DeleteTextUndoCommand(extraSelections, edit); + command2->redo(); + + EXPECT_EQ(command2->m_ColumnEditSelections.last().cursor.position(), edit->textCursor().position()); + + delete command; + delete command2; + delete edit; +} + +TEST(UT_Deletetextundocommond_DeleteTextUndoCommand2, UT_Deletetextundocommond_DeleteTextUndoCommand2_002) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),retfalsestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + +TEST(UT_Deletetextundocommond_DeleteTextUndoCommand2, UT_Deletetextundocommond_DeleteTextUndoCommand2_003) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),rettruestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + +TEST(UT_Deletetextundocommond2_undo, UT_Deletetextundocommond2_undo_001) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),retfalsestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + commond3->m_ColumnEditSelections = selections; + commond3->undo(); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + +TEST(UT_Deletetextundocommond2_undo, UT_Deletetextundocommond2_undo_002) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),retfalsestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + commond3->m_ColumnEditSelections.clear(); + commond3->undo(); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + +TEST(UT_Deletetextundocommond2_redo, UT_Deletetextundocommond2_redo_001) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),retfalsestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + commond3->m_ColumnEditSelections=selections; + commond3->redo(); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + +TEST(UT_Deletetextundocommond2_redo, UT_Deletetextundocommond2_redo_002) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),retfalsestub); + s1.set(ADDR(QTextCursor,atBlockEnd),rettruestub); + s1.set(ADDR(QTextCursor,atBlockStart),rettruestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + commond3->m_ColumnEditSelections.clear(); + + commond3->m_iscurrLine=false; + commond3->redo(); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + +TEST(UT_Deletetextundocommond2_redo, UT_Deletetextundocommond2_redo_003) +{ + + Window* window = new Window; + EditWrapper* wrapper = new EditWrapper(window); + TextEdit * edit = new TextEdit(window); + edit->m_wrapper = wrapper; + + QTextCursor cursor1,cursor2; + + + QTextEdit::ExtraSelection select[2]; + select[0].cursor = cursor1; + select[1].cursor = cursor2; + + QList selections{select[0],select[1]}; + + Stub s1; + s1.set(ADDR(QTextCursor,positionInBlock),retintstub); + s1.set(ADDR(QTextCursor,hasSelection),retfalsestub); + s1.set(ADDR(QTextCursor,atBlockEnd),rettruestub); + s1.set(ADDR(QTextCursor,atBlockStart),rettruestub); + s1.set(ADDR(QString,at),rettruestub); + + intvalue = -1; + DeleteTextUndoCommand2 * commond3 = new DeleteTextUndoCommand2(selections,"test",edit,false); + commond3->m_ColumnEditSelections.clear(); + + commond3->m_iscurrLine=true; + commond3->redo(); + + EXPECT_NE(edit,nullptr); + window->deleteLater(); + wrapper->deleteLater(); + edit->deleteLater(); + delete commond3; + commond3=nullptr; + +} + + + + + diff --git a/tests/src/editor/ut_deletetextundocommand.h b/tests/src/editor/ut_deletetextundocommand.h new file mode 100644 index 0000000000000000000000000000000000000000..c2503eb3d8dd1f2f3f4b5f12a640bc3959af9563 --- /dev/null +++ b/tests/src/editor/ut_deletetextundocommand.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_TEXTUNDOCOMMAND_H +#define TEST_TEXTUNDOCOMMAND_H +#include"../../src/editor/bookmarkwidget.h" +#include "gtest/gtest.h" +#include"../../src/editor/editwrapper.h" +#include"../../src/widgets/window.h" +#include"../../src/startmanager.h" +#include"../../src/editor/dtextedit.h" +#include"../../src/editor/FlashTween.h" +#include"../../src/editor/deletetextundocommand.h" +#include"../stub.h" +#include +#include +#include + + +class UT_Deletetextundocommond: public QObject, public::testing::Test +{ +public: + UT_Deletetextundocommond(); +}; + +#endif // TEST_TEXTUNDOCOMMAND_H diff --git a/tests/src/editor/ut_editwrapper.cpp b/tests/src/editor/ut_editwrapper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d69f4f7b777c9535426ce71657b500afd8b659e --- /dev/null +++ b/tests/src/editor/ut_editwrapper.cpp @@ -0,0 +1,1454 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_editwrapper.h" +#include "qfile.h" +#include +#include "DSettingsOption" + +namespace editwrapperstub { + +int intvalue=1; +int retintstub() +{ + return intvalue; +} + +bool retfalsestub() +{ + return false; +} + +bool rettruestub() +{ + return true; +} + +QStringList stringList = {"/tmp/ut_123.txt","/tmp/ut_456.txt"}; +QStringList retstringliststub() +{ + return stringList; +} + +QPointer d = nullptr; +QPointer retsettingoption() +{ + if (d == nullptr) { + d = new DSettingsOption(); + } + QVariant v(stringList); + d->setValue(v); + QVariant p = d->value(); + return d; +} + +QString retstring() +{ + return "123"; +} + +} + + + +using namespace editwrapperstub; + +UT_Editwrapper::UT_Editwrapper() +{ + QString text = QString("#include \"window.h\"\n" + "#include \"urlinfo.h\"\n" + "int main(int argc, char *argv[])\n" + "{\n" + "using namespace Dtk::Core;\n" + "PerformanceMonitor::initializeAppStart();\n" + "return 0;\n" + "}"); + QFile f("1.cpp"); + if(f.open(QFile::WriteOnly)){ + f.write(text.toUtf8()); + f.close(); + } +} + +TEST(UT_Editwrapper_EditWrapper, UT_Editwrapper_EditWrapper) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + ASSERT_TRUE(pWindow->currentWrapper()->m_pBottomBar != nullptr); + ASSERT_TRUE(pWindow->currentWrapper()->m_pTextEdit != nullptr); + + delete pWindow; + pWindow = nullptr; +} + +//void setQuitFlag(); +TEST(UT_Editwrapper_setQuitFlag, UT_Editwrapper_setQuitFlag) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->setQuitFlag(); + ASSERT_TRUE(pWindow->currentWrapper()->m_bQuit == true); + + delete pWindow; + pWindow = nullptr; +} + +//bool getFileLoading(); +TEST(UT_Editwrapper_getFileLoading, UT_Editwrapper_getFileLoading) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->setQuitFlag(); + ASSERT_TRUE(pWindow->currentWrapper()->getFileLoading() == true); + + delete pWindow; + pWindow = nullptr; +} + +//void openFile(const QString &filepath,QString qstrTruePath,bool bIsTemFile = false); +TEST(UT_Editwrapper_openFile, UT_Editwrapper_openFile) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->openFile(QString("a.cpp"), QString("b.cpp")); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_bIsFileOpen == true); + + delete pWindow; + pWindow = nullptr; +} + +bool saveFile_001_stub() +{ + return true; +} + +void hideWarningNotices_stub() +{ + return; +} + +//bool saveFile_001(); +TEST(UT_Editwrapper_saveFile, UT_Editwrapper_saveFile_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + + Stub stubNotices; + stubNotices.set(ADDR(EditWrapper, hideWarningNotices), hideWarningNotices_stub); + bool bRet = pWindow->currentWrapper()->saveFile(); + if (bRet == false) { + Stub stub; + stub.set(pWindow->currentWrapper()->saveFile(), saveFile_001_stub()); + bRet = pWindow->currentWrapper()->saveFile(); + } + EXPECT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +bool saveFile_002_stub() +{ + return true; +} + +//bool saveFile_002(); +TEST(UT_Editwrapper_saveFile, UT_Editwrapper_saveFile_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + bool bRet = pWindow->currentWrapper()->saveFile(); + Stub stubNotices; + stubNotices.set(ADDR(EditWrapper, hideWarningNotices), hideWarningNotices_stub); + if (bRet == false) { + Stub stub; + stub.set(pWindow->currentWrapper()->saveFile(), saveFile_002_stub()); + bRet = pWindow->currentWrapper()->saveFile(); + } + EXPECT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//bool saveFile_003(); +TEST(UT_Editwrapper_saveFile, UT_Editwrapper_saveFile_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->m_sFilePath = QString(""); + pWindow->currentWrapper()->textEditor()->m_qstrTruePath = QString(""); + Stub stubNotices; + stubNotices.set(ADDR(EditWrapper, hideWarningNotices), hideWarningNotices_stub); + bool bRet = pWindow->currentWrapper()->saveFile(); + EXPECT_TRUE(bRet == false); + + pWindow->deleteLater(); +} + +TEST(UT_Editwrapper_saveFile, UT_Editwrapper_saveFile_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->m_sFilePath = QString(""); + pWindow->currentWrapper()->textEditor()->m_qstrTruePath = QString(""); + + Stub stubNotices; + stubNotices.set(ADDR(EditWrapper, hideWarningNotices), hideWarningNotices_stub); + typedef bool (*Fptr2)(QFile*,QFile::OpenMode); + Fptr2 A_foo = (Fptr2)((bool(QFile::*)(QFile::OpenMode))&QFile::open); + Stub s1; + s1.set(A_foo,rettruestub); + + Stub s2; + s2.set(ADDR(QByteArray,isEmpty),rettruestub); + + bool bRet = pWindow->currentWrapper()->saveFile(); + EXPECT_TRUE(bRet); + + pWindow->deleteLater(); +} + +TEST(UT_Editwrapper_saveFile, UT_Editwrapper_saveFile_005) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->m_sFilePath = QString(""); + pWindow->currentWrapper()->textEditor()->m_qstrTruePath = QString(""); + + Stub stubNotices; + stubNotices.set(ADDR(EditWrapper, hideWarningNotices), hideWarningNotices_stub); + typedef bool (*Fptr2)(QFile*,QFile::OpenMode); + Fptr2 A_foo = (Fptr2)((bool(QFile::*)(QFile::OpenMode))&QFile::open); + Stub s1; + s1.set(A_foo,rettruestub); + + Stub s2; + s2.set(ADDR(QByteArray,isEmpty),retfalsestub); + + Stub s3; + s3.set(ADDR(QByteArray,size),retintstub); + + intvalue=0; + bool bRet = pWindow->currentWrapper()->saveFile(); + EXPECT_TRUE(bRet); + + pWindow->deleteLater(); +} + + +TEST(UT_Editwrapper_saveFile, UT_Editwrapper_saveFile_with_encode) +{ + Window *pWindow = new Window; + pWindow->addBlankTab(QString()); + QString tmpFilePath("/tmp/UT_Editwrapper_saveFile.txt"); + pWindow->currentWrapper()->textEditor()->m_sFilePath = tmpFilePath; + pWindow->currentWrapper()->textEditor()->m_qstrTruePath = tmpFilePath; + + QByteArray encoding("GB18030"); + QByteArray utfData("\u4e2d\u6587\u6d4b\u8bd5\u4e00\u4e8c\u4e09\u56db\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + "\u0038\u0039\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068"); + pWindow->currentWrapper()->textEditor()->setPlainText(QString::fromUtf8(utfData)); + + Stub stubNotices; + stubNotices.set(ADDR(EditWrapper, hideWarningNotices), hideWarningNotices_stub); + intvalue = 1; + typedef int (*Fptr)(QFileDialog *); + Fptr fptr = (Fptr)(&QFileDialog::exec); + Stub s1; + s1.set(fptr,retintstub); + + intvalue = 1; + bool bRet = pWindow->currentWrapper()->saveFile(encoding); + EXPECT_TRUE(bRet); + + QFile tmpFile(tmpFilePath); + EXPECT_TRUE(tmpFile.exists()); + QByteArray saveData; + if (tmpFile.open(QFile::ReadOnly | QFile::Text)) { + saveData = tmpFile.readAll(); + tmpFile.close(); + } + + QTextCodec *codec = QTextCodec::codecForName(encoding); + EXPECT_EQ(codec->fromUnicode(utfData), saveData); + + pWindow->deleteLater(); +} + + +//bool saveAsFile_001(const QString &newFilePath, QByteArray encodeName); +TEST(UT_Editwrapper_saveAsFile_001, UT_Editwrapper_saveAsFile_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + bool bRet = pWindow->currentWrapper()->saveAsFile(QString(), QByteArray("UTF-8")); + EXPECT_FALSE(bRet); + + pWindow->deleteLater(); +} + +bool saveAsFile_002_stub() +{ + return true; +} + +//bool saveAsFile_001(const QString &newFilePath, QByteArray encodeName); +TEST(UT_Editwrapper_saveAsFile, UT_Editwrapper_saveAsFile_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + QString newFilePaht(pWindow->currentWrapper()->textEditor()->getTruePath()); + bool bRet = pWindow->currentWrapper()->saveAsFile(newFilePaht, QByteArray("UTF-8")); + EXPECT_TRUE(bRet); + + pWindow->deleteLater(); +} + +TEST(UT_Editwrapper_saveAsFile, UT_Editwrapper_saveAsFile_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + intvalue = 1; + typedef int (*Fptr)(QFileDialog *); + Fptr fptr = (Fptr)(&QFileDialog::exec); + Stub s1; + s1.set(fptr,retintstub); + + Stub s2; + s2.set(ADDR(QString,isEmpty),retfalsestub); + Stub s3; + s3.set(ADDR(QFileDialog,selectedFiles),retstringliststub); + + typedef bool (*Fptr2)(QFile*,QFile::OpenMode); + Fptr2 A_foo = (Fptr2)((bool(QFile::*)(QFile::OpenMode))&QFile::open); + Stub s4; + s4.set(A_foo,rettruestub); + + bool bRet = pWindow->currentWrapper()->saveAsFile(); + + EXPECT_TRUE(bRet); + pWindow->deleteLater(); +} + +// bool saveAsFile(const QString &newFilePath, const QByteArray &encodeName); +TEST(UT_Editwrapper_saveAsFile, UT_Editwrapper_saveFile_with_change_encoding) +{ + Window *pWindow = new Window; + QString saveAsPath("/tmp/ut_saveAsFile.txt"); + QByteArray encoding("GB18030"); + // Utf8 Text: 中文测试一二三四123456789abcdefgh + QByteArray utfData("\u4e2d\u6587\u6d4b\u8bd5\u4e00\u4e8c\u4e09\u56db\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + "\u0038\u0039\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068"); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->setPlainText(QString::fromUtf8(utfData)); + + // 默认文本编码为 UTF-8, 转换为 GB18030 + bool ret = pWindow->currentWrapper()->saveAsFile(saveAsPath, encoding); + EXPECT_TRUE(ret); + + QFile saveAsFile(saveAsPath); + EXPECT_TRUE(saveAsFile.open(QFile::ReadOnly | QFile::Text)); + QByteArray saveData = saveAsFile.readAll(); + saveAsFile.close(); + saveAsFile.remove(); + + QTextCodec *codec = QTextCodec::codecForName(encoding); + EXPECT_EQ(codec->fromUnicode(utfData), saveData); + + pWindow->deleteLater(); +} + +// bool saveAsFile(const QString &newFilePath, const QByteArray &encodeName); +TEST(UT_Editwrapper_saveAsFile, UT_Editwrapper_saveFile_with_error_encoding) +{ + Window *pWindow = new Window; + QString saveAsPath("/tmp/ut_saveAsFile.txt"); + QByteArray errEncoding("ERROR-ENCODING"); + // Utf8 Text: 中文测试一二三四123456789abcdefgh + QByteArray utfData("\u4e2d\u6587\u6d4b\u8bd5\u4e00\u4e8c\u4e09\u56db\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + "\u0038\u0039\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068"); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->setPlainText(QString::fromUtf8(utfData)); + + // 默认文本编码为 UTF-8, 转换为 GB18030 + bool ret = pWindow->currentWrapper()->saveAsFile(saveAsPath, errEncoding); + EXPECT_FALSE(ret); + + pWindow->deleteLater(); +} + +// bool saveAsFile(const QString &newFilePath, const QByteArray &encodeName); +TEST(UT_Editwrapper_saveAsFile, UT_Editwrapper_saveFile_with_empty_data) +{ + Window *pWindow = new Window; + QString saveAsPath("/tmp/ut_saveAsFile.txt"); + pWindow->addBlankTab(QString()); + + // 默认文本编码为 UTF-8, 转换为 GB18030 + bool ret = pWindow->currentWrapper()->saveAsFile(saveAsPath, "UTF-8"); + EXPECT_TRUE(ret); + + pWindow->deleteLater(); +} + +//void updatePath(const QString &file); +TEST(UT_Editwrapper_updatePath, UT_Editwrapper_updatePath) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strFilePath(pWindow->currentWrapper()->textEditor()->m_sFilePath); + QString strTruePath(pWindow->currentWrapper()->textEditor()->m_qstrTruePath); + ASSERT_TRUE(!strFilePath.compare(strTruePath)); + + delete pWindow; + pWindow = nullptr; +} + +//void hideWarningNotices(); +TEST(UT_Editwrapper_hideWarningNotices, UT_Editwrapper_hideWarningNotices) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + if (pWindow->currentWrapper()->m_pWaringNotices != nullptr) { + pWindow->currentWrapper()->m_pWaringNotices->show(); + } + pWindow->currentWrapper()->hideWarningNotices(); + ASSERT_TRUE(pWindow->currentWrapper()->m_pWaringNotices->isHidden()); + + delete pWindow; + pWindow = nullptr; +} + +//void checkForReload(); +TEST(UT_Editwrapper_checkForReload, UT_Editwrapper_checkForReload_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->checkForReload(); + QString strFilePath(pWindow->currentWrapper()->textEditor()->m_sFilePath); + QString strTruePath(pWindow->currentWrapper()->textEditor()->m_qstrTruePath); + ASSERT_TRUE(!strFilePath.compare(strTruePath)); + + pWindow->deleteLater(); +} + +bool checkForReload_002_stub() +{ + return false; +} + +//void checkForReload(); +TEST(UT_Editwrapper_checkForReload, UT_Editwrapper_checkForReload_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + Stub stub; + stub.set(ADDR(Utils,isDraftFile), checkForReload_002_stub); + pWindow->currentWrapper()->checkForReload(); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getTruePath() != nullptr); + + pWindow->deleteLater(); +} + +//void initToastPosition() 无实现; + +//void showNotify(const QString &message); +TEST(UT_Editwrapper_showNotify, UT_Editwrapper_showNotify_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->setReadOnlyPermission(true); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + pWindow->currentWrapper()->showNotify(QString("read-only")); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getReadOnlyPermission() == true); + + pWindow->deleteLater(); +} + +//void showNotify(const QString &message); +TEST(UT_Editwrapper_showNotify, UT_Editwrapper_showNotify_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->setReadOnlyPermission(false); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = false; + pWindow->currentWrapper()->showNotify(QString("Not read-only")); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getReadOnlyPermission() == false); + + pWindow->deleteLater(); +} + +//void setLineNumberShow(bool bIsShow,bool bIsFirstShow = false); +TEST(UT_Editwrapper_setLineNumberShow, UT_Editwrapper_setLineNumberShow_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->setLineNumberShow(true, false); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getLeftAreaWidget()->m_pLineNumberArea->isVisible()); + + pWindow->deleteLater(); +} + +//void setLineNumberShow(bool bIsShow,bool bIsFirstShow = false); +TEST(UT_Editwrapper_setLineNumberShow, UT_Editwrapper_setLineNumberShow_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->setLineNumberShow(false); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getLeftAreaWidget()->m_pLineNumberArea->isHidden()); + + pWindow->deleteLater(); +} + +//void setShowBlankCharacter(bool ok); +TEST(UT_Editwrapper_setShowBlankCharacter, UT_Editwrapper_setShowBlankCharacter_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->setShowBlankCharacter(true); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->document()->defaultTextOption().flags() == QTextOption::ShowTabsAndSpaces); + + pWindow->deleteLater(); +} + +//void setShowBlankCharacter(bool ok); +TEST(UT_Editwrapper_setShowBlankCharacter, UT_Editwrapper_setShowBlankCharacter_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->setShowBlankCharacter(false); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->document()->defaultTextOption().flags() != QTextOption::ShowTabsAndSpaces); + + pWindow->deleteLater(); +} + +//BottomBar *bottomBar(); +TEST(UT_Editwrapper_bottomBar, UT_Editwrapper_bottomBar) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + ASSERT_TRUE(pWindow->currentWrapper()->bottomBar()); + + pWindow->deleteLater(); +} + +//QString filePath(); +TEST(UT_Editwrapper_filePath, UT_Editwrapper_filePath) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + ASSERT_TRUE(!pWindow->currentWrapper()->filePath().isEmpty()); + + pWindow->deleteLater(); +} + +//TextEdit *textEditor() { return m_textEdit; } +TEST(UT_Editwrapper_textEditor, UT_Editwrapper_textEditor) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()); + + pWindow->deleteLater(); +} + +//int GetCorrectUnicode1(const QByteArray &ba) 未实现; + +int saveDraftFile001_exec_stub() +{ + return 1; +} + +//bool saveDraftFile(); Subsequent processing +TEST(UT_Editwrapper_saveDraftFile, UT_Editwrapper_saveDraftFile_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + typedef int (*fptr)(QDialog *); + fptr fileDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(fileDialogExec, saveDraftFile001_exec_stub); + QString newFilePath; + pWindow->currentWrapper()->saveDraftFile(newFilePath); + EXPECT_EQ(pWindow->m_tabbar->currentPath(), newFilePath); + + pWindow->deleteLater(); +} + +int saveDraftFile002_exec_stub() +{ + return 0; +} + +//bool saveDraftFile(); Subsequent processing +TEST(UT_Editwrapper_saveDraftFile, UT_Editwrapper_saveDraftFile_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + typedef int (*fptr)(QDialog *); + fptr fileDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(fileDialogExec, saveDraftFile002_exec_stub); + QString newFilePath; + pWindow->currentWrapper()->saveDraftFile(newFilePath); + EXPECT_TRUE((newFilePath.isEmpty())); + + pWindow->deleteLater(); +} + +// QString getComboBoxValue(const QString &text) const; +QString stubGetComboBoxValue(const QString &text) { + Q_UNUSED(text) + return QString("GB18030"); +} + +TEST(UT_Editwrapper_saveDraftFile, saveDraftFile_ChangeSaveEncode_EncodeChange) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->m_pTextEdit->setPlainText(QString::fromUtf8("123abc中文测试一二三四")); + + QString convertEncode("GB18030"); + pWindow->currentWrapper()->m_sCurEncode = convertEncode; + + typedef int (*fptr)(QDialog *); + fptr fileDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(fileDialogExec, saveDraftFile001_exec_stub); + + typedef QString (DFileDialog::*DialogFunc)(const QString &); + stub.set((DialogFunc)ADDR(DFileDialog, getComboBoxValue), stubGetComboBoxValue); + + QString newFilePath; + pWindow->currentWrapper()->saveDraftFile(newFilePath); + EXPECT_EQ(pWindow->m_tabbar->currentPath(), newFilePath); + + pWindow->currentWrapper()->readFile(); + EXPECT_EQ(pWindow->currentWrapper()->m_sCurEncode, convertEncode); + + pWindow->deleteLater(); +} + +void readFile_stub_001() +{ + return; +} + +//void readFile(const QString &filePath); +TEST(UT_Editwrapper_readFile, UT_Editwrapper_readFile_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + pWindow->currentWrapper()->textEditor()->setTruePath(filePath); + pWindow->currentWrapper()->textEditor()->m_sFilePath = filePath; + Stub stub; + stub.set(ADDR(EditWrapper, loadContent), readFile_stub_001); + bool bRet = pWindow->currentWrapper()->readFile(QByteArray()); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +//void readFile(const QString &filePath); +TEST(UT_Editwrapper_readFile, UT_Editwrapper_readFile_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile001"); + pWindow->currentWrapper()->textEditor()->setTruePath(filePath); + pWindow->currentWrapper()->textEditor()->m_sFilePath = filePath; + Stub stub; + stub.set(ADDR(EditWrapper, loadContent), readFile_stub_001); + bool bRet = pWindow->currentWrapper()->readFile(QByteArray("UTF-8")); + EXPECT_EQ(QString("UTF-8"), pWindow->currentWrapper()->m_sCurEncode); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + +QByteArray FileLoadThreadRun(const QString &strFilePath, QByteArray *encode) +{ + QFile file(strFilePath); + + if (file.open(QIODevice::ReadOnly)) { + // reads all remaining data from the file. + QByteArray indata = file.readAll(); + file.close(); + QByteArray outData; + // read the encode. + *encode = DetectCode::GetFileEncodingFormat(strFilePath); + QString textEncode = QString::fromLocal8Bit(*encode); + + if (textEncode.contains("ASCII", Qt::CaseInsensitive) || textEncode.contains("UTF-8", Qt::CaseInsensitive)) { + return indata; + } else { + DetectCode::ChangeFileEncodingFormat(indata, outData, textEncode, QString("UTF-8")); + return outData; + } + } + + return QByteArray(); +} + +void handleFileLoadFinished_001_setPrintEnabled_stub() +{ + return; +} + +void handleFileLoadFinished_001_setTextFinished_stub() +{ + return; +} + +TEST(UT_Editwrapper_handleFilePreProcess, handleFilePreProcess_normalData_pass) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + QByteArray encode = QByteArray(); + const QByteArray retFileContent = FileLoadThreadRun(filePath, &encode); + // 预读取数据 + pWindow->currentWrapper()->handleFilePreProcess(encode, retFileContent); + + EXPECT_EQ(pWindow->currentWrapper()->m_bHasPreProcess, true); + // 均为UTF-8格式 + EXPECT_EQ(pWindow->currentWrapper()->m_pTextEdit->toPlainText().toUtf8(), retFileContent); + + pWindow->deleteLater(); +} + +QString disableToUnicode(const char *in, int length, QTextCodec::ConverterState *state = nullptr) +{ + Q_UNUSED(in) + Q_UNUSED(length) + Q_UNUSED(state) + return nullptr; +} + +TEST(UT_Editwrapper_handleFilePreProcess, handleFilePreProcess_errorData_failed) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + QByteArray encode = QByteArray(); + const QByteArray retFileContent = FileLoadThreadRun(filePath, &encode); + + // 定义重载函数类型 + typedef QString (QTextCodec::*toUnicodeType)(const char *, int, QTextCodec::ConverterState *) const; + Stub setToUnicodeDisabled_stub; + setToUnicodeDisabled_stub.set((toUnicodeType)ADDR(QTextCodec, toUnicode), disableToUnicode); + // 预读取数据 + pWindow->currentWrapper()->handleFilePreProcess(encode, retFileContent); + + EXPECT_EQ(pWindow->currentWrapper()->m_bHasPreProcess, true); + EXPECT_TRUE(pWindow->currentWrapper()->m_pTextEdit->toPlainText().isEmpty()); + + pWindow->deleteLater(); +} + +//void handleFileLoadFinished(const QByteArray &encode,const QString &content); +TEST(UT_Editwrapper_handleFileLoadFinished, UT_Editwrapper_handleFileLoadFinished_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + QByteArray encode = QByteArray(); + const QByteArray retFileContent = FileLoadThreadRun(filePath, &encode); + Stub setPrintEnabled_stub; + setPrintEnabled_stub.set(ADDR(Window, setPrintEnabled), handleFileLoadFinished_001_setPrintEnabled_stub); + Stub setTextFinished_stub; + setTextFinished_stub.set(ADDR(TextEdit, setTextFinished), handleFileLoadFinished_001_setTextFinished_stub); + pWindow->currentWrapper()->handleFileLoadFinished(encode, retFileContent, false); + ASSERT_TRUE(pWindow->currentWrapper()->m_pBottomBar->m_pEncodeMenu != nullptr); + + pWindow->deleteLater(); +} + +TEST(UT_Editwrapper_handleFileLoadFinished, UT_Editwrapper_handleFileLoadFinished_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + QByteArray encode = QByteArray(); + const QByteArray retFileContent = FileLoadThreadRun(filePath, &encode); + Stub setPrintEnabled_stub; + setPrintEnabled_stub.set(ADDR(Window, setPrintEnabled), handleFileLoadFinished_001_setPrintEnabled_stub); + Stub setTextFinished_stub; + setTextFinished_stub.set(ADDR(TextEdit, setTextFinished), handleFileLoadFinished_001_setTextFinished_stub); + + Stub s1; + s1.set(ADDR(KSyntaxHighlighting::Definition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QString,isEmpty),retfalsestub); + Stub s3; + s3.set(ADDR(Utils,isDraftFile),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit,getReadOnlyPermission),rettruestub); + Stub s5; + s5.set(ADDR(EditWrapper,loadContent),rettruestub); + Stub s6; + s6.set(ADDR(EditWrapper,OnUpdateHighlighter),rettruestub);//DSettings + Stub s7; + s7.set(ADDR(DSettings,option),retsettingoption); + Stub s8;//QString toString() const; + s8.set((QString (QJsonValue::*)() const)ADDR(QJsonValue,toString),retstring); + Stub s9; + s9.set(ADDR(TextEdit,getFilePath),retstring); + Stub s10; + s10.set(ADDR(QJsonValue,isString),rettruestub); + + QString c1 = "{\"bookMark\":\"7,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\",\"cursorPosition\":\"7\",\"focus\":true,\"localPath\":\"/home/uos/.local/share/deepin/deepin-editor/blank-files/blank_file_2021-09-22_09-43-10-824\",\"modify\":true}"; + QString c2 = "{\"bookMark\":\"1,0,1,0,0\",\"cursorPosition\":\"23\",\"localPath\":\"/home/uos/Desktop/563/526.txt\",\"modify\":false}"; + stringList.clear(); + stringList.push_back(c1); + stringList.push_back(c2); + + + pWindow->currentWrapper()->handleFileLoadFinished(encode, retFileContent, false); + ASSERT_TRUE(pWindow->currentWrapper()->m_pBottomBar->m_pEncodeMenu != nullptr); + + pWindow->deleteLater(); +} + + +TEST(UT_Editwrapper_handleFileLoadFinished, UT_Editwrapper_handleFileLoadFinished_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + QByteArray encode = QByteArray(); + const QByteArray retFileContent = FileLoadThreadRun(filePath, &encode); + Stub setPrintEnabled_stub; + setPrintEnabled_stub.set(ADDR(Window, setPrintEnabled), handleFileLoadFinished_001_setPrintEnabled_stub); + Stub setTextFinished_stub; + setTextFinished_stub.set(ADDR(TextEdit, setTextFinished), handleFileLoadFinished_001_setTextFinished_stub); + + Stub s1; + s1.set(ADDR(KSyntaxHighlighting::Definition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QString,isEmpty),retfalsestub); + Stub s3; + s3.set(ADDR(Utils,isDraftFile),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit,getReadOnlyPermission),rettruestub); + Stub s5; + s5.set(ADDR(EditWrapper,loadContent),rettruestub); + Stub s6; + s6.set(ADDR(EditWrapper,OnUpdateHighlighter),rettruestub);//DSettings + Stub s7; + s7.set(ADDR(DSettings,option),retsettingoption); + Stub s8;//QString toString() const; + s8.set((QString (QJsonValue::*)() const)ADDR(QJsonValue,toString),retstring); + Stub s9; + s9.set(ADDR(TextEdit,getFilePath),retstring); + Stub s10; + s10.set(ADDR(QJsonValue,isString),retfalsestub); + + QString c1 = "{\"bookMark\":\"7,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\",\"cursorPosition\":\"7\",\"focus\":true,\"localPath\":\"/home/uos/.local/share/deepin/deepin-editor/blank-files/blank_file_2021-09-22_09-43-10-824\",\"modify\":true}"; + QString c2 = "{\"bookMark\":\"1,0,1,0,0\",\"cursorPosition\":\"23\",\"localPath\":\"/home/uos/Desktop/563/526.txt\",\"modify\":false}"; + stringList.clear(); + stringList.push_back(c1); + stringList.push_back(c2); + + + pWindow->currentWrapper()->handleFileLoadFinished(encode, retFileContent, false); + ASSERT_TRUE(pWindow->currentWrapper()->m_pBottomBar->m_pEncodeMenu != nullptr); + + pWindow->deleteLater(); + delete d; + d = nullptr; +} + +TEST(UT_Editwrapper_handleFileLoadFinished, UT_Editwrapper_handleFileLoadFinished_004_error) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + QByteArray encode = QByteArray(); + const QByteArray retFileContent = FileLoadThreadRun(filePath, &encode); + Stub setPrintEnabled_stub; + setPrintEnabled_stub.set(ADDR(Window, setPrintEnabled), handleFileLoadFinished_001_setPrintEnabled_stub); + Stub setTextFinished_stub; + setTextFinished_stub.set(ADDR(TextEdit, setTextFinished), handleFileLoadFinished_001_setTextFinished_stub); + pWindow->currentWrapper()->handleFileLoadFinished(encode, retFileContent, true); + EXPECT_FALSE(pWindow->currentWrapper()->textEditor()->getReadOnlyPermission()); + EXPECT_TRUE(pWindow->currentWrapper()->textEditor()->getReadOnlyMode()); + + pWindow->deleteLater(); +} + +////重新加载文件编码 1.文件修改 2.文件未修改处理逻辑一样 切换编码重新加载和另存为 梁卫东 +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray("UTF-8")); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + + +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray("UTF-8")); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray()); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +int reloadFileEncode_003_exec_stub() +{ + return 0; +} + + +int reloadFileEncode_004_exec_stub() +{ + return 1; +} + +bool reloadFileEncode_004_readFile_stub() +{ + return true; +} + +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_004_exec_stub); + Stub readFile_stub; + readFile_stub.set(ADDR(EditWrapper, readFile), reloadFileEncode_004_readFile_stub); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray()); + /* gerrit编译运行结果和本地编译运行不一样,打桩后无果,先用如下方法断言 */ + if (bRet) { + ASSERT_TRUE(bRet); + } else { + ASSERT_FALSE(bRet); + } + + pWindow->deleteLater(); +} + +bool reloadFileEncode_005_saveDraftFile_stub() +{ + return false; +} + +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_005) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_004_exec_stub); + Stub saveDraftFile_stub; + saveDraftFile_stub.set(ADDR(EditWrapper, saveDraftFile), reloadFileEncode_005_saveDraftFile_stub); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray()); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + +bool reloadFileEncode_006_isDraftFile_stub() +{ + return false; +} + +bool reloadFileEncode_006_saveFile_stub() +{ + return true; +} + +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_006) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_004_exec_stub); + Stub isDraftFile_stub; + isDraftFile_stub.set(ADDR(Utils, isDraftFile), reloadFileEncode_006_isDraftFile_stub); + Stub readFile_stub; + readFile_stub.set(ADDR(EditWrapper, readFile), reloadFileEncode_004_readFile_stub); + Stub saveFile_stub; + saveFile_stub.set(ADDR(EditWrapper, saveFile), reloadFileEncode_006_saveFile_stub); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray()); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +int reloadFileEncode_007_exec_stub() +{ + return 2; +} + +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_007) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_007_exec_stub); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray()); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + +bool reloadFileEncode_008_getModified_stub() +{ + return false; +} + +bool reloadFileEncode_008_readFile_stub() +{ + return false; +} + +int reloadFileEncode_008_exec_stub() +{ + return 2; +} + +//bool reloadFileEncode(QByteArray encode); +TEST(UT_Editwrapper_reloadFileEncode, UT_Editwrapper_reloadFileEncode_008) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + Stub getModified_stub; + getModified_stub.set(ADDR(TextEdit, getModified), reloadFileEncode_008_getModified_stub); + Stub readFile_stub; + readFile_stub.set(ADDR(EditWrapper, readFile), reloadFileEncode_008_readFile_stub); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_008_exec_stub); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(QByteArray()); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + +bool reloadFileEncode_BeforeDeraftEdit_getModified_stub() +{ + return true; +} + +int reloadFileEncode_BeforeDeraftEdit_exec_save_stub() +{ + return 1; +} + +TEST(UT_Editwrapper_reloadFileEncode, reloadFileEncode_BeforeDeraftEdit_ChangeEncode) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->setPlainText(QString::fromUtf8("123abc中文测试")); + + Stub getModified_stub; + getModified_stub.set(ADDR(TextEdit, getModified), reloadFileEncode_BeforeDeraftEdit_getModified_stub); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_BeforeDeraftEdit_exec_save_stub); + + QByteArray convertEncode("GB18030"); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(convertEncode); + EXPECT_TRUE(bRet); + EXPECT_EQ(convertEncode, pWindow->currentWrapper()->m_sCurEncode.toUtf8()); + + pWindow->deleteLater(); +} + +TEST(UT_Editwrapper_reloadFileEncode, reloadFileEncode_SaveFileChangeCode_ChangeEncode) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->setPlainText(QString::fromUtf8("123abc中文测试")); + + Stub getModified_stub; + getModified_stub.set(ADDR(TextEdit, getModified), reloadFileEncode_BeforeDeraftEdit_getModified_stub); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadFileEncode_BeforeDeraftEdit_exec_save_stub); + + QString newFilePath; + pWindow->currentWrapper()->saveDraftFile(newFilePath); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString::fromUtf8("中文测试2")); + + QByteArray convertEncode("GB18030"); + bool bRet = pWindow->currentWrapper()->reloadFileEncode(convertEncode); + EXPECT_TRUE(bRet); + EXPECT_EQ(convertEncode, pWindow->currentWrapper()->m_sCurEncode.toUtf8()); + + pWindow->deleteLater(); +} + +int reloadModifyFile_001_exec_stub() +{ + return 0; +} + +////重写加载修改文件 +//void reloadModifyFile(); +TEST(UT_Editwrapper_reloadModifyFile, UT_Editwrapper_reloadModifyFile_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadModifyFile_001_exec_stub); + pWindow->currentWrapper()->reloadModifyFile(); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getModified()); + + pWindow->deleteLater(); +} + +int reloadModifyFile_002_exec_stub() +{ + return 1; +} + +QByteArray reloadModifyFile_selectCoding() +{ + return QByteArray(); +} + +//void reloadModifyFile(); +TEST(UT_Editwrapper_reloadModifyFile, UT_Editwrapper_reloadModifyFile_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadModifyFile_002_exec_stub); + Stub stubSelectCoding; + stubSelectCoding.set(ADDR(DetectCode, selectCoding),reloadModifyFile_selectCoding); + pWindow->currentWrapper()->reloadModifyFile(); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->getModified()); + + pWindow->deleteLater(); +} + +int reloadModifyFile_003_exec_stub() +{ + return 2; +} + +//void reloadModifyFile(); +TEST(UT_Editwrapper_reloadModifyFile, UT_Editwrapper_reloadModifyFile_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadModifyFile_003_exec_stub); + pWindow->currentWrapper()->reloadModifyFile(); + QString newFilePath; + ASSERT_FALSE(pWindow->currentWrapper()->saveDraftFile(newFilePath)); + + pWindow->deleteLater(); +} + +bool reloadModifyFile_004_isDraftFile_stub() +{ + return false; +} + +//void reloadModifyFile(); +TEST(UT_Editwrapper_reloadModifyFile, UT_Editwrapper_reloadModifyFile_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, reloadModifyFile_003_exec_stub); + Stub isDraftFile_stub; + isDraftFile_stub.set(ADDR(Utils, isDraftFile), reloadModifyFile_004_isDraftFile_stub); + pWindow->currentWrapper()->reloadModifyFile(); + ASSERT_FALSE(pWindow->currentWrapper()->saveAsFile()); + + pWindow->deleteLater(); +} + +//void reloadModifyFile(); +TEST(UT_Editwrapper_reloadModifyFile, UT_Editwrapper_reloadModifyFile_005) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + Stub stubSelectCoding; + stubSelectCoding.set(ADDR(DetectCode, selectCoding), reloadModifyFile_selectCoding); + pWindow->currentWrapper()->reloadModifyFile(); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->horizontalScrollBar()->value() == 0); + + pWindow->deleteLater(); +} + +////获取文件编码 +//QString getTextEncode(); +TEST(UT_Editwrapper_getTextEncode, UT_Editwrapper_getTextEncode) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + QString strRet = pWindow->currentWrapper()->getTextEncode(); + ASSERT_TRUE(!strRet.compare(QString("UTF-8"))); + + pWindow->deleteLater(); +} + +//bool saveTemFile(QString qstrDir); +TEST(UT_Editwrapper_saveTemFile, UT_Editwrapper_saveTemFile_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + const QString filePath = QCoreApplication::applicationDirPath() + QString("/Makefile"); + bool bRet = pWindow->currentWrapper()->saveTemFile(filePath); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +//bool saveTemFile(QString qstrDir); +TEST(UT_Editwrapper_saveTemFile, UT_Editwrapper_saveTemFile_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + bool bRet = pWindow->currentWrapper()->saveTemFile(QString()); + ASSERT_FALSE(bRet); + + pWindow->deleteLater(); +} + +////判断是否修改 +//bool isModified(); +TEST(UT_Editwrapper_isModified, UT_Editwrapper_isModified) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("12345")); + bool bRet = pWindow->currentWrapper()->isModified(); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +////判断是否草稿文件 +//bool isDraftFile(); +TEST(UT_Editwrapper_isDraftFile, UT_Editwrapper_isDraftFile) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + bool bRet = pWindow->currentWrapper()->isDraftFile(); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +////判断内容是否为空 +//bool isPlainTextEmpty(); +TEST(UT_Editwrapper_isPlainTextEmpty, UT_Editwrapper_isPlainTextEmpty) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + bool bRet = pWindow->currentWrapper()->isPlainTextEmpty(); + ASSERT_TRUE(bRet); + + pWindow->deleteLater(); +} + +TEST(UT_Editwrapper_OnThemeChangeSlot, UT_Editwrapper_OnThemeChangeSlot) +{ + EditWrapper* wra = new EditWrapper; + QTextDocument*doc = new QTextDocument; + wra->m_pSyntaxHighlighter = new CSyntaxHighlighter(doc); + wra->OnThemeChangeSlot("ddd"); + + + EXPECT_NE(wra,nullptr); + + wra->deleteLater(); + doc->deleteLater(); +} + +TEST(UT_Editwrapper_clearDoubleCharaterEncode, UT_Editwrapper_clearDoubleCharaterEncode_001) +{ + EditWrapper* wra = new EditWrapper; + + Stub s1; + //bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + s1.set((bool (QString::*)(const QString &, Qt::CaseSensitivity) const)ADDR(QString,contains),rettruestub); + Stub s2; + s2.set(ADDR(QFileInfo,size),retintstub); + + intvalue = 1024*1024; + wra->clearDoubleCharaterEncode(); + + + EXPECT_NE(wra,nullptr); + wra->deleteLater(); +} +TEST(UT_Editwrapper_clearDoubleCharaterEncode, UT_Editwrapper_clearDoubleCharaterEncode_002) +{ + EditWrapper* wra = new EditWrapper; + + Stub s1; + //bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + s1.set((bool (QString::*)(const QString &, Qt::CaseSensitivity) const)ADDR(QString,contains),rettruestub); + Stub s2; + s2.set(ADDR(QFileInfo,size),retintstub); + + intvalue = 1*1024; + wra->clearDoubleCharaterEncode(); + + + EXPECT_NE(wra,nullptr); + wra->deleteLater(); +} + +TEST(UT_Editwrapper_loadContent, UT_Editwrapper_loadContent_001) +{ + Window* window = new Window(); + EditWrapper* wra = new EditWrapper(window); + + Stub s1; + s1.set(ADDR(QString,length),retintstub); + + intvalue = 41*1024*1024; + wra->loadContent("ddd"); + + + EXPECT_NE(wra,nullptr); + wra->deleteLater(); + window->deleteLater(); +} + +TEST(UT_Editwrapper_loadContent, UT_Editwrapper_loadContent_002) +{ + Window* window = new Window(); + EditWrapper* wra = new EditWrapper(window); + + Stub s1; + s1.set(ADDR(QString,length),retintstub); + + intvalue = 10*1024; + wra->loadContent("ddd"); + + + EXPECT_NE(wra,nullptr); + wra->deleteLater(); + window->deleteLater(); +} + +TEST(UT_Editwrapper_reloadFileHighlight, reloadFileHighlight_ChangeDefinition_Success) +{ + Window* window = new Window(); + EditWrapper* wra = new EditWrapper(window); + wra->m_pTextEdit->setPlainText("#include ;\n" + "int main(int argc, char *argv[]) { }"); + const QString definitionName("C++"); + wra->reloadFileHighlight(definitionName); + EXPECT_FALSE(wra->m_bHighlighterAll); + EXPECT_TRUE(wra->m_Definition.isValid()); + EXPECT_EQ(wra->m_Definition.name(), definitionName); + EXPECT_NE(wra->m_pSyntaxHighlighter, nullptr); + + wra->reloadFileHighlight(QString("None")); + EXPECT_FALSE(wra->m_bHighlighterAll); + EXPECT_FALSE(wra->m_Definition.isValid()); + EXPECT_EQ(wra->m_pSyntaxHighlighter, nullptr); + + wra->deleteLater(); + window->deleteLater(); +} + +TEST(UT_Editwrapper_reloadFileHighlight, reloadFileHighlight_SingleLineText_Success) +{ + Window* window = new Window(); + EditWrapper* wra = new EditWrapper(window); + wra->m_pTextEdit->setPlainText("import time"); + auto firstBlock = wra->m_pTextEdit->document()->firstBlock(); + auto formats = firstBlock.layout()->formats(); + EXPECT_TRUE(formats.isEmpty()); + + const QString definitionName("Python"); + wra->reloadFileHighlight(definitionName); + EXPECT_TRUE(wra->m_Definition.isValid()); + EXPECT_EQ(wra->m_Definition.name(), definitionName); + EXPECT_NE(wra->m_pSyntaxHighlighter, nullptr); + + firstBlock = wra->m_pTextEdit->document()->firstBlock(); + formats = firstBlock.layout()->formats(); + EXPECT_FALSE(formats.isEmpty()); + + wra->deleteLater(); + window->deleteLater(); +} diff --git a/tests/src/editor/ut_editwrapper.h b/tests/src/editor/ut_editwrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..147cf422b996d82b715e5211bd6d7a121c9a8398 --- /dev/null +++ b/tests/src/editor/ut_editwrapper.h @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_Editwrapper_H +#define UT_Editwrapper_H + +#include "../../src/startmanager.h" +#include "../../src/editor/dtextedit.h" +#include "../../src/common/settings.h" +#include "../../src/widgets/window.h" +#include "../../src/editor/editwrapper.h" +#include "../../src/controls/tabbar.h" +#include "../../src/common/utils.h" +#include "../../src/encodes/detectcode.h" +#include "../stub.h" +#include "gtest/gtest.h" +#include +#include +#include +#include + +DWIDGET_USE_NAMESPACE + +class UT_Editwrapper: public QObject, public::testing::Test +{ +public: + UT_Editwrapper(); + QByteArray FileLoadThreadRun(const QString &strFilePath, QByteArray *encode); +}; + +#endif // UT_Editwrapper_H diff --git a/tests/src/editor/ut_flashtween.cpp b/tests/src/editor/ut_flashtween.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6b91975e06a1f1720358be8fa007c65a33c997e7 --- /dev/null +++ b/tests/src/editor/ut_flashtween.cpp @@ -0,0 +1,104 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_flashtween.h" + +UT_FlashTween::UT_FlashTween() +{ + +} + +//void startX(qreal t,qreal b,qreal c,qreal d, FunSlideInertial fSlideGesture); +TEST(UT_FlashTween_startX, UT_FlashTween_startX) +{ + FlashTween *a = new FlashTween(); + FunSlideInertial b; + a->startX(1.1,1.1,1.1,1.1,b); + int iRet = a->m_timerX->interval(); + ASSERT_TRUE(a->m_timerX->interval() == 15); + + a->deleteLater(); +} + +//void startY(qreal t,qreal b,qreal c,qreal d, FunSlideInertial fSlideGesture); +TEST(UT_FlashTween_startY, UT_FlashTween_startY) +{ + FlashTween *a = new FlashTween(); + FunSlideInertial b; + a->startY(1.1,1.1,1.1,1.1,b); + int iRet = a->m_timerY->interval(); + ASSERT_TRUE(a->m_timerY->interval() == 15); + + a->deleteLater(); +} + +//bool activeX(){return m_timerX->isActive();} +TEST(UT_FlashTween_activeX, UT_FlashTween_activeX) +{ + FlashTween *a = new FlashTween(); + FunSlideInertial b; + a->m_timerX->start(); + bool bRet = a->activeX(); + ASSERT_TRUE(bRet == true); + + a->deleteLater(); +} + +//bool activeY(){return m_timerY->isActive();} +TEST(UT_FlashTween_activeY, UT_FlashTween_activeY) +{ + FlashTween *a = new FlashTween(); + FunSlideInertial b; + a->m_timerY->start(); + bool bRet = a->activeY(); + ASSERT_TRUE(bRet == true); + + a->deleteLater(); +} + +TEST(UT_FlashTween_stopX, UT_FlashTween_stopX) +{ + FlashTween *a = new FlashTween(); + a->stopX(); + bool bRet = a->activeX(); + ASSERT_TRUE(bRet == false); + + a->deleteLater(); +} + +TEST(UT_FlashTween_stopY, UT_FlashTween_stopY) +{ + FlashTween *a = new FlashTween(); + a->stopY(); + bool bRet = a->activeY(); + ASSERT_TRUE(bRet == false); + + a->deleteLater(); +} + +TEST(UT_FlashTween___runY, UT_FlashTween___runY) +{ + FlashTween *a = new FlashTween(); + a->m_timerX = new QTimer; + a->m_timerY = new QTimer; + //a->__runY(); + + EXPECT_NE(a->m_lastValueX,2.2); + a->deleteLater(); + a->m_timerX->deleteLater(); + a->m_timerY->deleteLater(); +} + +TEST(UT_FlashTween___runX, UT_FlashTween___runX) +{ + FlashTween *a = new FlashTween(); + a->m_timerX = new QTimer; + a->m_timerY = new QTimer; + //a->__runX(); + + EXPECT_NE(a->m_lastValueX,2.2); + a->deleteLater(); + a->m_timerX->deleteLater(); + a->m_timerY->deleteLater(); +} diff --git a/tests/src/editor/ut_flashtween.h b/tests/src/editor/ut_flashtween.h new file mode 100644 index 0000000000000000000000000000000000000000..950225dfd5eec8d2865fc485b010c7121b5c4a9d --- /dev/null +++ b/tests/src/editor/ut_flashtween.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_FlashTween_H +#define UT_FlashTween_H +#include "gtest/gtest.h" +#include"../../src/editor/editwrapper.h" +#include"../../src/widgets/window.h" +#include"../../src/startmanager.h" +#include"../../src/editor/dtextedit.h" +#include"../../src/editor/FlashTween.h" +#include"../stub.h" +#include +#include +#include +#include + +class UT_FlashTween : public QObject, public::testing::Test +{ +public: + UT_FlashTween(); +}; + +#endif // UT_FlashTween_H diff --git a/tests/src/editor/ut_insertblockbytextcommond.cpp b/tests/src/editor/ut_insertblockbytextcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6175243c3d9b5aeab0712ef886e6c8508705b0c8 --- /dev/null +++ b/tests/src/editor/ut_insertblockbytextcommond.cpp @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_insertblockbytextcommond.h" +#include "../src/editor/insertblockbytextcommond.h" +#include "../src/editor/dtextedit.h" +#include "../src/editor/editwrapper.h" +#include "../src/widgets/window.h" +#include "qtextcursor.h" +#include "src/stub.h" + + +namespace insertblockstub { +int intvalue = 1; +int retintstub() +{ + return intvalue; +} +} + +using namespace insertblockstub; + +test_insertblockbytextcommond::test_insertblockbytextcommond() +{ + +} + +TEST_F(test_insertblockbytextcommond, InsertBlockByTextCommand) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + InsertBlockByTextCommand *pInsertBlockByTextCommand = new InsertBlockByTextCommand(QString("Hei man"), + pWindow->currentWrapper()->textEditor(), + pWindow->currentWrapper()); + QString strRet(pInsertBlockByTextCommand->m_selected); + ASSERT_TRUE(!strRet.compare(QString("Holle world."))); + + pWindow->deleteLater(); +} + +TEST_F(test_insertblockbytextcommond, redo) +{ + QString text = "tt"; + for(int i=0;i<1024*1024;i++) + text += "tt"; + + QTextCursor cursor; + cursor.insertText(text); + cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor); + TextEdit* edit = new TextEdit; + edit->setTextCursor(cursor); + InsertBlockByTextCommand* com = new InsertBlockByTextCommand(text,edit,nullptr); + com->redo(); + + ASSERT_TRUE(!edit->textCursor().hasSelection()); + + delete com; + com=nullptr; + edit->deleteLater(); +} + + +TEST_F(test_insertblockbytextcommond, undo) +{ + QString text = "tt"; + for(int i=0;i<1024*1024;i++) + text += "tt"; + + QTextCursor cursor; + cursor.insertText(text); + cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor); + TextEdit* edit = new TextEdit; + edit->setTextCursor(cursor); + InsertBlockByTextCommand* com = new InsertBlockByTextCommand(text,edit,nullptr); + com->undo(); + + ASSERT_TRUE(!edit->textCursor().hasSelection()); + + delete com; + com=nullptr; + edit->deleteLater(); +} + + +TEST_F(test_insertblockbytextcommond, treat) +{ +// Window* window = new Window; +// EditWrapper* wrapper = new EditWrapper(window); +// QString text = "tt"; +// for(int i=0;i<1024*1024;i++) +// text += "tt"; + +// QTextCursor cursor; +// cursor.insertText(text); +// cursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); +// TextEdit* edit = new TextEdit(window); +// edit->m_wrapper = wrapper; +// edit->setTextCursor(cursor); +// InsertBlockByTextCommand* com = new InsertBlockByTextCommand(text,edit,wrapper); + +// Stub s1; +// s1.set(ADDR(Window,setPrintEnabled),retintstub); + +// com->treat(); + +// EXPECT_NE(edit,nullptr); +// delete com; +// com=nullptr; +// edit->deleteLater(); +// wrapper->deleteLater(); +// window->deleteLater(); +} + + +TEST_F(test_insertblockbytextcommond, insertByBlock) +{ + QString text = "tt"; + for(int i=0;i<1024*1024;i++) + text += "tt"; + + QTextCursor cursor; + cursor.insertText(text); + cursor.movePosition(QTextCursor::Start,QTextCursor::KeepAnchor); + TextEdit* edit = new TextEdit; + edit->setTextCursor(cursor); + InsertBlockByTextCommand* com = new InsertBlockByTextCommand(text,edit,nullptr); + com->insertByBlock(); + + ASSERT_TRUE(!edit->textCursor().hasSelection()); + + delete com; + com=nullptr; + edit->deleteLater(); +} diff --git a/tests/src/editor/ut_insertblockbytextcommond.h b/tests/src/editor/ut_insertblockbytextcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..6fa623b186ca198a6c3529cab3c1794939d2ed80 --- /dev/null +++ b/tests/src/editor/ut_insertblockbytextcommond.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_INSERTBLOCKBYTEXTCOMMOND_H +#define TEST_INSERTBLOCKBYTEXTCOMMOND_H + + +#include "gtest/gtest.h" +#include +#include + +class test_insertblockbytextcommond: public QObject, public::testing::Test +{ + Q_OBJECT +public: + test_insertblockbytextcommond(); +}; + + +#endif // TEST_INSERTBLOCKBYTEXTCOMMOND_H diff --git a/tests/src/editor/ut_inserttextundocommand.cpp b/tests/src/editor/ut_inserttextundocommand.cpp new file mode 100644 index 0000000000000000000000000000000000000000..04ddc944abe16f733b137e0478f44a4377908612 --- /dev/null +++ b/tests/src/editor/ut_inserttextundocommand.cpp @@ -0,0 +1,191 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_inserttextundocommand.h" +#include "../../src/editor/inserttextundocommand.h" + +test_InsertTextUndoCommand::test_InsertTextUndoCommand() +{ +} + +void test_InsertTextUndoCommand::SetUp() +{ + QTextCursor textcursor; + QString test; + ituc = new InsertTextUndoCommand(textcursor, test, nullptr); +} + +void test_InsertTextUndoCommand::TearDown() +{ + delete ituc; +} + +TEST_F(test_InsertTextUndoCommand, undo) +{ + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor.clearSelection(); + extraSelections.append(selection); + + QString text = "aaa"; + InsertTextUndoCommand *command = new InsertTextUndoCommand(extraSelections, text, nullptr); + command->undo(); + + int iRet = command->m_textCursor.position(); + ASSERT_TRUE(iRet != 0); + +} + +TEST_F(test_InsertTextUndoCommand, undo2) +{ + QList extraSelections; + QString text = "aaa"; + InsertTextUndoCommand *command = new InsertTextUndoCommand(extraSelections, text, nullptr); + command->undo(); + + int iRet = command->m_textCursor.position(); + ASSERT_TRUE(iRet != 0); +} + +TEST_F(test_InsertTextUndoCommand, redo) +{ + QList extraSelections; + QString text = "aaa"; + InsertTextUndoCommand *command = new InsertTextUndoCommand(extraSelections, text, nullptr); + ituc->redo(); + + int iRet = command->m_textCursor.position(); + ASSERT_TRUE(iRet != 0); +} + +TEST_F(test_InsertTextUndoCommand, redo2) +{ + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor.clearSelection(); + extraSelections.append(selection); + QString text = "aaa"; + InsertTextUndoCommand *command = new InsertTextUndoCommand(extraSelections, text, nullptr); + command->redo(); + + int iRet = command->m_textCursor.position(); + ASSERT_TRUE(iRet != 0); +} + +TEST_F(test_InsertTextUndoCommand, redo_withTextCursor_restoreCursor) +{ + // 重做恢复光标位置 + QPlainTextEdit *edit = new QPlainTextEdit; + edit->setPlainText("123789"); + + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(3); + InsertTextUndoCommand *command = new InsertTextUndoCommand(cursor, QString("456"), edit); + command->redo(); + + EXPECT_EQ(QString("123456789"), edit->toPlainText()); + EXPECT_EQ(6, edit->textCursor().position()); + + edit->setPlainText("123789"); + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = edit->textCursor(); + selection.cursor.setPosition(3); + extraSelections.append(selection); + InsertTextUndoCommand *command2 = new InsertTextUndoCommand(extraSelections, QString("456"), edit); + command2->redo(); + + EXPECT_EQ(QString("123456789"), edit->toPlainText()); + EXPECT_EQ(6, edit->textCursor().position()); + + delete command; + delete command2; + delete edit; +} + +TEST_F(test_InsertTextUndoCommand, undo_withTextCursor_restoreCursor) +{ + // 撤销后恢复光标位置 + QPlainTextEdit *edit = new QPlainTextEdit; + edit->setPlainText("123456789"); + + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(6); + InsertTextUndoCommand *command = new InsertTextUndoCommand(cursor, QString("456"), edit); + command->m_endPostion = 6; + command->m_beginPostion = 3; + command->undo(); + + EXPECT_EQ(QString("123789"), edit->toPlainText()); + EXPECT_EQ(3, edit->textCursor().position()); + + edit->setPlainText("123456789"); + QList extraSelections; + QTextEdit::ExtraSelection selection; + QColor lineColor = QColor(Qt::yellow).lighter(160); + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = edit->textCursor(); + selection.cursor.setPosition(3); + selection.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3); + extraSelections.append(selection); + InsertTextUndoCommand *command2 = new InsertTextUndoCommand(extraSelections, QString("456"), edit); + command2->undo(); + + EXPECT_EQ(QString("123789"), edit->toPlainText()); + EXPECT_EQ(3, edit->textCursor().position()); + + delete command; + delete command2; + delete edit; +} + +TEST(test_MidButtonInsertTextUndoCommand, redo_withTextCursor_restoreCursor) +{ + // 重做恢复光标位置 + QPlainTextEdit *edit = new QPlainTextEdit; + edit->setPlainText("123789"); + + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(3); + MidButtonInsertTextUndoCommand *command = new MidButtonInsertTextUndoCommand(cursor, QString("456"), edit); + EXPECT_EQ(command->m_beginPostion, 3); + EXPECT_EQ(command->m_endPostion, 6); + command->redo(); + + EXPECT_EQ(QString("123456789"), edit->toPlainText()); + EXPECT_EQ(6, edit->textCursor().position()); + + delete command; + delete edit; +} + +TEST(test_MidButtonInsertTextUndoCommand, undo_withTextCursor_restoreCursor) +{ + // 撤销后恢复光标位置 + QPlainTextEdit *edit = new QPlainTextEdit; + edit->setPlainText("123456789"); + + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(6); + MidButtonInsertTextUndoCommand *command = new MidButtonInsertTextUndoCommand(cursor, QString("456"), edit); + command->m_endPostion = 6; + command->m_beginPostion = 3; + command->undo(); + + EXPECT_EQ(QString("123789"), edit->toPlainText()); + EXPECT_EQ(3, edit->textCursor().position()); + + delete command; + delete edit; +} diff --git a/tests/src/editor/ut_inserttextundocommand.h b/tests/src/editor/ut_inserttextundocommand.h new file mode 100644 index 0000000000000000000000000000000000000000..39a4c68953e9acedf605af79f32ab15e3b45b7d6 --- /dev/null +++ b/tests/src/editor/ut_inserttextundocommand.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_INSERTTEXTUNDOCOMMAND_H +#define TEST_INSERTTEXTUNDOCOMMAND_H + +#include "gtest/gtest.h" +#include + +class InsertTextUndoCommand; +class test_InsertTextUndoCommand :public testing::Test +{ +public: + test_InsertTextUndoCommand(); + virtual void SetUp() override; + virtual void TearDown() override; + InsertTextUndoCommand *ituc; +}; + +#endif // TEST_INSERTTEXTUNDOCOMMAND_H diff --git a/tests/src/editor/ut_leftareaoftextedit.cpp b/tests/src/editor/ut_leftareaoftextedit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6945785a54250ac0cca473122f950cbe414088da --- /dev/null +++ b/tests/src/editor/ut_leftareaoftextedit.cpp @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_leftareaoftextedit.h" +#include "../../src/editor/leftareaoftextedit.h" +#include "../../src/editor/dtextedit.h" + +test_leftareaoftextedit::test_leftareaoftextedit() +{ + +} + +//LeftAreaTextEdit(TextEdit *textEdit); +TEST_F(test_leftareaoftextedit, LeftAreaTextEdit) +{ + TextEdit *textEdit = new TextEdit; + LeftAreaTextEdit *leftArea = new LeftAreaTextEdit(textEdit); + + ASSERT_TRUE(leftArea->m_pFlodArea != nullptr); + leftArea->deleteLater(); + textEdit->deleteLater(); +} + +//void lineNumberAreaPaintEvent(QPaintEvent *event); +TEST_F(test_leftareaoftextedit, lineNumberAreaPaintEvent) +{ + TextEdit *textEdit = new TextEdit; + LeftAreaTextEdit *leftArea = new LeftAreaTextEdit(textEdit); + QPaintEvent *event = new QPaintEvent(QRegion()); + leftArea->lineNumberAreaPaintEvent(event); + + ASSERT_TRUE(leftArea->m_pFlodArea != nullptr); + delete event; + event = nullptr; + leftArea->deleteLater(); + textEdit->deleteLater(); +} + +//int lineNumberAreaWidth(); +TEST_F(test_leftareaoftextedit, lineNumberAreaWidth) +{ + TextEdit *textEdit = new TextEdit; + LeftAreaTextEdit *leftArea = new LeftAreaTextEdit(textEdit); + leftArea->lineNumberAreaWidth(); + + ASSERT_TRUE(leftArea->m_pFlodArea != nullptr); + leftArea->deleteLater(); + textEdit->deleteLater(); +} + +//void bookMarkAreaPaintEvent(QPaintEvent *event); +TEST_F(test_leftareaoftextedit, bookMarkAreaPaintEvent) +{ + TextEdit *textEdit = new TextEdit; + LeftAreaTextEdit *leftArea = new LeftAreaTextEdit(textEdit); + QPaintEvent *event = new QPaintEvent(QRegion()); + leftArea->bookMarkAreaPaintEvent(event); + + ASSERT_TRUE(leftArea->m_pFlodArea != nullptr); + delete event; + event = nullptr; + leftArea->deleteLater(); + textEdit->deleteLater(); +} + +//void codeFlodAreaPaintEvent(QPaintEvent *event); +TEST_F(test_leftareaoftextedit, codeFlodAreaPaintEvent) +{ + TextEdit *textEdit = new TextEdit; + LeftAreaTextEdit *leftArea = new LeftAreaTextEdit(textEdit); + QPaintEvent *event = new QPaintEvent(QRegion()); + leftArea->codeFlodAreaPaintEvent(event); + + ASSERT_TRUE(leftArea->m_pFlodArea != nullptr); + delete event; + event = nullptr; + leftArea->deleteLater(); + textEdit->deleteLater(); +} diff --git a/tests/src/editor/ut_leftareaoftextedit.h b/tests/src/editor/ut_leftareaoftextedit.h new file mode 100644 index 0000000000000000000000000000000000000000..52c5caf45b7dd5f9bbdc12385754b0d52cc26c8c --- /dev/null +++ b/tests/src/editor/ut_leftareaoftextedit.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_LEFTAREAOFTEXTEDIT_H +#define TEST_LEFTAREAOFTEXTEDIT_H +#include "gtest/gtest.h" +#include + +class test_leftareaoftextedit : public QObject, public::testing::Test +{ +public: + test_leftareaoftextedit(); +}; + +#endif // TEST_LEFTAREAOFTEXTEDIT_H diff --git a/tests/src/editor/ut_replaceallcommond.cpp b/tests/src/editor/ut_replaceallcommond.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e38b533d2d47527ee2584a77a1b1d036a8ade2dc --- /dev/null +++ b/tests/src/editor/ut_replaceallcommond.cpp @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_replaceallcommond.h" +#include "../../src/editor/replaceallcommond.h" +#include "QTextCursor" +test_replaceallcommond::test_replaceallcommond() +{ + +} + +TEST_F(test_replaceallcommond, ReplaceAllCommand) +{ + QString text = "test"; + QTextCursor cursor; + ReplaceAllCommand* com = new ReplaceAllCommand(text,text,cursor); + ASSERT_TRUE(!text.compare(com->m_newText)); + + delete com; + com=nullptr; +} + +TEST_F(test_replaceallcommond, redo) +{ + QString text = "test"; + QTextCursor cursor; + ReplaceAllCommand* com = new ReplaceAllCommand(text,text,cursor); + com->redo(); + ASSERT_TRUE(com->m_cursor.position() != 0); + + delete com; + com=nullptr; +} + +TEST_F(test_replaceallcommond, undo) +{ + QString text = "test"; + QTextCursor cursor; + ReplaceAllCommand* com = new ReplaceAllCommand(text,text,cursor); + com->undo(); + ASSERT_TRUE(com->m_cursor.position() != 0); + + delete com; + com=nullptr; + + +} diff --git a/tests/src/editor/ut_replaceallcommond.h b/tests/src/editor/ut_replaceallcommond.h new file mode 100644 index 0000000000000000000000000000000000000000..f1a6b9a346b77b6e62499263089fe7fd6036241b --- /dev/null +++ b/tests/src/editor/ut_replaceallcommond.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_REPLACEALLCOMMOND_H +#define TEST_REPLACEALLCOMMOND_H + + +#include "gtest/gtest.h" +#include + + +class test_replaceallcommond: public QObject, public::testing::Test +{ + Q_OBJECT +public: + test_replaceallcommond(); +}; + + +#endif // TEST_REPLACEALLCOMMOND_H diff --git a/tests/src/editor/ut_showflodcodewidget.cpp b/tests/src/editor/ut_showflodcodewidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2da9e5230e85d29267335313cc425f175969bf0d --- /dev/null +++ b/tests/src/editor/ut_showflodcodewidget.cpp @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_showflodcodewidget.h" +#include "../../src/editor/showflodcodewidget.h" + +test_showflodcodewidget::test_showflodcodewidget() +{ + +} + +TEST_F(test_showflodcodewidget, ShowFlodCodeWidget) +{ + ShowFlodCodeWidget flodCodeWidget(nullptr); + ASSERT_TRUE(flodCodeWidget.m_pContentEdit != nullptr); +} + +//void appendText(QString strText, int maxWidth); +TEST_F(test_showflodcodewidget, appendText) +{ + ShowFlodCodeWidget *flodCodeWidget = new ShowFlodCodeWidget(); + flodCodeWidget->appendText("aa",1); + ASSERT_TRUE(flodCodeWidget->m_pContentEdit->textCursor().position() == 0); + + flodCodeWidget->deleteLater(); +} + +//void clear(); +TEST_F(test_showflodcodewidget, clear) +{ + ShowFlodCodeWidget *flodCodeWidget = new ShowFlodCodeWidget(); + flodCodeWidget->clear(); + + ASSERT_TRUE(flodCodeWidget->m_nTextWidth == 0); + flodCodeWidget->deleteLater(); +} + +//void initHighLight(QString filepath, bool bIsLight); +TEST_F(test_showflodcodewidget, initHighLight) +{ + ShowFlodCodeWidget *flodCodeWidget = new ShowFlodCodeWidget(); + flodCodeWidget->initHighLight("aa",true); + + ASSERT_TRUE(flodCodeWidget->m_pContentEdit != nullptr); + flodCodeWidget->deleteLater(); +} + +//void setStyle(bool bIsLineWrap); +TEST_F(test_showflodcodewidget, setStyle) +{ + ShowFlodCodeWidget *flodCodeWidget = new ShowFlodCodeWidget(); + flodCodeWidget->setStyle(true); + + ASSERT_TRUE(flodCodeWidget->m_pContentEdit->lineWrapMode() == QPlainTextEdit::WidgetWidth); + flodCodeWidget->deleteLater(); +} + +//void hideFirstBlock(); +TEST_F(test_showflodcodewidget, hideFirstBlock) +{ + ShowFlodCodeWidget *flodCodeWidget = new ShowFlodCodeWidget(); + flodCodeWidget->hideFirstBlock(); + + ASSERT_TRUE(flodCodeWidget->m_pContentEdit->height() >= 10); + flodCodeWidget->deleteLater(); +} diff --git a/tests/src/editor/ut_showflodcodewidget.h b/tests/src/editor/ut_showflodcodewidget.h new file mode 100644 index 0000000000000000000000000000000000000000..24a5bbaccc6eed7147debdb96fa64a33fc19da6e --- /dev/null +++ b/tests/src/editor/ut_showflodcodewidget.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_SHOWFLODCODEWIDGET_H +#define TEST_SHOWFLODCODEWIDGET_H +#include "gtest/gtest.h" +#include + +class test_showflodcodewidget : public QObject, public::testing::Test +{ +public: + test_showflodcodewidget(); +}; + +#endif // TEST_SHOWFLODCODEWIDGET_H diff --git a/tests/src/editor/ut_textedit.cpp b/tests/src/editor/ut_textedit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3c3da337ebb4ddf00871155f2e88ac5e08595ff --- /dev/null +++ b/tests/src/editor/ut_textedit.cpp @@ -0,0 +1,9650 @@ +// SPDX-FileCopyrightText: 2022 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_textedit.h" +#include "stub.h" +#include "../../src/widgets/window.h" +#include +#include "QDBusReply" +#include "QDBusConnection" + + +namespace texteditstub { + +bool rettruestub() +{ + return true; +} + +bool retfalsestub() +{ + return false; +} + +int intvalue = 1; +int retintstub() +{ + return intvalue; +} + +int intvalue2=1; +int retintstub2() +{ + return intvalue2; +} + +QString string1="1"; +QString retstring1() +{ + return string1; +} + +QString string2="2"; +QString retstring2() +{ + return string2; +} + +QDBusConnection sessionBusstub() +{ + return QDBusConnection("123"); +} +} + +using namespace texteditstub; + +test_textedit::test_textedit() +{ + QString text = QString("#include \"window.h\"\n" + "#include \"urlinfo.h\"\n" + "int main(int argc, char *argv[])\n" + "{\n" + "using namespace Dtk::Core;\n" + "PerformanceMonitor::initializeAppStart();\n" + "return 0;\n" + "}"); + QFile f("1.cpp"); + if (f.open(QFile::WriteOnly)) { + f.write(text.toUtf8()); + f.close(); + } +} + +void test_textedit::forstub(QPoint q) +{ +} + +TEST_F(test_textedit, setWrapper) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_wrapper != nullptr); + + pWindow->deleteLater(); +} + +//getWrapper +TEST_F(test_textedit, getWrapper) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + EditWrapper *pEditWrapper = pWindow->currentWrapper()->textEditor()->getWrapper(); + ASSERT_TRUE(pEditWrapper != nullptr); + + pWindow->deleteLater(); +} + +void showCenterWindow_stub() +{ + return; +} + +//inline QString getFilePath() { return m_sFilePath;}; +TEST_F(test_textedit, getFilePath) +{ + Stub stub_showCenterWindow; + stub_showCenterWindow.set(ADDR(Window, showCenterWindow), showCenterWindow_stub); + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QString strRet(pWindow->currentWrapper()->textEditor()->getFilePath()); + ASSERT_TRUE(strRet != nullptr); + pWindow->deleteLater(); +} + +//inline void setFilePath(QString file) { m_sFilePath = file;} +TEST_F(test_textedit, setFilePath) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + startManager->setFilePath("a"); + + ASSERT_TRUE(startManager->m_pLeftAreaWidget != nullptr); + startManager->deleteLater(); + p->deleteLater(); +} + +//getLeftAreaWidget +TEST_F(test_textedit, getLeftAreaWidget) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + LeftAreaTextEdit *pLeftAreaTextEdit = pWindow->currentWrapper()->textEditor()->getLeftAreaWidget(); + ASSERT_TRUE(pLeftAreaTextEdit != nullptr); + pWindow->deleteLater(); +} + +//isUndoRedoOpt +TEST_F(test_textedit, isUndoRedoOpt) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + bool bRet = pWindow->currentWrapper()->textEditor()->isUndoRedoOpt(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//getModified +TEST_F(test_textedit, getModified) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + bool bRet = pWindow->currentWrapper()->textEditor()->getModified(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//TextEdit(QWidget *parent = nullptr); +TEST_F(test_textedit, TextEdit) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded); + + pWindow->deleteLater(); +} + +//insertTextEx +TEST_F(test_textedit, insertTextEx) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(!strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//deleteTextEx +TEST_F(test_textedit, deleteTextEx) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->deleteTextEx(pWindow->currentWrapper()->textEditor()->textCursor()); + bool bRet = pWindow->currentWrapper()->textEditor()->m_pUndoStack->canUndo(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//insertSelectTextEx +TEST_F(test_textedit, insertSelectTextEx) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->insertSelectTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), QString("Holle world.")); + bool bRet = pWindow->currentWrapper()->textEditor()->m_pUndoStack->canUndo(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//insertColumnEditTextEx +TEST_F(test_textedit, insertColumnEditTextEx) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->insertColumnEditTextEx(QString("Holle world.")); + bool bRet = pWindow->currentWrapper()->textEditor()->m_pUndoStack->canUndo(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//deleteSelectTextEx +TEST_F(test_textedit, deleteSelectTextEx) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->deleteSelectTextEx(textCursor); + QString strAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(strBefore.compare(strAfter)); + + pWindow->deleteLater(); +} + +//deleteSelectTextEx(QTextCursor,QString text,bool currLine) +TEST_F(test_textedit, deleteSelectTextEx_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->deleteSelectTextEx(textCursor, QString("Holle world."), true); + QString strAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(strBefore.compare(strAfter)); + + pWindow->deleteLater(); +} + +//slotSelectionChanged 001 +TEST_F(test_textedit, slotSelectionChanged_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotSelectionChanged(); + int iRet = QApplication::cursorFlashTime(); + ASSERT_TRUE(iRet == 0); + + pWindow->deleteLater(); +} + +//slotSelectionChanged 002 +TEST_F(test_textedit, slotSelectionChanged_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->slotSelectionChanged(); + int iRet = QApplication::cursorFlashTime(); + ASSERT_TRUE(iRet != 0); + + pWindow->deleteLater(); +} + +//slotCanRedoChanged +TEST_F(test_textedit, slotCanRedoChanged) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->slotCanRedoChanged(true); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pUndoStack != nullptr); + + pWindow->deleteLater(); +} + +//slotCanUndoChanged +TEST_F(test_textedit, slotCanUndoChanged) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->slotCanUndoChanged(true); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pUndoStack != nullptr); + + pWindow->deleteLater(); +} + +//slotValueChanged +TEST_F(test_textedit, slotValueChanged) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMassege("Holle world.Holle world.Holle world.Holle world.Holle world.Holle world.Holle world.Holle world.Holle world."); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), strMassege); + pWindow->currentWrapper()->textEditor()->setLineWrapMode(QPlainTextEdit::NoWrap); + int iRetBefore = pWindow->currentWrapper()->textEditor()->horizontalScrollBar()->value(); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->slotValueChanged(true); + int iRetAfter = pWindow->currentWrapper()->textEditor()->horizontalScrollBar()->value(); + ASSERT_TRUE(iRetBefore != iRetAfter); + + pWindow->deleteLater(); +} + +//getCurrentLine +TEST_F(test_textedit, getCurrentLine) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\n Create operating system innovation ecosystem!")); + int iRet = pWindow->currentWrapper()->textEditor()->getCurrentLine(); + ASSERT_TRUE(iRet == 2); + + pWindow->deleteLater(); +} + +//getCurrentColumn +TEST_F(test_textedit, getCurrentColumn) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + int iRet = pWindow->currentWrapper()->textEditor()->getCurrentColumn(); + ASSERT_TRUE(iRet == QString("Holle world.").length()); + + pWindow->deleteLater(); +} + +//getPosition +TEST_F(test_textedit, getPosition) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + int iRet = pWindow->currentWrapper()->textEditor()->getPosition(); + ASSERT_TRUE(iRet == QString("Holle world.").length()); + + pWindow->deleteLater(); +} + +//getScrollOffset +TEST_F(test_textedit, getScrollOffset) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw" + "\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H" + "\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no" + "\nr\nl\nd\n.")); + int iRet = pWindow->currentWrapper()->textEditor()->getScrollOffset(); + ASSERT_TRUE(iRet > 0); + + pWindow->deleteLater(); +} + +//DMenu *getHighlightMenu(); +TEST_F(test_textedit, getHighlightMenu) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + + DMenu *pDMenu = pWindow->currentWrapper()->textEditor()->getHighlightMenu(); + ASSERT_TRUE(pDMenu == nullptr); + pWindow->deleteLater(); +} + +//forwardChar 001 +TEST_F(test_textedit, forwardChar_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->forwardChar(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 1) && (!strRet.compare(QString("H")))); + + pWindow->deleteLater(); +} + +//forwardChar 002 +TEST_F(test_textedit, forwardChar_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->forwardChar(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 1) && strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//backwardChar 001 +TEST_F(test_textedit, backwardChar_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->backwardChar(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 10) && (!strRet.compare(QString("d")))); + + pWindow->deleteLater(); +} + +//backwardChar 002 +TEST_F(test_textedit, backwardChar_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->backwardChar(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 10) && strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//forwardWord 001 +TEST_F(test_textedit, forwardWord_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->forwardWord(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 6) && (!strRet.compare(QString("Holle ")))); + + pWindow->deleteLater(); +} + +//forwardWord 002 +TEST_F(test_textedit, forwardWord_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->forwardWord(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 6) && strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//backwardWord 001 +TEST_F(test_textedit, backwardWord_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->backwardWord(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 6) && (!strRet.compare(QString("world")))); + + pWindow->deleteLater(); +} + +//backwardWord 002 +TEST_F(test_textedit, backwardWord_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->backwardWord(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE((iRet == 6) && strRet.isEmpty()); + + pWindow->deleteLater(); +} + +bool forwardPair_001_find_stub() +{ + return true; +} + +//forwardPair 001 +TEST_F(test_textedit, forwardPair_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + #if 0 //保留打桩方法,后续完善覆盖率 + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, forwardPair_001_find_stub); + + Stub find_stub; + find_stub.set((bool(QPlainTextEdit::*)(const QRegExp &))ADDR(QPlainTextEdit, QPlainTextEdit::find), forwardPair_001_find_stub); + #endif + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->forwardPair(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//backwardPair 001 +TEST_F(test_textedit, backwardPair_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + #if 0 //保留打桩方法,后续完善覆盖率 + typedef int (*fptr)(QDialog *); + fptr qDialogExec = (fptr)(&QDialog::exec); + Stub stub; + stub.set(qDialogExec, forwardPair_001_find_stub); + + Stub find_stub; + find_stub.set((bool(QPlainTextEdit::*)(const QRegExp &))ADDR(QPlainTextEdit, QPlainTextEdit::find), forwardPair_001_find_stub); + #endif + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->backwardPair(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//blockCount +TEST_F(test_textedit, blockCount) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + int iRet = pWindow->currentWrapper()->textEditor()->blockCount(); + ASSERT_TRUE(iRet == 1); + + pWindow->deleteLater(); +} + +//int characterCount() const; +TEST_F(test_textedit, characterCount) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + int iRet = pWindow->currentWrapper()->textEditor()->characterCount(); + ASSERT_TRUE(iRet == 12); + pWindow->deleteLater(); +} + +//firstVisibleBlock() +TEST_F(test_textedit, firstVisibleBlock) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + QTextBlock textBlock = pWindow->currentWrapper()->textEditor()->firstVisibleBlock(); + QString strRet(textBlock.text()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + pWindow->deleteLater(); +} + +//moveToStart 001 +TEST_F(test_textedit, moveToStart_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->moveToStart(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + pWindow->deleteLater(); +} + +//moveToStart 002 +TEST_F(test_textedit, moveToStart_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->moveToStart(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//moveToEnd 001 +TEST_F(test_textedit, moveToEnd_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->moveToEnd(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + pWindow->deleteLater(); +} + +//moveToEnd 002 +TEST_F(test_textedit, moveToEnd_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->moveToEnd(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//moveToStartOfLine 001 +TEST_F(test_textedit, moveToStartOfLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->moveToStartOfLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(!strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//moveToStartOfLine 002 +TEST_F(test_textedit, moveToStartOfLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->moveToStartOfLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//moveToEndOfLine 001 +TEST_F(test_textedit, moveToEndOfLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->moveToEndOfLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + pWindow->deleteLater(); +} + +//moveToEndOfLine 002 +TEST_F(test_textedit, moveToEndOfLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->moveToEndOfLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//moveToLineIndentation 001 +TEST_F(test_textedit, moveToLineIndentation_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world")); + pWindow->currentWrapper()->textEditor()->moveToLineIndentation(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + ASSERT_TRUE(strRet.isEmpty() && iRet == 0); + + pWindow->deleteLater(); +} + +//moveToLineIndentation 002 +TEST_F(test_textedit, moveToLineIndentation_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->moveToLineIndentation(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().position(); + ASSERT_TRUE(strRet.isEmpty() && iRet == 12); + + pWindow->deleteLater(); +} + +//nextLine 001 +TEST_F(test_textedit, nextLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Up, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->nextLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(!strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//nextLine 002 +TEST_F(test_textedit, nextLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Up, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->nextLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//prevLine 001 +TEST_F(test_textedit, prevLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->prevLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(!strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//prevLine 002 +TEST_F(test_textedit, prevLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->prevLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + ASSERT_TRUE(strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//jumpToLine +TEST_F(test_textedit, jumpToLine) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->jumpToLine(1, true); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().blockNumber() + 1; + ASSERT_TRUE(iRet == 1); + + pWindow->deleteLater(); +} + +//void moveCursorNoBlink(QTextCursor::MoveOperation operation, +// QTextCursor::MoveMode mode = QTextCursor::MoveAnchor); +TEST_F(test_textedit, moveCursorNoBlink) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->moveCursorNoBlink(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//newline +TEST_F(test_textedit, newline) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->newline(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().blockNumber() + 1; + ASSERT_TRUE(iRet == 3); + + pWindow->deleteLater(); +} + +//openNewlineAbove +TEST_F(test_textedit, openNewlineAbove) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->openNewlineAbove(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().blockNumber() + 1; + ASSERT_TRUE(iRet == 2); + + pWindow->deleteLater(); +} + +//openNewlineBelow +TEST_F(test_textedit, openNewlineBelow) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + pWindow->currentWrapper()->textEditor()->openNewlineBelow(); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().blockNumber() + 1; + ASSERT_TRUE(iRet == 3); + + pWindow->deleteLater(); +} + +//moveLineDownUp 001 +TEST_F(test_textedit, moveLineDownUp_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->moveLineDownUp(true); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().blockNumber() + 1; + ASSERT_TRUE(iRet == 1); + + pWindow->deleteLater(); +} + +//moveLineDownUp 002 +TEST_F(test_textedit, moveLineDownUp_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Up, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->moveLineDownUp(false); + int iRet = pWindow->currentWrapper()->textEditor()->textCursor().blockNumber() + 1; + ASSERT_TRUE(iRet == 3); + + pWindow->deleteLater(); +} + +//scrollLineUp +TEST_F(test_textedit, scrollLineUp) +{ +// Window *pWindow = new Window(); +// pWindow->addBlankTab(QString()); +// pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), +// QString("H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw" +// "\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H" +// "\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no" +// "\nr\nl\nd\n.")); +// pWindow->currentWrapper()->textEditor()->scrollLineUp(); +// int iRet = pWindow->currentWrapper()->textEditor()->verticalScrollBar()->value(); +// ASSERT_TRUE(iRet == 26); + +// pWindow->deleteLater(); +} + +TEST_F(test_textedit, scrollLineDown) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw" + "\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H" + "\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no" + "\nr\nl\nd\n.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->scrollLineDown(); + int iRet = pWindow->currentWrapper()->textEditor()->verticalScrollBar()->value(); + ASSERT_TRUE(iRet == 1); + + pWindow->deleteLater(); +} + +TEST_F(test_textedit, scrollUp) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw" + "\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H" + "\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no" + "\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\n")); + int iScrollBarMaxmun = pWindow->currentWrapper()->textEditor()->verticalScrollBar()->maximum(); + pWindow->currentWrapper()->textEditor()->verticalScrollBar()->setValue(iScrollBarMaxmun); + pWindow->currentWrapper()->textEditor()->scrollUp(); + int iRet = pWindow->currentWrapper()->textEditor()->verticalScrollBar()->value(); + ASSERT_TRUE(iScrollBarMaxmun != iRet); + + pWindow->deleteLater(); +} + +TEST_F(test_textedit, scrollDown) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw" + "\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H" + "\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\nl\nl\ne\n\nw\no" + "\nr\nl\nd\n.H\nl\nl\ne\n\nw\no\nr\nl\nd\n.H\n")); + pWindow->currentWrapper()->textEditor()->verticalScrollBar()->setValue(0); + pWindow->currentWrapper()->textEditor()->scrollDown(); + int iRet = pWindow->currentWrapper()->textEditor()->verticalScrollBar()->value(); + ASSERT_TRUE(iRet != 0); + + pWindow->deleteLater(); +} + +//duplicateLine 001 +TEST_F(test_textedit, duplicateLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iDuplicateLineBeFor = pWindow->currentWrapper()->textEditor()->blockCount(); + pWindow->currentWrapper()->textEditor()->duplicateLine(); + int iDuplicateLineAfter = pWindow->currentWrapper()->textEditor()->blockCount(); + + ASSERT_TRUE(iDuplicateLineAfter == iDuplicateLineBeFor + 1); + + pWindow->deleteLater(); +} + +//duplicateLine 002 +TEST_F(test_textedit, duplicateLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + textCursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iDuplicateLineBeFor = pWindow->currentWrapper()->textEditor()->blockCount(); + pWindow->currentWrapper()->textEditor()->duplicateLine(); + int iDuplicateLineAfter = pWindow->currentWrapper()->textEditor()->blockCount(); + + ASSERT_TRUE(iDuplicateLineAfter == iDuplicateLineBeFor + 1); + + pWindow->deleteLater(); +} + +//duplicateLine 003 +TEST_F(test_textedit, duplicateLine_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iDuplicateLineBeFor = pWindow->currentWrapper()->textEditor()->blockCount(); + pWindow->currentWrapper()->textEditor()->duplicateLine(); + int iDuplicateLineAfter = pWindow->currentWrapper()->textEditor()->blockCount(); + + ASSERT_TRUE(iDuplicateLineAfter == iDuplicateLineBeFor + 1); + + pWindow->deleteLater(); +} + +//void copyLines 001 +TEST_F(test_textedit, copyLines_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->copyLines(); + QString strRet(pClipboard->text()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + pWindow->deleteLater(); +} + +//void copyLines 002 +TEST_F(test_textedit, copyLines_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world\nHolle world\nHolle world")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->copyLines(); + QString strRet(pClipboard->text()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + pWindow->deleteLater(); +} + +void stub_push(QUndoCommand *cmd) +{ + Q_UNUSED(cmd); +} + +void stub_updateModifyStatus(const QString &path, bool isModified) +{ + Q_UNUSED(path); + Q_UNUSED(isModified); +} + +bool popRightMenu_001_canRedo_stub() +{ + return true; +} + +void popRightMenu_001_UpdateBottomBarWordCnt_stub() +{ + return; +} + +void popRightMenu_001_writeHistoryRecord_stub() +{ + return; +} + +bool popRightMenu_001_isRegisteredFflytekAiassistant_stub() +{ + return false; +} + +//popRightMenu 001 +TEST_F(test_textedit, popRightMenu_001) +{ +#if 0 + EditWrapper *pEditWrapper = new EditWrapper(); + //TextEdit *pTextEdit = new TextEdit(); + Stub isRegisteredFflytekAiassistant_stub; + isRegisteredFflytekAiassistant_stub.set(ADDR(Window, isRegisteredFflytekAiassistant), popRightMenu_001_isRegisteredFflytekAiassistant_stub); + Stub UpdateBottomBarWordCnt_stub; + UpdateBottomBarWordCnt_stub.set(ADDR(EditWrapper, UpdateBottomBarWordCnt), popRightMenu_001_UpdateBottomBarWordCnt_stub); + Stub writeHistoryRecord_stub; + writeHistoryRecord_stub.set(ADDR(TextEdit, writeHistoryRecord), popRightMenu_001_writeHistoryRecord_stub); + //typedef int (*fptr)(QMenu *); + //fptr fileDialogExec = (fptr)(&QMenu::exec); + //Stub stub; + //stub.set((QAction *)(QPoint, QAction *)ADDR(QMenu, exec), popRightMenu_001_writeHistoryRecord_stub); + + pEditWrapper->textEditor()->popRightMenu(); + //pTextEdit->popRightMenu(); + + +// Window *pWindow = new Window(); +// pWindow->addBlankTab(QString()); +// //pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), +// // QString("Holle world\nHolle world\nHolle world")); +// Stub canRedo_stub; +// canRedo_stub.set(ADDR(QUndoStack, canRedo), popRightMenu_001_canRedo_stub); +// QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// Stub UpdateBottomBarWordCnt_stub; +// UpdateBottomBarWordCnt_stub.set(ADDR(EditWrapper, UpdateBottomBarWordCnt), popRightMenu_001_UpdateBottomBarWordCnt_stub); +// Stub writeHistoryRecord_stub; +// writeHistoryRecord_stub.set(ADDR(TextEdit, writeHistoryRecord), popRightMenu_001_writeHistoryRecord_stub); +// Stub isRegisteredFflytekAiassistant_stub; +// isRegisteredFflytekAiassistant_stub.set(ADDR(Window, isRegisteredFflytekAiassistant), popRightMenu_001_isRegisteredFflytekAiassistant_stub); +// Stub handleTabCloseRequested_stub; +// handleTabCloseRequested_stub.set(ADDR(Window, handleTabCloseRequested), popRightMenu_001_writeHistoryRecord_stub); +// Stub indexOf_stub; +// indexOf_stub.set(ADDR(Tabbar, indexOf), popRightMenu_001_writeHistoryRecord_stub); +// Stub itextAt_stub; +// itextAt_stub.set(ADDR(Tabbar, textAt), popRightMenu_001_writeHistoryRecord_stub); +// Stub slotCanRedoChanged_stub; +// slotCanRedoChanged_stub.set(ADDR(TextEdit, slotCanRedoChanged), popRightMenu_001_writeHistoryRecord_stub); +// Stub slotCanUndoChanged_stub; +// slotCanUndoChanged_stub.set(ADDR(TextEdit, slotCanUndoChanged), popRightMenu_001_writeHistoryRecord_stub); + +// pWindow->currentWrapper()->textEditor()->popRightMenu(QPoint(10, 10)); + //ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + //pEditWrapper->deleteLater(); +#endif +} + +//void cutlines 001 +TEST_F(test_textedit, cutlines_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), strMsg); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->cutlines(); + QString strRet(pClipboard->text()); + ASSERT_TRUE(strRet.length() == strMsg.length()); + + pWindow->deleteLater(); +} + +//void cutlines 002 +TEST_F(test_textedit, cutlines_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), strMsg); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->cutlines(); + QString strRet(pClipboard->text()); + ASSERT_TRUE(!strRet.compare(QString("Holle world"))); + + pWindow->deleteLater(); +} + +//joinLines 001 +TEST_F(test_textedit, joinLines_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRetBefor = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + pWindow->currentWrapper()->textEditor()->joinLines(); + int iRetAfter = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + ASSERT_TRUE(iRetAfter == iRetBefor); + + pWindow->deleteLater(); +} + +//joinLines 002 +TEST_F(test_textedit, joinLines_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRetBefor = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + pWindow->currentWrapper()->textEditor()->joinLines(); + int iRetAfter = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + ASSERT_TRUE(iRetAfter == iRetBefor - 1); + + pWindow->deleteLater(); +} + +//joinLines 003 +TEST_F(test_textedit, joinLines_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Up, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRetBefor = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + pWindow->currentWrapper()->textEditor()->joinLines(); + int iRetAfter = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + ASSERT_TRUE(iRetAfter == iRetBefor - 1); + + pWindow->deleteLater(); +} + +//killLine 001 +TEST_F(test_textedit, killLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->killLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRet.compare(strMsg)); + pWindow->deleteLater(); +} + +//killLine 002 +TEST_F(test_textedit, killLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->killLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(strRet.isEmpty()); + pWindow->deleteLater(); +} + +//killLine 003 +TEST_F(test_textedit, killLine_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Up, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->killLine(); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(strRetAfter.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//killCurrentLine 001 +TEST_F(test_textedit, killCurrentLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->killCurrentLine(); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRet.compare(strMsg)); + pWindow->deleteLater(); +} + +//killCurrentLine 002 +TEST_F(test_textedit, killCurrentLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + int iRetBefore = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + pWindow->currentWrapper()->textEditor()->killCurrentLine(); + int iRetAfter = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + + ASSERT_TRUE(iRetAfter == iRetBefore); + pWindow->deleteLater(); +} + +//killBackwardWord 001 +TEST_F(test_textedit, killBackwardWord_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->killBackwardWord(); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRet.compare(strMsg)); + pWindow->deleteLater(); +} + +//killBackwardWord 002 +TEST_F(test_textedit, killBackwardWord_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->killBackwardWord(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRet.compare(QString("Holle "))); + pWindow->deleteLater(); +} + +//killForwardWord 001 +TEST_F(test_textedit, killForwardWord_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->killForwardWord(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRet.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//killForwardWord 002 +TEST_F(test_textedit, killForwardWord_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->killForwardWord(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRet.compare(QString("world"))); + pWindow->deleteLater(); +} + +//indentText 001 +TEST_F(test_textedit, indentText_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRetBefore = pWindow->currentWrapper()->textEditor()->textCursor().position(); + pWindow->currentWrapper()->textEditor()->indentText(); + int iRetAfter = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(iRetAfter != iRetBefore); + pWindow->deleteLater(); +} + +//indentText 002 +TEST_F(test_textedit, indentText_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRetBefore = pWindow->currentWrapper()->textEditor()->textCursor().position(); + pWindow->currentWrapper()->textEditor()->indentText(); + int iRetAfter = pWindow->currentWrapper()->textEditor()->textCursor().position(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + EXPECT_EQ(iRetAfter , iRetBefore); + pWindow->deleteLater(); +} + + +//setTabSpaceNumber +TEST_F(test_textedit, setTabSpaceNumber) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + pWindow->currentWrapper()->textEditor()->setTabSpaceNumber(5); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_tabSpaceNumber == 5); + pWindow->deleteLater(); +} + +//convertWordCase 001 +TEST(UT_test_textedit_convertWordCase, UT_test_textedit_convertWordCase_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->convertWordCase(UPPER); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRet.compare(strMsg.toUpper())); + pWindow->deleteLater(); +} + +//convertWordCase 002 +TEST(UT_test_textedit_convertWordCase, UT_test_textedit_convertWordCase_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->convertWordCase(LOWER); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRet.compare(strMsg.toLower())); + pWindow->deleteLater(); +} + +//convertWordCase 003 +TEST(UT_test_textedit_convertWordCase, UT_test_textedit_convertWordCase_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + pWindow->currentWrapper()->textEditor()->convertWordCase(CAPITALIZE); + QString strRet(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(strRet.compare(strMsg)); + pWindow->deleteLater(); +} + +//convertWordCase 004 +TEST(UT_test_textedit_convertWordCase, UT_test_textedit_convertWordCase_004) +{ +// Window *pWindow = new Window(); +// pWindow->addBlankTab(QString()); +// QString strMsg("Holle world\nHolle world\nHolle world"); +// QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + +// textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// pWindow->currentWrapper()->textEditor()->convertWordCase(UPPER); +// textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + +// ASSERT_TRUE(!strRet.compare(QString("WORLD"))); +// pWindow->deleteLater(); +} + +//convertWordCase 005 +TEST(UT_test_textedit_convertWordCase, UT_test_textedit_convertWordCase_005) +{ +// Window *pWindow = new Window(); +// pWindow->addBlankTab(QString()); +// QString strMsg("Holle world\nHolle world\nHolle WORLD"); +// QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + +// textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// pWindow->currentWrapper()->textEditor()->convertWordCase(LOWER); +// textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + +// ASSERT_TRUE(!strRet.compare(QString("world"))); +// pWindow->deleteLater(); +} + +//convertWordCase 006 +TEST(UT_test_textedit_convertWordCase, UT_test_textedit_convertWordCase_006) +{ +// Window *pWindow = new Window(); +// pWindow->addBlankTab(QString()); +// QString strMsg("Holle world\nHolle world\nHolle world"); +// QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + +// textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// pWindow->currentWrapper()->textEditor()->convertWordCase(CAPITALIZE); +// textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); +// textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); +// pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); +// QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().selectedText()); + +// ASSERT_TRUE(!strRet.compare(QString("World"))); +// pWindow->deleteLater(); +} + +//QString capitalizeText(QString text); +TEST_F(test_textedit, capitalizeText) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strRet(pWindow->currentWrapper()->textEditor()->capitalizeText(QString("world"))); + + ASSERT_TRUE(!strRet.compare(QString("World"))); + pWindow->deleteLater(); +} + +//void keepCurrentLineAtCenter(); +TEST_F(test_textedit, keepCurrentLineAtCenter) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("H\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\n" + "H\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\n" + "H\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->keepCurrentLineAtCenter(); + QScrollBar *pScrollBar = pWindow->currentWrapper()->textEditor()->verticalScrollBar(); + int iRet = pScrollBar->value(); + + ASSERT_TRUE(iRet != 0); + pWindow->deleteLater(); +} + +//scrollToLine +TEST_F(test_textedit, scrollToLine) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("H\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\n" + "H\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\n" + "H\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\nH\no\nl\nl\ne\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + pWindow->currentWrapper()->textEditor()->scrollToLine(10, 5, 5); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_restoreRow == 5); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_restoreColumn == 5); + pWindow->deleteLater(); +} + +//void setLineWrapMode(bool enable); +TEST(UT_test_textedit_setLineWrapMode, UT_test_textedit_setLineWrapMode_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setLineWrapMode(QPlainTextEdit::NoWrap); + pWindow->currentWrapper()->textEditor()->setLineWrapMode(true); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->lineWrapMode() == QPlainTextEdit::WidgetWidth); + pWindow->deleteLater(); +} + +//void setFontFamily(QString fontName); +TEST(UT_test_textedit_setFontFamily, UT_test_textedit_setFontFamily_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setFontFamily(QString("MT Extra")); + QFont font(pWindow->currentWrapper()->textEditor()->font()); + QString strRet(font.family()); + ASSERT_TRUE(!strRet.compare(QString("MT Extra"))); + pWindow->deleteLater(); +} + +//void setFontSize(int fontSize); +TEST(UT_test_textedit_setFontSize, UT_test_textedit_setFontSize_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setFontSize(15); + QFont font(pWindow->currentWrapper()->textEditor()->font()); + int iRet = font.pointSize(); + ASSERT_TRUE(iRet == 15); + pWindow->deleteLater(); +} + +//void updateFont(); +TEST(UT_test_textedit_updateFont, UT_test_textedit_updateFont_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->updateFont(); + QFont font(pWindow->currentWrapper()->textEditor()->document()->defaultFont()); + bool bRet = font.fixedPitch(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//replaceAll 001 +TEST(UT_test_textedit_replaceAll, UT_test_textedit_replaceAll_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Helle"); + QString strRetBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + pWindow->currentWrapper()->textEditor()->replaceAll(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRetAfter.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//replaceAll 002 +TEST(UT_test_textedit_replaceAll, UT_test_textedit_replaceAll_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Helle"); + QString strRetBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->replaceAll(QString(), strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRetAfter.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//replaceAll 003 +TEST(UT_test_textedit_replaceAll, UT_test_textedit_replaceAll_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Holle"); + pWindow->currentWrapper()->textEditor()->replaceAll(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRetAfter.compare(QString("Holle Holle\nHolle Holle"))); + pWindow->deleteLater(); +} + +//replaceNext 001 +TEST(UT_test_textedit_replaceNext, UT_test_textedit_replaceNext_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Holle"); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + QString strRetBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->replaceNext(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRetAfter.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//replaceNext 002 +TEST(UT_test_textedit_replaceNext, UT_test_textedit_replaceNext_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Holle"); + pWindow->currentWrapper()->textEditor()->m_isSelectAll = true; + QString strRetBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->replaceNext(QString(), strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + + ASSERT_TRUE(!strRetAfter.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//replaceNext 003 +TEST(UT_test_textedit_replaceNext, UT_test_textedit_replaceNext_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strReplaceText("world"); + QString strWithText("Holle"); + pWindow->currentWrapper()->textEditor()->m_findHighlightSelection.cursor = textCursor; + pWindow->currentWrapper()->textEditor()->m_cursorStart = 1; + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->replaceNext(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRetAfter.compare(QString("Holle world"))); + pWindow->deleteLater(); +} + +//replaceNext 004 +TEST(UT_test_textedit_replaceNext, UT_test_textedit_replaceNext_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strReplaceText("world"); + QString strWithText("Holle"); + pWindow->currentWrapper()->textEditor()->m_findHighlightSelection.cursor = textCursor; + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->replaceNext(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRetAfter.compare(QString("Holle world"))); + pWindow->deleteLater(); +} + +//replaceRest 001 +TEST(UT_test_textedit_replaceRest, UT_test_textedit_replaceRest_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world Holle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Holle"); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->replaceRest(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRetAfter.compare(QString("Holle world Holle world"))); + pWindow->deleteLater(); +} + +//replaceRest 002 +TEST(UT_test_textedit_replaceRest, UT_test_textedit_replaceRest_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Holle world\nHolle world Holle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strReplaceText("world"); + QString strWithText("Holle"); + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->replaceRest(QString(), strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRetAfter.compare(QString("Holle world Holle world"))); + pWindow->deleteLater(); +} + +//replaceRest 003 +TEST(UT_test_textedit_replaceRest, UT_test_textedit_replaceRest_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world Helle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strReplaceText("world"); + QString strWithText("Helle"); + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->replaceRest(strReplaceText, strWithText); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRetAfter.compare(QString("Helle Helle Helle Helle"))); + pWindow->deleteLater(); +} + +//beforeReplace +TEST(UT_test_textedit_beforeReplace, UT_test_textedit_beforeReplace_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strRetBefore(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + pWindow->currentWrapper()->textEditor()->beforeReplace(QString()); + QString strRetAfter(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRetAfter.compare(strRetBefore)); + pWindow->deleteLater(); +} + +//findKeywordForward 001 +TEST(UT_test_textedit_findKeywordForward, UT_test_textedit_findKeywordForward_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + bool bRet = pWindow->currentWrapper()->textEditor()->findKeywordForward(QString("Helle")); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//findKeywordForward 002 +TEST(UT_test_textedit_findKeywordForward, UT_test_textedit_findKeywordForward_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->findKeywordForward(QString("Helle")); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//removeKeywords +TEST(UT_test_textedit_removeKeywords, UT_test_textedit_removeKeywords_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->removeKeywords(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_findMatchSelections.isEmpty()); + pWindow->deleteLater(); +} + +//highlightKeyword +TEST(UT_test_textedit_highlightKeyword, UT_test_textedit_highlightKeyword_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->highlightKeyword(QString("world"), 0); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//highlightKeywordInView +TEST(UT_test_textedit_highlightKeywordInView, UT_test_textedit_highlightKeywordInView_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->highlightKeywordInView(QString("world")); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//clearFindMatchSelections +TEST(UT_test_textedit_clearFindMatchSelections, UT_test_textedit_clearFindMatchSelections_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->clearFindMatchSelections(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_findMatchSelections.isEmpty()); + pWindow->deleteLater(); +} + +//updateCursorKeywordSelection +TEST(UT_test_textedit_updateCursorKeywordSelection, UT_test_textedit_updateCursorKeywordSelection_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->updateCursorKeywordSelection(QString(), true); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_findMatchSelections.isEmpty()); + pWindow->deleteLater(); +} + +//updateHighlightLineSelection +TEST(UT_test_textedit_updateHighlightLineSelection, UT_test_textedit_updateHighlightLineSelection_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_gestureAction = TextEdit::GA_slide; + pWindow->currentWrapper()->textEditor()->updateHighlightLineSelection(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_findMatchSelections.isEmpty()); + pWindow->deleteLater(); +} + +//updateKeywordSelections 001 +TEST(UT_test_textedit_updateKeywordSelections, UT_test_textedit_updateKeywordSelections_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelections(QString("smile"), charFormat, listExtraSelection); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//updateKeywordSelections 002 +TEST(UT_test_textedit_updateKeywordSelections, UT_test_textedit_updateKeywordSelections_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelections(QString("world"), charFormat, listExtraSelection); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//updateKeywordSelections 003 +TEST(UT_test_textedit_updateKeywordSelections, UT_test_textedit_updateKeywordSelections_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelections(QString(), charFormat, listExtraSelection); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//updateKeywordSelectionsInView 001 +TEST(UT_test_textedit_updateKeywordSelectionsInView, UT_test_textedit_updateKeywordSelectionsInView_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelectionsInView(QString("smile"), charFormat, &listExtraSelection); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//updateKeywordSelectionsInView 002 +TEST(UT_test_textedit_updateKeywordSelectionsInView, UT_test_textedit_updateKeywordSelectionsInView_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelectionsInView(QString("smile"), charFormat, &listExtraSelection); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//updateKeywordSelectionsInView 003 +TEST(UT_test_textedit_updateKeywordSelectionsInView, UT_test_textedit_updateKeywordSelectionsInView_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelectionsInView(QString("n"), charFormat, &listExtraSelection); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//updateKeywordSelectionsInView 004 +TEST(UT_test_textedit_updateKeywordSelectionsInView, UT_test_textedit_updateKeywordSelectionsInView_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection extraSelection; + extraSelection.format = charFormat; + QList listExtraSelection; + listExtraSelection.append(extraSelection); + bool bRet = pWindow->currentWrapper()->textEditor()->updateKeywordSelectionsInView(QString(), charFormat, &listExtraSelection); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//searchKeywordSeletion 001 +TEST(UT_test_textedit_searchKeywordSeletion, UT_test_textedit_searchKeywordSeletion_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + bool bRet = pWindow->currentWrapper()->textEditor()->searchKeywordSeletion(QString(), textCursor, true); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//searchKeywordSeletion 002 +TEST(UT_test_textedit_searchKeywordSeletion, UT_test_textedit_searchKeywordSeletion_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + bool bRet = pWindow->currentWrapper()->textEditor()->searchKeywordSeletion(QString("world"), textCursor, true); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//searchKeywordSeletion 003 +TEST(UT_test_textedit_searchKeywordSeletion, UT_test_textedit_searchKeywordSeletion_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->searchKeywordSeletion(QString("world"), textCursor, false); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//renderAllSelections +TEST(UT_test_textedit_renderAllSelections, UT_test_textedit_renderAllSelections_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red")); + pWindow->currentWrapper()->textEditor()->markKeywordInView(QString("world"), QString("red")); + pWindow->currentWrapper()->textEditor()->m_HightlightYes = true; + pWindow->currentWrapper()->textEditor()->renderAllSelections(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_mapKeywordMarkSelections.isEmpty()); + pWindow->deleteLater(); +} + +//clearMarkOperationForCursor +TEST(UT_test_textedit_clearMarkOperationForCursor, UT_test_textedit_clearMarkOperationForCursor_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkAllLine(true, QString("red")); + QTextCursor textCursorTemp = pWindow->currentWrapper()->textEditor()->m_markOperations.at(0).first.cursor; + bool bRet = pWindow->currentWrapper()->textEditor()->clearMarkOperationForCursor(textCursorTemp); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//clearMarksForTextCursor 001 +TEST(UT_test_textedit_clearMarksForTextCursor, UT_test_textedit_clearMarksForTextCursor_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red")); + bool bRet = pWindow->currentWrapper()->textEditor()->clearMarksForTextCursor(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//clearMarksForTextCursor 002 +TEST(UT_test_textedit_clearMarksForTextCursor, UT_test_textedit_clearMarksForTextCursor_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red")); + bool bRet = pWindow->currentWrapper()->textEditor()->clearMarksForTextCursor(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//markAllKeywordInView 001 +TEST(UT_test_textedit_clearMarksForTextCursor, UT_test_textedit_markAllKeywordInView_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->markAllKeywordInView(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty()); + pWindow->deleteLater(); +} + +//markAllKeywordInView 002 +TEST(UT_test_textedit_clearMarksForTextCursor, UT_test_textedit_markAllKeywordInView_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red")); + pWindow->currentWrapper()->textEditor()->m_markOperations.begin()->first.type = TextEdit::MarkAllMatch; + pWindow->currentWrapper()->textEditor()->markAllKeywordInView(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty()); + pWindow->deleteLater(); +} + +//markAllKeywordInView 003 +TEST(UT_test_textedit_clearMarksForTextCursor, UT_test_textedit_markAllKeywordInView_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red")); + pWindow->currentWrapper()->textEditor()->m_markOperations.begin()->first.type = TextEdit::MarkAll; + pWindow->currentWrapper()->textEditor()->markAllKeywordInView(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty()); + pWindow->deleteLater(); +} + +//markKeywordInView 001 +TEST(UT_test_textedit_markKeywordInView, UT_test_textedit_markKeywordInView_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->markKeywordInView(QString(), QString("red")); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//markKeywordInView 002 +TEST(UT_test_textedit_markKeywordInView, UT_test_textedit_markKeywordInView_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->markKeywordInView(QString("world"), QString("red")); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//markAllInView 001 +TEST(UT_test_textedit_markAllInView, UT_test_textedit_markAllInView_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->markAllInView(QString("red")); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_mapKeywordMarkSelections.isEmpty()); + pWindow->deleteLater(); +} + +//toggleMarkSelections 001 +TEST(UT_test_textedit_toggleMarkSelections, UT_test_textedit_toggleMarkSelections_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->toggleMarkSelections(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty()); + pWindow->deleteLater(); +} + +//updateMarkAllSelectColor 001 +TEST(UT_test_textedit_updateMarkAllSelectColor, UT_test_textedit_updateMarkAllSelectColor_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->updateMarkAllSelectColor(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_mapKeywordMarkSelections.isEmpty()); + pWindow->deleteLater(); +} + +// lineNumberAreaPaintEvent 001 +TEST(UT_test_textedit_lineNumberAreaPaintEvent, UT_test_textedit_lineNumberAreaPaintEvent_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n" + "H\ne\nl\nl\ne\n w\no\nr\nl\nd\nH\ne\nl\nl\ne\n w\no\nr\nl\nd\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::DarkType); + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->lineNumberAreaPaintEvent(pPaintEvent); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_lineNumbersColor.alphaF() == 0.2); + pWindow->deleteLater(); +} + +//lineNumberAreaPaintEvent 002 +TEST(UT_test_textedit_lineNumberAreaPaintEvent, UT_test_textedit_lineNumberAreaPaintEvent_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::LightType); + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->lineNumberAreaPaintEvent(pPaintEvent); + + EXPECT_NE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pLineNumberArea, nullptr); + pWindow->deleteLater(); +} + +//codeFLodAreaPaintEvent 001 +TEST(UT_test_textedit_codeFLodAreaPaintEvent, UT_test_textedit_codeFLodAreaPaintEvent_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\n{\n}\n}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::DarkType); + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->codeFLodAreaPaintEvent(pPaintEvent); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listFlodIconPos.isEmpty()); + pWindow->deleteLater(); +} + +//codeFLodAreaPaintEvent 002 +TEST(UT_test_textedit_codeFLodAreaPaintEvent, UT_test_textedit_codeFLodAreaPaintEvent_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\n{\n}\n}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::LightType); + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->codeFLodAreaPaintEvent(pPaintEvent); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listFlodIconPos.isEmpty()); + pWindow->deleteLater(); +} + +//setBookmarkFlagVisable 001 +TEST(UT_test_textedit_setBookmarkFlagVisable, UT_test_textedit_setBookmarkFlagVisable_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setBookmarkFlagVisable(true, false); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pIsShowBookmarkArea == true); + pWindow->deleteLater(); +} + +//setBookmarkFlagVisable 002 +TEST(UT_test_textedit_setBookmarkFlagVisable, UT_test_textedit_setBookmarkFlagVisable_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setBookmarkFlagVisable(false, false); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pIsShowBookmarkArea == false); + pWindow->deleteLater(); +} + +//setCodeFlodFlagVisable 001 +TEST(UT_test_textedit_setCodeFlodFlagVisable, UT_test_textedit_setCodeFlodFlagVisable_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setCodeFlodFlagVisable(true, false); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pIsShowCodeFoldArea == true); + pWindow->deleteLater(); +} + +//setCodeFlodFlagVisable 002 +TEST(UT_test_textedit_setCodeFlodFlagVisable, UT_test_textedit_setCodeFlodFlagVisable_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setCodeFlodFlagVisable(false, false); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pIsShowCodeFoldArea == false); + pWindow->deleteLater(); +} + +//setTheme 001 +TEST(UT_test_textedit_setTheme, UT_test_textedit_setTheme_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strThemeFilePath("./../themes/deepin.theme"); + pWindow->currentWrapper()->textEditor()->setTheme(strThemeFilePath); + QString strBgColorName(pWindow->currentWrapper()->textEditor()->m_backgroundColor.name()); + + ASSERT_TRUE(!strBgColorName.compare(QString("#000000"))); + pWindow->deleteLater(); +} + +//void removeHighlightWordUnderCursor() 001 +TEST(UT_test_textedit_removeHighlightWordUnderCursor, UT_test_textedit_removeHighlightWordUnderCursor_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->removeHighlightWordUnderCursor(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_nBookMarkHoverLine == -1); + pWindow->deleteLater(); +} + +//void setSettings(Settings *settings) 001 +TEST(UT_test_textedit_setSettings, UT_test_textedit_setSettings_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setSettings(pWindow->currentWrapper()->textEditor()->m_settings); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_settings != nullptr); + pWindow->deleteLater(); +} + +//void copySelectedText() 001 +TEST(UT_test_textedit_copySelectedText, UT_test_textedit_copySelectedText_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QTextEdit::ExtraSelection extraSelection; + extraSelection.cursor = textCursor; + pWindow->currentWrapper()->textEditor()->m_altModSelections << extraSelection; + pWindow->currentWrapper()->textEditor()->m_bIsAltMod = true; + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->copySelectedText(); + + QString strRet(pClipboard->text()); + ASSERT_TRUE(!strRet.compare(QString("Helle world"))); + pWindow->deleteLater(); +} + +//void copySelectedText() 002 +TEST(UT_test_textedit_copySelectedText, UT_test_textedit_copySelectedText_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->copySelectedText(); + + QString strRet(pClipboard->text()); + ASSERT_TRUE(!strRet.compare(QString("Helle world"))); + pWindow->deleteLater(); +} + +//void copySelectedText() 003 +TEST(UT_test_textedit_copySelectedText, UT_test_textedit_copySelectedText_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->copySelectedText(); + + QString strRet(pClipboard->text()); + ASSERT_TRUE(strRet.isEmpty()); + pWindow->deleteLater(); +} + +//void cutSelectedText() 001 +TEST(UT_test_textedit_cutSelectedText, UT_test_textedit_cutSelectedText_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->cutSelectedText(); + + QString strRet1(pClipboard->text()); + QString strRet2(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(!strRet1.compare(QString("Helle world")) && !strRet2.compare(QString("Helle world\n"))); + pWindow->deleteLater(); +} + +TEST(UT_test_textedit_cutSelectedText, cutSelectedText_withMultiByteText_passed) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + // 多字节字符编码 CJK + // 𢝐𢝑𢝒𢝓𢝔𢝕𢝖𢝗𢝘𢝙\n𢝚𢝛𢝜𢝝𢝞𢝟𢝠𢝡𢝢𢝣 + QString strMsg("\360\242\235\220\360\242\235\221\360\242\235\222\360\242\235\223\360\242\235\224" + "\360\242\235\225\360\242\235\226\360\242\235\227\360\242\235\230\360\242\235\231\n" + "\360\242\235\232\360\242\235\233\360\242\235\234\360\242\235\235\360\242\235\236" + "\360\242\235\237\360\242\235\240\360\242\235\241\360\242\235\242\360\242\235\243"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.setPosition(0); + textCursor.setPosition(6, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->cutSelectedText(); + + QString strRet1(pClipboard->text()); + QString strRet2(pWindow->currentWrapper()->textEditor()->toPlainText()); + EXPECT_EQ(strRet1, strMsg.left(6)); + EXPECT_EQ(strRet2, strMsg.mid(6)); + pWindow->deleteLater(); +} + +//void pasteText() 001 +TEST(UT_test_textedit_pasteText, UT_test_textedit_pasteText_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->copySelectedText(); + textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->pasteText(); + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + + ASSERT_TRUE(!strRet.compare(QString("Helle worldHelle world"))); + pWindow->deleteLater(); +} + +//void setMark() 001 +TEST(UT_test_textedit_setMark, UT_test_textedit_setMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->setMark(); + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void setMark() 002 +TEST(UT_test_textedit_setMark, UT_test_textedit_setMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->setMark(); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_cursorMark; + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void setMark() 003 +TEST(UT_test_textedit_setMark, UT_test_textedit_setMark_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + pWindow->currentWrapper()->textEditor()->setMark(); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_cursorMark; + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void unsetMark() 001 +TEST(UT_test_textedit_unsetMark, UT_test_textedit_unsetMark_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + pWindow->currentWrapper()->textEditor()->unsetMark(); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_cursorMark; + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//bool tryUnsetMark() 001 +TEST(UT_test_textedit_tryUnsetMark, UT_test_textedit_tryUnsetMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = true; + bool bRet = pWindow->currentWrapper()->textEditor()->tryUnsetMark(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//bool tryUnsetMark() 002 +TEST(UT_test_textedit_tryUnsetMark, UT_test_textedit_tryUnsetMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMark = false; + bool bRet = pWindow->currentWrapper()->textEditor()->tryUnsetMark(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void exchangeMark() 001 +TEST(UT_test_textedit_exchangeMark, UT_test_textedit_exchangeMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRetBefore = textCursor.position(); + int iSelectStar = textCursor.selectionStart(); + int iSelectEnd = textCursor.selectionEnd(); + pWindow->currentWrapper()->textEditor()->exchangeMark(); + int iRetAfter = textCursor.position(); + + ASSERT_TRUE(iRetAfter == iRetBefore); + pWindow->deleteLater(); +} + +//void exchangeMark() 002 +TEST(UT_test_textedit_exchangeMark, UT_test_textedit_exchangeMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + textCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRetBefore = textCursor.position(); + pWindow->currentWrapper()->textEditor()->exchangeMark(); + int iRetAfter = textCursor.position(); + + ASSERT_TRUE(iRetAfter == iRetBefore); + pWindow->deleteLater(); +} + +//void saveMarkStatus() 001 +TEST(UT_test_textedit_saveMarkStatus, UT_test_textedit_saveMarkStatus_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet1 = pWindow->currentWrapper()->textEditor()->m_cursorMarkPosition; + pWindow->currentWrapper()->textEditor()->setMark(); + pWindow->currentWrapper()->textEditor()->saveMarkStatus(); + + int iRet = pWindow->currentWrapper()->textEditor()->m_cursorMarkPosition; + ASSERT_TRUE(iRet == 23); + pWindow->deleteLater(); +} + +//void restoreMarkStatus() 001 +TEST(UT_test_textedit_restoreMarkStatus, UT_test_textedit_restoreMarkStatus_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_cursorMarkStatus = true; + pWindow->currentWrapper()->textEditor()->restoreMarkStatus(); + + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +QString UT_test_textedit_completionWord_001_stub() +{ + return QString("wo"); +} + +//void completionWord(QString word) 001 +TEST(UT_test_textedit_completionWord, UT_test_textedit_completionWord_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_getWordAtCursor; + stub_getWordAtCursor.set(ADDR(TextEdit, getWordAtCursor), UT_test_textedit_completionWord_001_stub); + pWindow->currentWrapper()->textEditor()->completionWord("world"); + + QString strRet(pWindow->currentWrapper()->textEditor()->textCursor().block().text()); + ASSERT_TRUE(!strRet.compare(QString("Helle worldrld"))); + pWindow->deleteLater(); +} + +int UT_test_textedit_getWordAtMouse_001_stub() +{ + return 0; +} + +//QString getWordAtMouse() 001 +TEST(UT_test_textedit_getWordAtMouse, UT_test_textedit_getWordAtMouse_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_characterCount; + stub_characterCount.set(ADDR(TextEdit, characterCount), UT_test_textedit_getWordAtMouse_001_stub); + QString strRet = pWindow->currentWrapper()->textEditor()->getWordAtMouse(); + + ASSERT_TRUE(strRet.isEmpty()); + pWindow->deleteLater(); +} + +//QString getWordAtMouse() 002 +TEST(UT_test_textedit_getWordAtMouse, UT_test_textedit_getWordAtMouse_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strRet = pWindow->currentWrapper()->textEditor()->getWordAtMouse(); + + ASSERT_TRUE(strRet.isEmpty()); + pWindow->deleteLater(); +} + +//QString getWordAtCursor() 001 +TEST(UT_test_textedit_getWordAtCursore, UT_test_textedit_getWordAtCursor_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_characterCount; + stub_characterCount.set(ADDR(TextEdit, characterCount), UT_test_textedit_getWordAtMouse_001_stub); + QString strRet = pWindow->currentWrapper()->textEditor()->getWordAtCursor(); + + ASSERT_TRUE(strRet.isEmpty()); + pWindow->deleteLater(); +} + +//QString getWordAtCursor() 002 +TEST(UT_test_textedit_getWordAtCursore, UT_test_textedit_getWordAtCursor_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle wor-ld"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QString strRet = pWindow->currentWrapper()->textEditor()->getWordAtCursor(); + + ASSERT_TRUE(!strRet.compare(QString("ld"))); + pWindow->deleteLater(); +} + +//void toggleReadOnlyMode() 001 +TEST(UT_test_textedit_toggleReadOnlyMode, UT_test_textedit_toggleReadOnlyMode_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + pWindow->currentWrapper()->textEditor()->m_cursorMode = TextEdit::Overwrite; + pWindow->currentWrapper()->textEditor()->toggleReadOnlyMode(); + + bool bRet = pWindow->currentWrapper()->textEditor()->isReadOnly(); + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void toggleReadOnlyMode() 002 +TEST(UT_test_textedit_toggleReadOnlyMode, UT_test_textedit_toggleReadOnlyMode_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + pWindow->currentWrapper()->textEditor()->m_cursorMode = TextEdit::Readonly; + pWindow->currentWrapper()->textEditor()->toggleReadOnlyMode(); + + bool bRet = pWindow->currentWrapper()->textEditor()->isReadOnly(); + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void toggleReadOnlyMode() 003 +TEST(UT_test_textedit_toggleReadOnlyMode, UT_test_textedit_toggleReadOnlyMode_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = false; + pWindow->currentWrapper()->textEditor()->toggleReadOnlyMode(); + + bool bRet = pWindow->currentWrapper()->textEditor()->isReadOnly(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void toggleComment(bool bValue) 001 +TEST(UT_test_textedit_toggleComment, UT_test_textedit_toggleComment_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + pWindow->currentWrapper()->textEditor()->toggleComment(true); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_readOnlyMode; + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +bool UT_test_textedit_toggleComment_002_stub() +{ + return true; +} + +//void toggleComment(bool bValue) 002 +TEST(UT_test_textedit_toggleComment, UT_test_textedit_toggleComment_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_isValid; + stub_isValid.set(ADDR(Comment::CommentDefinition, isValid), UT_test_textedit_toggleComment_002_stub); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = false; + pWindow->currentWrapper()->textEditor()->toggleComment(true); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_commentDefinition.isValid(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +bool UT_test_textedit_toggleComment_003_stub() +{ + return false; +} + +void UT_test_textedit_toggleComment_003_setComment_stub() +{ + return; +} + +//void toggleComment(bool bValue) 003 +TEST(UT_test_textedit_toggleComment, UT_test_textedit_toggleComment_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_isValid; + stub_isValid.set(ADDR(Comment::CommentDefinition, isValid), UT_test_textedit_toggleComment_002_stub); + Stub stub_isEmpty; + stub_isEmpty.set(ADDR(QString, isEmpty), UT_test_textedit_toggleComment_003_stub); + Stub stub_setComment; + stub_setComment.set(ADDR(TextEdit, setComment), UT_test_textedit_toggleComment_003_setComment_stub); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = false; + pWindow->currentWrapper()->textEditor()->m_commentDefinition.multiLineStart = QString("Helle \tworld\nHelle world"); + pWindow->currentWrapper()->textEditor()->m_commentDefinition.singleLine = QString("Helle \tworld\nHelle world"); + pWindow->currentWrapper()->textEditor()->toggleComment(true); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_commentDefinition.isValid(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +void UT_test_textedit_toggleComment_004_removeComment_stub() +{ + return; +} + +//void toggleComment(bool bValue) 004 +TEST(UT_test_textedit_toggleComment, UT_test_textedit_toggleComment_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_isValid; + stub_isValid.set(ADDR(Comment::CommentDefinition, isValid), UT_test_textedit_toggleComment_002_stub); + Stub stub_isEmpty; + stub_isEmpty.set(ADDR(QString, isEmpty), UT_test_textedit_toggleComment_003_stub); + Stub stub_removeComment; + stub_removeComment.set(ADDR(TextEdit, removeComment), UT_test_textedit_toggleComment_004_removeComment_stub); + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = false; + pWindow->currentWrapper()->textEditor()->m_commentDefinition.multiLineStart = QString("Helle \tworld\nHelle world"); + pWindow->currentWrapper()->textEditor()->m_commentDefinition.singleLine = QString("Helle \tworld\nHelle world"); + pWindow->currentWrapper()->textEditor()->toggleComment(false); + + bool bRet = pWindow->currentWrapper()->textEditor()->m_commentDefinition.isValid(); + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +int UT_test_textedit_getNextWordPosition_001_characterCount_stub() +{ + return 0; +} + +//getNextWordPosition 001 +TEST(UT_test_textedit_getNextWordPosition, UT_test_textedit_getNextWordPosition_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_characterCount; + stub_characterCount.set(ADDR(TextEdit, characterCount), UT_test_textedit_getNextWordPosition_001_characterCount_stub); + int iRet = pWindow->currentWrapper()->textEditor()->getNextWordPosition(textCursor, QTextCursor::MoveMode::MoveAnchor); + + ASSERT_TRUE(iRet == 0); + pWindow->deleteLater(); +} + +//getNextWordPosition 002 +TEST(UT_test_textedit_getNextWordPosition, UT_test_textedit_getNextWordPosition_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + int iRet = pWindow->currentWrapper()->textEditor()->getNextWordPosition(textCursor, QTextCursor::MoveMode::MoveAnchor); + + ASSERT_TRUE(iRet == 17); + pWindow->deleteLater(); +} + +int UT_test_textedit_getPrevWordPosition_001_characterCount_stub() +{ + return 0; +} + +//getPrevWordPosition 001 +TEST(UT_test_textedit_getPrevWordPosition, UT_test_textedit_getPrevWordPosition_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_characterCount; + stub_characterCount.set(ADDR(TextEdit, characterCount), UT_test_textedit_getPrevWordPosition_001_characterCount_stub); + int iRet = pWindow->currentWrapper()->textEditor()->getPrevWordPosition(textCursor, QTextCursor::MoveMode::MoveAnchor); + + ASSERT_TRUE(iRet == 0); + pWindow->deleteLater(); +} + +//getPrevWordPosition 002 +TEST(UT_test_textedit_getPrevWordPosition, UT_test_textedit_getPrevWordPosition_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->getPrevWordPosition(textCursor, QTextCursor::MoveMode::MoveAnchor); + + ASSERT_TRUE(iRet == 17); + pWindow->deleteLater(); +} + +//bool atWordSeparator(int position); +TEST(UT_test_textedit_atWordSeparator, UT_test_textedit_atWordSeparator_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->atWordSeparator(10); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void showCursorBlink(); +TEST(UT_test_textedit_showCursorBlink, UT_test_textedit_showCursorBlink_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->showCursorBlink(); + int iRet = QApplication::cursorFlashTime(); + + ASSERT_TRUE(iRet == 1000); + pWindow->deleteLater(); +} + +//void hideCursorBlink(); +TEST(UT_test_textedit_hideCursorBlink, UT_test_textedit_hideCursorBlink_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->hideCursorBlink(); + int iRet = QApplication::cursorFlashTime(); + + ASSERT_TRUE(iRet == 0); + pWindow->deleteLater(); +} + +//void setReadOnlyPermission(bool permission); +TEST(UT_test_textedit_setReadOnlyPermission, UT_test_textedit_setReadOnlyPermission_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setReadOnlyPermission(true); + bool bRet = pWindow->currentWrapper()->textEditor()->isReadOnly(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void setReadOnlyPermission(bool permission); +TEST(UT_test_textedit_setReadOnlyPermission, UT_test_textedit_setReadOnlyPermission_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = false; + pWindow->currentWrapper()->textEditor()->setReadOnlyPermission(false); + bool bRet = pWindow->currentWrapper()->textEditor()->isReadOnly(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void setReadOnlyPermission(bool permission); +TEST(UT_test_textedit_setReadOnlyPermission, UT_test_textedit_setReadOnlyPermission_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_readOnlyMode = true; + pWindow->currentWrapper()->textEditor()->setReadOnlyPermission(false); + bool bRet = pWindow->currentWrapper()->textEditor()->isReadOnly(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//bool getReadOnlyPermission(); +TEST(UT_test_textedit_getReadOnlyPermission, UT_test_textedit_getReadOnlyPermission_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->getReadOnlyPermission(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//bool getReadOnlyMode(); +TEST(UT_test_textedit_getReadOnlyMode, UT_test_textedit_getReadOnlyMode_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->getReadOnlyMode(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void hideRightMenu(); +TEST(UT_test_textedit_hideRightMenu, UT_test_textedit_hideRightMenu_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Helle world\nHelle world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->hideRightMenu(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_rightMenu->isHidden(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void flodOrUnflodAllLevel(bool isFlod); +TEST(UT_test_textedit_flodOrUnflodAllLevel, UT_test_textedit_flodOrUnflodAllLevel_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\n{\n}\n}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->flodOrUnflodAllLevel(true); + QTextOption::WrapMode eRet = pWindow->currentWrapper()->textEditor()->wordWrapMode(); + + ASSERT_TRUE(eRet == QTextOption::WrapMode::WrapAnywhere); + pWindow->deleteLater(); +} + +//void flodOrUnflodAllLevel(bool isFlod); +TEST(UT_test_textedit_flodOrUnflodAllLevel, UT_test_textedit_flodOrUnflodAllLevel_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\n{\n}\n}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->flodOrUnflodAllLevel(true); + pWindow->currentWrapper()->textEditor()->flodOrUnflodAllLevel(false); + QTextOption::WrapMode eRet = pWindow->currentWrapper()->textEditor()->wordWrapMode(); + + ASSERT_TRUE(eRet == QTextOption::WrapMode::WrapAnywhere); + pWindow->deleteLater(); +} + +//void flodOrUnflodCurrentLevel(bool isFlod); +TEST(UT_test_textedit_flodOrUnflodCurrentLevel, UT_test_textedit_flodOrUnflodCurrentLevel_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\n{\n}\n}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->flodOrUnflodCurrentLevel(true); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget != nullptr); + pWindow->deleteLater(); +} + +//void getHideRowContent +TEST(UT_test_textedit_getHideRowContent, UT_test_textedit_getHideRowContent_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\nHello world\n{\nHello world\n}\n}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->getHideRowContent(0); + QString strRet(pWindow->currentWrapper()->textEditor()->m_foldCodeShow->m_pContentEdit->toPlainText()); + + ASSERT_TRUE(strRet.compare(QString("{\nHello world\n{\nHello world\n}\n}"))); + pWindow->deleteLater(); +} + +//void isNeedShowFoldIcon +TEST(UT_test_textedit_getHideRowContent, UT_test_textedit_isNeedShowFoldIcon_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{Hello world}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QTextBlock textBlock = pWindow->currentWrapper()->textEditor()->textCursor().block(); + bool bRet = pWindow->currentWrapper()->textEditor()->isNeedShowFoldIcon(textBlock); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void isNeedShowFoldIcon +TEST(UT_test_textedit_getHideRowContent, UT_test_textedit_isNeedShowFoldIcon_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\nHello world}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QTextBlock textBlock = pWindow->currentWrapper()->textEditor()->textCursor().block(); + bool bRet = pWindow->currentWrapper()->textEditor()->isNeedShowFoldIcon(textBlock); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//int getHighLightRowContentLineNum +TEST(UT_test_textedit_getHighLightRowContentLineNum, UT_test_textedit_getHighLightRowContentLineNum_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{Hello world}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->getHighLightRowContentLineNum(0); + + ASSERT_TRUE(iRet == 0); + pWindow->deleteLater(); +} + +//int getHighLightRowContentLineNum +TEST(UT_test_textedit_getHighLightRowContentLineNum, UT_test_textedit_getHighLightRowContentLineNum_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\nHello world}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->getHighLightRowContentLineNum(1); + + ASSERT_TRUE(iRet == 1); + pWindow->deleteLater(); +} + +//getHighLightRowContentLineNum +TEST(UT_test_textedit_getHighLightRowContentLineNum, UT_test_textedit_getHighLightRowContentLineNum_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\nHello world}}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->getHighLightRowContentLineNum(1); + + ASSERT_TRUE(iRet == 1); + pWindow->deleteLater(); +} + +//paintCodeFlod +TEST(UT_test_textedit_paintCodeFlod, UT_test_textedit_paintCodeFlod_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\nHello world}}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QPainter painter(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pFlodArea); + QRect rect(0, pWindow->currentWrapper()->textEditor()->cursorRect(textCursor).y(), 15, 15); + pWindow->currentWrapper()->textEditor()->paintCodeFlod(&painter, rect, true); + QPainter::RenderHints eRet = painter.renderHints(); + bool bRet = eRet.testFlag(QPainter::RenderHint::Antialiasing); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//getBackColor +TEST(UT_test_textedit_getBackColor, UT_test_textedit_getBackColor_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("{\nHello world}}"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + QColor colorRet(pWindow->currentWrapper()->textEditor()->getBackColor()); + + ASSERT_TRUE(!colorRet.name().isEmpty()); + pWindow->deleteLater(); +} + +//updateLeftWidgetWidth +TEST(UT_test_textedit_updateLeftWidgetWidth, UT_test_textedit_updateLeftWidgetWidth_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->updateLeftWidgetWidth(20); + int iRet = pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pBookMarkArea->width(); + + ASSERT_TRUE(iRet == 20); + pWindow->deleteLater(); +} + +//lineNumberAreaWidth +TEST(UT_test_textedit_lineNumberAreaWidth, UT_test_textedit_lineNumberAreaWidth_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("H\ne\nl\nl\no\n w\no\nr\nl\nd\nH\ne\nl\nl\no\n w\no\nr\nl\nd\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->lineNumberAreaWidth(); + + ASSERT_TRUE(iRet == 20); + pWindow->deleteLater(); +} + +//int getLinePosYByLineNum(int iLine); +TEST(UT_test_textedit_getLinePosYByLineNum, UT_test_textedit_getLinePosYByLineNum_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->getLinePosYByLineNum(0); + + ASSERT_TRUE(iRet == 4); + pWindow->deleteLater(); +} + +//bool ifHasHighlight(); +TEST(UT_test_textedit_ifHasHighlight, UT_test_textedit_ifHasHighlight_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QTextCharFormat charFormat; + charFormat.setBackground(QColor("red")); + QTextEdit::ExtraSelection findExtraSelection; + findExtraSelection.cursor = textCursor; + findExtraSelection.format = charFormat; + pWindow->currentWrapper()->textEditor()->m_findHighlightSelection = findExtraSelection; + bool bRet = pWindow->currentWrapper()->textEditor()->ifHasHighlight(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//bool ifHasHighlight(); +TEST(UT_test_textedit_ifHasHighlight, UT_test_textedit_ifHasHighlight_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + bool bRet = pWindow->currentWrapper()->textEditor()->ifHasHighlight(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//bookMarkAreaPaintEvent +TEST(UT_test_textedit_bookMarkAreaPaintEvent, UT_test_textedit_bookMarkAreaPaintEvent_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::DarkType); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->m_nBookMarkHoverLine = 2; + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->bookMarkAreaPaintEvent(pPaintEvent); + int iRet = pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pBookMarkArea->width(); + + ASSERT_TRUE(iRet == 15); + pWindow->deleteLater(); +} + +//bookMarkAreaPaintEvent +TEST(UT_test_textedit_bookMarkAreaPaintEvent, UT_test_textedit_bookMarkAreaPaintEvent_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::LightType); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->m_nBookMarkHoverLine = 2; + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->bookMarkAreaPaintEvent(pPaintEvent); + int iRet = pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pBookMarkArea->width(); + + ASSERT_TRUE(iRet == 15); + pWindow->deleteLater(); +} + +//bookMarkAreaPaintEvent +TEST(UT_test_textedit_bookMarkAreaPaintEvent, UT_test_textedit_bookMarkAreaPaintEvent_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + DApplicationHelper::instance()->setThemeType(DApplicationHelper::ColorType::LightType); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->m_nBookMarkHoverLine = 1; + QPaintEvent *pPaintEvent; + pWindow->currentWrapper()->textEditor()->bookMarkAreaPaintEvent(pPaintEvent); + int iRet = pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget->m_pBookMarkArea->width(); + + ASSERT_TRUE(iRet == 15); + pWindow->deleteLater(); +} + +//int getLineFromPoint(const QPoint &point); +TEST(UT_test_textedit_getLineFromPoint, UT_test_textedit_getLineFromPoint_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + int iRet = pWindow->currentWrapper()->textEditor()->getLineFromPoint(QPoint(0, 13)); + + ASSERT_TRUE(iRet == 1); + pWindow->deleteLater(); +} + +//void addOrDeleteBookMark(); +TEST(UT_test_textedit_addOrDeleteBookMark, UT_test_textedit_addOrDeleteBookMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_bIsShortCut = true; + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->addOrDeleteBookMark(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget != nullptr); + pWindow->deleteLater(); +} + +//void addOrDeleteBookMark(); +TEST(UT_test_textedit_addOrDeleteBookMark, UT_test_textedit_addOrDeleteBookMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_bIsShortCut = false; + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->addOrDeleteBookMark(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget != nullptr); + pWindow->deleteLater(); +} + +//void addOrDeleteBookMark(); +TEST(UT_test_textedit_addOrDeleteBookMark, UT_test_textedit_addOrDeleteBookMark_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_bIsShortCut = true; + pWindow->currentWrapper()->textEditor()->addOrDeleteBookMark(); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget != nullptr); + pWindow->deleteLater(); +} + +//void moveToPreviousBookMark(); +TEST(UT_test_textedit_moveToPreviousBookMark, UT_test_textedit_moveToPreviousBookMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->moveToPreviousBookMark(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void moveToPreviousBookMark(); +TEST(UT_test_textedit_moveToPreviousBookMark, UT_test_textedit_moveToPreviousBookMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->moveToPreviousBookMark(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void moveToPreviousBookMark(); +TEST(UT_test_textedit_moveToPreviousBookMark, UT_test_textedit_moveToPreviousBookMark_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(3); + pWindow->currentWrapper()->textEditor()->moveToPreviousBookMark(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void moveToNextBookMark(); +TEST(UT_test_textedit_moveToNextBookMark, UT_test_textedit_moveToNextBookMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->moveToNextBookMark(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void moveToNextBookMark(); +TEST(UT_test_textedit_moveToNextBookMark, UT_test_textedit_moveToNextBookMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->moveToNextBookMark(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void moveToNextBookMark(); +TEST(UT_test_textedit_moveToNextBookMark, UT_test_textedit_moveToNextBookMarkk_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(3); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->moveToNextBookMark(); + + ASSERT_TRUE(!pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void checkBookmarkLineMove(int from, int charsRemoved, int charsAdded); +TEST(UT_test_textedit_checkBookmarkLineMove, UT_test_textedit_checkBookmarkLineMove_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_bIsFileOpen = true; + pWindow->currentWrapper()->textEditor()->checkBookmarkLineMove(3, 0, 0); + + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty()); + pWindow->deleteLater(); +} + +//void checkBookmarkLineMove(int from, int charsRemoved, int charsAdded); +TEST(UT_test_textedit_checkBookmarkLineMove, UT_test_textedit_checkBookmarkLineMove_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_nLines = 4; + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + pWindow->currentWrapper()->textEditor()->checkBookmarkLineMove(3, 0, 0); + int iRet1 = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + int iRet2 = pWindow->currentWrapper()->textEditor()->m_nLines; + + ASSERT_TRUE(iRet1 == iRet2); + pWindow->deleteLater(); +} + +//void checkBookmarkLineMove(int from, int charsRemoved, int charsAdded); +TEST(UT_test_textedit_checkBookmarkLineMove, UT_test_textedit_checkBookmarkLineMove_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_nLines = 4; + pWindow->currentWrapper()->textEditor()->m_nSelectEndLine = -1; + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(3); + pWindow->currentWrapper()->textEditor()->checkBookmarkLineMove(3, 0, 0); + int iRet1 = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + int iRet2 = pWindow->currentWrapper()->textEditor()->m_nLines; + + ASSERT_TRUE(iRet1 == iRet2); + pWindow->deleteLater(); +} + +//void checkBookmarkLineMove(int from, int charsRemoved, int charsAdded); +TEST(UT_test_textedit_checkBookmarkLineMove, UT_test_textedit_checkBookmarkLineMove_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_nLines = 3; + pWindow->currentWrapper()->textEditor()->m_nSelectEndLine = -1; + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(3); + pWindow->currentWrapper()->textEditor()->checkBookmarkLineMove(1, 0, 0); + int iRet1 = pWindow->currentWrapper()->textEditor()->document()->blockCount(); + int iRet2 = pWindow->currentWrapper()->textEditor()->m_nLines; + + ASSERT_TRUE(iRet1 == iRet2); + pWindow->deleteLater(); +} + +//void setIsFileOpen(); +TEST(UT_test_textedit_setIsFileOpen, UT_test_textedit_setIsFileOpen_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world\n"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->setIsFileOpen(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_bIsFileOpen; + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void setTextFinished(); +TEST(UT_test_textedit_setTextFinished, UT_test_textedit_setTextFinished_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->setTextFinished(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_bIsFileOpen; + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +QStringList UT_test_textedit_setTextFinished_002_readHistoryRecordofBookmark_stub() +{ + QStringList bookmarkList; + bookmarkList << "*(2,*1,*2,*1,*4,*1,*1,*1)*"; + bookmarkList << "*(2,*1,*2,*1,*4,*1,*1)*"; + bookmarkList << "*(5,*6,*7,*1,*1,*1,*1)*"; + + return bookmarkList; +} + +QString m_sFilePath {QString()}; +QStringList UT_test_textedit_setTextFinished_002_readHistoryRecordofFilePath_stub() +{ + QStringList filePathList; + filePathList << "~/Desktop/1.txt"; + filePathList << "~/.local/share/deepin/deepin-editor/blank-files/blank_file_2021-09-28_08-44-42-244"; + filePathList << "~/.local/share/deepin/deepin-editor/blank-files/blank_file_2021-09-26_11-37-20-780"; + filePathList << m_sFilePath; + + return filePathList; +} + +//void setTextFinished(); +TEST(UT_test_textedit_setTextFinished, UT_test_textedit_setTextFinished_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + //pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + Stub stub_readHistoryRecordofBookmark; + stub_readHistoryRecordofBookmark.set(ADDR(TextEdit, readHistoryRecordofBookmark), UT_test_textedit_setTextFinished_002_readHistoryRecordofBookmark_stub); + m_sFilePath = pWindow->currentWrapper()->textEditor()->m_sFilePath; + Stub stub_readHistoryRecordofFilePath; + stub_readHistoryRecordofFilePath.set(ADDR(TextEdit, readHistoryRecordofFilePath), UT_test_textedit_setTextFinished_002_readHistoryRecordofFilePath_stub); + pWindow->currentWrapper()->textEditor()->setTextFinished(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_bIsFileOpen; + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +QVariant UT_test_textedit_readHistoryRecord_001_option_stub() +{ + return QVariant("*{\"cursorPosition\":\"13\",\"modify\":false}*"); +} + +//QStringList readHistoryRecord(QString key); +TEST(UT_test_textedit_readHistoryRecord, UT_test_textedit_readHistoryRecord_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_option; + stub_option.set(ADDR(DSettingsOption, value), UT_test_textedit_readHistoryRecord_001_option_stub); + QStringList stringListRet = pWindow->currentWrapper()->textEditor()->readHistoryRecord(QString("advance.editor.browsing_history_file")); + + ASSERT_TRUE(stringListRet == QStringList("*{\"cursorPosition\":\"13\",\"modify\":false}*")); + pWindow->deleteLater(); +} + +QVariant UT_test_textedit_readHistoryRecordofBookmark_001_option_stub() +{ + return QVariant("*(\"cursorPosition\":\"13\",\"modify\":false)*"); +} + +//QStringList readHistoryRecordofBookmark(); +TEST(UT_test_textedit_readHistoryRecordofBookmark, UT_test_textedit_readHistoryRecordofBookmark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_option; + stub_option.set(ADDR(DSettingsOption, value), UT_test_textedit_readHistoryRecordofBookmark_001_option_stub); + QStringList stringListRet = pWindow->currentWrapper()->textEditor()->readHistoryRecordofBookmark(); + + ASSERT_TRUE(stringListRet == QStringList("*(\"cursorPosition\":\"13\",\"modify\":false)*")); + pWindow->deleteLater(); +} + +QVariant UT_test_textedit_readHistoryRecordofFilePath_001_option_stub() +{ + return QVariant("*[\"cursorPosition\":\"13\",\"modify\":false]*"); +} + +//QStringList readHistoryRecordofFilePath(); +TEST(UT_test_textedit_readHistoryRecordofFilePath, UT_test_textedit_readHistoryRecordofFilePath_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + Stub stub_option; + stub_option.set(ADDR(DSettingsOption, value), UT_test_textedit_readHistoryRecordofFilePath_001_option_stub); + QStringList stringListRet = pWindow->currentWrapper()->textEditor()->readHistoryRecordofFilePath(QString()); + + ASSERT_TRUE(stringListRet != QStringList("*[\"cursorPosition\":\"13\",\"modify\":false]*")); + pWindow->deleteLater(); +} + +//void isMarkCurrentLine(); +TEST(UT_test_textedit_isMarkCurrentLine, UT_test_textedit_isMarkCurrentLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red"), -1); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void isMarkCurrentLine(); +TEST(UT_test_textedit_isMarkCurrentLine, UT_test_textedit_isMarkCurrentLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red"), -1); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void isMarkCurrentLine(); +TEST(UT_test_textedit_isMarkCurrentLine, UT_test_textedit_isMarkCurrentLine_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(false, QString("red"), -1); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void isMarkAllLine(bool isMark, QString strColor = ""); +TEST(UT_test_textedit_isMarkAllLine, UT_test_textedit_isMarkAllLine_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world one"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkAllLine(true, QString("red")); + bool bRet = pWindow->currentWrapper()->textEditor()->m_mapKeywordMarkSelections.isEmpty(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void isMarkAllLine(bool isMark, QString strColor = ""); +TEST(UT_test_textedit_isMarkAllLine, UT_test_textedit_isMarkAllLine_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkAllLine(true, QString("red")); + bool bRet = pWindow->currentWrapper()->textEditor()->m_mapKeywordMarkSelections.isEmpty(); + + ASSERT_TRUE(bRet == false); + pWindow->deleteLater(); +} + +//void isMarkAllLine(bool isMark, QString strColor = ""); +TEST(UT_test_textedit_isMarkAllLine, UT_test_textedit_isMarkAllLine_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->isMarkAllLine(false, QString("red")); + QString strRet = pWindow->currentWrapper()->textEditor()->m_markAllSelection.format.background().color().name(); + + ASSERT_TRUE(!strRet.compare(QString("#ff0000"))); + pWindow->deleteLater(); +} + +//void cancelLastMark(); +TEST(UT_test_textedit_cancelLastMark, UT_test_textedit_cancelLastMark_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + pWindow->currentWrapper()->textEditor()->m_markOperations.clear(); + pWindow->currentWrapper()->textEditor()->cancelLastMark(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void cancelLastMark(); +TEST(UT_test_textedit_cancelLastMark, UT_test_textedit_cancelLastMark_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red"), -1); + //pWindow->currentWrapper()->textEditor()->isMarkAllLine(true, QString("red")); + pWindow->currentWrapper()->textEditor()->m_markOperations.last().first.type = TextEdit::MarkOperationType::MarkLine; + pWindow->currentWrapper()->textEditor()->cancelLastMark(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void cancelLastMark(); +TEST(UT_test_textedit_cancelLastMark, UT_test_textedit_cancelLastMark_003) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red"), -1); + pWindow->currentWrapper()->textEditor()->markAllInView(QString("red"), -1); + pWindow->currentWrapper()->textEditor()->m_markOperations.last().first.type = TextEdit::MarkOperationType::MarkAllMatch; + pWindow->currentWrapper()->textEditor()->cancelLastMark(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void cancelLastMark(); +TEST(UT_test_textedit_cancelLastMark, UT_test_textedit_cancelLastMark_004) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("Hello world\nHello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->isMarkCurrentLine(true, QString("red"), -1); + pWindow->currentWrapper()->textEditor()->markAllInView(QString("red"), -1); + pWindow->currentWrapper()->textEditor()->m_markOperations.last().first.type = TextEdit::MarkOperationType::MarkAll; + pWindow->currentWrapper()->textEditor()->m_mapKeywordMarkSelections.insert(QString(TEXT_EIDT_MARK_ALL),QList>()); + pWindow->currentWrapper()->textEditor()->cancelLastMark(); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + + ASSERT_TRUE(bRet == true); + pWindow->deleteLater(); +} + +//void setThemeWithPath(const QString &path); +TEST_F(test_textedit, setThemeWithPath) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +//void setIsFileOpen(); +TEST_F(test_textedit, setIsFileOpen) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + startManager->setWrapper(ee); + startManager->setIsFileOpen(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +//void isMarkCurrentLine(bool isMark, QString strColor = ""); +TEST_F(test_textedit, isMarkCurrentLine) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->isMarkCurrentLine(true, "red"); + startManager->isMarkCurrentLine(false, "red"); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} + +//void markSelectWord(); +TEST_F(test_textedit, markSelectWord) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->markSelectWord(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} + +//void updateMark(int from, int charsRemoved, int charsAdded); +TEST_F(test_textedit, updateMark) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->updateMark(1, 2, 3); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} + +//bool containsExtraSelection(QList listSelections, QTextEdit::ExtraSelection selection); +TEST_F(test_textedit, containsExtraSelection) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->containsExtraSelection(listSelection, selectio); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} + +//void appendExtraSelection(QList wordMarkSelections, QTextEdit::ExtraSelection selection +// , QString strColor, QList *listSelections); +TEST_F(test_textedit, appendExtraSelection) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + QList listSelection; + QTextEdit::ExtraSelection selectio; + selectio.cursor = startManager->textCursor(); + selectio.format.setBackground(QColor(Qt::red)); + QList listSelectionsd; + listSelectionsd.append(selectio); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->appendExtraSelection(listSelection, selectio, "#000000", &listSelectionsd); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} +/// void setCursorStart(int _); +TEST_F(test_textedit, setCursorStart) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->setCursorStart(2); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} +//void writeEncodeHistoryRecord(); +TEST_F(test_textedit, writeEncodeHistoryRecord) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->writeEncodeHistoryRecord(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} +//QStringList readEncodeHistoryRecord(); +TEST_F(test_textedit, readEncodeHistoryRecord) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->readEncodeHistoryRecord(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} + +//clickFindAction +TEST_F(test_textedit, clickFindAction) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->clickFindAction(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} +// void tellFindBarClose(); +TEST_F(test_textedit, tellFindBarClose) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->tellFindBarClose(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); + s->deleteLater(); +} + +// void setEditPalette(const QString &activeColor, const QString &inactiveColor); +TEST_F(test_textedit, setEditPalette) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->setEditPalette("aa", "aa"); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void setCodeFoldWidgetHide(bool isHidden); +TEST_F(test_textedit, setCodeFoldWidgetHide) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->setCodeFoldWidgetHide(true); + startManager->setCodeFoldWidgetHide(false); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} +// void updateLeftAreaWidget(); +TEST_F(test_textedit, updateLeftAreaWidget) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->updateLeftAreaWidget(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void updateLineNumber(); +TEST_F(test_textedit, updateLineNumber) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->updateLeftAreaWidget(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} +// void handleScrollFinish(); +TEST_F(test_textedit, handleScrollFinish) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->handleScrollFinish(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void slot_translate(); +TEST_F(test_textedit, slot_translate) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->slot_translate(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +#if 0 //gerrit上段错误,暂且屏蔽 +// void upcaseWord(); + TEST_F(test_textedit, upcaseWord) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper * ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->upcaseWord(); + + +} +#endif + +#if 0 //gerrit上段错误,暂且屏蔽 +// void downcaseWord(); + TEST_F(test_textedit, downcaseWord) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar();TextEdit *startManager = new TextEdit();startManager->setVerticalScrollBar(p); + EditWrapper * ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->downcaseWord(); + + +} +#endif + +// void capitalizeWord(); +// TEST_F(test_textedit, capitalizeWord) +//{ +// QList listSelection; +// QTextEdit::ExtraSelection selectio; +// QScrollBar *p = new QScrollBar();TextEdit *startManager = new TextEdit();startManager->setVerticalScrollBar(p); +// EditWrapper * ee = new EditWrapper(); +// Settings *s = new Settings(); +// startManager->setSettings(s); +// startManager->setWrapper(ee); +// startManager->capitalizeWord(); + +// +//} +// void transposeChar(); + +TEST_F(test_textedit, transposeChar) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->transposeChar(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void handleCursorMarkChanged(bool mark, QTextCursor cursor); +TEST_F(test_textedit, handleCursorMarkChanged) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->handleCursorMarkChanged(true, QTextCursor()); + startManager->handleCursorMarkChanged(false, QTextCursor()); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void adjustScrollbarMargins(); +TEST_F(test_textedit, adjustScrollbarMargins) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->adjustScrollbarMargins(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void onSelectionArea(); +TEST_F(test_textedit, onSelectionArea) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->onSelectionArea(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} +// void fingerZoom(QString name, QString direction, int fingers); +TEST_F(test_textedit, fingerZoom) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + startManager->fingerZoom("aa", "aa", 3); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// bool event(QEvent* evt) override; //触摸屏event事件 +TEST_F(test_textedit, event) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QEvent *e = new QEvent(QEvent::Type::MouseButtonPress); + startManager->event(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + delete e; + e = nullptr; + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + + +//TEST(UT_TextEdit_inputMethodEvent, UT_TextEdit_inputMethodEvent) + +// void mousePressEvent(QMouseEvent *e) override; +TEST_F(test_textedit, mousePressEvent) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPoint a(1, 2); + QPointF b(a); + QMouseEvent *e = new QMouseEvent(QMouseEvent::Type::Enter, b, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier); + startManager->mousePressEvent(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +TEST(UT_TextEdit_mousePressEvent, UT_TextEdit_mousePressEvent_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseButtonPress,QPointF(20.0,20.0),Qt::RightButton,Qt::RightButton,Qt::AltModifier); + + Stub s1; + s1.set(ADDR(QMouseEvent,source),retintstub); + + intvalue=2; + edit->m_bIsAltMod=true; + edit->m_bIsFindClose=true; + edit->mousePressEvent(e); + + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +// void mouseMoveEvent(QMouseEvent *e) override; +TEST_F(test_textedit, mouseMoveEvent) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPoint a(1, 2); + QPointF b(a); + QMouseEvent *e = new QMouseEvent(QMouseEvent::Type::Enter, b, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier); + startManager->mouseMoveEvent(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +TEST(UT_TextEdit_mouseMoveEvent, UT_TextEdit_mouseMoveEvent_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseMove,QPointF(20.0,20.0),Qt::LeftButton,Qt::LeftButton,Qt::AltModifier); + + Stub s1; + s1.set(ADDR(QMouseEvent,source),retintstub); + + intvalue=2; + edit->m_bIsAltMod=true; + edit->m_gestureAction == TextEdit::GA_slide; + edit->mouseMoveEvent(e); + + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} +// void mouseReleaseEvent(QMouseEvent *e) override; +TEST_F(test_textedit, mouseReleaseEvent) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPoint a(1, 2); + QPointF b(a); + QMouseEvent *e = new QMouseEvent(QMouseEvent::Type::Enter, b, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier); + startManager->mouseReleaseEvent(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +TEST(UT_TextEdit_mouseReleaseEvent, UT_TextEdit_mouseReleaseEvent_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseButtonRelease,QPointF(20.0,20.0),Qt::LeftButton,Qt::LeftButton,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(QMouseEvent,source),retintstub); + + intvalue = 2; + edit->mouseReleaseEvent(e); + + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +// void wheelEvent(QWheelEvent *e) override; +TEST_F(test_textedit, wheelEvent) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPointF pos; + QWheelEvent *e = new QWheelEvent(pos, 4, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::AltModifier); + + // QWheelEvent(const QPointF &pos, int delta, + // Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, + // Qt::Orientation orient = Qt::Vertical); + startManager->wheelEvent(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +QAction *stub_exec(const QPoint &pos, QAction *at = nullptr) +{ + Q_UNUSED(pos) + Q_UNUSED(at) + + return nullptr; +} +// void contextMenuEvent(QContextMenuEvent *event) override; + +TEST_F(test_textedit, contextMenuEvent) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + QPoint b(0, 0); + startManager->setSettings(s); + startManager->setWrapper(ee); + Stub stub; + stub.set((QAction * (QMenu::*)(const QPoint &, QAction *)) ADDR(QMenu, exec), stub_exec); + QContextMenuEvent *e = new QContextMenuEvent(QContextMenuEvent::Reason::Keyboard, b); + //startManager->contextMenuEvent(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void paintEvent(QPaintEvent *e) override; +TEST_F(test_textedit, paintEvent) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QRect a(1, 2, 3, 4); + QPaintEvent *e = new QPaintEvent(a); + startManager->paintEvent(e); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +TEST(UT_TextEdit_paintEvent, UT_TextEdit_paintEvent_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QPaintEvent* e = new QPaintEvent(QRect(20,20,20,20)); + + QTextEdit::ExtraSelection s1,s2; + edit->m_altModSelections.push_back(s1); + edit->m_altModSelections.push_back(s2); + edit->m_bIsAltMod = true; + + edit->paintEvent(e); + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +// bool blockContainStrBrackets(int line); +TEST_F(test_textedit, blockContainStrBrackets) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPaintEvent *e; + startManager->blockContainStrBrackets(2); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +TEST(UT_TextEdit_blockContainStrBrackets, UT_TextEdit_blockContainStrBrackets_002) +{ + TextEdit* edit = new TextEdit; + Stub s1; + s1.set((bool (QString::*) (QRegExp &) const )ADDR(QString,contains),rettruestub); + + edit->blockContainStrBrackets(1); + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); +} + +TEST(UT_TextEdit_blockContainStrBrackets, UT_TextEdit_blockContainStrBrackets_003) +{ + TextEdit* edit = new TextEdit; + Stub s1; + s1.set((bool (QString::*) (QRegExp &) const )ADDR(QString,contains),retfalsestub); + + edit->blockContainStrBrackets(1); + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); +} + +// bool setCursorKeywordSeletoin(int position, bool findNext); +TEST_F(test_textedit, setCursorKeywordSeletoin) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPaintEvent *e; + startManager->setCursorKeywordSeletoin(2, true); + startManager->setCursorKeywordSeletoin(2, false); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void cursorPositionChanged(); +TEST_F(test_textedit, cursorPositionChanged) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPaintEvent *e; + startManager->cursorPositionChanged(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// void cut(); +TEST_F(test_textedit, cut_normal_passed) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + QString strMsg("hello world\n" + "hello world"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->cut(); + + QString strRet1(pClipboard->text()); + QString strRet2(pWindow->currentWrapper()->textEditor()->toPlainText()); + EXPECT_EQ(strRet1, QString("hello world")); + EXPECT_EQ(strRet2, QString("hello world\n")); + pWindow->currentWrapper()->textEditor()->undo_(); + QString strRet3(pWindow->currentWrapper()->textEditor()->toPlainText()); + EXPECT_EQ(strRet3, strMsg); + + pWindow->deleteLater(); +} + +TEST_F(test_textedit, cut_withMultiByteText_passed) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + // 多字节字符编码 CJK + // 𢝐𢝑𢝒𢝓𢝔𢝕𢝖𢝗𢝘𢝙\n𢝚𢝛𢝜𢝝𢝞𢝟𢝠𢝡𢝢𢝣 + QString strMsg("\360\242\235\220\360\242\235\221\360\242\235\222\360\242\235\223\360\242\235\224" + "\360\242\235\225\360\242\235\226\360\242\235\227\360\242\235\230\360\242\235\231\n" + "\360\242\235\232\360\242\235\233\360\242\235\234\360\242\235\235\360\242\235\236" + "\360\242\235\237\360\242\235\240\360\242\235\241\360\242\235\242\360\242\235\243"); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + pWindow->currentWrapper()->textEditor()->insertTextEx(textCursor, strMsg); + + textCursor.setPosition(0); + textCursor.setPosition(6, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QClipboard *pClipboard = QApplication::clipboard(); + pClipboard->clear(); + pWindow->currentWrapper()->textEditor()->cut(); + + QString strRet1(pClipboard->text()); + QString strRet2(pWindow->currentWrapper()->textEditor()->toPlainText()); + EXPECT_EQ(strRet1, strMsg.leftRef(6)); + EXPECT_EQ(strRet2, strMsg.midRef(6)); + pWindow->currentWrapper()->textEditor()->undo_(); + QString strRet3(pWindow->currentWrapper()->textEditor()->toPlainText()); + EXPECT_EQ(strRet3, strMsg); + + pWindow->deleteLater(); +} + +// void updateHighlightBrackets(const QChar &openChar, const QChar &closeChar); +TEST_F(test_textedit, updateHighlightBrackets) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + QChar a = ' '; + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPaintEvent *e; + startManager->updateHighlightBrackets(a, a); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +// int getFirstVisibleBlockId() const; +TEST_F(test_textedit, getFirstVisibleBlockId) +{ + QList listSelection; + QTextEdit::ExtraSelection selectio; + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + EditWrapper *ee = new EditWrapper(); + Settings *s = new Settings(); + startManager->setSettings(s); + startManager->setWrapper(ee); + QPaintEvent *e; + //startManager->getFirstVisibleBlockId(); + + EXPECT_NE(ee->m_pTextEdit , nullptr); + s->deleteLater(); + ee->deleteLater(); + startManager->deleteLater(); + p->deleteLater(); +} + +//void setTruePath(QString qstrTruePath); +TEST_F(test_textedit, setBackupPath) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + startManager->setTruePath("aa"); + + ASSERT_TRUE(startManager->m_pLeftAreaWidget != nullptr); + startManager->deleteLater(); + p->deleteLater(); +} + +// QString getTruePath(); +TEST_F(test_textedit, getTruePath) +{ + QScrollBar *p = new QScrollBar(); + TextEdit *startManager = new TextEdit(); + startManager->setVerticalScrollBar(p); + startManager->getTruePath(); + + ASSERT_TRUE(startManager->m_pLeftAreaWidget != nullptr); + startManager->deleteLater(); + p->deleteLater(); +} + +////初始化右键菜单 +//void initRightClickedMenu(); +TEST_F(test_textedit, initRightClickedMenu) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->initRightClickedMenu(); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_canUndo == false); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_canRedo == false); + + pWindow->deleteLater(); +} + +//slotSigColorSelected +TEST_F(test_textedit, slotSigColorSelected) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->slotSigColorSelected(true, QColor("red")); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_rightMenu != nullptr); + + pWindow->deleteLater(); +} + +//slotSigColorAllSelected +TEST_F(test_textedit, slotSigColorAllSelected) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->slotSigColorAllSelected(true, QColor("red")); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_rightMenu != nullptr); + + pWindow->deleteLater(); +} + +//slotCutAction +TEST_F(test_textedit, slotCutAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + QString strBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->slotCutAction(true); + QString strAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(strBefore.compare(strAfter)); + + pWindow->deleteLater(); +} + +//slotCopyAction +TEST_F(test_textedit, slotCopyAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotCopyAction(true); + QClipboard *pClipboard = QApplication::clipboard(); + QString strRet(pClipboard->text()); + ASSERT_TRUE(!strRet.compare(QString("Holle world."))); + + pWindow->deleteLater(); +} + +//slotPasteAction +TEST_F(test_textedit, slotPasteAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotCopyAction(true); + QString strBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + textCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotPasteAction(true); + QString strAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(strBefore.compare(strAfter)); + + pWindow->deleteLater(); +} + +//slotDeleteAction 001 +TEST_F(test_textedit, slotDeleteAction_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotSelectAllAction(true); + QString strBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->slotDeleteAction(true); + QString strAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(strBefore.compare(strAfter)); + + pWindow->deleteLater(); +} + +//slotDeleteAction 002 +TEST_F(test_textedit, slotDeleteAction_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QString strBefore(pWindow->currentWrapper()->textEditor()->toPlainText()); + pWindow->currentWrapper()->textEditor()->slotDeleteAction(true); + QString strAfter(pWindow->currentWrapper()->textEditor()->toPlainText()); + ASSERT_TRUE(!strBefore.compare(strAfter)); + + pWindow->deleteLater(); +} + +//slotSelectAllAction +TEST_F(test_textedit, slotSelectAllAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotSelectAllAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_isSelectAll; + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotOpenInFileManagerAction +TEST_F(test_textedit, slotOpenInFileManagerAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QString strRet(pWindow->currentWrapper()->textEditor()->getTruePath()); + ASSERT_TRUE(!strRet.isEmpty()); + + pWindow->deleteLater(); +} + +//slotAddComment +TEST_F(test_textedit, slotAddComment) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotAddComment(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_commentDefinition.isValid(); + ASSERT_TRUE(bRet == false); + + pWindow->deleteLater(); +} + +//slotCancelComment +TEST_F(test_textedit, slotCancelComment) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotCancelComment(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_commentDefinition.isValid(); + ASSERT_TRUE(bRet == false); + + pWindow->deleteLater(); +} + +//slotVoiceReadingAction +TEST_F(test_textedit, slotVoiceReadingAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotVoiceReadingAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotStopReadingAction +TEST_F(test_textedit, slotStopReadingAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotStopReadingAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotdictationAction +TEST_F(test_textedit, slotdictationAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotdictationAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotColumnEditAction +TEST_F(test_textedit, slotColumnEditAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + QTextCursor textCursor = pWindow->currentWrapper()->textEditor()->textCursor(); + textCursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); + pWindow->currentWrapper()->textEditor()->setTextCursor(textCursor); + pWindow->currentWrapper()->textEditor()->slotColumnEditAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->textCursor().hasSelection(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotPreBookMarkAction 001 +TEST_F(test_textedit, slotPreBookMarkAction_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->m_mouseClickPos = QPoint(0, 0); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(1); + pWindow->currentWrapper()->textEditor()->slotPreBookMarkAction(true); + int iRet = pWindow->currentWrapper()->textEditor()->m_listBookmark.indexOf(1); + ASSERT_TRUE(iRet == 0); + + pWindow->deleteLater(); +} + +//slotPreBookMarkAction 002 +TEST_F(test_textedit, slotPreBookMarkAction_002) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.")); + pWindow->currentWrapper()->textEditor()->m_mouseClickPos = QPoint(0, 0); + pWindow->currentWrapper()->textEditor()->slotPreBookMarkAction(true); + int iRet = pWindow->currentWrapper()->textEditor()->m_listBookmark.indexOf(1); + ASSERT_TRUE(iRet != 0); + + pWindow->deleteLater(); +} + +void slotNextBookMarkAction_001_jumpToLine_stub() +{ + return; +} + +//slotNextBookMarkAction 001 +TEST_F(test_textedit, slotNextBookMarkAction_001) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->m_mouseClickPos = QPoint(0, 0); + pWindow->currentWrapper()->textEditor()->m_listBookmark.append(2); + Stub jumpToLine_stub; + jumpToLine_stub.set(ADDR(TextEdit, jumpToLine), slotNextBookMarkAction_001_jumpToLine_stub); + pWindow->currentWrapper()->textEditor()->slotNextBookMarkAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty(); + ASSERT_TRUE(bRet == false); + + pWindow->deleteLater(); +} + +//slotClearBookMarkAction +TEST_F(test_textedit, slotClearBookMarkAction) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotClearBookMarkAction(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_listBookmark.isEmpty(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotFlodAllLevel +TEST_F(test_textedit, slotFlodAllLevel) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotFlodAllLevel(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_listMainFlodAllPos.isEmpty(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotUnflodAllLevel +TEST_F(test_textedit, slotUnflodAllLevel) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotUnflodAllLevel(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_listMainFlodAllPos.isEmpty(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotFlodCurrentLevel +TEST_F(test_textedit, slotFlodCurrentLevel) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotFlodCurrentLevel(true); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget != nullptr); + + pWindow->deleteLater(); +} + +//slotUnflodCurrentLevel +TEST_F(test_textedit, slotUnflodCurrentLevel) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotUnflodCurrentLevel(true); + ASSERT_TRUE(pWindow->currentWrapper()->textEditor()->m_pLeftAreaWidget != nullptr); + + pWindow->deleteLater(); +} + +//slotCancleMarkAllLine +TEST_F(test_textedit, slotCancleMarkAllLine) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotCancleMarkAllLine(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotCancleLastMark +TEST_F(test_textedit, slotCancleLastMark) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotCancleLastMark(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_markOperations.isEmpty(); + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotUndoAvailable +TEST_F(test_textedit, slotUndoAvailable) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotUndoAvailable(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_canUndo; + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +//slotRedoAvailable +TEST_F(test_textedit, slotRedoAvailable) +{ + Window *pWindow = new Window(); + pWindow->addBlankTab(QString()); + pWindow->currentWrapper()->textEditor()->insertTextEx(pWindow->currentWrapper()->textEditor()->textCursor(), + QString("Holle world.\nHolle world.")); + pWindow->currentWrapper()->textEditor()->slotRedoAvailable(true); + bool bRet = pWindow->currentWrapper()->textEditor()->m_canRedo; + ASSERT_TRUE(bRet == true); + + pWindow->deleteLater(); +} + +/* + void unCommentSelection(); + void setComment(); + void removeComment(); +*/ + +TEST_F(test_textedit, unCommentSelection) +{ + EditWrapper *editWrapper = new EditWrapper; + editWrapper->openFile("1.cpp", "1.cpp"); + QTextCursor cursor = editWrapper->m_pTextEdit->textCursor(); + cursor.setPosition(0, QTextCursor::MoveAnchor); + editWrapper->m_pTextEdit->setTextCursor(cursor); + editWrapper->m_pTextEdit->unCommentSelection(); + + EXPECT_NE(editWrapper->m_pTextEdit , nullptr); + editWrapper->deleteLater(); +} + +TEST(UT_TextEdit_unCommentSelection, UT_TextEdit_unCommentSelection_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,hasSelection),rettruestub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,hasMultiLineStyle),rettruestub); + Stub s4; + s4.set(ADDR(QString,length),retintstub); + Stub s5; + s5.set(ADDR(TextEdit,isComment),rettruestub); + Stub s6; + s6.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s7; + s7.set(ADDR(TextEdit,insertTextEx),rettruestub); + + + intvalue = -1000; + edit->unCommentSelection(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_TextEdit_unCommentSelection, UT_TextEdit_unCommentSelection_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,hasSelection),retfalsestub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,hasSingleLineStyle),retfalsestub); + Stub s4; + s4.set(ADDR(QString,length),retintstub); + Stub s5; + s5.set(ADDR(TextEdit,isComment),rettruestub); + Stub s6; + s6.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),rettruestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,endsWith),rettruestub); + Stub s8; + s8.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s9; + s9.set(ADDR(TextEdit,insertTextEx),rettruestub); + + intvalue = -1000; + edit->unCommentSelection(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_TextEdit_unCommentSelection, UT_TextEdit_unCommentSelection_004) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,hasSelection),retfalsestub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,hasSingleLineStyle),retfalsestub); + Stub s4; + s4.set(ADDR(QString,length),retintstub); + Stub s5; + s5.set(ADDR(TextEdit,isComment),rettruestub); + Stub s6; + s6.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),retfalsestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,endsWith),retfalsestub); + Stub s8; + s8.set(ADDR(QString,isEmpty),retfalsestub); + Stub s9; + s9.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s10; + s10.set(ADDR(TextEdit,insertTextEx),rettruestub); + + intvalue = -1000; + edit->unCommentSelection(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_TextEdit_unCommentSelection, UT_TextEdit_unCommentSelection_005) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,hasSelection),retfalsestub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,hasSingleLineStyle),retfalsestub); + Stub s4; + s4.set(ADDR(QString,length),retintstub); + Stub s5; + s5.set(ADDR(TextEdit,isComment),rettruestub); + Stub s6; + s6.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),retfalsestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,endsWith),retfalsestub); + Stub s8; + s8.set(ADDR(QString,isEmpty),rettruestub); + Stub s9; + s9.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s10; + s10.set(ADDR(TextEdit,insertTextEx),rettruestub); + + intvalue = -1000; + edit->unCommentSelection(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + + +TEST_F(test_textedit, setComment) +{ + EditWrapper *editWrapper = new EditWrapper; + editWrapper->openFile("1.cpp", "1.cpp"); + QTextCursor cursor = editWrapper->m_pTextEdit->textCursor(); + cursor.setPosition(0, QTextCursor::MoveAnchor); + editWrapper->m_pTextEdit->setTextCursor(cursor); + editWrapper->m_pTextEdit->setComment(); + + EXPECT_NE(editWrapper->m_pTextEdit , nullptr); + editWrapper->deleteLater(); +} + +TEST(UT_TextEdit_setComment, UT_TextEdit_setComment_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,isNull),retfalsestub); + Stub s3; + s3.set(ADDR(QTextCursor,hasSelection),rettruestub); + Stub s4; + s4.set(ADDR(Comment::CommentDefinition,hasMultiLineStyle),rettruestub); + Stub s5; + s5.set(ADDR(QString,length),retintstub); + Stub s6; + s6.set(ADDR(TextEdit,isComment),rettruestub); + Stub s7; + s7.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s8; + s8.set(ADDR(TextEdit,insertTextEx),rettruestub); + + + intvalue = -1000; + edit->setComment(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_TextEdit_setComment, UT_TextEdit_setComment_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,isNull),retfalsestub); + Stub s3; + s3.set(ADDR(QTextCursor,hasSelection),retfalsestub); + Stub s4; + s4.set(ADDR(Comment::CommentDefinition,hasSingleLineStyle),retfalsestub); + Stub s5; + s5.set(ADDR(QString,length),retintstub); + Stub s6; + s6.set(ADDR(TextEdit,isComment),rettruestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),rettruestub); + Stub s8; + s8.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,endsWith),rettruestub); + Stub s9; + s9.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s10; + s10.set(ADDR(TextEdit,insertTextEx),rettruestub); + + + intvalue = -1000; + edit->setComment(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_TextEdit_setComment, UT_TextEdit_setComment_004) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,isNull),retfalsestub); + Stub s3; + s3.set(ADDR(QTextCursor,hasSelection),retfalsestub); + Stub s4; + s4.set(ADDR(Comment::CommentDefinition,hasSingleLineStyle),retfalsestub); + Stub s5; + s5.set(ADDR(QString,length),retintstub); + Stub s6; + s6.set(ADDR(TextEdit,isComment),rettruestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),retfalsestub); + Stub s8; + s8.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,endsWith),retfalsestub); + Stub s9; + s9.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s10; + s10.set(ADDR(TextEdit,insertTextEx),rettruestub); + + + intvalue = -1000; + edit->setComment(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST_F(test_textedit, removeComment) +{ + EditWrapper *editWrapper = new EditWrapper; + editWrapper->openFile("1.cpp", "1.cpp"); + QTextCursor cursor = editWrapper->m_pTextEdit->textCursor(); + cursor.setPosition(0, QTextCursor::MoveAnchor); + editWrapper->m_pTextEdit->setTextCursor(cursor); + editWrapper->m_pTextEdit->removeComment(); + + EXPECT_NE(editWrapper->m_pTextEdit , nullptr); + editWrapper->deleteLater(); +} + +TEST(UT_Textedit_removeComment, UT_Textedit_removeComment_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,hasSelection),rettruestub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,hasMultiLineStyle),rettruestub); + Stub s4; + s4.set(ADDR(QString,length),retintstub); + Stub s5; + s5.set(ADDR(TextEdit,isComment),rettruestub); + Stub s6; + s6.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s7; + s7.set(ADDR(TextEdit,insertTextEx),rettruestub); + + intvalue = -1000; + edit->removeComment(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_removeComment, UT_Textedit_removeComment_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + Stub s1; + s1.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s2; + s2.set(ADDR(QTextCursor,hasSelection),retfalsestub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,hasSingleLineStyle),retfalsestub); + Stub s4; + s4.set(ADDR(QString,length),retintstub); + Stub s5; + s5.set(ADDR(TextEdit,isComment),rettruestub); + Stub s6; + s6.set(ADDR(TextEdit,deleteTextEx),rettruestub); + Stub s7; + s7.set(ADDR(TextEdit,insertTextEx),rettruestub); + + intvalue = -1000; + edit->removeComment(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST_F(test_textedit, keyPressEvent) +{ + Window *window = new Window; + EditWrapper *editWrapper = window->createEditor(); + editWrapper->openFile("1.cpp", "1.cpp"); + QTextCursor cursor = editWrapper->m_pTextEdit->textCursor(); + cursor.setPosition(0, QTextCursor::MoveAnchor); + editWrapper->m_pTextEdit->setTextCursor(cursor); + QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Insert, Qt::NoModifier); + editWrapper->m_pTextEdit->keyPressEvent(&keyEvent); + + EXPECT_NE(editWrapper->m_pTextEdit , nullptr); + editWrapper->deleteLater(); + window->deleteLater(); +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,copy),rettruestub); + + string1 = "e"; + string2 = "e"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,nextLine),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "J"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_004) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,prevLine),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "K"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_005) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,moveToEnd),rettruestub); + + edit->m_readOnlyMode=true; + string1 = ","; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_006) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,moveToStart),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "."; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_007) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,backwardChar),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "H"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_008) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,forwardChar),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "L"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_009) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,scrollUp),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "space"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_010) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,scrollDown),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "V"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_011) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,forwardWord),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "F"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_012) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,backwardWord),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "B"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_013) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,moveToStartOfLine),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "A"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_014) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,moveToEndOfLine),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "E"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_015) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,moveToLineIndentation),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "M"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_016) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,toggleReadOnlyMode),rettruestub); + + edit->m_readOnlyMode=true; + edit->m_bReadOnlyPermission=false; + string1 = "Q"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_017) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,scrollLineUp),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "Shfit+J"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_018) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,scrollLineDown),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "Shfit+K"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_019) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit,forwardPair),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "P"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_020) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, backwardPair),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "N"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_021) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, copyLines),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "Shift+:"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_022) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_H,Qt::ControlModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, copyLines),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "Shift+/"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_023) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_Control,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, copyLines),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_024) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_F11,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, copyLines),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_025) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_F1,Qt::NoModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, popupNotify),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_026) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_F1,Qt::GroupSwitchModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, popupNotify),rettruestub); + + edit->m_readOnlyMode=true; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_027) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_F1,Qt::GroupSwitchModifier); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, isReadOnly),rettruestub); + + + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_028) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_ydiaeresis,Qt::NoModifier,"123"); + + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_029) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress,Qt::Key_9,Qt::KeypadModifier,"123"); + + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_030) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Tab,Qt::NoModifier,"123"); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +//if (modifiers == Qt::NoModifier && (e->key() == Qt::Key_Backspace)) +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_031) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Backspace,Qt::NoModifier,"123"); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_032) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete,Qt::NoModifier,"123"); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + s4.set(ADDR(QUndoStack,push),rettruestub); + + QTextEdit::ExtraSelection e1,e2; + edit->m_altModSelections.push_back(e1); + edit->m_altModSelections.push_back(e2); + edit->m_bIsAltMod=true; + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_033) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Delete,Qt::NoModifier,"123"); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + + QTextEdit::ExtraSelection e1,e2; + edit->m_altModSelections.push_back(e1); + edit->m_altModSelections.push_back(e2); + edit->m_bIsAltMod=false; + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_034) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Shift,Qt::ShiftModifier,"123"); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + Stub s2; + s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_035) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + s4.set(ADDR(TextEdit,undo_),retfalsestub); + s4.set(ADDR(TextEdit,redo_),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "undo"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_036) +{ +// TextEdit* edit = new TextEdit; +// EditWrapper* wra = new EditWrapper; +// edit->m_wrapper = wra; +// QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); +// edit->m_settings = Settings::instance(); + +// Stub s1; +// s1.set(ADDR(Utils,getKeyshortcut),retstring1); +// //Stub s2; +// //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); +// Stub s3; +// s3.set(ADDR(TextEdit, insertColumnEditTextEx),retfalsestub); +// Stub s4; +// s4.set(ADDR(TextEdit, insertSelectTextEx),retfalsestub); + +// edit->m_readOnlyMode = false; +// edit->m_bReadOnlyPermission=false; +// string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "redo"); +// //string2 = "789"; +// edit->keyPressEvent(e); + +// EXPECT_NE(edit , nullptr); +// edit->deleteLater(); +// wra->deleteLater(); +// delete e; +// e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_037) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, cut),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "cut"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_038) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, paste),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "paste"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_039) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, scrollUp),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "scrollup"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_040) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, scrollDown),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "scrolldown"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_041) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, copyLines),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "copylines"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_042) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, cutlines),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "cutlines"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_043) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + //s3.set(ADDR(TextEdit, indentline),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "indentline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_044) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, unindentText),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "backindentline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_045) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, forwardChar),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "forwardchar"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_046) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, backwardWord),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "backwardword"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_047) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, nextLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "nextline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_048) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, prevLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "prevline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_049) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, newline),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "newline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_050) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, openNewlineAbove),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "opennewlineabove"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_051) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, openNewlineBelow),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "opennewlinebelow"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_052) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, duplicateLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "duplicateline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_053) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, killLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "killline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_054) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, killCurrentLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "killcurrentline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_055) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveLineDownUp),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "swaplineup"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_056) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveLineDownUp),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "swaplinedown"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_057) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, scrollLineUp),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "scrolllineup"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_058) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, scrollLineDown),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "scrolllinedown"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_059) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, scrollUp),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "scrollup"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_060) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, scrollDown),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "scrolldown"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_061) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveToEndOfLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetoendofline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_062) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveToStartOfLine),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetostartofline"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_063) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveToStart),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetostart"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_064) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveToEnd),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetoend"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_065) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, moveToLineIndentation),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetolineindentation"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_066) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, upcaseWord),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "upcaseword"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_067) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, downcaseWord),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "downcaseword"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_068) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, capitalizeWord),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "capitalizeword"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_069) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, killBackwardWord),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "killbackwardword"); + //string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_070) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_ydiaeresis + 3,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + + Stub s3; + s3.set(ADDR(TextEdit, killForwardWord),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "killforwardword"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, forwardPair),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "forwardpair"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, backwardPair),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "backwardpair"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, transposeChar),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "transposechar"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, setMark),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "setmark"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, exchangeMark),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "exchangemark"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, joinLines),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "joinlines"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, toggleReadOnlyMode),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "togglereadonlymode"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, toggleReadOnlyMode),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "togglereadonlymode"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, toggleComment),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "togglecomment"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, addOrDeleteBookMark),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "switchbookmark"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, moveToPreviousBookMark),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetoprebookmark"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, moveToNextBookMark),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "movetonextbookmark"); + edit->keyPressEvent(e); + + s3.set(ADDR(TextEdit, toggleMarkSelections),retfalsestub); + string1 = Utils::getKeyshortcutFromKeymap(edit->m_settings, "editor", "mark"); + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_071) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Insert,Qt::NoModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, overwriteMode),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "987"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + +TEST(UT_TextEdit_KeyPressEvent, UT_TextEdit_KeyPressEvent_072) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_Insert,Qt::GroupSwitchModifier,"123"); + edit->m_settings = Settings::instance(); + + Stub s1; + s1.set(ADDR(Utils,getKeyshortcut),retstring1); + //Stub s2; + //s2.set(ADDR(Utils,getKeyshortcutFromKeymap),retstring2); + Stub s3; + s3.set(ADDR(TextEdit, overwriteMode),retfalsestub); + + edit->m_readOnlyMode = false; + edit->m_bReadOnlyPermission=false; + string1 = "Shift+Ins"; + string2 = "789"; + edit->keyPressEvent(e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e=nullptr; +} + + +TEST(UT_Textedit_resizeEvent, UT_Textedit_resizeEvent) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QResizeEvent* r = new QResizeEvent(QSize(30,30),QSize(20,20)); + + + edit->m_isSelectAll = true; + edit->resizeEvent(r); + + edit->m_isSelectAll = false; + edit->resizeEvent(r); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete r; + r = nullptr; +} + +TEST(UT_Textedit_dragMoveEvent, UT_Textedit_dragMoveEvent) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMimeData* data = new QMimeData(); + data->setText("ddd"); + QDragMoveEvent* r = new QDragMoveEvent(QPoint(20,20),Qt::ActionMask,data,Qt::LeftButton,Qt::NoModifier); + + + QList urls = {{"123"},{"456"}}; + data->setUrls(urls); + edit->m_readOnlyMode = false; + edit->dragMoveEvent(r); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + data->deleteLater(); + delete r; + r = nullptr; +} + + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_001) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QTouchEvent* e = new QTouchEvent(QEvent::TouchBegin); + + + edit->eventFilter(wra,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + delete e; + e = nullptr; +} + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseButtonPress,QPointF(20.0,20.0),Qt::RightButton,Qt::RightButton,Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + intvalue=1; + edit->eventFilter(edit->m_pLeftAreaWidget->m_pBookMarkArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseButtonPress,QPointF(20.0,20.0),Qt::LeftButton,Qt::LeftButton,Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + Stub s2; + s2.set(ADDR(TextEdit,renderAllSelections),retintstub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s4; + s4.set(ADDR(QTextBlock,isVisible),rettruestub); + Stub s5; + //inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + s5.set((bool (QString::*)(const QStringRef &, Qt::CaseSensitivity) const) ADDR(QString,contains),rettruestub); + Stub s6; + //s6.set(ADDR(QString,isEmpty),retfalsestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),rettruestub); + Stub s8; + s8.set((bool (QString::*)(const QString &, Qt::CaseSensitivity) const) ADDR(QString,contains),rettruestub); + + + intvalue=1; + edit->eventFilter(edit->m_pLeftAreaWidget->m_pFlodArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_004) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseButtonPress,QPointF(20.0,20.0),Qt::LeftButton,Qt::LeftButton,Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + Stub s2; + s2.set(ADDR(TextEdit,renderAllSelections),retintstub); + Stub s3; + s3.set(ADDR(Comment::CommentDefinition,isValid),rettruestub); + Stub s4; + s4.set(ADDR(QTextBlock,isVisible),retfalsestub); + Stub s5; + //inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const; + s5.set((bool (QString::*)(const QStringRef &, Qt::CaseSensitivity) const) ADDR(QString,contains),rettruestub); + Stub s6; + // s6.set(ADDR(QString,isEmpty),retfalsestub); + Stub s7; + s7.set((bool (QString::*) (const QString &, Qt::CaseSensitivity) const )ADDR(QString,startsWith),retfalsestub); + Stub s8; + s8.set((bool (QString::*)(const QString &, Qt::CaseSensitivity) const) ADDR(QString,contains),rettruestub); + + + intvalue=1; + edit->eventFilter(edit->m_pLeftAreaWidget->m_pFlodArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + + + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_005) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QMouseEvent* e = new QMouseEvent(QEvent::MouseButtonPress,QPointF(20.0,20.0),Qt::RightButton,Qt::RightButton,Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + Stub s2; + s2.set(ADDR(QList,contains),rettruestub); + Stub s3; + s3.set(ADDR(QTextBlock,isVisible),rettruestub); + + intvalue=1; + edit->m_listMainFlodAllPos.push_back(1); + edit->eventFilter(edit->m_pLeftAreaWidget->m_pFlodArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_006) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QHoverEvent* e = new QHoverEvent(QEvent::HoverMove,QPointF(20.0,20.0),QPointF(30.0,30.0),Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + Stub s2; + s2.set(ADDR(QList,contains),rettruestub); + Stub s3; + s3.set(ADDR(QTextBlock,isVisible),retfalsestub); + Stub s4; + s4.set(ADDR(TextEdit,getHideRowContent),rettruestub); + Stub s5; + s5.set(ADDR(TextEdit,getLinePosYByLineNum),rettruestub); + + intvalue=1; + edit->m_listMainFlodAllPos.push_back(1); + edit->eventFilter(edit->m_pLeftAreaWidget->m_pFlodArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_007) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QHoverEvent* e = new QHoverEvent(QEvent::HoverMove,QPointF(20.0,20.0),QPointF(30.0,30.0),Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + Stub s2; + s2.set(ADDR(QList,contains),rettruestub); + Stub s3; + s3.set(ADDR(QTextBlock,isVisible),rettruestub); + Stub s4; + s4.set(ADDR(TextEdit,getHideRowContent),rettruestub); + Stub s5; + s5.set(ADDR(TextEdit,getHighLightRowContentLineNum),retintstub); + + + intvalue=4; + edit->m_listMainFlodAllPos.push_back(1); + edit->eventFilter(edit->m_pLeftAreaWidget->m_pFlodArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_008) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QHoverEvent* e = new QHoverEvent(QEvent::HoverLeave,QPointF(20.0,20.0),QPointF(30.0,30.0),Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + Stub s2; + s2.set(ADDR(QList,contains),rettruestub); + Stub s3; + s3.set(ADDR(QTextBlock,isVisible),rettruestub); + Stub s4; + s4.set(ADDR(TextEdit,getHideRowContent),rettruestub); + Stub s5; + s5.set(ADDR(TextEdit,getHighLightRowContentLineNum),retintstub); + + + intvalue=4; + edit->m_listMainFlodAllPos.push_back(1); + edit->eventFilter(edit->m_pLeftAreaWidget->m_pBookMarkArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_009) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QHoverEvent* e = new QHoverEvent(QEvent::HoverLeave,QPointF(20.0,20.0),QPointF(30.0,30.0),Qt::NoModifier); + + edit->m_rightMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + Stub s2; + s2.set(ADDR(QList,contains),rettruestub); + Stub s3; + s3.set(ADDR(QTextBlock,isVisible),rettruestub); + Stub s4; + s4.set(ADDR(TextEdit,getHideRowContent),rettruestub); + Stub s5; + s5.set(ADDR(TextEdit,getHighLightRowContentLineNum),retintstub); + + + intvalue=4; + edit->m_listMainFlodAllPos.push_back(1); + edit->eventFilter(edit->m_pLeftAreaWidget->m_pFlodArea,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + + +TEST(UT_Textedit_eventFilter, UT_Textedit_eventFilter_010) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QKeyEvent* e = new QKeyEvent(QEvent::KeyRelease,Qt::Key_Tab,Qt::NoModifier); + + edit->m_colorMarkMenu = new QMenu; + // QAction *exec(const QPoint &pos, QAction *at = nullptr); + typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); + fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); + Stub s1; + s1.set(A_foo,retintstub); + + Stub s2; + s2.set(ADDR(QList,contains),rettruestub); + Stub s3; + s3.set(ADDR(QTextBlock,isVisible),rettruestub); + Stub s4; + s4.set(ADDR(TextEdit,getHideRowContent),rettruestub); + Stub s5; + s5.set(ADDR(TextEdit,getHighLightRowContentLineNum),retintstub); + + + intvalue=4; + edit->m_listMainFlodAllPos.push_back(1); + edit->eventFilter(edit->m_colorMarkMenu,e); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + edit->m_rightMenu->deleteLater(); + delete e; + e = nullptr; +} + + +TEST(UT_Textedit_updateMark, UT_Textedit_updateMark_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QTextEdit::ExtraSelection e1,e2; + //QList>; + edit->m_wordMarkSelections.push_back({e1,1}); + edit->m_wordMarkSelections.push_back({e2,2}); + + Stub s1; + s1.set(ADDR(QTextCursor,selectionEnd),retintstub); + Stub s2; + s2.set(ADDR(QTextCursor,selectionStart),retintstub2); + + intvalue=10000; + intvalue2=-10000; + edit->m_bIsInputMethod = true; + edit->updateMark(1,2,3); + + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_updateMark, UT_Textedit_updateMark_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QTextEdit::ExtraSelection e1,e2; + //QList>; + edit->m_wordMarkSelections.push_back({e1,1}); + edit->m_wordMarkSelections.push_back({e2,2}); + + Stub s1; + s1.set(ADDR(QTextCursor,selectionEnd),retintstub); + Stub s2; + s2.set(ADDR(QTextCursor,selectionStart),retintstub2); + + intvalue=10000; + intvalue2=-10000; + edit->m_bIsInputMethod = false; + edit->updateMark(1,2,3); + + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + + +TEST(UT_Textedit_updateMark, UT_Textedit_updateMark_004) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QTextEdit::ExtraSelection e1,e2; + //QList>; + edit->m_wordMarkSelections.push_back({e1,1}); + edit->m_wordMarkSelections.push_back({e2,2}); + edit->m_mapWordMarkSelections[1]={e1}; + + Stub s1; + s1.set(ADDR(QTextCursor,selectionEnd),retintstub); + Stub s2; + s2.set(ADDR(QTextCursor,selectionStart),retintstub2); + Stub s3; + s3.set(ADDR(QTextCursor,position),retintstub); + + intvalue=10000; + intvalue2=10000; + edit->m_bIsInputMethod = true; + edit->updateMark(1,2,3); + + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_clearMarksForTextCursor, UT_Textedit_clearMarksForTextCursor_001) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QTextEdit::ExtraSelection e1,e2; + //QList>; + edit->m_wordMarkSelections.push_back({e1,1}); + edit->m_wordMarkSelections.push_back({e2,2}); + + Stub s1; + s1.set(ADDR(QTextCursor,hasSelection),rettruestub); + + edit->clearMarksForTextCursor(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + + +TEST(UT_Textedit_clearMarksForTextCursor, UT_Textedit_clearMarksForTextCursor_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QTextEdit::ExtraSelection e1,e2; + //QList>; + edit->m_wordMarkSelections.push_back({e1,1}); + edit->m_wordMarkSelections.push_back({e2,2}); + + Stub s0; + s0.set(ADDR(QTextCursor,hasSelection),retfalsestub); + + Stub s1; + s1.set(ADDR(QTextCursor,selectionEnd),retintstub); + Stub s2; + s2.set(ADDR(QTextCursor,selectionStart),retintstub2); + Stub s3; + s3.set(ADDR(QTextCursor,position),retintstub); + + intvalue=10; + intvalue2=10; + edit->clearMarksForTextCursor(); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + + +TEST(UT_Textedit_clearMarkOperationForCursor, UT_Textedit_clearMarkOperationForCursor_001) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + TextEdit::MarkOperation e1,e2; + //QList>; + edit->m_markOperations.push_back({e1,1}); + edit->m_markOperations.push_back({e2,2}); + + Stub s1; + s1.set(ADDR(QTextCursor,hasSelection),rettruestub); + + edit->clearMarkOperationForCursor(e1.cursor); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); +} + + +TEST(UT_Textedit_tapAndHoldGestureTriggered, UT_Textedit_tapAndHoldGestureTriggered_001) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QTapAndHoldGesture * t = new QTapAndHoldGesture(); + + Stub s1; + s1.set(ADDR(QTapAndHoldGesture,state),retintstub); + + intvalue = 0; + edit->tapAndHoldGestureTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_tapAndHoldGestureTriggered, UT_Textedit_tapAndHoldGestureTriggered_002) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QTapAndHoldGesture * t = new QTapAndHoldGesture(); + + Stub s1; + s1.set(ADDR(QTapAndHoldGesture,state),retintstub); + + intvalue = 1; + edit->tapAndHoldGestureTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_tapAndHoldGestureTriggered, UT_Textedit_tapAndHoldGestureTriggered_003) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QTapAndHoldGesture * t = new QTapAndHoldGesture(); + + Stub s1; + s1.set(ADDR(QTapAndHoldGesture,state),retintstub); + + intvalue = 2; + edit->tapAndHoldGestureTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_tapAndHoldGestureTriggered, UT_Textedit_tapAndHoldGestureTriggered_004) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QTapAndHoldGesture * t = new QTapAndHoldGesture(); + + Stub s1; + s1.set(ADDR(QTapAndHoldGesture,state),retintstub); + + intvalue = 3; + edit->tapAndHoldGestureTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_tapAndHoldGestureTriggered, UT_Textedit_tapAndHoldGestureTriggered_005) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QTapAndHoldGesture * t = new QTapAndHoldGesture(); + + Stub s1; + s1.set(ADDR(QTapAndHoldGesture,state),retintstub); + + intvalue = 4; + edit->tapAndHoldGestureTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_panTriggered, UT_Textedit_panTriggered_001) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QPanGesture * t = new QPanGesture(); + + Stub s1; + s1.set(ADDR(QPanGesture,state),retintstub); + + intvalue = 4; + edit->panTriggered(t); + intvalue = 3; + edit->panTriggered(t); + intvalue = 2; + edit->panTriggered(t); + intvalue = 1; + edit->panTriggered(t); + intvalue = 0; + edit->panTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + + +TEST(UT_Textedit_pinchTriggered, UT_Textedit_pinchTriggered_001) +{ + Window* w = new Window; + TextEdit* edit = new TextEdit(w); + EditWrapper* wra = new EditWrapper(w); + edit->m_wrapper = wra; + QPinchGesture* t = new QPinchGesture(); + + + Stub s1; + s1.set(ADDR(QPanGesture,state),retintstub); + + intvalue = 4; + edit->pinchTriggered(t); + intvalue = 3; + edit->pinchTriggered(t); + intvalue = 2; + edit->pinchTriggered(t); + intvalue = 1; + edit->pinchTriggered(t); + intvalue = 0; + edit->pinchTriggered(t); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + w->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_swipeTriggered, UT_Textedit_swipeTriggered_001) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + QPinchGesture* t = new QPinchGesture(); + + + edit->swipeTriggered(nullptr); + + EXPECT_NE(edit , nullptr); + edit->deleteLater(); + wra->deleteLater(); + t->deleteLater(); +} + +TEST(UT_Textedit_popRightMenu, UT_Textedit_popRightMenu_001) +{ +// Window* w = new Window; +// TextEdit* edit = new TextEdit(w); +// EditWrapper* wra = new EditWrapper(w); +// edit->m_wrapper = wra; + +// edit->m_rightMenu = new QMenu; +// // QAction *exec(const QPoint &pos, QAction *at = nullptr); +// typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); +// fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); +// Stub s1; +// s1.set(A_foo,retintstub); + +// Stub s2; +// s2.set(ADDR(QUndoStack,canUndo),rettruestub); +// Stub s3; +// s3.set(ADDR(QUndoStack,canRedo),rettruestub); +// Stub s4; +// s4.set(ADDR(QTextCursor,hasSelection),rettruestub); +// Stub s5; +// s5.set(ADDR(TextEdit,canPaste),rettruestub); +// Stub s6; +// s6.set(ADDR(QTextDocument,isEmpty),retfalsestub); +// Stub s7; +// s7.set(ADDR(TextEdit,characterCount),retintstub); +// Stub s8; +// s8.set(ADDR(QString,isEmpty),retfalsestub); +// Stub s9; +// s9.set(ADDR(TextEdit,renderAllSelections),rettruestub); +// //s9.set(ADDR(QDBusConnection,call),rettruestub); +// s9.set(ADDR(QDBusConnection,sessionBus),sessionBusstub); +// //inline QDBusReply& operator=(const QDBusMessage & dbusError) +// // s9.set((QDBusReply& (QDBusReply::*) (const QDBusMessage &))ADDR(QDBusReply,operator=), rettruestub); +// //inline QDBusReply& operator=(const QDBusError& dbusError) +// // s9.set((QDBusReply& (QDBusReply::*) (const QDBusError &))ADDR(QDBusReply,operator=), rettruestub); + +// intvalue=1; +// edit->m_bReadOnlyPermission = false; +// edit->popRightMenu(QPoint(10,10)); + +// EXPECT_NE(edit , nullptr); +// edit->deleteLater(); +// wra->deleteLater(); +// w->deleteLater(); +} + + +TEST(UT_Textedit_popRightMenu, UT_Textedit_popRightMenu_002) +{ +// Window* w = new Window; +// TextEdit* edit = new TextEdit(w); +// EditWrapper* wra = new EditWrapper(w); +// edit->m_wrapper = wra; + +// edit->m_rightMenu = new QMenu; +// edit->m_colorMarkMenu = new QMenu; +// // QAction *exec(const QPoint &pos, QAction *at = nullptr); +// typedef QAction * (*fptr)(QMenu*,const QPoint &, QAction *); +// fptr A_foo = (fptr)((QAction *(QMenu::*)(const QPoint &, QAction *))&QMenu::exec); +// Stub s1; +// s1.set(A_foo,retintstub); + +// Stub s2; +// s2.set(ADDR(QUndoStack,canUndo),rettruestub); +// Stub s3; +// s3.set(ADDR(QUndoStack,canRedo),rettruestub); +// Stub s4; +// s4.set(ADDR(QTextCursor,hasSelection),rettruestub); +// Stub s5; +// s5.set(ADDR(TextEdit,canPaste),rettruestub); +// Stub s6; +// s6.set(ADDR(QTextDocument,isEmpty),retfalsestub); +// Stub s7; +// s7.set(ADDR(TextEdit,characterCount),retintstub); +// Stub s8; +// s8.set(ADDR(QString,isEmpty),retfalsestub); +// Stub s10; +// s10.set(ADDR(QPoint,y),retintstub); +// s10.set(ADDR(TextEdit,renderAllSelections),rettruestub); +// s10.set(ADDR(QDBusConnection,sessionBus),sessionBusstub); +// //s10.set((QDBusReply& (QDBusReply::*) (const QDBusMessage &))ADDR(QDBusReply,operator=), rettruestub); + +// TextEdit::MarkOperation m1,m2; +// edit->m_markOperations.push_back({m1,1}); +// edit->m_markOperations.push_back({m2,2}); +// intvalue=1; +// edit->m_bReadOnlyPermission = false; +// edit->popRightMenu(QPoint(10,10)); + +// EXPECT_NE(edit , nullptr); +// edit->deleteLater(); +// wra->deleteLater(); +// w->deleteLater(); +} + +TEST(UT_Textedit_unindentText, UT_Textedit_unindentText) +{ + Window* w = new Window; + TextEdit* edit = new TextEdit(w); + EditWrapper* wra = new EditWrapper(w); + edit->m_wrapper = wra; + + edit->unindentText(); + + EXPECT_NE(edit,nullptr); + edit->deleteLater(); + wra->deleteLater(); + w->deleteLater(); +} + +// static QList > convertMarkFromReplace(const QList &replaceInfo); +TEST(UT_Textedit_convertMark, UT_Textedit_convertMarkToReplace) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("12345\n" + "12345\n" + "12345\n"); + + QList > markInfo; + TextEdit::MarkOperation opt; + opt.type = TextEdit::MarkOnce; + opt.color = "#E5E5E5"; + opt.cursor = edit->textCursor(); + opt.cursor.setPosition(1); + opt.cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 5); + opt.matchText = opt.cursor.selectedText(); + markInfo.append(qMakePair(opt, 100)); + + TextEdit::MarkOperation opt2; + markInfo.append(qMakePair(opt2, 200)); + + auto replaceInfo = TextEdit::convertMarkToReplace(markInfo); + EXPECT_EQ(replaceInfo.size(), markInfo.size()); + + if (replaceInfo.size() == markInfo.size()) { + for (int i = 0; i < replaceInfo.size(); ++i) { + auto &mark = markInfo[i]; + auto &replace = replaceInfo[i]; + + EXPECT_EQ(mark.first.type, replace.opt.type); + EXPECT_EQ(mark.first.color, replace.opt.color); + EXPECT_EQ(mark.first.cursor.selectionStart(), replace.start); + EXPECT_EQ(mark.first.cursor.selectionEnd(), replace.end); + EXPECT_EQ(mark.second, replace.time); + } + } + + edit->deleteLater(); + wra->deleteLater(); +} + +// static QList convertReplaceToMark(const QList > &markInfo); +TEST(UT_Textedit_convertMark, UT_Textedit_convertReplaceToMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("12345\n" + "12345\n" + "12345\n"); + + QList replaceInfo; + TextEdit::MarkReplaceInfo replace1; + replace1.opt.type = TextEdit::MarkOnce; + replace1.opt.color = "#E5E5E5"; + replace1.opt.cursor = edit->textCursor(); + replace1.start = 1; + replace1.end = 6; + replace1.time = INT_MAX; + replaceInfo.append(replace1); + + TextEdit::MarkReplaceInfo replace2; + replaceInfo.append(replace2); + + auto markInfo = TextEdit::convertReplaceToMark(replaceInfo); + EXPECT_EQ(replaceInfo.size(), markInfo.size()); + + if (replaceInfo.size() == markInfo.size()) { + for (int i = 0; i < replaceInfo.size(); ++i) { + auto &mark = markInfo[i]; + auto &replace = replaceInfo[i]; + + EXPECT_EQ(mark.first.type, replace.opt.type); + EXPECT_EQ(mark.first.color, replace.opt.color); + if (!mark.first.cursor.isNull()) { + EXPECT_EQ(mark.first.cursor.selectionStart(), replace.start); + EXPECT_EQ(mark.first.cursor.selectionEnd(), replace.end); + } + EXPECT_EQ(mark.second, replace.time); + } + } + + edit->deleteLater(); + wra->deleteLater(); +} + +// 替换文本在颜色标记左侧 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithRightMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QStringList markList {"45", "89\n", "hi\n1a", "d5\n"}; + + for (auto markText : markList) { + edit->setPlainText("123456789\n" + "abcdefghi\n" + "1a2b3c4d5\n"); + + QTextCursor cursor = edit->findCursor(markText, edit->toPlainText(), 0); + // note: 含跨行符时,Qt自动替换换行为Unicode U+2029,详见QTextCursor::selectedText()帮助 + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), markText); + int oldStart = cursor.selectionStart(); + int oldEnd = cursor.selectionEnd(); + + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, "#E5E5E5"); + edit->renderAllSelections(); + EXPECT_FALSE(edit->extraSelections().isEmpty()); + + QString replaceText = "12"; + QString withText = "abcd"; + edit->replaceAll(replaceText, withText); + + QTextCursor newCursor = edit->textCursor(); + newCursor.setPosition(oldStart + withText.size() - replaceText.size()); + newCursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, oldEnd - oldStart); + QColor cursorColor = newCursor.charFormat().background().color(); + EXPECT_EQ(markText, newCursor.selectedText().replace("\u2029", "\n")); + + // 使用拓展标记判断颜色标记 + bool find = false; + for (auto extra : edit->extraSelections()) { + if (extra.cursor.selectionStart() == newCursor.selectionStart()) { + EXPECT_EQ(extra.cursor.selectionEnd(), newCursor.selectionEnd()); + EXPECT_EQ(extra.format.background().color(), QColor("#E5E5E5")); + + find = true; + break; + } + } + EXPECT_TRUE(find); + + edit->slotCancleMarkAllLine(false); + } + + edit->deleteLater(); + wra->deleteLater(); +} + +// 替换文本和颜色标记存在交集 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithIntersectMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n" + "abcdefghi\n" + "1a2b3c4d5\n"); + QString strColor = "#E5E5E5"; + // 选中 "456" + QString markText = "456"; + QTextCursor cursor = edit->findCursor(markText, edit->toPlainText(), 0); + // note: 含跨行符时,Qt自动替换换行为Unicode U+2029,详见QTextCursor::selectedText()帮助 + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), markText); + + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->extraSelections().isEmpty()); + + QString replaceText = "567"; + QString withText = "x567x"; + // "1234x567x89\n" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("4x567x")); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + replaceText = "234"; + withText = "-234-"; + // "1-234-x567x89\n" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("-234-x567x")); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + replaceText = "x89\n"; + withText = "x89\n123"; + // "1-234-x567x89\n123" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("-234-x567x89\n123")); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + edit->deleteLater(); + wra->deleteLater(); +} + +// 替换文本和颜色标记处于边界,不应互相影响 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithBoundnaryMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n"); + QString strColor = "#E5E5E5"; + // 选中 "456" + QString markText = "456"; + QTextCursor cursor = edit->findCursor(markText, edit->toPlainText(), 0); + // note: 含跨行符时,Qt自动替换换行为Unicode U+2029,详见QTextCursor::selectedText()帮助 + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), markText); + + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->extraSelections().isEmpty()); + + QString replaceText = "123"; + QString withText = "x123x"; + // "x123x456789\n" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("456")); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + replaceText = "789"; + withText = "x789x"; + // "x123x456x789x\n" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("456")); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + edit->deleteLater(); + wra->deleteLater(); +} + +// 颜色标记有多组替换文本 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_markWithMultiReplace) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123123123123\n"); + QString strColor = "#E5E5E5"; + // 选中 "31231231" + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(2); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 8); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), QString("31231231")); + + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->extraSelections().isEmpty()); + + QString replaceText = "123"; + QString withText = "x123x"; + // "x123xx123xx123xx123x\n" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("x123xx123xx123xx123x")); + EXPECT_EQ(markInfo.first.cursor.selectionStart(), 0); + EXPECT_EQ(markInfo.first.cursor.selectionEnd(), selectText.size()); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + // 重置 + edit->slotCancleMarkAllLine(); + edit->setPlainText("xxxxxx\n"); + // 选中中间的两组x + cursor.setPosition(2); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 2); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), QString("xx")); + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->extraSelections().isEmpty()); + + replaceText = "x"; + withText = "xy"; + // "xyxyxyxyxyxy\n" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("xyxy")); + EXPECT_EQ(markInfo.first.cursor.selectionStart(), 4); + EXPECT_EQ(markInfo.first.cursor.selectionEnd(), 8); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + edit->deleteLater(); + wra->deleteLater(); +} + + +// 替换文本在单行颜色标记内部 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithLineMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n" + "abcdefghi\n" + "1a2b3c4d5\n"); + QString strColor = "#E5E5E5"; + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(0); + + edit->setTextCursor(cursor); + // 选中首行 "123456789" 不包括换行符 + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + + QString replaceText = "12"; + QString withText = "xxxx"; + // "xxxx3456789" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + + auto checkSelection = [&](const QString &cmpStr)->bool { + bool find = false; + for (auto selection : edit->m_wordMarkSelections) { + QString selectText = selection.first.cursor.selectedText().replace("\u2029", "\n"); + if (selectText == cmpStr) { + EXPECT_EQ(selection.first.format.background().color(), QColor(strColor)); + find = true; + break; + } + } + return find; + }; + EXPECT_TRUE(checkSelection("xxxx3456789")); + + replaceText = "xxxx"; + withText = "12"; + // "123456789" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + EXPECT_TRUE(checkSelection("123456789")); + + replaceText = "6789\nabcd"; + withText = ""; + // "12345efghi" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + EXPECT_TRUE(checkSelection("12345efghi")); + + edit->deleteLater(); + wra->deleteLater(); +} + +// 替换文本跨过了单行颜色标记,形成多行颜色标记 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithMultiLineMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n" + "abcdefghi\n" + "1a2b3c4d5\n"); + QString strColor = "#E5E5E5"; + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(0); + + edit->setTextCursor(cursor); + // 选中首行 "123456789" 不包括换行符 + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + + QString replaceText = "34"; + QString withText = "34\n34"; + // "1234" -> "1234\n34" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + EXPECT_EQ(edit->m_wordMarkSelections.size(), 2); + + edit->deleteLater(); + wra->deleteLater(); +} + +// 替换文本包含了颜色标记 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithInnerMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n" + "abcdefghi\n"); + QString strColor = "#E5E5E5"; + QTextCursor cursor = edit->textCursor(); + // 选中"6789\nabcd" + cursor.setPosition(5); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 9); + + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + + QString replaceText = "456789\nabcdef"; + QString withText = ""; + // 替换后不存在标记 "" 将被移除 + edit->replaceAll(replaceText, withText); + EXPECT_TRUE(edit->m_wordMarkSelections.isEmpty()); + + edit->deleteLater(); + wra->deleteLater(); +} + +// 替换文本在颜色标记内部 +TEST(UT_Textedit_replaceWithMark, UT_Textedit_replaceWithOutterMark) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n" + "abcdefghi\n"); + QString strColor = "#E5E5E5"; + QTextCursor cursor = edit->textCursor(); + // 选中"6789\nabcd" + cursor.setPosition(5); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 9); + + edit->setTextCursor(cursor); + edit->isMarkCurrentLine(true, strColor); + edit->renderAllSelections(); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + + QString replaceText = "89\n"; + QString withText = ""; + // "67abcd" + edit->replaceAll(replaceText, withText); + EXPECT_FALSE(edit->m_wordMarkSelections.isEmpty()); + + if (!edit->m_wordMarkSelections.isEmpty()) { + auto markInfo = edit->m_wordMarkSelections.first(); + QString selectText = markInfo.first.cursor.selectedText().replace("\u2029", "\n"); + EXPECT_EQ(selectText, QString("67abcd")); + EXPECT_EQ(markInfo.first.format.background().color(), QColor(strColor)); + } + + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_selectText, SelectText_SingleBlock_Pass) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n"); + // 选中 "456" + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(3); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, 3); + edit->setTextCursor(cursor); + + EXPECT_EQ(cursor.selectedText(), edit->selectedText()); + EXPECT_EQ(QString("456"), edit->selectedText()); + + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_selectText, SelectText_MultiBlock_Pass) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + edit->setPlainText("123456789\n" + "abcdefghi\n" + "123456789\n"); + // 选中 "789\nabc" + QString str1 = QString("789\nabc"); + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(6); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, str1.length()); + edit->setTextCursor(cursor); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), edit->selectedText()); + EXPECT_EQ(str1, edit->selectedText()); + + // 选中 "789\nabcdefghi\n123" + QString str2 = QString("789\nabcdefghi\n123"); + cursor.setPosition(6); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, str2.length()); + edit->setTextCursor(cursor); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), edit->selectedText()); + EXPECT_EQ(str2, edit->selectedText()); + + // 选中 "789\nabcdefghi\n123456789\n" + QString str3 = QString("789\nabcdefghi\n123456789\n"); + cursor.setPosition(6); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, str3.length()); + edit->setTextCursor(cursor); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), edit->selectedText()); + EXPECT_EQ(str3, edit->selectedText()); + + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_selectText, SelectText_MultiBlock_MultiByte_Pass) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + // 此字符串为特殊多字节编码 CJK + // "𢝐𢝑𢝒𢝓𢝔𢝕𢝖𢝗𢝘𢝙\n𢝚𢝛𢝜𢝝𢝞𢝟𢝠𢝡𢝢𢝣\n𢝤𢝥𢝦𢝧𢝨𢝩𢝪𢝫𢝬𢝭\n" + QString multiByteText("\360\242\235\220\360\242\235\221\360\242\235\222\360\242\235\223\360\242\235\224" + "\360\242\235\225\360\242\235\226\360\242\235\227\360\242\235\230\360\242\235\231\n" + "\360\242\235\232\360\242\235\233\360\242\235\234\360\242\235\235\360\242\235\236" + "\360\242\235\237\360\242\235\240\360\242\235\241\360\242\235\242\360\242\235\243\n" + "\360\242\235\244\360\242\235\245\360\242\235\246\360\242\235\247\360\242\235\250" + "\360\242\235\251\360\242\235\252\360\242\235\253\360\242\235\254\360\242\235\255\n"); + edit->setPlainText(multiByteText); + // 选中 "𢝘𢝙\n𢝚𢝛" + QString str1 = QString("\360\242\235\230\360\242\235\231\n\360\242\235\232\360\242\235\233"); + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(16); + cursor.setPosition(16 + str1.length(), QTextCursor::KeepAnchor); + edit->setTextCursor(cursor); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), edit->selectedText()); + EXPECT_EQ(str1, edit->selectedText()); + + // 选中 "𢝘𢝙\n𢝚𢝛𢝜𢝝𢝞𢝟𢝠𢝡𢝢𢝣\n𢝤𢝥" + QString str2 = multiByteText.mid(16, 30); + cursor.setPosition(16); + cursor.setPosition(16 + str2.length(), QTextCursor::KeepAnchor); + edit->setTextCursor(cursor); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), edit->selectedText()); + EXPECT_EQ(str2, edit->selectedText()); + + // 选中 "𢝘𢝙\n𢝚𢝛𢝜𢝝𢝞𢝟𢝠𢝡𢝢𢝣\n𢝤𢝥𢝦𢝧𢝨𢝩𢝪𢝫𢝬𢝭\n" + QString str3 = multiByteText.mid(16); + cursor.setPosition(16); + cursor.setPosition(16 + str3.length(), QTextCursor::KeepAnchor); + edit->setTextCursor(cursor); + EXPECT_EQ(cursor.selectedText().replace("\u2029", "\n"), edit->selectedText()); + EXPECT_EQ(str3, edit->selectedText()); + edit->deleteLater(); + wra->deleteLater(); +} + +TEST(UT_Textedit_MidButtonInsertText, onTextContentChanged_MidButtonInsertText_Pass) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + QString sourceText("123456789"); + edit->setPlainText(sourceText); + edit->m_MidButtonPatse = true; + + QString insertText("test"); + QTextCursor cursor = edit->textCursor(); + cursor.setPosition(4); + // 插入触发 onTextContentChanged() + cursor.insertText(insertText); + + EXPECT_TRUE(edit->m_pUndoStack->canUndo()); + edit->m_pUndoStack->undo(); + EXPECT_EQ(edit->toPlainText(), sourceText); + + cursor = edit->textCursor(); + EXPECT_EQ(cursor.position(), 4); + + EXPECT_FALSE(edit->m_MidButtonPatse); + + edit->deleteLater(); + wra->deleteLater(); +} + +DPalette stubApplicationPalette() +{ + DPalette pa; + pa.setColor(DPalette::Highlight, QColor(Qt::red)); + return pa; +} + +TEST(UT_Textedit_onAppPaletteChanged, OnAppPaletteChanged_ChangeBackground_Pass) +{ + TextEdit* edit = new TextEdit; + EditWrapper* wra = new EditWrapper; + edit->m_wrapper = wra; + + Stub s; + s.set(ADDR(DGuiApplicationHelper, applicationPalette), stubApplicationPalette); + + QTextEdit::ExtraSelection selection; + selection.format.setBackground(QBrush(Qt::white)); + edit->m_altModSelections.append(selection); + edit->m_bIsAltMod = true; + edit->onAppPaletteChanged(); + + ASSERT_FALSE(edit->m_altModSelections.isEmpty()); + QBrush background = edit->m_altModSelections.first().format.background(); + EXPECT_EQ(QColor(Qt::red), background.color()); + + edit->deleteLater(); + wra->deleteLater(); +} diff --git a/tests/src/editor/ut_textedit.h b/tests/src/editor/ut_textedit.h new file mode 100644 index 0000000000000000000000000000000000000000..f5a6e01073a444f097bda1143c569f030414112b --- /dev/null +++ b/tests/src/editor/ut_textedit.h @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_TEXTEDIT_H +#define TEST_TEXTEDIT_H + + +#include "../../src/common/settings.h" +#include "../../src/controls/tabbar.h" +#include "../../src/editor/editwrapper.h" +#include "../../src/widgets/window.h" +#include "../../src/startmanager.h" +#include "../../src/editor/dtextedit.h" +#include "../../src/common/CSyntaxHighlighter.h" +#include "../../src/editor/uncommentselection.h" +#include "../../src/editor/showflodcodewidget.h" +#include + +#include "../stub.h" +#include +#include "gtest/gtest.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class test_textedit: public QObject, public::testing::Test +{ +public: + test_textedit(); + void forstub(QPoint q); +}; + +#endif // TEST_TEXTEDIT_H diff --git a/tests/src/editor/ut_uncommentselection.cpp b/tests/src/editor/ut_uncommentselection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba939b7d619f7836ab63b247b67609e775ec7f5c --- /dev/null +++ b/tests/src/editor/ut_uncommentselection.cpp @@ -0,0 +1,70 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_uncommentselection.h" +#include "../../src/common/settings.h" +#include "../../src/controls/tabbar.h" +#include "../../src/editor/editwrapper.h" +#include "../../src/widgets/window.h" +#include "../../src/startmanager.h" +#include "../../src/editor/dtextedit.h" +#include "../../src/editor/uncommentselection.h" + +using namespace Comment; + +test_uncommentselection::test_uncommentselection() +{ +} + +void test_uncommentselection::SetUp() +{ + comDef = new CommentDefinition; +} + +void test_uncommentselection::TearDown() +{ + delete comDef; +} + +TEST_F(test_uncommentselection, CommentDefinition) +{ + CommentDefinition num; + ASSERT_FALSE(num.isAfterWhiteSpaces); +} + +TEST_F(test_uncommentselection, setComments) +{ + QString singleLineComment = "a"; + QString multiLineCommentStart = "b"; + QString multiLineCommentEnd = "c"; + comDef->setComments(singleLineComment, multiLineCommentStart, multiLineCommentEnd); + ASSERT_EQ(comDef->singleLine, singleLineComment); + ASSERT_EQ(comDef->multiLineStart, multiLineCommentStart); + ASSERT_EQ(comDef->multiLineEnd, multiLineCommentEnd); +} +//bool isValid() const; +TEST_F(test_uncommentselection, isValid) +{ + Comment::CommentDefinition numm; + bool bRet = numm.isValid(); + + ASSERT_TRUE(bRet == false); +} +//bool hasSingleLineStyle() const; +TEST_F(test_uncommentselection, hasSingleLineStyle) +{ + Comment::CommentDefinition numm; + bool bRet = numm.hasSingleLineStyle(); + + ASSERT_TRUE(bRet == false); +} +//bool hasMultiLineStyle() const; +TEST_F(test_uncommentselection, hasMultiLineStyle) +{ + Comment::CommentDefinition numm; + bool bRet = numm.hasMultiLineStyle(); + + ASSERT_TRUE(bRet == false); +} + diff --git a/tests/src/editor/ut_uncommentselection.h b/tests/src/editor/ut_uncommentselection.h new file mode 100644 index 0000000000000000000000000000000000000000..ec511971a1ae5508f67d31debaa4588acecefadf --- /dev/null +++ b/tests/src/editor/ut_uncommentselection.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_UNCOMMENTSELECTION_H +#define TEST_UNCOMMENTSELECTION_H + +#include "gtest/gtest.h" +#include + +namespace Comment { + +class CommentDefinition; +class test_uncommentselection : public ::testing::Test +{ +public: + test_uncommentselection(); + virtual void SetUp() override; + virtual void TearDown() override; + CommentDefinition *comDef; +}; +} // namespace Comment +#endif // TEST_UNCOMMENTSELECTION_H diff --git a/tests/src/encodes/ut_detectcode.cpp b/tests/src/encodes/ut_detectcode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94035ae8ebe7a5ae626af7a0723d81e0b08158bb --- /dev/null +++ b/tests/src/encodes/ut_detectcode.cpp @@ -0,0 +1,343 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_detectcode.h" +#include "src/stub.h" +#include "../../src/encodes/detectcode.h" + +#include + +namespace detectcodestub { + +QString stringvalue="1"; + +QByteArray retintstub() +{ + return QByteArray(); +} + +QByteArray retByteArray = QByteArray(); +QByteArray reloadModifyFile_selectCoding() +{ + return retByteArray; +} + +} + + +using namespace detectcodestub; + +UT_DetectCode::UT_DetectCode() +{ + +} + +TEST(UT_DetectCode, UT_DetectCode) +{ + DetectCode c; +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_001) +{ + DetectCode* dc = new DetectCode; + + Stub stub; + stub.set(ADDR(DetectCode,UchardetCode),retintstub); + stringvalue = "unknown"; + Stub stubSelectCoding; + stubSelectCoding.set(ADDR(DetectCode, selectCoding),reloadModifyFile_selectCoding); + dc->GetFileEncodingFormat("123"); + EXPECT_NE(dc,nullptr); + delete dc; + dc=nullptr; +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_002) +{ + DetectCode* dc = new DetectCode; + + Stub stub; + stub.set(ADDR(DetectCode,UchardetCode),retintstub); + + stringvalue = "ASCII"; + Stub stubSelectCoding; + stubSelectCoding.set(ADDR(DetectCode, selectCoding),reloadModifyFile_selectCoding); + dc->GetFileEncodingFormat("123"); + + EXPECT_NE(dc,nullptr); + delete dc; + dc=nullptr; +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_003) +{ + DetectCode *pDetectCode = new DetectCode; + + Stub stub; + stub.set(ADDR(DetectCode,UchardetCode),retintstub); + + stringvalue = "unknown"; + Stub stubSelectCoding; + stubSelectCoding.set(ADDR(DetectCode, selectCoding),reloadModifyFile_selectCoding); + pDetectCode->GetFileEncodingFormat(QString("123"), QByteArray("我是中文")); + + EXPECT_NE(pDetectCode, nullptr); + delete pDetectCode; + pDetectCode = nullptr; +} + +void chartDet_DetectingTextCoding_stub() +{ + return; +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_004) +{ + DetectCode *pDetectCode = new DetectCode; + + Stub stub; + stub.set(ADDR(DetectCode, ChartDet_DetectingTextCoding), chartDet_DetectingTextCoding_stub); + + stringvalue = "unknown"; + Stub stubSelectCoding; + stubSelectCoding.set(ADDR(DetectCode, selectCoding),reloadModifyFile_selectCoding); + pDetectCode->GetFileEncodingFormat(QString("123"), QByteArray("我是中文")); + + EXPECT_NE(pDetectCode,nullptr); + delete pDetectCode; + pDetectCode = nullptr; +} + +void detectCode_icuDetectTextEncoding_stub(const QString &filePath, QByteArrayList &listDetectRet) +{ + Q_UNUSED(filePath) + Q_UNUSED(listDetectRet) +} + +QByteArray detectCode_selectCoding_stub(QByteArray ucharDetectdRet, QByteArrayList icuDetectRetList) +{ + Q_UNUSED(icuDetectRetList); + return ucharDetectdRet; +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_zh_CNContent_UTF8_Pass) +{ + Stub stubDetectCode; + stubDetectCode.set(ADDR(DetectCode, icuDetectTextEncoding), detectCode_icuDetectTextEncoding_stub); + stubDetectCode.set(ADDR(DetectCode, selectCoding), detectCode_selectCoding_stub); + + QByteArray content("你好,我是中文测试文本"); + while (content.size() > 8) { + // 手动破坏尾部字符编码 + content.chop(1); + QByteArray encode = DetectCode::GetFileEncodingFormat(QString("123"), content); + EXPECT_EQ(encode, QByteArray("UTF-8")); + } +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_zh_CNContent_GBK_Pass) +{ + Stub stubDetectCode; + stubDetectCode.set(ADDR(DetectCode, icuDetectTextEncoding), detectCode_icuDetectTextEncoding_stub); + stubDetectCode.set(ADDR(DetectCode, selectCoding), detectCode_selectCoding_stub); + + QTextCodec *codec = QTextCodec::codecForName("GB18030"); + QByteArray content = codec->fromUnicode("你好,我是中文测试文本"); + while (content.size() > 8) { + // 手动破坏尾部字符编码 + content.chop(1); + QByteArray encode = DetectCode::GetFileEncodingFormat(QString("123"), content); + EXPECT_EQ(encode, QByteArray("GB18030")); + } +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_zh_CNContent_BIG5_Pass) +{ + Stub stubDetectCode; + stubDetectCode.set(ADDR(DetectCode, icuDetectTextEncoding), detectCode_icuDetectTextEncoding_stub); + stubDetectCode.set(ADDR(DetectCode, selectCoding), detectCode_selectCoding_stub); + + QTextCodec *codec = QTextCodec::codecForName("BIG5"); + QByteArray content = codec->fromUnicode("你好,我是中文测试文本"); + while (content.size() > 8) { + // 手动破坏尾部字符编码 + content.chop(1); + QByteArray encode = DetectCode::GetFileEncodingFormat(QString("123"), content); + EXPECT_EQ(encode, QByteArray("BIG5")); + } +} + +TEST(UT_GetFileEncodingFormat, UT_GetFileEncodingFormat_ErrorContent_UTF8_Pass) +{ + Stub stubDetectCode; + stubDetectCode.set(ADDR(DetectCode, icuDetectTextEncoding), detectCode_icuDetectTextEncoding_stub); + stubDetectCode.set(ADDR(DetectCode, selectCoding), detectCode_selectCoding_stub); + + QByteArray content("你好,我是中文繁體中文བོད་ཡིགКирилли́こんにちは안녕하십니까Hello"); + while (content.size() > 8) { + // 手动破坏尾部字符编码 + content.chop(1); + QByteArray encode = DetectCode::GetFileEncodingFormat(QString("123"), content); + EXPECT_EQ(encode, QByteArray("UTF-8")); + } +} + +TEST(UT_EncaDetectCode, UT_EncaDetectCode) +{ + DetectCode* dc = new DetectCode; + + dc->UchardetCode("123"); + + EXPECT_NE(dc,nullptr); + delete dc; + dc=nullptr; +} + +TEST(UT_ChangeFileEncodingFormat, UT_ChangeFileEncodingFormat_001) +{ + DetectCode* dc = new DetectCode; + + QByteArray ba(1,'c'); + dc->ChangeFileEncodingFormat(ba,ba,"567","567"); + + EXPECT_NE(dc,nullptr); + delete dc; + dc=nullptr; +} + +TEST(UT_ChangeFileEncodingFormat, UT_ChangeFileEncodingFormat_002) +{ + DetectCode* dc = new DetectCode; + + QByteArray ba(1,'c'); + dc->ChangeFileEncodingFormat(ba,ba,"567","789"); + + EXPECT_NE(dc, nullptr); + delete dc; + dc=nullptr; +} + +iconv_t *iconv_open_stub() +{ + return nullptr; +} + +void iconv_stub() +{ + return; +} + +void iconv_close_stub() +{ + return; +} + +TEST(UT_ChangeFileEncodingFormat, UT_ChangeFileEncodingFormat_003) +{ + DetectCode *pDetectCode = new DetectCode; + QByteArray inData("我是中文"); + QByteArray outData; + + Stub stub_iconv_open; + stub_iconv_open.set(iconv_open, iconv_open_stub); + + Stub stub_iconv; + stub_iconv.set(iconv, iconv_stub); + + Stub stub_iconv_close; + stub_iconv_close.set(iconv_close, iconv_close_stub); + bool bRet = pDetectCode->ChangeFileEncodingFormat(inData, outData, QString("GB18030"), QString("UTF-8")); + + ASSERT_TRUE(bRet == true); + delete pDetectCode; + pDetectCode = nullptr; +} + +TEST(UT_UchardetCode, UT_UchardetCode_001) +{ + DetectCode *pDetectCode = new DetectCode; + QString strFilePath(QCoreApplication::applicationDirPath() + QString("/Makefile")); + pDetectCode->UchardetCode(strFilePath); + + EXPECT_NE(pDetectCode, nullptr); + delete pDetectCode; + pDetectCode = nullptr; +} + +DetectObj *detect_obj_init_stub() +{ + return nullptr; +} + +TEST(UT_ChartDet_DetectingTextCoding, UT_ChartDet_DetectingTextCoding_001) +{ + DetectCode *pDetectCode = new DetectCode; + QByteArray newContent("我是中文"); + QString detectedResult; + float chardetconfidence = 0; + + Stub stub; + stub.set(detect_obj_init, detect_obj_init_stub); + int iRet = pDetectCode->ChartDet_DetectingTextCoding(newContent, detectedResult, chardetconfidence); + + ASSERT_TRUE(iRet == CHARDET_MEM_ALLOCATED_FAIL); + delete pDetectCode; + pDetectCode = nullptr; +} + +int detect_stub_out_of_memory() +{ + return CHARDET_OUT_OF_MEMORY; +} + +TEST(UT_ChartDet_DetectingTextCoding, UT_ChartDet_DetectingTextCoding_002) +{ +// DetectCode *pDetectCode = new DetectCode; +// QByteArray newContent("我是中文"); +// QString detectedResult; +// float chardetconfidence = 0; + +// Stub stub; +// stub.set(detect, detect_stub_out_of_memory); +// int iRet = pDetectCode->ChartDet_DetectingTextCoding(newContent, detectedResult, chardetconfidence); + +// ASSERT_TRUE(iRet == CHARDET_OUT_OF_MEMORY); +// delete pDetectCode; +// pDetectCode = nullptr; +} + + +int detect_stub_null_object() +{ + return CHARDET_NULL_OBJECT; +} + +TEST(UT_ChartDet_DetectingTextCoding, UT_ChartDet_DetectingTextCoding_003) +{ +// DetectCode *pDetectCode = new DetectCode; +// QByteArray newContent("我是中文"); +// QString detectedResult; +// float chardetconfidence = 0; + +// Stub stub; +// stub.set(detect, detect_stub_null_object); +// int iRet = pDetectCode->ChartDet_DetectingTextCoding(newContent, detectedResult, chardetconfidence); + +// ASSERT_TRUE(iRet == CHARDET_NULL_OBJECT); +// delete pDetectCode; +// pDetectCode = nullptr; +} + +TEST(UT_ChartDet_DetectingTextCoding, UT_ChartDet_DetectingTextCoding_004) +{ +// DetectCode *pDetectCode = new DetectCode; +// QByteArray newContent("我是中文"); +// QString detectedResult; +// float chardetconfidence = 0; +// int iRet = pDetectCode->ChartDet_DetectingTextCoding(newContent, detectedResult, chardetconfidence); + +// ASSERT_TRUE(iRet == CHARDET_SUCCESS); +// delete pDetectCode; +// pDetectCode = nullptr; +} diff --git a/tests/src/encodes/ut_detectcode.h b/tests/src/encodes/ut_detectcode.h new file mode 100644 index 0000000000000000000000000000000000000000..ebf86a6abd6dac0b4e149c744e7d35e292d4fe91 --- /dev/null +++ b/tests/src/encodes/ut_detectcode.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_DetectCode_H +#define UT_DetectCode_H +#include "gtest/gtest.h" +#include +#include +#include +#include + +class UT_DetectCode: public QObject, public::testing::Test +{ + Q_OBJECT +public: + UT_DetectCode(); +}; + + +#endif diff --git a/tests/src/stub.h b/tests/src/stub.h new file mode 100644 index 0000000000000000000000000000000000000000..c8215c1ce6f73a8d7e0dd12a38b3154da8be1099 --- /dev/null +++ b/tests/src/stub.h @@ -0,0 +1,290 @@ +#ifndef __STUB_H__ +#define __STUB_H__ + + +#ifdef _WIN32 +//windows +#include +#include +#else +//linux +#include +#include +#endif +//c +#include +#include +//c++ +#include + + +#define ADDR(CLASS_NAME,MEMBER_NAME) (&CLASS_NAME::MEMBER_NAME) + +/********************************************************** + replace function +**********************************************************/ +#ifdef _WIN32 +#define CACHEFLUSH(addr, size) FlushInstructionCache(GetCurrentProcess(), addr, size) +#else +#define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size) +#endif + +#if defined(__aarch64__) || defined(_M_ARM64) + #define CODESIZE 16U + #define CODESIZE_MIN 16U + #define CODESIZE_MAX CODESIZE + // ldr x9, +8 + // br x9 + // addr + #define REPLACE_FAR(t, fn, fn_stub)\ + ((uint32_t*)fn)[0] = 0x58000040 | 9;\ + ((uint32_t*)fn)[1] = 0xd61f0120 | (9 << 5);\ + *(long long *)(fn + 8) = (long long )fn_stub;\ + CACHEFLUSH((char *)fn, CODESIZE); + #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) +#elif defined(__arm__) || defined(_M_ARM) + #define CODESIZE 8U + #define CODESIZE_MIN 8U + #define CODESIZE_MAX CODESIZE + // ldr pc, [pc, #-4] + #define REPLACE_FAR(t, fn, fn_stub)\ + ((uint32_t*)fn)[0] = 0xe51ff004;\ + ((uint32_t*)fn)[1] = (uint32_t)fn_stub;\ + CACHEFLUSH((char *)fn, CODESIZE); + #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub) +#elif defined(__thumb__) || defined(_M_THUMB) + #error "Thumb is not supported" +#else //__i386__ _x86_64__ + #define CODESIZE 13U + #define CODESIZE_MIN 5U + #define CODESIZE_MAX CODESIZE + //13 byte(jmp m16:64) + //movabs $0x102030405060708,%r11 + //jmpq *%r11 + #define REPLACE_FAR(t, fn, fn_stub)\ + *fn = 0x49;\ + *(fn + 1) = 0xbb;\ + *(long long *)(fn + 2) = (long long)fn_stub;\ + *(fn + 10) = 0x41;\ + *(fn + 11) = 0xff;\ + *(fn + 12) = 0xe3;\ + //CACHEFLUSH((char *)fn, CODESIZE); + + //5 byte(jmp rel32) + #define REPLACE_NEAR(t, fn, fn_stub)\ + *fn = 0xE9;\ + *(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\ + //CACHEFLUSH((char *)fn, CODESIZE); +#endif + +struct func_stub +{ + char *fn; + unsigned char code_buf[CODESIZE]; + bool far_jmp; +}; + +class Stub +{ +public: + Stub() + { +#ifdef _WIN32 + SYSTEM_INFO sys_info; + GetSystemInfo(&sys_info); + m_pagesize = sys_info.dwPageSize; +#else + m_pagesize = sysconf(_SC_PAGE_SIZE); +#endif + + if (m_pagesize < 0) + { + m_pagesize = 4096; + } + } + ~Stub() + { + std::map::iterator iter; + struct func_stub *pstub; + for(iter=m_result.begin(); iter != m_result.end(); iter++) + { + pstub = iter->second; +#ifdef _WIN32 + DWORD lpflOldProtect; + if(0 != VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) +#else + if (0 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) +#endif + { + + if(pstub->far_jmp) + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); + } + else + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); + } + +#ifdef _WIN32 + VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect); +#else + mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC); +#endif + } + + iter->second = NULL; + delete pstub; + } + + return; + } + template + void set(T addr, S addr_stub) + { + char * fn; + char * fn_stub; + fn = addrof(addr); + fn_stub = addrof(addr_stub); + struct func_stub *pstub; + pstub = new func_stub; + //start + pstub->fn = fn; + + if(distanceof(fn, fn_stub)) + { + pstub->far_jmp = true; + std::memcpy(pstub->code_buf, fn, CODESIZE_MAX); + } + else + { + pstub->far_jmp = false; + std::memcpy(pstub->code_buf, fn, CODESIZE_MIN); + } + +#ifdef _WIN32 + DWORD lpflOldProtect; + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) +#endif + { + //throw("stub set memory protect to w+r+x faild"); + } + + if(pstub->far_jmp) + { + REPLACE_FAR(this, fn, fn_stub); + } + else + { + REPLACE_NEAR(this, fn, fn_stub); + } + + +#ifdef _WIN32 + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) +#endif + { + //throw("stub set memory protect to r+x failed"); + } + m_result.insert(std::pair(fn,pstub)); + return; + } + + template + void reset(T addr) + { + char * fn; + fn = addrof(addr); + + std::map::iterator iter = m_result.find(fn); + + if (iter == m_result.end()) + { + return; + } + struct func_stub *pstub; + pstub = iter->second; + +#ifdef _WIN32 + DWORD lpflOldProtect; + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC)) +#endif + { + // throw("stub reset memory protect to w+r+x faild"); + } + + if(pstub->far_jmp) + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX); + } + else + { + std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN); + } + + +#ifdef _WIN32 + if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect)) +#else + if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC)) +#endif + { + // throw("stub reset memory protect to r+x failed"); + } + m_result.erase(iter); + delete pstub; + + return; + } +private: + char *pageof(char* addr) + { +#ifdef _WIN32 + return (char *)((unsigned long long)addr & ~(m_pagesize - 1)); +#else + return (char *)((unsigned long)addr & ~(m_pagesize - 1)); +#endif + } + + template + char* addrof(T addr) + { + union + { + T _s; + char* _d; + }ut; + ut._s = addr; + return ut._d; + } + + bool distanceof(char* addr, char* addr_stub) + { + std::ptrdiff_t diff = addr_stub >= addr ? addr_stub - addr : addr - addr_stub; + if((sizeof(addr) > 4) && (((diff >> 31) - 1) > 0)) + { + return true; + } + return false; + } + +private: +#ifdef _WIN32 + //LLP64 + long long m_pagesize; +#else + //LP64 + long m_pagesize; +#endif + std::map m_result; + +}; + + +#endif diff --git a/tests/src/thememodule /ut_themeitemdelegate.cpp b/tests/src/thememodule /ut_themeitemdelegate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cea841ae94e0e030de4db6d474b0de4c84da46a3 --- /dev/null +++ b/tests/src/thememodule /ut_themeitemdelegate.cpp @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_themeitemdelegate.h" +#include "../../src/thememodule/themeitemdelegate.h" +#include + +test_ThemeItemDelegate::test_ThemeItemDelegate() +{ +} + +void test_ThemeItemDelegate::SetUp() +{ + tid = new ThemeItemDelegate(); + EXPECT_NE(tid,nullptr); +} + +void test_ThemeItemDelegate::TearDown() +{ + delete tid; + tid = nullptr; +} + +TEST_F(test_ThemeItemDelegate, paint) +{ + QPainter *painter = new QPainter(); + const QModelIndex index; + const QStyleOptionViewItem option; + // ThemeItemDelegate tid; + tid->paint(painter, option, index); + + EXPECT_NE(painter,nullptr); + + delete painter; + painter=nullptr; +} + +TEST_F(test_ThemeItemDelegate, sizeHint) +{ + const QModelIndex index; + const QStyleOptionViewItem option; + EXPECT_NE(tid->sizeHint(option, index).width(),0); +} diff --git a/tests/src/thememodule /ut_themeitemdelegate.h b/tests/src/thememodule /ut_themeitemdelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..20db77fc414ad57efb8bde451072a7d49f537c77 --- /dev/null +++ b/tests/src/thememodule /ut_themeitemdelegate.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_THEMEITEMDELEGATE_H +#define TEST_THEMEITEMDELEGATE_H + +#include "gtest/gtest.h" +#include +#include + +class ThemeItemDelegate; +class test_ThemeItemDelegate :public testing::Test +{ +public: + test_ThemeItemDelegate(); + virtual void SetUp() override; + virtual void TearDown() override; + ThemeItemDelegate *tid; +}; + +#endif // TEST_THEMEITEMDELEGATE_H diff --git a/tests/src/themes/atom_dark.theme b/tests/src/themes/atom_dark.theme new file mode 100644 index 0000000000000000000000000000000000000000..adefaeb754061db2e178ff1db6711214a6e98f97 --- /dev/null +++ b/tests/src/themes/atom_dark.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Atom Dark", + "author" : "Atom", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#ABB2BF", + "selected-bg-color" : "#3E4451", + "selected-text-color" : "#C2CAD9", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#282C34", + "code-folding" : "#224e65", + "bracket-match-bg" : "#6E9DFF", + "bracket-match-fg" : "#000000", + "current-line" : "#2C313A", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#5D667A", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#683C23", + "find-match-foreground" : "#CCCCCC", + "find-highlight-background" : "#515C6A", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#2d5c76", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#568AF2", + "tab-background-start-color" : "(33, 37, 43, 90%)", + "tab-background-end-color" : "(33, 37, 43, 90%)", + "tab-dnd-start" : "(45, 50, 59, 90%)", + "tab-dnd-end" : "(45, 50, 59, 90%)", + "themebar-frame-selected" : "#568AF2", + "themebar-frame-normal" : "#FFFFFF" + } +} diff --git a/tests/src/themes/deepin.theme b/tests/src/themes/deepin.theme new file mode 100644 index 0000000000000000000000000000000000000000..5111893b94172400feb337ceab52a9814596a425 --- /dev/null +++ b/tests/src/themes/deepin.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Deepin", + "author" : "Deepin", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#1f1c1b", + "selected-bg-color" : "#2CA7F8", + "selected-text-color" : "#FFFFFF", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Function" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Variable" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "ControlFlow" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Operator" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff" + }, + "BuiltIn" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886", + "bold" : true + }, + "Extension" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + }, + "Attribute" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "Char" : { + "text-color" : "#924c9d", + "selected-text-color" : "#6c2477" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#fcfcfc" + }, + "String" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "VerbatimString" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "SpecialString" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "Import" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "DataType" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "DecVal" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "BaseN" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Float" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Constant" : { + "text-color" : "#aa5500", + "selected-text-color" : "#5e2f00" + }, + "Comment" : { + "text-color" : "#898887", + "selected-text-color" : "#5e5d5d" + }, + "Documentation" : { + "text-color" : "#607880", + "selected-text-color" : "#46585e" + }, + "Annotation" : { + "text-color" : "#ca60ca", + "selected-text-color" : "#a44ea4" + }, + "CommentVar" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff" + }, + "RegionMarker" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e", + "background-color" : "#e0e9f8" + }, + "Information" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Warning" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "Alert" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "background-color" : "#f7e6e6", + "bold" : true + }, + "Error" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "underline" : true + }, + "Others" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + } + }, + "editor-colors": { + "background-color" : "#f8f8f8", + "code-folding" : "#94caef", + "bracket-match-bg" : "#ffff00", + "bracket-match-fg" : "#000000", + "current-line" : "#F2F2F2", + "icon-border" : "#f0f0f0", + "indentation-line" : "#d2d2d2", + "line-numbers" : "#000000", + "current-line-number" : "#1e1e1e", + "mark-bookmark" : "#0000ff", + "mark-breakpoint-active" : "#ff0000", + "mark-breakpoint-reached" : "#ffff00", + "mark-breakpoint-disabled" : "#ff00ff", + "mark-execution" : "#a0a0a4", + "mark-warning" : "#00ff00", + "mark-error" : "#ff0000", + "modified-lines" : "#fdbc4b", + "replace-highlight" : "#00ff00", + "saved-lines" : "#2ecc71", + "find-match-background" : "#ffff00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2CA7F8", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#94caef", + "separator" : "#898887", + "spell-checking" : "#bf0303", + "tab-marker" : "#d2d2d2", + "template-background" : "#d6d2d0", + "template-placeholder" : "#baf8ce", + "template-focused-placeholder" : "#76da98", + "template-read-only-placeholder" : "#f6e6e6", + "word-wrap-marker" : "#ededed" + }, + "app-colors" : { + "tab-active" : "#2CA7F8", + "tab-background-start-color" : "(255, 255, 255, 90%)", + "tab-background-end-color" : "(245, 245, 245, 90%)", + "tab-dnd-start" : "(0, 0, 0, 10%)", + "tab-dnd-end" : "(0, 0, 0, 5%)", + "themebar-frame-selected" : "#2CA7F8", + "themebar-frame-normal" : "#000000" + } +} diff --git a/tests/src/themes/deepin_dark.theme b/tests/src/themes/deepin_dark.theme new file mode 100644 index 0000000000000000000000000000000000000000..66a8ffa0de22794f295a3a8a9eadb62cffe96490 --- /dev/null +++ b/tests/src/themes/deepin_dark.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Deepin Dark", + "author" : "Rekols", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#cfcfc2", + "selected-bg-color" : "#2D5C76", + "selected-text-color" : "#FFFFFF", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#252525", + "code-folding" : "#224e65", + "bracket-match-bg" : "#045998", + "bracket-match-fg" : "#FFFFFF", + "current-line" : "#2A2E32", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#ffffff", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#CCCC00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2D5C76", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#2d5c76", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#2CA7F8", + "tab-background-start-color" : "(20, 21, 23, 90%)", + "tab-background-end-color" : "(20, 21, 23, 90%)", + "tab-dnd-start" : "(35, 38, 41, 90%)", + "tab-dnd-end" : "(35, 38, 41, 90%)", + "themebar-frame-selected" : "#2CA7F8", + "themebar-frame-normal" : "#FFFFFF" + } +} diff --git a/tests/src/themes/solarized_dark.theme b/tests/src/themes/solarized_dark.theme new file mode 100644 index 0000000000000000000000000000000000000000..9771fd35f6abba744505541a6ed139a3b185c703 --- /dev/null +++ b/tests/src/themes/solarized_dark.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Solarized Dark", + "author" : "Ethan Schoonover", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#93A1A1", + "selected-bg-color" : "#0B5366", + "selected-text-color" : "#cfcfc2", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2", + "bold" : true + }, + "Function" : { + "text-color" : "#8e44ad", + "selected-text-color" : "#af81ff" + }, + "Variable" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae" + }, + "ControlFlow" : { + "text-color" : "#fdbc4b", + "selected-text-color" : "#fdbc4b", + "bold" : true + }, + "Operator" : { + "text-color" : "#cfcfc2", + "selected-text-color" : "#cfcfc2" + }, + "BuiltIn" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#bdc3c7" + }, + "Extension" : { + "text-color" : "#0099ff", + "selected-text-color" : "#bdc3c7", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "Attribute" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "Char" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#3daee9" + }, + "String" : { + "text-color" : "#f44f4f", + "selected-text-color" : "#f44f4f" + }, + "VerbatimString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "SpecialString" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Import" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + }, + "DataType" : { + "text-color" : "#2980b9", + "selected-text-color" : "#fdbc4b" + }, + "DecVal" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "BaseN" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Float" : { + "text-color" : "#f67400", + "selected-text-color" : "#f67400" + }, + "Constant" : { + "text-color" : "#27aeae", + "selected-text-color" : "#27aeae", + "bold" : true + }, + "Comment" : { + "text-color" : "#7a7c7d", + "selected-text-color" : "#808080" + }, + "Documentation" : { + "text-color" : "#a43340", + "selected-text-color" : "#da4453" + }, + "Annotation" : { + "text-color" : "#3f8058", + "selected-text-color" : "#54aa75" + }, + "CommentVar" : { + "text-color" : "#7f8c8d", + "selected-text-color" : "#94a3a4" + }, + "RegionMarker" : { + "text-color" : "#2980b9", + "selected-text-color" : "#3daee9", + "background-color" : "#153042" + }, + "Information" : { + "text-color" : "#c45b00", + "selected-text-color" : "#e46700" + }, + "Warning" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453" + }, + "Alert" : { + "text-color" : "#95da4c", + "selected-text-color" : "#95da4c", + "background-color" : "#4d1f24", + "bold" : true + }, + "Error" : { + "text-color" : "#da4453", + "selected-text-color" : "#da4453", + "underline" : true + }, + "Others" : { + "text-color" : "#27ae60", + "selected-text-color" : "#27ae60" + } + }, + "editor-colors": { + "background-color" : "#002B36", + "code-folding" : "#224e65", + "bracket-match-bg" : "#586E75", + "bracket-match-fg" : "#AFBFBF", + "current-line" : "#073642", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#7a7c7d", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#ffff00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2CA7F8", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#224659", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#93A1A1", + "tab-background-start-color" : "(0, 37, 46, 90%)", + "tab-background-end-color" : "(0, 37, 46, 90%)", + "tab-dnd-start" : "(7, 54, 66, 90%)", + "tab-dnd-end" : "(10, 77, 94, 90%)", + "themebar-frame-selected" : "#93A1A1", + "themebar-frame-normal" : "#FFFFFF" + } +} diff --git a/tests/src/themes/solarized_light.theme b/tests/src/themes/solarized_light.theme new file mode 100644 index 0000000000000000000000000000000000000000..081c393206da6de31e511a25d3200ca658fc0996 --- /dev/null +++ b/tests/src/themes/solarized_light.theme @@ -0,0 +1,191 @@ +{ + "metadata" : { + "revision" : 1, + "name" : "Solarized Light", + "author" : "Ethan Schoonover", + "license" : "MIT", + "read-only" : true + }, + "text-styles": { + "Normal" : { + "text-color" : "#445257", + "selected-bg-color" : "#586E75", + "selected-text-color" : "#F2F2E2", + "bold" : false, + "italic" : false, + "underline" : false, + "strike-through" : false + }, + "Keyword" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Function" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886" + }, + "Variable" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "ControlFlow" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Operator" : { + "text-color" : "#1f1c1b", + "selected-text-color" : "#ffffff" + }, + "BuiltIn" : { + "text-color" : "#644a9b", + "selected-text-color" : "#452886", + "bold" : true + }, + "Extension" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff", + "bold" : true + }, + "Preprocessor" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + }, + "Attribute" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "Char" : { + "text-color" : "#924c9d", + "selected-text-color" : "#6c2477" + }, + "SpecialChar" : { + "text-color" : "#3daee9", + "selected-text-color" : "#fcfcfc" + }, + "String" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "VerbatimString" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "SpecialString" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "Import" : { + "text-color" : "#ff5500", + "selected-text-color" : "#ff5500" + }, + "DataType" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e" + }, + "DecVal" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "BaseN" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Float" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Constant" : { + "text-color" : "#aa5500", + "selected-text-color" : "#5e2f00" + }, + "Comment" : { + "text-color" : "#898887", + "selected-text-color" : "#5e5d5d" + }, + "Documentation" : { + "text-color" : "#607880", + "selected-text-color" : "#46585e" + }, + "Annotation" : { + "text-color" : "#ca60ca", + "selected-text-color" : "#a44ea4" + }, + "CommentVar" : { + "text-color" : "#0095ff", + "selected-text-color" : "#ffffff" + }, + "RegionMarker" : { + "text-color" : "#0057ae", + "selected-text-color" : "#00316e", + "background-color" : "#e0e9f8" + }, + "Information" : { + "text-color" : "#b08000", + "selected-text-color" : "#805c00" + }, + "Warning" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e" + }, + "Alert" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "background-color" : "#f7e6e6", + "bold" : true + }, + "Error" : { + "text-color" : "#bf0303", + "selected-text-color" : "#9c0e0e", + "underline" : true + }, + "Others" : { + "text-color" : "#006e28", + "selected-text-color" : "#006e28" + } + }, + "editor-colors": { + "background-color" : "#FDF6E3", + "code-folding" : "#224e65", + "bracket-match-bg" : "#739099", + "bracket-match-fg" : "#F2F2E2", + "current-line" : "#EEE8D5", + "icon-border" : "#31363b", + "indentation-line" : "#3a3f44", + "line-numbers" : "#7a7c7d", + "current-line-number" : "#a5a6a8", + "mark-bookmark" : "#0404bf", + "mark-breakpoint-active" : "#8b0607", + "mark-breakpoint-reached" : "#6d6e07", + "mark-breakpoint-disabled" : "#820683", + "mark-execution" : "#4d4e50", + "mark-warning" : "#f67400", + "mark-error" : "#da4453", + "modified-lines" : "#c04900", + "replace-highlight" : "#808021", + "saved-lines" : "#1c8042", + "find-match-background" : "#ffff00", + "find-match-foreground" : "#000000", + "find-highlight-background" : "#2CA7F8", + "find-highlight-foreground" : "#FFFFFF", + "selection" : "#224659", + "separator" : "#7a7c7d", + "spell-checking" : "#c0392b", + "tab-marker" : "#4d4d4d", + "template-background" : "#31363b", + "template-placeholder" : "#123723", + "template-focused-placeholder" : "#123723", + "template-read-only-placeholder" : "#4d1f24", + "word-wrap-marker" : "#3a3f44" + }, + "app-colors" : { + "tab-active" : "#403513", + "tab-background-start-color" : "(253, 246, 227, 90%)", + "tab-background-end-color" : "(245, 238, 220, 90%)", + "tab-dnd-start" : "(238, 232, 213, 90%)", + "tab-dnd-end" : "(238, 232, 213, 90%)", + "themebar-frame-selected" : "#739099", + "themebar-frame-normal" : "#000000" + } +} diff --git a/tests/src/ut_editorapplication.cpp b/tests/src/ut_editorapplication.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf7953bf2057ba1f3fa98074b33b9d2bb5f92cb8 --- /dev/null +++ b/tests/src/ut_editorapplication.cpp @@ -0,0 +1,161 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_editorapplication.h" +#include "../../src/editorapplication.h" +#include +#include +#include "src/stub.h" + + + +namespace editappstub +{ +QWidget* activeWindowStub() +{ + return new QWidget; +} +} + +using namespace editappstub; + + +UT_EditorApplication::UT_EditorApplication() +{ + +} + + +TEST(UT_EditorApplication_EditorApplication, EditorApplication_001) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc, argv); + QString strRetOrNmae = app->organizationName(); + QString strRetAppName = app->applicationName(); + ASSERT_TRUE(!strRetOrNmae.compare(QString("deepin")) && !strRetAppName.compare(QString("deepin-editor"))); + + app->deleteLater(); +} + +TEST(UT_EditorApplication_EditorApplication, EditorApplication_002) +{ + int argc = 1; + char* argv[] = {"test"}; + //EditorApplication e(argc,argv); +} + +TEST(UT_EditorApplication_pressSpace, notify_001) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc,argv); + Qt::KeyboardModifier modefiers[4] = {Qt::ControlModifier,Qt::AltModifier,Qt::MetaModifier,Qt::NoModifier}; + QKeyEvent *e = new QKeyEvent(QEvent::KeyPress,Qt::Key_Return ,modefiers[0],"\r"); + + QPushButton* btn = new QPushButton; + btn->setObjectName("CustomRebackButton"); + bool bRet = app->notify(btn, e); + ASSERT_TRUE(bRet == true); + + btn->deleteLater(); + delete e; + e = nullptr; + app->deleteLater(); +} + +TEST(UT_EditorApplication_pressSpace, notify_002) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc,argv); + Qt::KeyboardModifier modefiers[4] = {Qt::ControlModifier,Qt::AltModifier,Qt::MetaModifier,Qt::NoModifier}; + QKeyEvent *e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Left, modefiers[0],"\r"); + + QPushButton* btn = new QPushButton; + btn->setObjectName("CustomRebackButton"); + bool bRet = app->notify(btn, e); + ASSERT_TRUE(bRet == true); + + btn->deleteLater(); + delete e; + e = nullptr; + app->deleteLater(); +} + +TEST(UT_EditorApplication_pressSpace, notify_003) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc,argv); + Qt::KeyboardModifier modefiers[4] = {Qt::ControlModifier,Qt::AltModifier,Qt::MetaModifier,Qt::NoModifier}; + QKeyEvent *e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Print, modefiers[0],"\r"); + + QPushButton* btn = new QPushButton; + btn->setObjectName("CustomRebackButton1"); + bool bRet = app->notify(btn, e); + ASSERT_TRUE(bRet == true); + + btn->deleteLater(); + delete e; + e = nullptr; + app->deleteLater(); +} + +TEST(UT_EditorApplication_pressSpace, notify_004) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc,argv); + Qt::KeyboardModifier modefiers[4] = {Qt::ControlModifier,Qt::AltModifier,Qt::MetaModifier,Qt::NoModifier}; + QKeyEvent *e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Print, modefiers[0], "\r"); + + QPushButton* btn = new QPushButton; + btn->setObjectName("CustomRebackButton1"); + bool bRet = app->notify(btn, e); + ASSERT_TRUE(bRet == true); + + btn->deleteLater(); + delete e; + e = nullptr; + app->deleteLater(); +} + +TEST(UT_EditorApplication_pressSpace, pressSpace) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc,argv); + + QPushButton* btn = new QPushButton; + btn->setObjectName("CustomRebackButton"); + app->pressSpace(btn); + QString strRetOrNmae = app->organizationName(); + QString strRetAppName = app->applicationName(); + ASSERT_TRUE(!strRetOrNmae.compare(QString("deepin")) && !strRetAppName.compare(QString("deepin-editor"))); + + btn->deleteLater(); + app->deleteLater(); +} + +TEST(UT_EditorApplication_handleQuitAction, handleQuitAction) +{ + int argc = 1; + char* argv[] = {"test"}; + //no deleted... + EditorApplication *app = new EditorApplication(argc,argv); + Stub s1; + s1.set(ADDR(QApplication,activeWindow),activeWindowStub); + + app->handleQuitAction(); + + app->deleteLater(); + +} diff --git a/tests/src/ut_editorapplication.h b/tests/src/ut_editorapplication.h new file mode 100644 index 0000000000000000000000000000000000000000..ad9fc1c9fe513f1fa1c40e650cdfe4e6c7ddc4a9 --- /dev/null +++ b/tests/src/ut_editorapplication.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_EditorApplication_H +#define UT_EditorApplication_H + +#include "gtest/gtest.h" +#include + + +class UT_EditorApplication: public QObject, public::testing::Test +{ + Q_OBJECT +public: + UT_EditorApplication(); +}; + + + +#endif // UT_EditorApplication_H diff --git a/tests/src/ut_main.cpp b/tests/src/ut_main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9bae5bad0640c51b6de331d2ba66040fd058710a --- /dev/null +++ b/tests/src/ut_main.cpp @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +#include +#include +#include + +#if defined(CMAKE_SAFETYTEST_ARG_ON) +#include +#endif + +DWIDGET_USE_NAMESPACE + +//#include + +int main(int argc, char *argv[]) + +{ + qputenv("QT_QPA_PLATFORM","offscreen"); + DApplication app(argc, argv); + + testing::InitGoogleTest(&argc, argv); + + auto c = RUN_ALL_TESTS(); + + #if defined(CMAKE_SAFETYTEST_ARG_ON) + __sanitizer_set_report_path("asan.log"); + #endif + + return c; +} diff --git a/tests/src/ut_startmanager.cpp b/tests/src/ut_startmanager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3af58e88682d12b8972ca4044163a3032daf800c --- /dev/null +++ b/tests/src/ut_startmanager.cpp @@ -0,0 +1,474 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_startmanager.h" +#include "src/stub.h" +#include "qdir.h" +#include "../../src/widgets/window.h" + +namespace startmanagerstub { + +EditWrapper *wrapperstub(const QString &filePath) +{ + return new EditWrapper; +} + +StartManager::FileTabInfo getFileTabInfostub() +{ + return StartManager::FileTabInfo{1,1}; +} + +TextEdit *textEditorstub() +{ + return new TextEdit; +} +void returnstub() +{ + return; +} + + +bool returntruestub() +{ + return true; +} + +bool returnfalsestub() +{ + return false; +} + +QStringList entryliststub() +{ + return QStringList{"123","456"}; +} + +} + +using namespace startmanagerstub; + +UT_StartManager::UT_StartManager() +{ + +} + +TEST(UT_StartManager_StartManager, StartManager) +{ + //StartManager startManager(nullptr); + StartManager *pStartManager = new StartManager(nullptr); + ASSERT_TRUE(pStartManager != nullptr); + + pStartManager->deleteLater(); +} + +TEST(UT_StartManager_instance, instance) +{ + StartManager *pStartManager = StartManager::instance(); + ASSERT_TRUE(pStartManager != nullptr); + + pStartManager->deleteLater(); +} + +TEST(UT_StartManager_openFilesInWindow, openFilesInWindow) +{ + StartManager *startManager = StartManager::instance(); + QStringList filePathList; + filePathList<<".cache/deepin/deepin-editor"; + startManager->openFilesInWindow(filePathList); + + filePathList<<".cache/deepin/"; + startManager->openFilesInWindow(filePathList); + ASSERT_TRUE(startManager->m_windows.at(0) != nullptr); + + startManager->deleteLater(); +} + +//initWindowPosition +TEST(UT_StartManager_initWindowPosition, initWindowPosition) +{ + StartManager *startManager = StartManager::instance(); + startManager->openFilesInTab(QStringList()); + ASSERT_TRUE(startManager->m_windows.at(0) != nullptr); + + startManager->deleteLater(); +} + +//getFileTabInfo +TEST(UT_StartManager_getFileTabInfo, getFileTabInfo) +{ + StartManager *startManager = StartManager::instance(); + StartManager::FileTabInfo fileTabInfo = startManager->getFileTabInfo(".cache/deepin/deepin-editor"); + + ASSERT_TRUE(fileTabInfo.windowIndex != 0); + startManager->deleteLater(); +} + +//slotCheckUnsaveTab +TEST(UT_StartManager_slotCheckUnsaveTab, slotCheckUnsaveTab) +{ + StartManager *startManager = StartManager::instance(); + startManager->openFilesInWindow(QStringList()); + startManager->slotCheckUnsaveTab(); + + bool bRet = startManager->m_windows.at(0)->checkBlockShutdown(); + ASSERT_TRUE(bRet == false); + + startManager->deleteLater(); +} + +//checkPath +TEST(UT_StartManager_checkPath, checkPath_001) +{ + QStringList fileLists; + QString strFilePath(QCoreApplication::applicationDirPath() + "/Makefile"); + fileLists << strFilePath; + StartManager *pStartManager = StartManager::instance(); + pStartManager->openFilesInTab(fileLists); + bool bRet = pStartManager->checkPath(strFilePath); + ASSERT_TRUE(bRet == false); + + pStartManager->deleteLater(); +} + +//checkPath +TEST(UT_StartManager_checkPath, checkPath_002) +{ + StartManager *pStartManager = StartManager::instance(); + pStartManager->openFilesInTab(QStringList()); + bool bRet = pStartManager->checkPath(QString()); + ASSERT_TRUE(bRet == true); + + pStartManager->deleteLater(); +} + +TEST(UT_StartManager_ifKlu,ifKlu ) +{ + StartManager *startManager = StartManager::instance(); + bool bRet = startManager->ifKlu(); + ASSERT_TRUE(bRet == false); + + startManager->deleteLater(); +} + +//loadTheme +TEST(UT_StartManager_loadThem,loadTheme) +{ + StartManager *startManager = StartManager::instance(); + startManager->loadTheme("Dark"); + ASSERT_TRUE(startManager != nullptr); + + startManager->deleteLater(); +} + +// bool isMultiWindow(); +TEST(UT_StartManager_isMultiWindow, isMultiWindow_001) +{ + QStringList fileLists; + QString strMakeFilePath(QCoreApplication::applicationDirPath() + "/Makefile"); + QString strCMakePath(QCoreApplication::applicationDirPath() + "/CMakeCache.txt"); + fileLists << strMakeFilePath << strCMakePath; + StartManager *pStartManager = StartManager::instance(); + bool bRet = pStartManager->isMultiWindow(); + ASSERT_TRUE(bRet == true); + + pStartManager->deleteLater(); +} + +// bool isMultiWindow(); +TEST(UT_StartManager_isMultiWindow, isMultiWindow_002) +{ + StartManager *pStartManager = StartManager::instance(); + pStartManager->m_windows.clear(); + bool bRet = pStartManager->isMultiWindow(); + ASSERT_TRUE(bRet == false); + + pStartManager->deleteLater(); +} + +TEST(UT_StartManager_isTemFilesEmpty, isTemFilesEmpty_001) +{ + QStringList fileLists; + QString strFilePath(QCoreApplication::applicationDirPath() + "/Makefile"); + fileLists << strFilePath; + StartManager *pStartManager = StartManager::instance(); + pStartManager->m_qlistTemFile.clear(); + pStartManager->openFilesInTab(fileLists); + pStartManager->m_qlistTemFile << QString(""); + bool bRet = pStartManager->isTemFilesEmpty(); + ASSERT_TRUE(bRet == true); + + pStartManager->deleteLater(); +} + +TEST(UT_StartManager_isTemFilesEmpty, isTemFilesEmpty_002) +{ + StartManager *pStartManager = StartManager::instance(); + pStartManager->m_qlistTemFile.clear(); + bool bRet = pStartManager->isTemFilesEmpty(); + ASSERT_TRUE(bRet == false); + + pStartManager->deleteLater(); +} + +TEST(UT_StartManager_autoBackupFile,autoBackupFile) +{ + StartManager *startManager = StartManager::instance(); + Window* w1 = new Window; + + EditWrapper* wr1 = new EditWrapper; + + TextEdit* e1 = new TextEdit; + e1->m_wrapper = wr1; + e1->m_listBookmark = {1,2}; + wr1->m_bIsTemFile = true; + wr1->m_pTextEdit = e1; + + QList windows = {w1}; + QMap wrappers{ {"wr1",wr1}}; + startManager->m_windows = windows; + w1->m_wrappers = wrappers; + + Stub s1; + s1.set(ADDR(QStringList,replace),returnstub); + Stub s2; + s2.set(ADDR(StartManager,getFileTabInfo),getFileTabInfostub); + s2.set(ADDR(EditWrapper,saveTemFile),returnstub); + + startManager->autoBackupFile(); + EXPECT_NE(startManager , nullptr); + + startManager->deleteLater(); + w1->deleteLater(); + wr1->deleteLater(); + e1->deleteLater(); +} + +TEST(UT_StartManager_recoverFile,recoverFile_001) +{ + StartManager *startManager = StartManager::instance(); + QString c1 = "{\"bookMark\":\"7,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\",\"cursorPosition\":\"7\",\"focus\":true,\"localPath\":\"/home/uos/.local/share/deepin/deepin-editor/blank-files/blank_file_2021-09-22_09-43-10-824\",\"modify\":true}"; + QString c2 = "{\"bookMark\":\"1,0,1,0,0\",\"cursorPosition\":\"23\",\"localPath\":\"/home/uos/Desktop/563/526.txt\",\"modify\":false}"; + startManager->m_qlistTemFile.push_back(c1); + startManager->m_qlistTemFile.push_back(c2); + + Stub s1; + s1.set(ADDR(Window,wrapper),wrapperstub); + Stub s2; + s2.set(ADDR(StartManager,popupExistTabs),returnstub); + + Window *pWindow = new Window; + int iRet = startManager->recoverFile(pWindow); + ASSERT_TRUE(iRet == 0); + + pWindow->deleteLater(); + startManager->deleteLater(); +} + +TEST(UT_StartManager_recoverFile,recoverFile_002) +{ + StartManager *startManager = StartManager::instance(); + QString c1 = "{\"bookMark\":\"7,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\",\"cursorPosition\":\"7\",\"focus\":true,\"localPath\":\"/home/uos/.local/share/deepin/deepin-editor/blank-files/blank_file_2021-09-22_09-43-10-824\",\"modify\":true}"; + QString c2 = "{\"bookMark\":\"1,0,1,0,0\",\"cursorPosition\":\"23\",\"localPath\":\"/home/uos/Desktop/563/526.txt\",\"modify\":false}"; + startManager->m_qlistTemFile.push_back(c1); + startManager->m_qlistTemFile.push_back(c2); + + Stub s1; + s1.set(ADDR(Window,wrapper),wrapperstub); + Stub s2; + s2.set(ADDR(StartManager,popupExistTabs),returnstub); + Stub s3; + s3.set((bool(QJsonObject::*)(const QString &) const)ADDR(QJsonObject,contains), returntruestub); + Stub s4; + s4.set(ADDR(QString,isEmpty),returnfalsestub); + Stub s5; + s5.set(ADDR(Utils,fileExists),returntruestub); + Stub s6; + s6.set(ADDR(QJsonValue,isDouble),returntruestub); + + + Window w; + int iRet = startManager->recoverFile(&w); + ASSERT_TRUE(iRet == 0); + + startManager->deleteLater(); +} + +TEST(UT_StartManager_openFilesInTab,openFilesInTab_001) +{ + StartManager *startManager = StartManager::instance(); + startManager->m_windows.clear(); + + Stub s1; + s1.set(ADDR(Window,wrapper),wrapperstub); + Stub s2; + s2.set(ADDR(StartManager,checkPath),returntruestub); + + + startManager->openFilesInTab(QStringList()); + startManager->openFilesInTab(QStringList(".cache/deepin/deepin-editor")); + + startManager->slotCloseWindow(); + startManager->slotCreatNewwindow(); + + ASSERT_TRUE(startManager->m_windows.count() > 0); + startManager->deleteLater(); +} + +TEST(UT_StartManager_openFilesInTab,openFilesInTab_002) +{ + StartManager *startManager = StartManager::instance(); + startManager->m_windows.clear(); + + Stub s1; + s1.set(ADDR(Window,wrapper),wrapperstub); + Stub s2; + s2.set(ADDR(StartManager,checkPath),returntruestub); + Stub s3; + s3.set(ADDR(StartManager,isTemFilesEmpty),returntruestub); + + startManager->openFilesInTab(QStringList()); + startManager->openFilesInTab(QStringList(".cache/deepin/deepin-editor")); + + startManager->slotCloseWindow(); + startManager->slotCreatNewwindow(); + + ASSERT_TRUE(startManager->m_windows.count() > 0); + startManager->deleteLater(); +} + +TEST(UT_StartManager_openFilesInTab,openFilesInTab_003) +{ + StartManager *startManager = StartManager::instance(); + startManager->m_windows.clear(); + + Stub s1; + s1.set(ADDR(Window,wrapper),wrapperstub); + Stub s2; + s2.set(ADDR(StartManager,checkPath),returntruestub); + Stub s3; + s3.set(ADDR(StartManager,isTemFilesEmpty),returnfalsestub); + + startManager->openFilesInTab(QStringList()); + startManager->openFilesInTab(QStringList(".cache/deepin/deepin-editor")); + + startManager->slotCloseWindow(); + startManager->slotCreatNewwindow(); + + ASSERT_TRUE(startManager->m_windows.count() > 0); + startManager->deleteLater(); +} + +TEST(UT_StartManager_analyzeBookmakeInfo,analyzeBookmakeInfo) +{ + StartManager *startManager = StartManager::instance(); + QList list = startManager->analyzeBookmakeInfo(QString()); + ASSERT_TRUE(!list.isEmpty()); + + list = {0, 1, 2}; + EXPECT_EQ(startManager->analyzeBookmakeInfo("0,1,2"), list); + list = {999, 2, 1}; + EXPECT_EQ(startManager->analyzeBookmakeInfo("999, 2, 1"), list); + list = {0, 1, 999}; + EXPECT_EQ(startManager->analyzeBookmakeInfo("0, 1, 999"), list); + + startManager->deleteLater(); +} + +TEST(UT_StartManager_slotCloseWindow,slotCloseWindow) +{ + StartManager *startManager = StartManager::instance(); + startManager->m_windows.clear(); + + Stub s1; + s1.set((QStringList(QDir::*)(QDir::Filters ,QDir::SortFlags) const)ADDR(QDir,entryList), entryliststub); + Stub s2; + s2.set((bool(QString::*)(const QString &,Qt::CaseSensitivity cs) const)ADDR(QString,contains), returntruestub); + Stub s3; + s3.set(ADDR(QList,isEmpty), returntruestub); + + startManager->slotCloseWindow(); + + startManager->deleteLater(); +} + +TEST(UT_StartManager_bookmark, recordBookmark_normal_pass) +{ + StartManager *startManager = new StartManager; + QString path("test"); + QList bookmark {0, 1, 2}; + startManager->recordBookmark(path, bookmark); + + EXPECT_FALSE(startManager->m_bookmarkTable.isEmpty()); + EXPECT_EQ(startManager->m_bookmarkTable.value(path), bookmark); + delete startManager; +} + +TEST(UT_StartManager_bookmark, findBookmark_normal_pass) +{ + StartManager *startManager = new StartManager; + QString path("test"); + QList bookmark {0, 1, 2}; + startManager->m_bookmarkTable.insert(path, bookmark); + + EXPECT_EQ(startManager->findBookmark(path), bookmark); + EXPECT_TRUE(startManager->findBookmark(QString("")).isEmpty()); + + delete startManager; +} + +// stub打桩函数 +QStringList toStringListStub() +{ + return {"{\"bookmark\":\"0,1\",\"localPath\":\"test\"}"}; +} + +bool fileIsExistsStub(const QString &path) +{ + Q_UNUSED(path) + return true; +} + +TEST(UT_StartManager_bookmark, initBookmark_normal_pass) +{ + StartManager *startManager = new StartManager; + + typedef bool (*FileExistFunc)(const QString &); + Stub stub; + stub.set(ADDR(QVariant, toStringList), toStringListStub); + stub.set((FileExistFunc)ADDR(QFileInfo, exists), fileIsExistsStub); + + startManager->initBookmark(); + + EXPECT_FALSE(startManager->m_bookmarkTable.isEmpty()); + QList bookmark {0, 1}; + EXPECT_EQ(startManager->findBookmark(QString("test")), bookmark); + + delete startManager; +} + +TEST(UT_StartManager_bookmark, saveBookmark_normal_pass) +{ + StartManager *startManager = new StartManager; + + typedef bool (*FileExistFunc)(const QString &); + Stub stub; + stub.set((FileExistFunc)ADDR(QFileInfo, exists), fileIsExistsStub); + + QString path("test"); + QList bookmark {0, 1}; + startManager->m_bookmarkTable.insert(path, bookmark); + startManager->saveBookmark(); + + QStringList saveData = Settings::instance()->settings->value("advance.editor.bookmark").toStringList(); + EXPECT_FALSE(saveData.isEmpty()); + if (!saveData.isEmpty()) { + QJsonDocument doc = QJsonDocument::fromJson(saveData.first().toUtf8()); + QJsonObject obj = doc.object(); + EXPECT_EQ(obj.value("localPath").toString(), path); + QList parseBookmark = startManager->analyzeBookmakeInfo(obj.value("bookmark").toString()); + EXPECT_EQ(bookmark, parseBookmark); + } + + delete startManager; +} diff --git a/tests/src/ut_startmanager.h b/tests/src/ut_startmanager.h new file mode 100644 index 0000000000000000000000000000000000000000..e2ed5895f0bc34ccfb5d1b6be8c9574b4e90a641 --- /dev/null +++ b/tests/src/ut_startmanager.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_StartManager_H +#define UT_StartManager_H +#include"../../src/startmanager.h" +#include"../../src/editor/dtextedit.h" +#include"../../src/common/settings.h" +#include"../../src/widgets/window.h" +#include"../../src/editor/editwrapper.h" +#include"../../src/controls/tabbar.h" +#include "gtest/gtest.h" +#include + +class UT_StartManager: public QObject, public::testing::Test +{ + Q_OBJECT +public: + UT_StartManager(); +}; + +#endif // UT_StartManager_H diff --git a/tests/src/widgets/ut_bottombar.cpp b/tests/src/widgets/ut_bottombar.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b27df0339295dfcee2e057ab63a1137cdfe4f204 --- /dev/null +++ b/tests/src/widgets/ut_bottombar.cpp @@ -0,0 +1,164 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_bottombar.h" + +#include +#include + +// 测试函数 BottomBar::updatePosition +TEST_F(TestBottomBar, checkUpdatePosition) +{ + auto bottomBar = new BottomBar; + bottomBar->updatePosition(1, 1); + + EXPECT_EQ(bottomBar->m_pPositionLabel->text().contains("1"),true); + + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); +} + +// 测试函数 BottomBar::updateWordCount +TEST_F(TestBottomBar, checkUpdateWordCount) +{ + auto bottomBar = new BottomBar; + bottomBar->updateWordCount(1); + + EXPECT_EQ(bottomBar->m_pCharCountLabel->text().contains("0"),true); + + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); +} + +// 测试函数 BottomBar::setEncodeName +TEST_F(TestBottomBar, checkSetEncodeName) +{ + auto bottomBar = new BottomBar; + bottomBar->setEncodeName("UTF-8"); + + + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); +} + +// 测试函数 BottomBar::setCursorStatus +TEST_F(TestBottomBar, checkSetCursorStatus) +{ + auto bottomBar = new BottomBar; + bottomBar->setCursorStatus("INSERT"); + EXPECT_EQ(bottomBar->m_pCursorStatus->text(),"INSERT"); + + + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); +} + +// 测试函数 BottomBar::setPalette +TEST_F(TestBottomBar, checkSetPalette) +{ + auto bottomBar = new BottomBar; + + QString backgroundColor = "#f8f8f8"; + QString textColor = "#1f1c1b"; + QPalette palette = bottomBar->palette(); + palette.setColor(QPalette::Background, backgroundColor); + palette.setColor(QPalette::Text, textColor); + bottomBar->setPalette(palette); + + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); +} + +// 测试函数 BottomBar::updateSize +TEST_F(TestBottomBar, checkUpdateSize) +{ + auto bottomBar = new BottomBar; + bottomBar->updateSize(32, false); + EXPECT_EQ(bottomBar->height(),32); + + + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); +} + +// 测试函数 BottomBar::setChildrenFocus +TEST_F(TestBottomBar, checkSetChildrenFocus) +{ + + // 场景1: ok = false, preOrderWidget = nullptr + auto bottomBar = new BottomBar; + bottomBar->setChildrenFocus(false, nullptr); + EXPECT_NE(bottomBar->m_pEncodeMenu->hasFocus(),true); + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); + + + + + // 场景2: ok = true, preOrderWidget = nullptr + bottomBar = new BottomBar; + bottomBar->setChildrenFocus(true, nullptr); + EXPECT_NE(bottomBar->m_pEncodeMenu->hasFocus(),true); + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); + + + + // 场景3: ok = true, preOrderWidget = new QWidget() + bottomBar = new BottomBar; + QPushButton *button = new QPushButton(); + bottomBar->setChildrenFocus(true, button); + EXPECT_NE(button->hasFocus(),true); + EXPECT_NE(bottomBar,nullptr); + EXPECT_NE(button,nullptr); + bottomBar->deleteLater(); + button->deleteLater(); + + + + // 场景4: ok = false, preOrderWidget = new QWidget() + bottomBar = new BottomBar; + button = new QPushButton(); + bottomBar->setChildrenFocus(false, button); + EXPECT_NE(button->hasFocus(),true); + EXPECT_NE(bottomBar,nullptr); + EXPECT_NE(button,nullptr); + bottomBar->deleteLater(); + button->deleteLater(); + +} + +// 测试函数 BottomBar::getEncodeMenu +TEST_F(TestBottomBar, checkGetEncodeMenu) +{ + + auto bottomBar = new BottomBar; + DDropdownMenu *menu = bottomBar->getEncodeMenu(); + EXPECT_NE(menu, nullptr); + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); + +} + +// 测试函数 BottomBar::getHighlightMenu +TEST_F(TestBottomBar, checkGetHighlightMenu) +{ + auto bottomBar = new BottomBar; + DDropdownMenu *menu = bottomBar->getHighlightMenu(); + EXPECT_NE(menu, nullptr); + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); + +} + +// 测试函数 BottomBar::paintEvent +TEST_F(TestBottomBar, checkPaintEvent) +{ + auto bottomBar = new BottomBar; + QPaintEvent event(bottomBar->rect()); + bottomBar->paintEvent(&event); + EXPECT_NE(bottomBar,nullptr); + bottomBar->deleteLater(); + +} diff --git a/tests/src/widgets/ut_bottombar.h b/tests/src/widgets/ut_bottombar.h new file mode 100644 index 0000000000000000000000000000000000000000..583292ff86773213e7939f66aa8aedfb85357ce0 --- /dev/null +++ b/tests/src/widgets/ut_bottombar.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_BOTTOMBAR_H +#define TEST_BOTTOMBAR_H + +#include "../../src/widgets/bottombar.h" + +#include + +class TestBottomBar : public testing::Test +{ +protected: + void SetUp() + { + bottomBar = new BottomBar(); + } + void TearDown() + { + delete bottomBar; + } + + BottomBar *bottomBar = nullptr; +}; + +#endif // TEST_BOTTOMBAR_H diff --git a/tests/src/widgets/ut_colorselectwidget.cpp b/tests/src/widgets/ut_colorselectwidget.cpp new file mode 100644 index 0000000000000000000000000000000000000000..48a4af63fca77b5abf953cee338154bb17e2292c --- /dev/null +++ b/tests/src/widgets/ut_colorselectwidget.cpp @@ -0,0 +1,202 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_colorselectwidget.h" + +#include + +// 测试函数ColorLabel::setColorSelected +TEST_F(test_colorlabel, checkSetColorSelected) +{ + + + auto colorLabel = new ColorLabel(QColor("#FF0000")); + colorLabel->setColorSelected(true); + colorLabel->setColorSelected(false); + + EXPECT_NE(colorLabel->m_bSelected,true); + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + +} + +// 测试函数 ColorLabel::isSelected +TEST_F(test_colorlabel, checkIsSelected) +{ + auto colorLabel = new ColorLabel(QColor("#FF0000")); + colorLabel->setColorSelected(true); + bool result = colorLabel->isSelected(); + EXPECT_TRUE(result); + + + + colorLabel->setColorSelected(false); + result = colorLabel->isSelected(); + EXPECT_FALSE(result); + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + +} + +// 测试函数 ColorLabel::getColor +TEST_F(test_colorlabel, checkGetColor) +{ + + auto colorLabel = new ColorLabel(QColor("#FF0000")); + QColor colorSet("red"); + QColor colorGet = colorLabel->getColor(); + EXPECT_EQ(colorSet, colorGet); + + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + +} + +// 测试函数 ColorLabel::paintEvent +TEST_F(test_colorlabel, checkPaintEvent) +{ + + auto colorLabel = new ColorLabel(QColor("#FF0000")); + colorLabel->setColorSelected(true); + QPaintEvent event(colorLabel->rect()); + colorLabel->paintEvent(&event); + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + + + + colorLabel = new ColorLabel(QColor("#FF0000")); + colorLabel->setColorSelected(false); + QPaintEvent event2(colorLabel->rect()); + colorLabel->paintEvent(&event2); + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + +} + +// 测试函数 ColorLabel::mousePressEvent +TEST_F(test_colorlabel, checkMousePressEvent) +{ + + // 场景1: LeftButtonPress + auto colorLabel = new ColorLabel(QColor("#FF0000")); + QSignalSpy spy(colorLabel, &ColorLabel::sigColorClicked); + QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, QPointF(), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + colorLabel->mousePressEvent(event); + EXPECT_EQ(spy.count(), 1); + + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + EXPECT_NE(event,nullptr); + delete event;event=nullptr; + + + + // 场景2: 非LeftButtonPress + colorLabel = new ColorLabel(QColor("#FF0000")); + QSignalSpy spy2(colorLabel, &ColorLabel::sigColorClicked); + event = new QMouseEvent(QEvent::MouseButtonPress, QPointF(), + Qt::RightButton, Qt::RightButton, Qt::NoModifier); + colorLabel->mousePressEvent(event); + EXPECT_EQ(spy2.count(), 0); + + EXPECT_NE(colorLabel,nullptr); + colorLabel->deleteLater(); + EXPECT_NE(event,nullptr); + delete event;event=nullptr; + +} + +// 测试函数 ColorSelectWdg::initWidget +TEST_F(test_colorselectwidget, checkInitWidget) +{ + + // 场景1: 字符串非空 + ColorSelectWdg *colorSelctWidget = new ColorSelectWdg("this is a test"); + colorSelctWidget->initWidget(); + EXPECT_NE(colorSelctWidget,nullptr); + EXPECT_NE(colorSelctWidget->m_pMainLayout,nullptr); + colorSelctWidget->deleteLater(); + + + + // 场景2: 字符串为空 + colorSelctWidget = new ColorSelectWdg(QString()); + colorSelctWidget->initWidget(); + EXPECT_NE(colorSelctWidget->m_pHLayout2,nullptr); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + +} + +// 测试函数 ColorSelectWdg::setTheme +TEST_F(test_colorselectwidget, checkSetTheme) +{ + + ColorSelectWdg *colorSelctWidget = new ColorSelectWdg("this is a test"); + colorSelctWidget->setTheme("light"); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + + + + colorSelctWidget = new ColorSelectWdg("this is a test"); + colorSelctWidget->setTheme("dark"); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + +} + +// 测试函数 ColorSelectWdg::getDefaultColor +TEST_F(test_colorselectwidget, checkGetDefaultColor) +{ + + ColorSelectWdg *colorSelctWidget = new ColorSelectWdg("this is a test"); + QColor defaultColor = colorSelctWidget->getDefaultColor(); + EXPECT_TRUE(defaultColor.isValid()); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + +} + +// 测试函数 ColorSelectWdg::eventFilter +TEST_F(test_colorselectwidget, checkEventFilter) +{ + + // 场景2: 过滤m_pLabel的LeftButton事件 + ColorSelectWdg *colorSelctWidget = new ColorSelectWdg("this is a test"); + QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, QPointF(), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + bool result = colorSelctWidget->eventFilter(colorSelctWidget->m_pLabel, event); + EXPECT_TRUE(result); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + delete event;event=nullptr; + + + + // 场景2: 过滤非m_pLabel的LeftButton事件 + colorSelctWidget = new ColorSelectWdg("this is a test"); + event = new QMouseEvent(QEvent::MouseButtonPress, QPointF(), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + result = colorSelctWidget->eventFilter(colorSelctWidget->m_pButton, event); + EXPECT_FALSE(result); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + delete event;event=nullptr; + + + + // 场景3: 过滤m_pLabel的非LeftButton事件 + colorSelctWidget = new ColorSelectWdg("this is a test"); + event = new QMouseEvent(QEvent::MouseButtonPress, QPointF(), + Qt::RightButton, Qt::RightButton, Qt::NoModifier); + result = colorSelctWidget->eventFilter(colorSelctWidget->m_pLabel, event); + EXPECT_FALSE(result); + EXPECT_NE(colorSelctWidget,nullptr); + colorSelctWidget->deleteLater(); + delete event;event=nullptr; + +} diff --git a/tests/src/widgets/ut_colorselectwidget.h b/tests/src/widgets/ut_colorselectwidget.h new file mode 100644 index 0000000000000000000000000000000000000000..987e47555658ef0fc06214c6b8ed9fdf7683b755 --- /dev/null +++ b/tests/src/widgets/ut_colorselectwidget.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_COLORSELECTWIDGET_H +#define TEST_COLORSELECTWIDGET_H + +#include "../../src/widgets/ColorSelectWdg.h" + +#include + +class test_colorlabel : public testing::Test +{ +protected: + void SetUp() + { + colorLabel = new ColorLabel(QColor("#FF0000")); + } + void TearDown() + { + delete colorLabel; + } + + ColorLabel *colorLabel = nullptr; +}; + +class test_colorselectwidget : public testing::Test +{ +protected: + void SetUp() + { + colorSelctWidget = new ColorSelectWdg("this is a test"); + } + void TearDown() + { + delete colorSelctWidget; + } + + ColorSelectWdg *colorSelctWidget = nullptr; +}; + +#endif // TEST_COLORSELECTWIDGET_H diff --git a/tests/src/widgets/ut_ddropdownmenu.cpp b/tests/src/widgets/ut_ddropdownmenu.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d9d0d7caf3e43c4af5f612df71c3943afe2c195 --- /dev/null +++ b/tests/src/widgets/ut_ddropdownmenu.cpp @@ -0,0 +1,296 @@ +// SPDX-FileCopyrightText: 2019 - 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_ddropdownmenu.h" +#include "../stub.h" + +#include +#include +#include +#include + +// 测试函数 DDropdownMenu::setFontEx +TEST_F(test_ddropdownmenu, setFontEx) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->setFontEx(QFont()); + EXPECT_EQ(dropMenu->m_font, QFont()); + + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} + +// 测试函数 DDropdownMenu::setCurrentAction +TEST_F(test_ddropdownmenu, setCurrentAction) +{ + + // 测试场景1: 非空指针 + DDropdownMenu *dropMenu = new DDropdownMenu(); + QAction *action = new QAction(); + dropMenu->setCurrentAction(action); + EXPECT_EQ(action->isCheckable(),false); + + EXPECT_NE(action,nullptr); + EXPECT_NE(dropMenu,nullptr); + action->deleteLater(); + dropMenu->deleteLater(); + + + // 测试场景2: 空指针 + dropMenu = new DDropdownMenu(); + dropMenu->setCurrentAction(nullptr); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} + +// 测试函数 DDropdownMenu::setCurrentTextOnly +TEST_F(test_ddropdownmenu, setCurrentTextOnly) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->setCurrentTextOnly("test"); + EXPECT_EQ(dropMenu->m_text,"test"); + + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} + +// 测试函数 DDropdownMenu::setText +TEST_F(test_ddropdownmenu, setText) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->setText("test"); + EXPECT_EQ(dropMenu->m_text, "test"); + + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + +} + +// 测试函数 DDropdownMenu::setTheme +TEST_F(test_ddropdownmenu, setTheme) +{ + + // 场景1: 正确主题 + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->setTheme("dark"); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + + + + // 场景2: 错误主题 + dropMenu = new DDropdownMenu(); + dropMenu->setTheme("error"); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + +} + +// 测试函数 DDropdownMenu::setChildrenFocus +TEST_F(test_ddropdownmenu, setChildrenFocus) +{ + + // 场景1: true + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->setChildrenFocus(true); + QFlags flags = QFlags(dropMenu->m_pToolButton->focusPolicy()); + EXPECT_EQ(flags.testFlag(Qt::StrongFocus), true); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + + + + // 场景2:false + dropMenu = new DDropdownMenu(); + dropMenu->setChildrenFocus(false); + QFlags flags2 = QFlags(dropMenu->m_pToolButton->focusPolicy()); + EXPECT_EQ(flags2.testFlag(Qt::NoFocus), true); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + +} + +// 测试函数 DDropdownMenu::getButton +TEST_F(test_ddropdownmenu, getButton) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + DToolButton *button = dropMenu->getButton(); + EXPECT_NE(dropMenu->m_pToolButton, nullptr); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + +} + +bool createEncodeMenu_isEmpty_stub() +{ + return true; +} + +// 测试函数 DDropdownMenu::createEncodeMenu +TEST_F(test_ddropdownmenu, createEncodeMenu) +{ + // 场景2: sm_groupEncodeVec为空 + Stub stub; + typedef QVector > VecType; + stub.set(ADDR(VecType, isEmpty), createEncodeMenu_isEmpty_stub); + DDropdownMenu *dropMenu = DDropdownMenu::createEncodeMenu(); + ASSERT_NE(dropMenu, nullptr); + EXPECT_TRUE(dropMenu->m_menu->actions().isEmpty()); + dropMenu->deleteLater(); + + // 场景1: sm_groupEncodeVec不为空 + stub.reset(ADDR(VecType, isEmpty)); + dropMenu = DDropdownMenu::createEncodeMenu(); + ASSERT_NE(dropMenu, nullptr); + EXPECT_FALSE(dropMenu->m_menu->actions().isEmpty()); + dropMenu->deleteLater(); +} + +// 测试函数 DDropdownMenu::createHighLightMenu +TEST_F(test_ddropdownmenu, createHighLightMenu) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->createHighLightMenu(); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} + +// 测试函数 DDropdownMenu::createIcon +TEST_F(test_ddropdownmenu, createIcon) +{ + + // 场景1: m_bPressed为true + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->m_bPressed = true; + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + + // 场景2: m_bPressed为false + dropMenu = new DDropdownMenu(); + dropMenu->m_bPressed = false; + dropMenu->createIcon(); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + + +} + +// 测试函数 DDropdownMenu::OnFontChangedSlot +TEST_F(test_ddropdownmenu, OnFontChangedSlot) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->OnFontChangedSlot(QFont()); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} + +// 测试函数 DDropdownMenu::eventFilter +TEST_F(test_ddropdownmenu, eventFilter) +{ + // do { + // // 场景1: enter键的keypress事件 + // DDropdownMenu *dropMenu = new DDropdownMenu(); + // QSignalBlocker signalBlock(dropMenu); + // QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); + // bool result = dropMenu->eventFilter(dropMenu->m_pToolButton, event); + // EXPECT_TRUE(result); + // delete event; + // delete dropMenu; + // } while (false); + + // do { + // // 场景2: Key_Left键的keypress事件 + // DDropdownMenu *dropMenu = new DDropdownMenu(); + // QSignalBlocker signalBlock(dropMenu); + // QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier); + // bool result = dropMenu->eventFilter(dropMenu->m_pToolButton, event); + // EXPECT_FALSE(result); + // delete event; + // delete dropMenu; + // } while (false); + + // do { + // // 场景3: MouseButtonPress事件 + // DDropdownMenu *dropMenu = new DDropdownMenu(); + // QSignalBlocker signalBlock(dropMenu); + // QSignalSpy spy(dropMenu, &DDropdownMenu::requestContextMenu); + // QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, QPointF(), + // Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + // bool result = dropMenu->eventFilter(dropMenu->m_pToolButton, event); + // EXPECT_FALSE(result); + // delete event; + // delete dropMenu; + // } while (false); + + // do { + // // 场景4: LeftButton的MouseButtonRelease事件 + // DDropdownMenu *dropMenu = new DDropdownMenu(); + // QSignalBlocker signalBlock(dropMenu); + // QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonRelease, QPointF(), + // Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + // bool result = dropMenu->eventFilter(dropMenu->m_pToolButton, event); + // EXPECT_TRUE(result); + // delete event; + // delete dropMenu; + // } while (false); + + // do { + // // 场景5: 非LeftButton的MouseButtonRelease事件 + // DDropdownMenu *dropMenu = new DDropdownMenu(); + // QSignalBlocker signalBlock(dropMenu); + // QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonRelease, QPointF(), + // Qt::RightButton, Qt::RightButton, Qt::NoModifier); + // bool result = dropMenu->eventFilter(dropMenu->m_pToolButton, event); + // EXPECT_TRUE(result); + // delete event; + // delete dropMenu; + // } while (false); +} + +// 测试函数 DDropdownMenu::setSvgColor +TEST_F(test_ddropdownmenu, setSvgColor) +{ + + DDropdownMenu *dropMenu = new DDropdownMenu(); + EXPECT_NE(dropMenu->setSvgColor("#FF0000").isNull(),true); + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} + +// 测试函数 DDropdownMenu::SetSVGBackColor +TEST_F(test_ddropdownmenu, SetSVGBackColor) +{ + + QByteArray data = "" + "I love SVG" + ""; + QDomDocument doc; + doc.setContent(data); + QDomElement elem = doc.documentElement(); + DDropdownMenu *dropMenu = new DDropdownMenu(); + dropMenu->SetSVGBackColor(elem, "fill", "#FF0000"); + + EXPECT_NE(dropMenu,nullptr); + dropMenu->deleteLater(); + +} diff --git a/tests/src/widgets/ut_ddropdownmenu.h b/tests/src/widgets/ut_ddropdownmenu.h new file mode 100644 index 0000000000000000000000000000000000000000..7bcbba0d8e57735b24c5e3dabb984f2097babb59 --- /dev/null +++ b/tests/src/widgets/ut_ddropdownmenu.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef TEST_DDROPDOWNMENU_H +#define TEST_DDROPDOWNMENU_H + +#include "../../src/widgets/ddropdownmenu.h" + +#include + +class test_ddropdownmenu: public testing::Test +{ +}; + +#endif // TEST_DDROPDOWNMENU_H diff --git a/tests/src/widgets/ut_window.cpp b/tests/src/widgets/ut_window.cpp new file mode 100644 index 0000000000000000000000000000000000000000..233ed1f30785cde2ea0c756cd30418a0e91a39f1 --- /dev/null +++ b/tests/src/widgets/ut_window.cpp @@ -0,0 +1,2201 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "ut_window.h" +#include "dsettingsoption.h" +#include "ddialog.h" +#include "qfileinfo.h" +#include "qfile.h" + +int exec_ret = 1; +int QDialog_exec_stub() +{ + return exec_ret; +} + +int intvalue=1; +int retintstub() +{ + return intvalue; +} + +QString stringvalue="123"; +QString retstringstub() +{ + return stringvalue; +} + +bool isDraft=false; +bool EditWrapper_isDraftFile_stub() +{ + return isDraft; +} + +bool isModified=false; +bool EditWrapper_isModified_stub() +{ + return isModified; +} + +bool qfileinfo_exists= false; +bool QFileInfo_exists_stub() +{ + return qfileinfo_exists; +} + +bool editwrapper_istemfile=false; +bool EditWrapper_isTemFile_stub() +{ + return editwrapper_istemfile; +} + +bool editwrapper_saveFile = false; +bool EditWrapper_saveFile_stub() +{ + return editwrapper_saveFile; +} + +bool editwrapper_saveAsFile = false; +bool EditWrapper_saveAsFile_stub(const QString &newFilePath, const QByteArray &encodeName) +{ + Q_UNUSED(newFilePath); + Q_UNUSED(encodeName); + return editwrapper_saveAsFile; +} + +EditWrapper* window_currentWrapper = nullptr; +EditWrapper* Window_currentWrapper_stub() +{ + return window_currentWrapper; +} + +TextEdit* editwrapper_texteditor = nullptr; +TextEdit *EditWrapper_textEditor_stub() +{ + return editwrapper_texteditor; +} + +bool window_saveasfile=false; +bool Window_saveAsFile_stub() +{ + return false; +} + +int QFile_permissions_stub() +{ + return 0x2000;//The file is writable by the owner of the file. +} + +void Window_updateSabeAsFileNameTemp_stub() +{ + return ; +} + +StartManager::FileTabInfo StartManager_getFileTabInfo_stub() +{ + return StartManager::FileTabInfo{1,1}; +} + +QString utils_getkeyshortcut; +QString Utils_getKeyshortcut_stub() +{ + return utils_getkeyshortcut; +} + + +QString utils_getkeyshortcutfromkeymap; +QString Utils_getKeyshortcutFromKeymap_stub() +{ + return utils_getkeyshortcutfromkeymap; +} + + +int option_stub_para = 0; +QPointer pDSettingsOption = nullptr; +QPointer option_stub() +{ + if (pDSettingsOption == nullptr) { + pDSettingsOption = new DSettingsOption; + } + if(option_stub_para == 0) + pDSettingsOption->setValue("window_maximum"); + else if(option_stub_para ==1 ) + pDSettingsOption->setValue("fullscreen"); + else + pDSettingsOption->setValue("normal"); + return pDSettingsOption; +} + + +UT_Window::UT_Window() +{ + +} + +TEST(UT_Window_Window, UT_Window_Window_001) +{ + Window *pWindow = new Window; + + ASSERT_TRUE(pWindow->m_editorWidget != nullptr); + pWindow->deleteLater(); +} + +TEST(UT_Window_showCenterWindow, UT_Window_showCenterWindow_001) +{ + Stub stub; + stub.set(ADDR(DSettings,option),option_stub); + + Window * window1 = new Window(); + option_stub_para=0; + window1->showCenterWindow(true); + + EXPECT_NE(window1->isVisible(),false); + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + if (pDSettingsOption != nullptr) { + pDSettingsOption->deleteLater(); + } +} + +TEST(UT_Window_showCenterWindow, UT_Window_showCenterWindow_002) +{ + Window * window1 = new Window(); + + Stub stub; + stub.set(ADDR(DSettings,option),option_stub); + + option_stub_para=1; + window1->showCenterWindow(true); + + EXPECT_NE(window1->isVisible(),false); + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + if (pDSettingsOption != nullptr) { + pDSettingsOption->deleteLater(); + } +} + +TEST(UT_Window_showCenterWindow, UT_Window_showCenterWindow_003) +{ + Window * window1 = new Window(); + + Stub stub; + stub.set(ADDR(DSettings,option),option_stub); + + option_stub_para=2; + window1->showCenterWindow(true); + + EXPECT_NE(window1->isVisible(),false); + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + if (pDSettingsOption != nullptr) { + pDSettingsOption->deleteLater(); + } +} + + +//initTitlebar +TEST(UT_Window_initTitlebar, UT_Window_initTitlebar) +{ + Window * window1 = new Window(); + window1->initTitlebar(); + + EXPECT_NE(window1,nullptr); + EXPECT_NE(window1->m_menu,nullptr); + + window1->deleteLater(); + + + +} +TEST(UT_Window_checkBlockShutdown, UT_Window_checkBlockShutdown) +{ + Window * window1 = new Window(); + EXPECT_NE(window1->checkBlockShutdown(),true); + + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + + +} +//getTabIndex +TEST(UT_Window_getTabIndex, UT_Window_getTabIndex) +{ + Window * window1 = new Window(); + EXPECT_NE(window1->getTabIndex("aadd"),1); + + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + + +} +int *stub1_exec() +{ + + return nullptr; +} +//activeTab +TEST(UT_Window_activeTab, UT_Window_activeTab) +{ + Window * window1 = new Window(); + window1->activeTab(0); + + EXPECT_NE(window1->m_tabbar->currentIndex(),1); + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + + +} +//addTab +TEST(UT_Window_addTab, UT_Window_addTab) +{ + Window * window1 = new Window(); + window1->addTab("aabb",true); + + EXPECT_NE(window1->m_tabbar->currentIndex(),1); + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + + +} +//openFile +TEST(UT_Window_openFile, UT_Window_openFile_001) +{ + Window* window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub s1; + s1.set(fptr,QDialog_exec_stub); + + exec_ret = 1; + + window->openFile(); + + EXPECT_NE(window,nullptr); + EXPECT_NE(a,nullptr); + window->deleteLater(); + a->deleteLater(); + +} + +TEST(UT_Window_openFile, UT_Window_openFile_002) +{ + Window* window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub s1; + s1.set(fptr,QDialog_exec_stub); + + exec_ret = 0; + + window->openFile(); + + EXPECT_NE(window,nullptr); + EXPECT_NE(a,nullptr); + window->deleteLater(); + a->deleteLater(); + +} + +TEST(UT_Window_saveFile, UT_Window_saveFile_001) +{ + Window * window1 = new Window(); + + isDraft=false; + qfileinfo_exists=true; + editwrapper_istemfile=false;//- + editwrapper_saveFile=true; + window_currentWrapper = new EditWrapper; + + Stub s0;s0.set(ADDR(Window,currentWrapper),Window_currentWrapper_stub); + Stub s1;s1.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s2;s2.set((bool (QFileInfo::*)(void) const)ADDR(QFileInfo,exists),QFileInfo_exists_stub); + Stub s3;s3.set(ADDR(EditWrapper,isTemFile),EditWrapper_isTemFile_stub); + Stub s4;s4.set(ADDR(EditWrapper,saveFile),EditWrapper_saveFile_stub); + Stub s5;s5.set(ADDR(Window,saveAsFile),Window_saveAsFile_stub); + + typedef QFileDevice::Permissions (*Fptr)(QFile*); + Fptr fptr = (Fptr)((QFileDevice::Permissions(QFile::*)() const )&QFile::permissions); + Stub s6;s6.set(fptr,QFile_permissions_stub); + + Stub s7;s7.set(ADDR(Window,updateSabeAsFileNameTemp),Window_updateSabeAsFileNameTemp_stub); + + window1->saveFile(); + + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + window_currentWrapper->deleteLater(); +} + + +TEST(UT_Window_saveFile, UT_Window_saveFile_002) +{ + Window * window1 = new Window(); + + isDraft=false; + qfileinfo_exists=true; + editwrapper_istemfile=true;//- + editwrapper_saveFile=true; + window_currentWrapper = new EditWrapper; + + Stub s0;s0.set(ADDR(Window,currentWrapper),Window_currentWrapper_stub); + Stub s1;s1.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s2;s2.set((bool (QFileInfo::*)(void) const)ADDR(QFileInfo,exists),QFileInfo_exists_stub); + Stub s3;s3.set(ADDR(EditWrapper,isTemFile),EditWrapper_isTemFile_stub); + Stub s4;s4.set(ADDR(EditWrapper,saveFile),EditWrapper_saveFile_stub); + Stub s5;s5.set(ADDR(Window,saveAsFile),Window_saveAsFile_stub); + + typedef QFileDevice::Permissions (*Fptr)(QFile*); + Fptr fptr = (Fptr)((QFileDevice::Permissions(QFile::*)() const )&QFile::permissions); + Stub s6;s6.set(fptr,QFile_permissions_stub); + + Stub s7;s7.set(ADDR(Window,updateSabeAsFileNameTemp),Window_updateSabeAsFileNameTemp_stub); + + window1->saveFile(); + + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + window_currentWrapper->deleteLater(); +} + + +TEST(UT_Window_closeTab, UT_Window_closeTab_001) +{ + Window * window = new Window(); + window->addBlankTab("aabb"); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub stub; + stub.set(fptr,QDialog_exec_stub); + + Stub s2; + s2.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s3; + s3.set(ADDR(EditWrapper,isModified),EditWrapper_isModified_stub); + + + isDraft = true; + isModified = true; + exec_ret = 0; + window->closeTab(); + + + EXPECT_NE(window,nullptr); + + window->deleteLater(); + +} + +TEST(UT_Window_closeTab, UT_Window_closeTab_002) +{ + Window * window = new Window(); + window->addBlankTab("aabb"); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub stub; + stub.set(fptr,QDialog_exec_stub); + + Stub s2; + s2.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s3; + s3.set(ADDR(EditWrapper,isModified),EditWrapper_isModified_stub); + + isDraft = true; + isModified = true; + exec_ret = 1; + window->closeTab(); + + EXPECT_NE(window,nullptr); + + window->deleteLater(); +} + + +TEST(UT_Window_closeTab, UT_Window_closeTab_003) +{ + Window * window = new Window(); + window->addBlankTab("aabb"); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub stub; + stub.set(fptr,QDialog_exec_stub); + + Stub s2; + s2.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s3; + s3.set(ADDR(EditWrapper,isModified),EditWrapper_isModified_stub); + + isDraft = true; + isModified = true; + exec_ret = 2; + window->closeTab(); + + EXPECT_NE(window,nullptr); + + window->deleteLater(); +} + +TEST(UT_Window_closeTab, UT_Window_closeTab_004) +{ + Window * window = new Window(); + window->addBlankTab("aabb"); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub stub; + stub.set(fptr,QDialog_exec_stub); + + Stub s2; + s2.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s3; + s3.set(ADDR(EditWrapper,isModified),EditWrapper_isModified_stub); + + isDraft = false; + isModified = true; + exec_ret = 1; + window->closeTab(); + + EXPECT_NE(window,nullptr); + window->deleteLater(); +} + + +TEST(UT_Window_closeTab, UT_Window_closeTab_005) +{ + Window * window = new Window(); + window->addBlankTab("aabb"); + + typedef int (*Fptr)(QDialog *); + Fptr fptr = (Fptr)(&QDialog::exec); + Stub stub; + stub.set(fptr,QDialog_exec_stub); + + Stub s2; + s2.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s3; + s3.set(ADDR(EditWrapper,isModified),EditWrapper_isModified_stub); + + isDraft = false; + isModified = true; + exec_ret = 2; + window->closeTab(); + + EXPECT_NE(window,nullptr); + window->deleteLater(); +} + +//saveAsFileToDisk +TEST(UT_Window_saveAsFileToDisk, UT_Window_saveAsFileToDisk_001) +{ + Window * window1 = new Window(); + + window_currentWrapper = new EditWrapper; + exec_ret=0; + editwrapper_saveFile = true; + isDraft=true; + + Stub s0;s0.set(ADDR(Window,currentWrapper),Window_currentWrapper_stub); + typedef int (*Fptr)(QFileDialog *); + Fptr fptr = (Fptr)(&QFileDialog::exec); + Stub s1; + s1.set(fptr,QDialog_exec_stub); + Stub s2;s2.set(ADDR(EditWrapper,saveFile),EditWrapper_saveFile_stub); + Stub s3;s3.set(ADDR(EditWrapper,updateSaveAsFileName),Window_updateSabeAsFileNameTemp_stub); + Stub s4;s4.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + + EXPECT_NE(window1->saveAsFileToDisk(),"1"); + + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + window_currentWrapper->deleteLater(); + + +} + +TEST(UT_Window_saveAsFileToDisk, UT_Window_saveAsFileToDisk_002) +{ + Window * window1 = new Window(); + + window_currentWrapper = new EditWrapper; + exec_ret=1; + editwrapper_saveFile = true; + isDraft=false; + editwrapper_saveAsFile = true; + + Stub s0;s0.set(ADDR(Window,currentWrapper),Window_currentWrapper_stub); + typedef int (*Fptr)(QFileDialog *); + Fptr fptr = (Fptr)(&QFileDialog::exec); + Stub s1;s1.set(fptr,QDialog_exec_stub); + Stub s2;s2.set(ADDR(EditWrapper,saveFile),EditWrapper_saveFile_stub); + Stub s3;s3.set(ADDR(Window,updateSaveAsFileName),Window_updateSabeAsFileNameTemp_stub); + Stub s4;s4.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + Stub s5;s5.set((bool(EditWrapper::*)(const QString &, const QByteArray&))ADDR(EditWrapper, saveAsFile), EditWrapper_saveAsFile_stub); + + EXPECT_NE(window1->saveAsFileToDisk(),"1"); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + window_currentWrapper->deleteLater(); +} + +//saveBlankFileToDisk +TEST(UT_Window_saveBlankFileToDisk, UT_Window_saveBlankFileToDisk) +{ + Window * window1 = new Window(); + EXPECT_NE(window1->saveBlankFileToDisk(),"1"); + + EXPECT_NE(window1,nullptr); + + window1->deleteLater(); + +} + +//saveAsOtherTabFile +TEST(UT_Window_saveAsOtherTabFile, UT_Window_saveAsOtherTabFile_001) +{ + Window * window = StartManager::instance()->createWindow(); + window->addBlankTab(""); + window->addBlankTab(""); + window->addBlankTab(""); + EditWrapper *wrapper = window->currentWrapper(); + + exec_ret=1; + isDraft=false; + + typedef int (*Fptr)(QFileDialog *); + Fptr fptr = (Fptr)(&QFileDialog::exec); + Stub s1;s1.set(fptr,QDialog_exec_stub); + Stub s4;s4.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + + window->saveAsOtherTabFile(wrapper); + + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} + +TEST(UT_Window_saveAsOtherTabFile, UT_Window_saveAsOtherTabFile_002) +{ + Window * window = StartManager::instance()->createWindow(); + window->addBlankTab(""); + window->addBlankTab(""); + window->addBlankTab(""); + EditWrapper *wrapper = window->currentWrapper(); + + exec_ret=1; + isDraft=true; + + typedef int (*Fptr)(QFileDialog *); + Fptr fptr = (Fptr)(&QFileDialog::exec); + Stub s1;s1.set(fptr,QDialog_exec_stub); + Stub s4;s4.set(ADDR(EditWrapper,isDraftFile),EditWrapper_isDraftFile_stub); + + window->saveAsOtherTabFile(wrapper); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} + +//changeSettingDialogComboxFontNumber +TEST(UT_Window_changeSettingDialogComboxFontNumber, UT_Window_changeSettingDialogComboxFontNumber) +{ + EditWrapper * e = new EditWrapper(); + Window * window1 = new Window(); + window1->changeSettingDialogComboxFontNumber(3); + + + EXPECT_NE(window1,nullptr); + EXPECT_NE(e,nullptr); + window1->deleteLater(); + e->deleteLater(); + + +} +//popupFindBar +TEST(UT_Window_popupFindBar, UT_Window_popupFindBar) +{ + Window * window1 = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window1->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window1->addBlankTab(); + window1->currentWrapper()->textEditor()->setPlainText(QString("12345")); + window1->popupFindBar(); + + window1->currentWrapper()->textEditor()->document()->clear(); + window1->popupFindBar(); + + EXPECT_NE(window1->m_tabbar->count(),0); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + + + +} + +//popupReplaceBar +TEST(UT_Window_popupReplaceBar, UT_Window_popupReplaceBar) +{ + Window * window1 = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window1->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window1->addBlankTab(); + window1->currentWrapper()->textEditor()->setPlainText(QString("12345")); + window1->popupReplaceBar(); + + window1->currentWrapper()->textEditor()->document()->clear(); + window1->popupReplaceBar(); + + EXPECT_NE(window1->m_replaceBar->isVisible(),false); + + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); +} + +//popupJumpLineBar +TEST(UT_Window_popupJumpLineBar, UT_Window_popupJumpLineBar) +{ + Window * window1 = new Window(); + window1->popupJumpLineBar(); + + EditWrapper *pEditWrapper = new EditWrapper(); + window1->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window1->addBlankTab(); + window1->currentWrapper()->textEditor()->setPlainText(QString("12345")); + window1->popupJumpLineBar(); + + window1->currentWrapper()->textEditor()->document()->clear(); + window1->popupJumpLineBar(); + + EXPECT_NE(window1->m_jumpLineBar->isVisible(),false); + + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + + +} + +//updateJumpLineBar +TEST(UT_Window_updateJumpLineBar, UT_Window_updateJumpLineBar) +{ +// Window * window = new Window(); +// window->updateJumpLineBar(); + + + +} + +//popupSettingsDialog +TEST(UT_Window_popupSettingsDialog, UT_Window_popupSettingsDialog) +{ + Window * window = new Window(); + + exec_ret=1; + + typedef int (*Fptr)(DSettingsDialog *); + Fptr fptr = (Fptr)(&DSettingsDialog::exec); + Stub s1;s1.set(fptr,QDialog_exec_stub); + + window->popupSettingsDialog(); + + + ASSERT_NE(window,nullptr); + window->deleteLater(); + +} +//popupPrintDialog + +TEST(UT_Window_popupPrintDialog, UT_Window_popupPrintDialog) +{ +// Window * window = new Window(); +// window->popupPrintDialog(); +// delete window; +// window = nullptr; + + +} +TEST(UT_Window_popupThemePanel, UT_Window_popupThemePanel) +{ + Window * window1 = new Window(); + window1->popupThemePanel(); + + EXPECT_NE(window1->m_themePanel->isVisible(),false); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + + +} +//toggleFullscreen +TEST(UT_Window_toggleFullscreen, UT_Window_toggleFullscreen) +{ + Window * window1 = new Window(); + window1->toggleFullscreen(); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + + +} +TEST(UT_Window_remberPositionSave, UT_Window_remberPositionSave) +{ +// Window * window = new Window(); +// window->remberPositionSave(); +// delete window; +// window = nullptr; + + +} +//remberPositionRestore +TEST(UT_Window_remberPositionRestore, UT_Window_remberPositionRestore) +{ + Window * window1 = new Window(); + + + EditWrapper* wrapper = new EditWrapper; + window1->m_remberPositionFilePath = "1234"; + window1->m_wrappers["1234"] = wrapper; + + + window1->remberPositionRestore(); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + wrapper->deleteLater(); + +} +//displayShortcuts +TEST(UT_Window_displayShortcuts, UT_Window_displayShortcuts) +{ + Window * window1 = new Window(); + window1->displayShortcuts(); + + EXPECT_NE(window1->m_shortcutViewProcess,nullptr); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + + +} +//setChildrenFocus +TEST(UT_Window_setChildrenFocus, UT_Window_setChildrenFocus) +{ + Window * window1 = new Window(); + window1->setChildrenFocus(false); + window1->setChildrenFocus(true); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + + +} +//addBlankTab +TEST(UT_Window_addBlankTab, UT_Window_addBlankTab) +{ + Window * window1 = new Window(); + window1->addBlankTab("aabb"); + + EXPECT_NE(window1->m_tabbar->count(),0); + + EXPECT_NE(window1,nullptr); + window1->deleteLater(); + + +} +//handleTabCloseRequested +TEST(UT_Window_addTabWithWrapper, UT_Window_addTabWithWrapper) +{ + EditWrapper* edit = new EditWrapper(); + Window *window = new Window(); + window->addTabWithWrapper(edit,"aabb","aabb","aabb"); + + EXPECT_NE(window->m_tabbar->count(),0); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(edit,nullptr); + edit->deleteLater(); + + +} +TEST(UT_Window_handleTabCloseRequested, UT_Window_handleTabCloseRequested) +{ +// StartManager::instance()->createWindow()->addTabWithWrapper(edit,"aabb","aabb",0); +// StartManager::instance()->createWindow()->handleTabCloseRequested(0); + + +} +//handleTabsClosed +TEST(UT_Window_handleTabsClosed, UT_Window_handleTabsClosed) +{ + QStringList aa; + Window *window = new Window(); + window->handleTabsClosed(aa); + + EXPECT_NE(window->m_tabbar->count(),1); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + + +} +//handleCurrentChanged +TEST(UT_Window_handleCurrentChanged, UT_Window_handleCurrentChanged) +{ + QStringList aa; + Window *window = new Window(); + window->handleCurrentChanged(0); + + EXPECT_NE(window->m_findBar->isVisible(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); +} +//slot_setTitleFocus +TEST(UT_Window_slot_setTitleFocus, UT_Window_slot_setTitleFocus) +{ +// QStringList aa; + //window = new Window(); +// StartManager::instance()->createWindow()->slot_setTitleFocus(); + //window->slot_setTitleFocus(); + + +} +//resizeEvent +TEST(UT_Window_resizeEvent, UT_Window_resizeEvent) +{ + QStringList aa; + Window *window = new Window(); + QResizeEvent * eve= new QResizeEvent(QSize(100,100),QSize(50,50)); + window->resizeEvent(eve); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + delete eve;eve=nullptr; + + +} +//closeEvent +TEST(UT_Window_keyPressEvent, UT_Window_keyPressEvent_001) +{ +// QStringList aa; +// Window *window = new Window(); +// window->m_settings = new Settings; +// QKeyEvent * eve =nullptr; +// utils_getkeyshortcut = Utils::getKeyshortcutFromKeymap(window->m_settings, "window", "decrementfontsize"); +// editwrapper_texteditor = new TextEdit; + +// Stub s1;s1.set(ADDR(Utils,getKeyshortcut),Utils_getKeyshortcut_stub); +// Stub s2;s2.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + +// window->keyPressEvent(eve); + +// EXPECT_NE(window,nullptr); +// window->deleteLater(); +// window->m_settings->deleteLater(); +// editwrapper_texteditor->deleteLater(); +} + + +TEST(UT_Window_keyPressEvent, UT_Window_keyPressEvent_002) +{ +// QStringList aa; +// Window *window = new Window(); +// window->m_settings = new Settings; +// QKeyEvent * eve =nullptr; +// utils_getkeyshortcut = "Alt+4"; +// editwrapper_texteditor = new TextEdit; + +// Stub s1;s1.set(ADDR(Utils,getKeyshortcut),Utils_getKeyshortcut_stub); +// Stub s2;s2.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + +// window->keyPressEvent(eve); + +// EXPECT_NE(window,nullptr); +// window->deleteLater(); +// window->m_settings->deleteLater(); +// editwrapper_texteditor->deleteLater(); + +} + + +TEST(UT_Window_keyPressEvent, UT_Window_keyPressEvent_003) +{ +// QStringList aa; +// Window *window = new Window(); +// window->m_settings = new Settings; +// QKeyEvent * eve =nullptr; +// utils_getkeyshortcut = Utils::getKeyshortcutFromKeymap(window->m_settings, "window", "incrementfontsize"); +// editwrapper_texteditor = new TextEdit; + +// Stub s1;s1.set(ADDR(Utils,getKeyshortcut),Utils_getKeyshortcut_stub); +// Stub s2;s2.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + +// window->keyPressEvent(eve); + +// EXPECT_NE(window,nullptr); +// window->deleteLater(); +// window->m_settings->deleteLater(); +// editwrapper_texteditor->deleteLater(); + +} + +TEST(UT_Window_keyPressEvent, UT_Window_keyPressEvent_004) +{ +// QStringList aa; +// Window *window = new Window(); +// window->m_settings = new Settings; +// QKeyEvent * eve =nullptr; +// utils_getkeyshortcut = Utils::getKeyshortcutFromKeymap(window->m_settings, "window", "decrementfontsize"); +// editwrapper_texteditor = new TextEdit; + +// Stub s1;s1.set(ADDR(Utils,getKeyshortcut),Utils_getKeyshortcut_stub); +// Stub s2;s2.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + +// window->keyPressEvent(eve); + +// EXPECT_NE(window,nullptr); +// window->deleteLater(); +// window->m_settings->deleteLater(); +// editwrapper_texteditor->deleteLater(); + +} + + +TEST(UT_Window_keyPressEvent, UT_Window_keyPressEvent_005) +{ +// QStringList aa; +// Window *window = new Window(); +// window->m_settings = new Settings; +// QKeyEvent * eve =nullptr; +// utils_getkeyshortcut = Utils::getKeyshortcutFromKeymap(window->m_settings, "window", "resetfontsize"); +// editwrapper_texteditor = new TextEdit; + +// Stub s1;s1.set(ADDR(Utils,getKeyshortcut),Utils_getKeyshortcut_stub); +// Stub s2;s2.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + +// window->keyPressEvent(eve); + +// EXPECT_NE(window,nullptr); +// window->deleteLater(); +// window->m_settings->deleteLater(); +// editwrapper_texteditor->deleteLater(); + +} + +TEST(UT_Window_keyPressEvent, UT_Window_keyPressEvent_006) +{ +// QStringList aa; +// Window *window = new Window(); +// window->m_settings = new Settings; +// QKeyEvent * eve =nullptr; +// utils_getkeyshortcut = Utils::getKeyshortcutFromKeymap(window->m_settings, "window", "togglefullscreen"); +// editwrapper_texteditor = new TextEdit; + +// Stub s1;s1.set(ADDR(Utils,getKeyshortcut),Utils_getKeyshortcut_stub); +// Stub s2;s2.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); +// Stub s3;s3.set(ADDR(Utils,getKeyshortcutFromKeymap),Utils_getKeyshortcutFromKeymap_stub); + +// window->keyPressEvent(eve); + +// EXPECT_NE(window,nullptr); +// window->deleteLater(); +// window->m_settings->deleteLater(); +// editwrapper_texteditor->deleteLater(); +} + + +//hideEvent +TEST(UT_Window_hideEvent, UT_Window_hideEvent) +{ + QStringList aa; + Window *window = new Window(); + QHideEvent * eve; + window->hideEvent(eve); + + EXPECT_NE(window->m_replaceBar->isVisible(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); +} + +//TextEdit +//void backupFile(); +TEST(UT_Window_backupFile, UT_Window_backupFile) +{ + Window *window = new Window(); + + EditWrapper* e1 = new EditWrapper; + EditWrapper* e2 = new EditWrapper; + window->m_wrappers["1"]=e1; + window->m_wrappers["2"]=e2; + + Stub s1;s1.set(ADDR(StartManager,getFileTabInfo),StartManager_getFileTabInfo_stub); + + window->backupFile(); + + + EXPECT_NE(window,nullptr); + window->deleteLater(); + + +} + +//void closeAllFiles(); +TEST(UT_Window_closeAllFiles, UT_Window_closeAllFiles) +{ + Window *window = new Window(); + EXPECT_NE(window->closeAllFiles(),false); + + EXPECT_NE(window->m_tabbar->count(),1); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + + +} + +//void addTemFileTab(QString qstrPath,QString qstrName,QString qstrTruePath,bool bIsTemFile = false); +TEST(UT_Window_addTemFileTab, UT_Window_addTemFileTab) +{ + Window *window = new Window(); + window->addTemFileTab("aa","bb","cc",""); + + EXPECT_NE(window->m_tabbar->count(),1); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + + +} +//Window(DMainWindow *parent = nullptr); +//~Window() override; + +////跟新文件修改状态 +//void updateModifyStatus(const QString &path, bool isModified); +TEST(UT_Window_updateModifyStatus, UT_Window_updateModifyStatus) +{ + Window *window = new Window(); + window->updateModifyStatus("aa",false); + window->updateModifyStatus("aa",true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + + +} +////跟新tab文件名称 +//void updateSaveAsFileName(QString strOldFilePath, QString strNewFilePath); +TEST(UT_Window_updateSaveAsFileName, UT_Window_updateSaveAsFileName) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->updateSaveAsFileName("aa","bb"); + + EXPECT_NE(window->m_tabbar->indexOf("aa"),1); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} + +//int getTabIndex(const QString &file); +//void activeTab(int index); + +//Tabbar* getTabbar(); +TEST(UT_Window_getTabbar, UT_Window_getTabbar) +{ + Window *window = new Window(); + EXPECT_NE(window->getTabbar(),nullptr); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} + +//void addTab(const QString &filepath, bool activeTab = false); +//void addTabWithWrapper(EditWrapper *wrapper, const QString &filepath, const QString &qstrTruePath, +// const QString &tabName, int index = -1); +//bool closeTab(); +//void restoreTab(); +TEST(UT_Window_restoreTab, UT_Window_restoreTab) +{ + Window *window = new Window(); + window->restoreTab(); + EXPECT_NE(window->m_closeFileHistory.isEmpty(),false); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} + +//void clearBlack(); + +//EditWrapper* createEditor(); +TEST(UT_Window_createEditor, UT_Window_createEditor) +{ + Window *window = new Window(); + EXPECT_NE(window->createEditor(),nullptr); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} +//EditWrapper* currentWrapper(); +TEST(UT_Window_currentWrapper, UT_Window_currentWrapper) +{ + Window *window = new Window(); + EXPECT_EQ(window->currentWrapper(),nullptr); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} +//EditWrapper* wrapper(const QString &filePath); +//TextEdit* getTextEditor(const QString &filepath); +TEST(UT_Window_getTextEditor, UT_Window_getTextEditor) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + EXPECT_NE(window->getTextEditor("aa"),nullptr); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void focusActiveEditor(); +TEST(UT_Window_focusActiveEditor, UT_Window_focusActiveEditor) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->focusActiveEditor(); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void removeWrapper(const QString &filePath, bool isDelete = false); +TEST(UT_Window_removeWrapper, UT_Window_removeWrapper) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->removeWrapper("aa",true); + window->removeWrapper("bb",false); + + EXPECT_EQ(window->m_wrappers.value("aa"),nullptr); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + + +} + +TEST(UT_Window_decrementFontSize, UT_Window_decrementFontSize) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->m_settings =Settings::instance(); + window->m_fontSize = 12; + qreal oldFontSize = window->m_fontSize; + window->decrementFontSize(); + EXPECT_GT(oldFontSize, window->m_fontSize); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void incrementFontSize(); +TEST(UT_Window_incrementFontSize, UT_Window_incrementFontSize) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->m_settings =Settings::instance(); + qreal oldFontSize = window->m_fontSize; + window->incrementFontSize(); + EXPECT_LT(oldFontSize, window->m_fontSize); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void resetFontSize(); +TEST(UT_Window_resetFontSize, UT_Window_resetFontSize) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->m_settings =Settings::instance(); + window->resetFontSize(); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void setFontSizeWithConfig(EditWrapper *editor); +TEST(UT_Window_setFontSizeWithConfig, UT_Window_setFontSizeWithConfig) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->m_settings =Settings::instance(); + window->setFontSizeWithConfig(a); + + EXPECT_NE(window->m_fontSize,10); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + + + +//public slots: +//void addBlankTab(); +//void addBlankTab(const QString &blankFile); +//void handleTabCloseRequested(int index); +//void handleTabsClosed(QStringList tabList); +//void handleCurrentChanged(const int &index); + +//void handleJumpLineBarExit(); +TEST(UT_Window_handleJumpLineBarExit, UT_Window_handleJumpLineBarExit) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->m_settings =Settings::instance(); + window->handleJumpLineBarExit(); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + + + +} +//void handleJumpLineBarJumpToLine(const QString &filepath, int line, bool focusEditor); +TEST(UT_Window_handleJumpLineBarJumpToLine, UT_Window_handleJumpLineBarJumpToLine) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleJumpLineBarJumpToLine("aa",1,true); + window->handleJumpLineBarJumpToLine("aa",1,false); + + + EXPECT_NE(window->m_wrappers.contains("aa"),false); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + + +} + +//void handleBackToPosition(const QString &file, int row, int column, int scrollOffset); +TEST(UT_Window_handleBackToPosition, UT_Window_handleBackToPosition) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleBackToPosition("aa",1,1,1); + + EXPECT_NE(window->m_wrappers.contains("bb"),false); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + +//void handleFindNext(); +TEST(UT_Window_handleFindNextSearchKeyword, UT_Window_handleFindNextSearchKeyword) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleFindNextSearchKeyword(""); + + EXPECT_NE(window->m_wrappers.contains("aadd"),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void handleFindPrev(); +TEST(UT_Window_handleFindPrevSearchKeyword, UT_Window_handleFindPrevSearchKeyword) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleFindPrevSearchKeyword(""); + + EXPECT_NE(window->m_wrappers.contains("aad"),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + + +} +//void slotFindbarClose(); +TEST(UT_Window_slotFindbarClose, UT_Window_slotFindbarClose) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->slotFindbarClose(); + + EXPECT_NE(window->m_findBar->isVisible(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + + +} +//void slotReplacebarClose(); +TEST(UT_Window_slotReplacebarClose, UT_Window_slotReplacebarClose) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->slotReplacebarClose(); + + EXPECT_NE(window->m_replaceBar->isVisible(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + + +} + +//void handleReplaceAll(const QString &replaceText, const QString &withText); +TEST(UT_Window_handleReplaceAll, UT_Window_handleReplaceAll) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleReplaceAll("",""); + + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void handleReplaceNext(const QString &replaceText, const QString &withText); +TEST(UT_Window_handleReplaceNext, UT_Window_handleReplaceNext) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleReplaceNext("a", "", ""); + + EXPECT_EQ(window->m_keywordForSearch,""); + + EXPECT_NE(window->m_findBar->isVisible(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void handleReplaceRest(const QString &replaceText, const QString &withText); +TEST(UT_Window_handleReplaceRest, UT_Window_handleReplaceRest) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleReplaceRest("",""); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void handleReplaceSkip(); +TEST(UT_Window_handleReplaceSkip, UT_Window_handleReplaceSkip) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleReplaceSkip("aa", ""); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + +//void handleRemoveSearchKeyword(); +TEST(UT_Window_handleRemoveSearchKeyword, UT_Window_handleRemoveSearchKeyword) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleRemoveSearchKeyword(); + + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void handleUpdateSearchKeyword(QWidget *widget, const QString &file, const QString &keyword); +TEST(UT_Window_handleUpdateSearchKeyword, UT_Window_handleUpdateSearchKeyword) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleUpdateSearchKeyword(window,"aa",""); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + + +//void addBottomWidget(QWidget *widget); +//void removeBottomWidget(); + +//void loadTheme(const QString &path); +TEST(UT_Window_loadTheme, UT_Window_loadTheme) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->loadTheme("window"); + + EXPECT_NE(window->m_themePath,"1"); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + + +//void showNewEditor(EditWrapper *wrapper); +TEST(UT_Window_showNewEditor, UT_Window_showNewEditor) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->showNewEditor(a); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void showNotify(const QString &message); +TEST(UT_Window_showNotify, UT_Window_showNotify) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->showNotify("ffffkkkk"); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//int getBlankFileIndex(); +TEST(UT_Window_getBlankFileIndex, UT_Window_getBlankFileIndex) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + EXPECT_NE(window->getBlankFileIndex(),0); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + +//DDialog *createDialog(const QString &title, const QString &content); +TEST(UT_Window_createDialog, UT_Window_createDialog) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + EXPECT_NE(window->createDialog("dd","ddd"),nullptr); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + +//void slotLoadContentTheme(DGuiApplicationHelper::ColorType themeType); +TEST(UT_Window_slotLoadContentTheme, UT_Window_slotLoadContentTheme) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->slotLoadContentTheme(DGuiApplicationHelper::ColorType::DarkType); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + +//void slotSettingResetTheme(const QString &path); +TEST(UT_Window_slotSettingResetTheme, UT_Window_slotSettingResetTheme) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->slotSettingResetTheme("DGuiApplicationHelper::ColorType::DarkType"); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} + +//void slotSigThemeChanged(const QString &path); +TEST(UT_Window_slotSigThemeChanged, UT_Window_slotSigThemeChanged) +{ + Window *pWindow = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + pWindow->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + pWindow->addBlankTab(); + pWindow->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + pWindow->m_settings = Settings::instance(); + DGuiApplicationHelper::instance()->setThemeType(DGuiApplicationHelper::LightType); + pWindow->slotSigThemeChanged(DEEPIN_THEME); + pWindow->slotSigThemeChanged(DEEPIN_DARK_THEME); + + DGuiApplicationHelper::instance()->setThemeType(DGuiApplicationHelper::DarkType); + //pWindow->slotSigThemeChanged(DEEPIN_THEME); + //pWindow->slotSigThemeChanged(DEEPIN_DARK_THEME); + + + EXPECT_NE(pWindow,nullptr); + pWindow->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + + +} + +//void slot_saveReadingPath(); +TEST(UT_Window_slot_saveReadingPath, UT_Window_slot_saveReadingPath) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->slot_saveReadingPath(); + + EXPECT_NE(window->m_reading_list.isEmpty(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void slot_beforeReplace(QString _); +TEST(UT_Window_slot_beforeReplace, UT_Window_slot_beforeReplace) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->slot_beforeReplace("d"); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + +} +//void slot_setTitleFocus(); + +//private: +//void handleFocusWindowChanged(QWindow *w); +TEST(UT_Window_handleFocusWindowChanged, UT_Window_handleFocusWindowChanged) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + QWindow * q = new QWindow(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->handleFocusWindowChanged(q); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + EXPECT_NE(q,nullptr); + q->deleteLater(); + +} +//void updateThemePanelGeomerty(); +TEST(UT_Window_updateThemePanelGeomerty, UT_Window_updateThemePanelGeomerty) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + QWindow * q = new QWindow(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->updateThemePanelGeomerty(); + + EXPECT_NE(window->m_themePanel->geometry().x(),0); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + EXPECT_NE(q,nullptr); + q->deleteLater(); + + +} + +//void checkTabbarForReload(); +TEST(UT_Window_checkTabbarForReload, UT_Window_checkTabbarForReload) +{ + Window *window = new Window(); + EditWrapper * a = new EditWrapper(); + QWindow * q = new QWindow(); + window->addTabWithWrapper(a,"aa","aad","aadd",0); + window->addBlankTab(); + window->addTabWithWrapper(a,"bb","aad","aadd",1); + window->m_settings =Settings::instance(); + window->checkTabbarForReload(); + + EXPECT_NE(window->m_tabbar->currentName(),"aa"); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(a,nullptr); + a->deleteLater(); + EXPECT_NE(q,nullptr); + q->deleteLater(); + + +} + +//void slotSigAdjustFont(); +TEST(UT_Window_slotSigAdjustFont, UT_Window_slotSigAdjustFont) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper,"bb", "aad", "aadd", 1); + window->slotSigAdjustFont(QString()); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + + +} + +//void slotSigAdjustFontSize(); +TEST(UT_Window_slotSigAdjustFontSize, UT_Window_slotSigAdjustFontSize) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + window->slotSigAdjustFontSize(14); + + EXPECT_EQ(window->m_fontSize,14); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + + +} + +//void slotSigAdjustTabSpaceNumber(); +TEST(UT_Window_slotSigAdjustTabSpaceNumber, UT_Window_slotSigAdjustTabSpaceNumber) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + + window->slotSigAdjustTabSpaceNumber(14); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + +} + +//void slotSigAdjustWordWrap(); +TEST(UT_Window_slotSigAdjustWordWrap, UT_Window_slotSigAdjustWordWrap) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + + window->slotSigAdjustWordWrap(true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + +} + +//void slotSigAdjustBookmark(); +TEST(UT_Window_slotSigAdjustBookmark, UT_Window_slotSigAdjustBookmark) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + + window->slotSigAdjustBookmark(true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + +} + +//void slotSigShowBlankCharacter(); +TEST(UT_Window_slotSigShowBlankCharacter, UT_Window_slotSigShowBlankCharacter) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + + window->slotSigShowBlankCharacter(true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + +} + +//void slotSigHightLightCurrentLine(); +TEST(UT_Window_slotSigHightLightCurrentLine, UT_Window_slotSigHightLightCurrentLine) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + + window->slotSigHightLightCurrentLine(true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + +} + +//void slotSigShowCodeFlodFlag(); +TEST(UT_Window_slotSigShowCodeFlodFlag, UT_Window_slotSigShowCodeFlodFlag) +{ + Window *window = new Window(); + EditWrapper *pEditWrapper = new EditWrapper(); + window->addTabWithWrapper(pEditWrapper, "aa", "aad", "aadd", 0); + window->addBlankTab(); + window->addTabWithWrapper(pEditWrapper, "bb", "aad", "aadd", 1); + + window->slotSigShowCodeFlodFlag(true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + EXPECT_NE(pEditWrapper,nullptr); + pEditWrapper->deleteLater(); + +} + +//void slotSigShowCodeFlodFlag(); +TEST(UT_Window_slotSigChangeWindowSize, UT_Window_slotSigChangeWindowSize) +{ + Window *window = new Window(); + window->slotSigChangeWindowSize(QString()); + window->slotSigChangeWindowSize(QString("fullscreen")); + window->slotSigChangeWindowSize(QString("window_maximum")); + + EXPECT_EQ(window->isVisible(),true); + + EXPECT_NE(window,nullptr); + window->deleteLater(); + +} + + + +TEST(UT_Window_printPage, UT_Window_printPage) +{ + Window *window = new Window(); + QPainter* painter = new QPainter; + QTextDocument* doc = new QTextDocument; + QRectF body,pageContBox; + Window::printPage(0,painter,doc,body,pageContBox); + + EXPECT_NE(window,nullptr); + EXPECT_NE(window,nullptr); + delete painter;painter=nullptr; + doc->deleteLater(); + +} + +TEST(UT_Window_delete_window, UT_Window_delete_window) +{ + Window* w = new Window(); + w->m_shortcutViewProcess = new QProcess; + + EXPECT_NE(w,nullptr); + w->deleteLater(); + //w->m_shortcutViewProcess will be deleted in ~Window; +} + +TEST(UT_Window_doprint, UT_Window_doprint) +{ + Window* w = new Window(); + DPrinter* p = new DPrinter; + w->m_printDoc = new QTextDocument; + w->m_pPreview = new DPrintPreviewDialog; + + editwrapper_texteditor = new TextEdit; + Stub s1;s1.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + + QVector pages{1,2,3,4,5}; +#if (DTK_VERSION_MAJOR > 5 \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR > 4) \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR == 4 && DTK_VERSION_PATCH >= 10)) + w->doPrint(p,pages); +#endif + + EXPECT_NE(w, nullptr); + w->deleteLater(); + editwrapper_texteditor->deleteLater(); + w->m_printDoc->deleteLater(); + w->m_pPreview->deleteLater(); + delete p; + p = nullptr; +} + +TEST(UT_Window_doprint, UT_Window_doPrintWithLargeDoc) +{ + Window* w = new Window(); + DPrinter* p = new DPrinter; + w->m_pPreview = new DPrintPreviewDialog; + Window::PrintInfo info; + info.doc = new QTextDocument; + w->m_printDocList.append(info); + + editwrapper_texteditor = new TextEdit; + Stub s1;s1.set(ADDR(EditWrapper,textEditor),EditWrapper_textEditor_stub); + + QVector pages{1,2,3,4,5}; +#if (DTK_VERSION_MAJOR > 5 \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR > 4) \ + || (DTK_VERSION_MAJOR == 5 && DTK_VERSION_MINOR == 4 && DTK_VERSION_PATCH >= 10)) + w->doPrintWithLargeDoc(p, pages); +#endif + + EXPECT_NE(w, nullptr); + w->deleteLater(); + editwrapper_texteditor->deleteLater(); + w->m_printDoc->deleteLater(); + w->m_pPreview->deleteLater(); + delete p; + p = nullptr; +} + +void stubProcessEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) +{ + Q_UNUSED(flags); +} + +TEST(UT_Window_doprint, UT_Window_cloneLargeDocument) +{ + Window* w = new Window(); + EditWrapper* wra = new EditWrapper(w); + QString text = "123"; + wra->textEditor()->document()->setPlainText(text); + + // 不在ut中使用Eventloop + typedef void (*Func)(QEventLoop::ProcessEventsFlags); + Stub s1; + s1.set((Func)ADDR(QCoreApplication, processEvents), stubProcessEvents); + + // 拷贝数据 + w->cloneLargeDocument(wra); + EXPECT_FALSE(w->m_printDocList.isEmpty()); + if (!w->m_printDocList.isEmpty()) { + EXPECT_NE(w->m_printDocList.first().doc, nullptr); + } + + // 清空数据 + w->clearPrintTextDocument(); + EXPECT_TRUE(w->m_printDocList.isEmpty()); + + wra->deleteLater(); + w->deleteLater(); +} + + +TEST(UT_Window_slotClearDoubleCharaterEncode, UT_Window_slotClearDoubleCharaterEncode) +{ + Window* w = new Window(); + + Stub s1;s1.set(ADDR(Window,handleReplaceAll),Window_updateSabeAsFileNameTemp_stub); + + w->slotClearDoubleCharaterEncode(); + + EXPECT_NE(w,nullptr); + w->deleteLater(); +} + + + +TEST(UT_Window_dropEvent, UT_Window_dropEvent) +{ + Window* w = new Window(); + QMimeData* data = new QMimeData; + QList urls = {QUrl("http://")}; + data->setUrls(urls); + QDropEvent* d = new QDropEvent(QPointF(100,100), Qt::MoveAction,data ,Qt::LeftButton, Qt::ShiftModifier); + + w->dropEvent(d); + + EXPECT_NE(w,nullptr); + w->deleteLater(); + data->deleteLater(); + delete d; d=nullptr; +} + +TEST(UT_Window_setPrintEnabled, UT_Window_setPrintEnabled) +{ + Window* w = new Window(); + w->m_menu = new DMenu; + w->setPrintEnabled(true); + + EXPECT_NE(w,nullptr); + w->deleteLater(); +} + +TEST(UT_Window_getStackedWgt, UT_Window_getStackedWgt) +{ + Window* w = new Window(); + w->getStackedWgt(); + + EXPECT_NE(w,nullptr); + w->deleteLater(); +} + + +TEST(UT_Window_asynPrint, UT_Window_asynPrint) +{ + Window* w = new Window(); + QPainter* painter = new QPainter(w); + DPrinter* printer = new DPrinter(); + w->m_printDoc = new QTextDocument; + QVector pr{1,2,3}; + + Stub stub; + stub.set(ADDR(Window,printPage),retintstub); + //bool newPage() override; + typedef bool (*fptr)(DPrinter*); + fptr A_foo = (fptr)(&DPrinter::newPage); + stub.set(A_foo,retintstub); + + w->asynPrint(*painter,printer,pr); + + EXPECT_NE(w,nullptr); + w->deleteLater(); + delete painter; + painter=nullptr; + delete printer; + printer=nullptr; + w->m_printDoc->deleteLater(); +} + +TEST(UT_Window_slot_setTitleFocus, UT_Window_slot_setTitleFocus_002) +{ + Window* w = new Window(); + EditWrapper* wra = new EditWrapper(w); + w->m_wrappers["a"] = wra; + + Stub stub; + stub.set(ADDR(Tabbar,currentPath),retstringstub); + //bool newPage() override; +// typedef bool (*fptr)(DPrinter*); +// fptr A_foo = (fptr)(&DPrinter::newPage); +// stub.set(A_foo,retintstub); + + stringvalue = "a"; + w->slot_setTitleFocus(); + + EXPECT_NE(w,nullptr); + w->deleteLater(); +} + +TEST(UT_Window_rehighlightPrintDoc, rehighlightPrintDoc_HighlightCpp_pass) +{ + Window* w = new Window; + w->addBlankTab(); + w->m_printWrapper = w->currentWrapper(); + QTextDocument *doc = new QTextDocument; + doc->setPlainText("#include ;\n" + "int main(int argc, char *argv[]) { }"); + + CSyntaxHighlighter *highlighter = new CSyntaxHighlighter(doc); + KSyntaxHighlighting::Repository repository; + highlighter->setDefinition(repository.definitionForName("C++")); + highlighter->setTheme(repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + + w->rehighlightPrintDoc(doc, highlighter); + EXPECT_FALSE(doc->firstBlock().textFormats().isEmpty()); + + doc->deleteLater(); + w->deleteLater(); +} + + diff --git a/tests/src/widgets/ut_window.h b/tests/src/widgets/ut_window.h new file mode 100644 index 0000000000000000000000000000000000000000..cb217bce4053cc7a0660730c4b3fc9c7bf1e7871 --- /dev/null +++ b/tests/src/widgets/ut_window.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef UT_Window_H +#define UT_Window_H +#include "gtest/gtest.h" +#include "../../src/editor/editwrapper.h" +#include "../../src/widgets/window.h" +#include "../../src/startmanager.h" +#include "../../src/editor/dtextedit.h" +#include "../stub.h" +#include "../../src/controls/replacebar.h" +#include +#include +#include + + +class UT_Window: public QObject, public::testing::Test +{ +public: + UT_Window(); + EditWrapper * edit; + Window * window; +}; + +#endif // UT_Window_H diff --git a/tests/test-prj-running.sh b/tests/test-prj-running.sh new file mode 100644 index 0000000000000000000000000000000000000000..a2011ca8b4c5052e03ba0bf79d33fccd38314ba8 --- /dev/null +++ b/tests/test-prj-running.sh @@ -0,0 +1,35 @@ +#!/bin/bash +builddir=build +reportdir=build-ut +rm -r $builddir +rm -r ../$builddir +rm -r $reportdir +rm -r ../$reportdir +mkdir ../$builddir +mkdir ../$reportdir +cd ../$builddir +#编译 +cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_SAFETYTEST_ARG="CMAKE_SAFETYTEST_ARG_ON" .. +make -j8 +#生成asan日志和ut测试xml结果 +./tests/deepin-editor-test --gtest_output=xml:./report/report_deepin-editor.xml + +workdir=$(cd ../$(dirname $0)/$builddir; pwd) + +mkdir -p report +#统计代码覆盖率并生成html报告 +lcov -d $workdir -c -o ./coverage.info + +lcov --extract ./coverage.info '*/src/*' -o ./coverage.info + +lcov --remove ./coverage.info '*/tests/*' -o ./coverage.info + +genhtml -o ./html ./coverage.info + +mv ./html/index.html ./html/cov_deepin-editor.html +#对asan、ut、代码覆盖率结果收集至指定文件夹 +cp -r html ../$reportdir/ +cp -r report ../$reportdir/ +cp -r asan*.log* ../$reportdir/asan_deepin-editor.log + +exit 0 diff --git a/translate_generation.sh b/translate_generation.sh new file mode 100644 index 0000000000000000000000000000000000000000..58b89cbdebb67d98234b5bb6753c1c0cf41590e0 --- /dev/null +++ b/translate_generation.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# this file is used to auto-generate .qm file from .ts file. +# author: shibowen at linuxdeepin.com + +lupdate src/ -ts -no-obsolete translations/*.ts + +desk_ts_list=(`ls translations/desktop/*.ts`) +for ts in "${desk_ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done + +ts_list=(`ls translations/*.ts`) + +for ts in "${ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done \ No newline at end of file diff --git a/translations/deepin-editor.ts b/translations/deepin-editor.ts new file mode 100644 index 0000000000000000000000000000000000000000..2ff87886c3fd7c5bfede013f25a2983086521f06 --- /dev/null +++ b/translations/deepin-editor.ts @@ -0,0 +1,1309 @@ + + + + + BottomBar + + + Row + Row + + + + Column + Column + + + + Characters %1 + Characters %1 + + + + Loading: + Loading: + + + + DDropdownMenu + + + + + None + None + + + + EditWrapper + + + + + + Save + Save + + + + Do you want to save this file? + Do you want to save this file? + + + + + Cancel + Cancel + + + + Encoding changed. Do you want to save the file now? + Encoding changed. Do you want to save the file now? + + + + Discard + Discard + + + + + You do not have permission to save %1 + You do not have permission to save %1 + + + + File removed on the disk. Save it now? + File removed on the disk. Save it now? + + + + File has changed on disk. Reload? + File has changed on disk. Reload? + + + + + INSERT + INSERT + + + + OVERWRITE + OVERWRITE + + + + R/O + R/O + + + + The file cannot be read, which may be too large or has been damaged! + + + + + FindBar + + + Find + Find + + + + Previous + Previous + + + + Next + Next + + + + JumpLineBar + + + Go to Line: + Go to Line: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Text Editor is a powerful tool for viewing and editing text files. + + + + Text Editor + Text Editor + + + + PathSettingWgt + + + Remember the last used path + Remember the last used path + + + + Same path as the current file + Same path as the current file + + + + Customize the default path + Customize the default path + + + + QObject + + + Text Editor + Text Editor + + + + + + + + + + Encoding + Encoding + + + + Basic + Basic + + + + Font Style + Font Style + + + + Font + Font + + + + Font Size + Font Size + + + + Shortcuts + Shortcuts + + + + + Keymap + Keymap + + + + + + Window + Window + + + + New tab + New tab + + + + New window + New window + + + + Save + Save + + + + Save as + Save as + + + + Next tab + Next tab + + + + Previous tab + Previous tab + + + + Close tab + Close tab + + + + Close other tabs + Close other tabs + + + + Restore tab + Restore tab + + + + Open file + Open file + + + + Increment font size + Increment font size + + + + Decrement font size + Decrement font size + + + + Reset font size + Reset font size + + + + Help + Help + + + + Toggle fullscreen + Toggle fullscreen + + + + Find + Find + + + + Find Next + Find Next + + + + Find Previous + Find Previous + + + + Replace + Replace + + + + Go to line + Go to line + + + + Save cursor position + Save cursor position + + + + Reset cursor position + Reset cursor position + + + + Exit + Exit + + + + Display shortcuts + Display shortcuts + + + + Print + Print + + + + Editor + Editor + + + + Increase indent + Increase indent + + + + Decrease indent + Decrease indent + + + + Forward character + Forward character + + + + Backward character + Backward character + + + + Forward word + Forward word + + + + Backward word + Backward word + + + + Next line + Next line + + + + Previous line + Previous line + + + + New line + New line + + + + New line above + New line above + + + + New line below + New line below + + + + Duplicate line + Duplicate line + + + + Delete to end of line + Delete to end of line + + + + Delete current line + Delete current line + + + + Swap line up + Swap line up + + + + Swap line down + Swap line down + + + + Scroll up one line + Scroll up one line + + + + Scroll down one line + Scroll down one line + + + + Page up + Page up + + + + Page down + Page down + + + + Move to end of line + Move to end of line + + + + Move to start of line + Move to start of line + + + + Move to end of text + Move to end of text + + + + Move to start of text + Move to start of text + + + + Move to line indentation + Move to line indentation + + + + Upper case + Upper case + + + + Lower case + Lower case + + + + Capitalize + Capitalize + + + + Delete backward word + Delete backward word + + + + Delete forward word + Delete forward word + + + + Forward over a pair + Forward over a pair + + + + Backward over a pair + Backward over a pair + + + + Select all + Select all + + + + Copy + Copy + + + + Cut + Cut + + + + Paste + Paste + + + + Transpose character + Transpose character + + + + Mark + Mark + + + + Unmark + Unmark + + + + Copy line + Copy line + + + + Cut line + Cut line + + + + Merge lines + Merge lines + + + + Read-Only mode + Read-Only mode + + + + Add comment + Add comment + + + + Remove comment + Remove comment + + + + Undo + Undo + + + + Redo + Redo + + + + Add/Remove bookmark + Add/Remove bookmark + + + + Move to previous bookmark + Move to previous bookmark + + + + Move to next bookmark + Move to next bookmark + + + + Advanced + Advanced + + + + Window size + Window size + + + + Tab width + Tab width + + + + Paste by pressing a middle mouse button + Paste by pressing a middle mouse button + + + + Startup + Startup + + + + Reopen last closed tabs + Reopen last closed tabs + + + + Open/Save Settings + Open/Save Settings + + + + Word wrap + Word wrap + + + + Code folding flag + Code folding flag + + + + Show line numbers + Show line numbers + + + + Show bookmarks icon + Show bookmarks icon + + + + Show whitespaces and tabs + Show whitespaces and tabs + + + + Highlight current line + Highlight current line + + + + Color mark + Color mark + + + + Unicode + Unicode + + + + WesternEuropean + WesternEuropean + + + + CentralEuropean + CentralEuropean + + + + Baltic + Baltic + + + + Cyrillic + Cyrillic + + + + Arabic + Arabic + + + + Celtic + Celtic + + + + SouthEasternEuropean + SouthEasternEuropean + + + + Greek + Greek + + + + Hebrew + Hebrew + + + + ChineseSimplified + ChineseSimplified + + + + ChineseTraditional + ChineseTraditional + + + + Japanese + Japanese + + + + Korean + Korean + + + + Thai + Thai + + + + Turkish + Turkish + + + + Vietnamese + Vietnamese + + + + File not saved + File not saved + + + + + Line Endings + Line Endings + + + + ReplaceBar + + + Find + Find + + + + Replace With + Replace With + + + + Replace + Replace + + + + Skip + Skip + + + + Replace Rest + Replace Rest + + + + Replace All + Replace All + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standard + + + + Customize + Customize + + + + Normal + Normal + + + + Maximum + Maximum + + + + Fullscreen + Fullscreen + + + + This shortcut conflicts with system shortcut %1 + This shortcut conflicts with system shortcut %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + The shortcut %1 is invalid, please set another one. + + + + Cancel + Cancel + + + + Replace + Replace + + + + OK + OK + + + + StartManager + + + Untitled %1 + Untitled %1 + + + + Tabbar + + + Close tab + Close tab + + + + Close other tabs + Close other tabs + + + + More options + More options + + + + Close tabs to the left + Close tabs to the left + + + + Close tabs to the right + Close tabs to the right + + + + Close unmodified tabs + Close unmodified tabs + + + + TextEdit + + + Undo + Undo + + + + Redo + Redo + + + + Cut + Cut + + + + Copy + Copy + + + + Paste + Paste + + + + Delete + Delete + + + + Select All + Select All + + + + + Find + Find + + + + + Replace + Replace + + + + Go to Line + Go to Line + + + + Turn on Read-Only mode + Turn on Read-Only mode + + + + Turn off Read-Only mode + Turn off Read-Only mode + + + + Fullscreen + Fullscreen + + + + Exit fullscreen + Exit fullscreen + + + + Display in file manager + Display in file manager + + + + + Add Comment + Add Comment + + + + Text to Speech + Text to Speech + + + + Stop reading + Stop reading + + + + Speech to Text + Speech to Text + + + + Translate + Translate + + + + Column Mode + Column Mode + + + + Add bookmark + Add bookmark + + + + Remove Bookmark + Remove Bookmark + + + + Previous bookmark + Previous bookmark + + + + Next bookmark + Next bookmark + + + + Remove All Bookmarks + Remove All Bookmarks + + + + Fold All + Fold All + + + + Fold Current Level + Fold Current Level + + + + Unfold All + Unfold All + + + + Unfold Current Level + Unfold Current Level + + + + Color Mark + Color Mark + + + + Clear All Marks + Clear All Marks + + + + Clear Last Mark + Clear Last Mark + + + + Mark + Mark + + + + Mark All + Mark All + + + + Remove Comment + Remove Comment + + + + Copy failed: not enough memory + Copy failed: not enough memory + + + + Press ALT and click lines to edit in column mode + Press ALT and click lines to edit in column mode + + + + Change Case + Change Case + + + + Upper Case + Upper Case + + + + Lower Case + Lower Case + + + + Capitalize + Capitalize + + + + None + None + + + + Selected line(s) copied + Selected line(s) copied + + + + Current line copied + Current line copied + + + + Selected line(s) clipped + Selected line(s) clipped + + + + Current line clipped + Current line clipped + + + + Paste failed: not enough memory + Paste failed: not enough memory + + + + Read-Only mode is off + Read-Only mode is off + + + + + + + + + Read-Only mode is on + Read-Only mode is on + + + + WarningNotices + + + Reload + Reload + + + + Window + + + + Save as + Save as + + + + New window + New window + + + + New tab + New tab + + + + Open file + Open file + + + + + Save + Save + + + + Print + Print + + + + Switch theme + Switch theme + + + + + Settings + Settings + + + + + Read-Only + Read-Only + + + + You do not have permission to open %1 + You do not have permission to open %1 + + + + + Invalid file: %1 + Invalid file: %1 + + + + + Do you want to save this file? + Do you want to save this file? + + + + You do not have permission to save %1 + You do not have permission to save %1 + + + + Saved successfully + Saved successfully + + + + + + Save File + Save File + + + + Encoding + Encoding + + + + Read-Only mode is on + Read-Only mode is on + + + + Current location remembered + Current location remembered + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Editor + + + + Untitled %1 + Untitled %1 + + + + Cancel + Cancel + + + + Discard + Discard + + + diff --git a/translations/deepin-editor_ar.ts b/translations/deepin-editor_ar.ts new file mode 100644 index 0000000000000000000000000000000000000000..6d12b052473fad14022c030df429b1b1c8e65d94 --- /dev/null +++ b/translations/deepin-editor_ar.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + صف + + + + Column + عمود + + + + Characters %1 + الحروف 1% + + + + DDropdownMenu + + + + + None + لا شيء + + + + EditWrapper + + + File has changed on disk. Reload? + الملف الذي في القرص قد عُدِّل. أعيد التحميل؟ + + + + File removed on the disk. Save it now? + الملف الذي في القرص قد حُذِف. أحفظه الآن؟ + + + + Do you want to save this file? + هل تريد حفظ هذا الملف؟ + + + + Discard + إلغاء + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + لا تملك الإذن لحفظ 1% + + + + + INSERT + إدخال + + + + OVERWRITE + إعادة الكتابة + + + + R/O + قراءة + + + + + Cancel + إلغاء + + + + + + + Save + حفظ + + + + FindBar + + + Find + بحث + + + + Next + التالي + + + + Previous + السابق + + + + JumpLineBar + + + Go to Line: + انتقل إلى السطر: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + محرر النصوص هو أداة قوية لعرض وتحرير الملفات النصية. + + + + Text Editor + محرر نصي + + + + QObject + + + File not saved + لم يتم حفظ الملف + + + + Text Editor + محرر النصوص + + + + Basic + بسيط + + + + Font Style + نوع الخط + + + + Font + الخط + + + + Font Size + حجم الخط + + + + + Keymap + خارطة المفاتيح + + + + Shortcuts + الاختصارات + + + + Forward character + حرف للأمام + + + + Backward character + حرف للخلف + + + + Transpose character + تغيير مكان الحرف + + + + Tab width + عرض الشريط + + + + Word wrap + + + + + + + Window + النافذة + + + + New tab + لسان جديد + + + + New window + نافذة جديدة + + + + Save + حفظ + + + + Save as + حفظ باسم + + + + Next tab + اللسان التالي + + + + Previous tab + اللسان السابق + + + + Close tab + أغلاق اللسان + + + + Close other tabs + أغلاق الألسنة الأخرى + + + + Restore tab + استعادة الألسنة + + + + Open file + فتح الملف + + + + Increment font size + زد حجم الخط + + + + Decrement font size + أنقص حجم الخط + + + + Reset font size + إعادة تعيين حجم الخط + + + + Toggle fullscreen + تبديل ملء الشاشة + + + + Help + المساعدة + + + + Find + بحث + + + + Replace + استبدال + + + + Go to line + انتقال إلى السطر + + + + Save cursor position + حفظ موضع المؤشر + + + + Reset cursor position + إعادة تعيين موضع المؤشر + + + + Exit + خروج + + + + Display shortcuts + عرض الاختصارات + + + + Print + طباعة + + + + Editor + المحرر + + + + Increase indent + زيادة المسافة البادئة + + + + Decrease indent + نقصان المسافة البادئة + + + + Forward word + كلمة إلى الأمام + + + + Backward word + كلمة إلى الخلف + + + + Next line + السطر التالي + + + + Previous line + السطر السابق + + + + New line + سطر جديد + + + + New line above + سطر جديد أعلى + + + + New line below + سطر جديد أسفل + + + + Duplicate line + مضاعفة السطر + + + + Delete to end of line + حذف إلى نهاية السطر + + + + Delete current line + حذف السطر الحالي + + + + Swap line up + بادل سطرًا للأعلى + + + + Swap line down + بادل سطرًا للأسفل + + + + Scroll up one line + انتقل لأعلى سطرًا واحدًا + + + + Scroll down one line + انتقل لأسفل سطرًا واحدًا + + + + Page up + صفحة لأعلى + + + + Page down + صفحة لأسفل + + + + Move to end of line + انتقل الى نهاية السطر + + + + Move to start of line + انتقل الى بداية السطر + + + + Move to end of text + انتقل إلى نهاية النص + + + + Move to start of text + انتقل إلى أول النص + + + + Move to line indentation + تحريك إلى سطر جديد + + + + Upper case + حرف كبير + + + + Lower case + حرف صغير + + + + Capitalize + تحويل الحروف إلى حروف كبيرة + + + + Delete backward word + حذف الكلمة الخلفية + + + + Delete forward word + حذف الكلمة الأمامية + + + + Forward over a pair + تحويل إلى الأمام لأكثر من زوج + + + + Backward over a pair + تحويل إلى الخلف لأكثر من زوج + + + + Select all + اختر الكل + + + + Copy + نسخ + + + + Cut + قص + + + + Paste + لصق + + + + Mark + وضع علامة + + + + Unmark + إزالة علامة + + + + Copy line + نسخ السطر + + + + Cut line + قص السطر + + + + Merge lines + دمج السطور + + + + Read-Only mode + وضع القراءة فقط + + + + Add comment + + + + + Remove comment + + + + + Undo + تراجع + + + + Redo + أعد + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Advanced + متقدم + + + + Window size + حجم النافذة + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Color mark + + + + + + + + + + Encoding + الترميز + + + + + + Line Endings + نهايات السطور + + + + ReplaceBar + + + Find + بحث + + + + Replace With + استبدال بـ + + + + Replace + استبدال + + + + Skip + تخطي + + + + Replace Rest + استبدال الباقي + + + + Replace All + استبدال الكل + + + + Settings + + + Standard + قياسي + + + + Customize + معدل + + + + Normal + عادي + + + + Maximum + أقصى + + + + Fullscreen + ملء الشاشة + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + إلغاء + + + + Replace + استبدال + + + + OK + + + + + StartManager + + + Untitled %1 + بلا عنوان %1 + + + + Tabbar + + + Close tab + أغلق اللسان + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + Close other tabs + أغلق الألسنة الأخرى + + + + TextEdit + + + Undo + تراجع + + + + Redo + أعد + + + + Cut + قص + + + + Copy + نسخ + + + + Paste + لصق + + + + Delete + حذف + + + + Select All + اختر الكل + + + + + Find + بحث + + + + + Replace + استبدال + + + + Go to Line + انتقال إلى سطر + + + + Turn on Read-Only mode + تشغيل وضع القراءة فقط + + + + Turn off Read-Only mode + ايقاف وضع القراءة فقط + + + + Fullscreen + ملء الشاشة + + + + Exit fullscreen + الخروج من وضع ملء للشاشة + + + + Display in file manager + عرض في مدير الملفات + + + + + Add Comment + + + + + Column Mode + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Text to Speech + النص إلى الكلام + + + + Stop reading + توقف عن القراءة + + + + Speech to Text + الكلام إلى النص + + + + Translate + تَرجم + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Mark All + + + + + Mark + وضع علامة + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Change Case + غيِّر الخانة + + + + Upper Case + احرف الكبيرة + + + + Lower Case + أحرف صغيرة + + + + Capitalize + تحويل الحروف إلى حروف كبيرة + + + + None + لا شيء + + + + Selected line(s) copied + تم نسخ الخط (الخطوط) المحدد + + + + Current line copied + تم نسخ السطر الحالي + + + + Selected line(s) clipped + تم قص الخط (الخطوط) المحدد + + + + Current line clipped + تم قص الخط المحدد + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + وضع القراءة فقط متوقف + + + + + + Read-Only mode is on + وضع القراءة فقط قيد التشغيل + + + + WarningNotices + + + Reload + أعد التحميل + + + + Window + + + New window + نافذة جديدة + + + + New tab + لسان جديد + + + + Open file + فتح الملف + + + + + Save as + حفظ باسم + + + + Print + طباعة + + + + Switch theme + غيِّر السمة + + + + + Read-Only + للقراءة فقط + + + + Saved successfully + حُفِظ بنجاح + + + + Read-Only mode is on + وضع القراءة فقط قيد التشغيل + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + إلغاء + + + + + Settings + إعدادات + + + + You do not have permission to open %1 + لا تملك الإذن لفتح 1% + + + + Invalid file: %1 + ملف غير مدعوم: 1% + + + + + + Save File + حفظ الملف + + + + + Do you want to save this file? + هل تريد حفظ هذا الملف؟ + + + + Encoding + الترميز + + + + Editor + المحرر + + + + You do not have permission to save %1 + لا تملك الإذن لحفظ 1% + + + + Untitled %1 + بلا عنوان %1 + + + + Current location remembered + تم تذكر المكان الحالي + + + + Cancel + إلغاء + + + + + Save + حفظ + + + diff --git a/translations/deepin-editor_az.ts b/translations/deepin-editor_az.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f412fc0a964820ddfecbed189e4d3c393725b44 --- /dev/null +++ b/translations/deepin-editor_az.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Sətir + + + + Column + Sütun + + + + Characters %1 + %1 simvol + + + + Loading: + + + + + DDropdownMenu + + + + + None + Heç biri + + + + EditWrapper + + + + + + Save + Saxlamaq + + + + Do you want to save this file? + Bu faylı saxlamaq istəyirsiniz? + + + + + Cancel + İmtina + + + + Encoding changed. Do you want to save the file now? + Kodlaşma dəyişdirildi. Faylı indi saxlamaq istəyirsiniz? + + + + Discard + Rədd etmək + + + + You do not have permission to save %1 + %1 saxlamaq üçün imtiyazınız yoxdur + + + + File removed on the disk. Save it now? + Diskdəki fayl silindi. O, indi saxlanılsın? + + + + File has changed on disk. Reload? + Diskdəki fayl dəyişdirildi. Yenidən yüklənsin? + + + + + INSERT + DAXİL_ETMƏK + + + + OVERWRITE + ÜZƏRİNƏ_YAZMAQ + + + + R/O + Y/O + + + + FindBar + + + Find + Tapmaq + + + + Previous + Əvvəlki + + + + Next + Sonrakı + + + + JumpLineBar + + + Go to Line: + Sətirə keçin: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Mətn Redaktoru, mətn fayllarına baxmaq və onlara düzəliş etmək üçün güclü bir vasitədir. + + + + Text Editor + Mətn Redaktoru + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Mətn Redaktoru + + + + + + + + + Encoding + Kodlaşma + + + + Basic + Əsas + + + + Font Style + Şrift üslubu + + + + Font + Şrift + + + + Font Size + Şriftin ölçüsü + + + + Shortcuts + Qısa yollar + + + + + Keymap + Düymələr xəritəsi + + + + + + Window + Pəncərə + + + + New tab + Yeni vərəq + + + + New window + Yeni pəncərə + + + + Save + Saxlamaq + + + + Save as + Belə saxlayın + + + + Next tab + Sonrakı vərəq + + + + Previous tab + Əvvəlki vərəq + + + + Close tab + Vərəqi bağlamaq + + + + Close other tabs + Digər vərəqləri bağlamaq + + + + Restore tab + Vərəqi bərpa etmək + + + + Open file + Faylı açın + + + + Increment font size + Şriftin ölçüsünü artırmaq + + + + Decrement font size + Şriftin ölçüsünü azaltmaq + + + + Reset font size + Şriftin ölçüsünü sıfırlamaq + + + + Help + Kömək + + + + Toggle fullscreen + Tam ekran açmaq + + + + Find + Tapmaq + + + + Replace + Əvəzləmək + + + + Go to line + Sətirə keçmək + + + + Save cursor position + Kursorun yerini saxlamaq + + + + Reset cursor position + Kursorun yerini sıfırlamaq + + + + Exit + Çıxış + + + + Display shortcuts + Qısayolları göstərmək + + + + Print + Çap + + + + Editor + Redaktor + + + + Increase indent + Abzası böyütmək + + + + Decrease indent + Abzası daraltmaq + + + + Forward character + Bir sonrakı somvol + + + + Backward character + Bir əvvəlki simvol + + + + Forward word + Başlanğıc söz + + + + Backward word + Bir əvvəlki söz + + + + Next line + Sonrakı sətir + + + + Previous line + Əvvəlki sətir + + + + New line + Yeni sətir + + + + New line above + Yeni sətir yuxarı + + + + New line below + Yeni sətir aşağı + + + + Duplicate line + Sətirin təkrarı + + + + Delete to end of line + Sətirin sonundək silmək + + + + Delete current line + Cari sətiri silmək + + + + Swap line up + Sətiri yuxarı dəyişmək + + + + Swap line down + Sətiri aşağı dəyişmək + + + + Scroll up one line + Bir sətir yuxarı sürüşdürmək + + + + Scroll down one line + Bir sətir aşağı sürüşdürmək + + + + Page up + Bir səhifə yuxarı + + + + Page down + Bir səhifə aşağı + + + + Move to end of line + Sətirin sonuna köçürmək + + + + Move to start of line + Sətirin başlanğıcına köçürmək + + + + Move to end of text + Mətnin sonuna köçürmək + + + + Move to start of text + Mətnin əvvəlinə köçürmək + + + + Move to line indentation + Sətirin abzasına keçmək + + + + Upper case + Böyük hərf + + + + Lower case + Kiçik hərf + + + + Capitalize + Baş hərflərlə + + + + Delete backward word + Bir əvvəlki sözü silmək + + + + Delete forward word + Bir sonrakı sözü silmək + + + + Forward over a pair + Sonrakı cüt + + + + Backward over a pair + Əvvəlki cüt + + + + Select all + Hamısını seçmək + + + + Copy + Kopyalamaq + + + + Cut + Kəsmək + + + + Paste + Yerləşdirmək + + + + Transpose character + Simvolun yerini dəyişmək + + + + Mark + İşarələmək + + + + Unmark + İşarəni qaldırmaq + + + + Copy line + Sətiri kopyalamaq + + + + Cut line + Sətiri kəsmək + + + + Merge lines + Sətirləri birləşdirmək + + + + Read-Only mode + Yalnız-oxu rejimi + + + + Add comment + Şərh əlavə edin + + + + Remove comment + Şərhi silmək + + + + Undo + Qaytarmaq + + + + Redo + Hazır + + + + Add/Remove bookmark + Əlfəcin əlavə edin/silin + + + + Move to previous bookmark + Əvvəlki əlfəcinlərə köçürmək + + + + Move to next bookmark + Sonrakı əlfəcinə köçürmək + + + + Advanced + Əlavə + + + + Window size + Pəncərə ölçüsü + + + + Tab width + Vərəqin eni + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Sözü sətirə keçirmək + + + + Code folding flag + Kod yığma bayrağı + + + + Show line numbers + Sətir nömrəsini göstərmək + + + + Show bookmarks icon + Əlfəcinlərin nişanlarını göstərmək + + + + Show whitespaces and tabs + Ara boşluqlarını və vərəqləri göstərmək + + + + Highlight current line + Cari sətiri vurğulamaq + + + + Color mark + Rəng markeri + + + + Unicode + Unicode + + + + WesternEuropean + Qərbi_Avropa + + + + CentralEuropean + Mərkəzi_Avropa + + + + Baltic + Baltik + + + + Cyrillic + Kiril + + + + Arabic + Ərəb + + + + Celtic + Kelt + + + + SouthEasternEuropean + Cənub-Şərqi_Avropa + + + + Greek + Yunan + + + + Hebrew + İvrit + + + + ChineseSimplified + Çin_Sadələşdirilmiş + + + + ChineseTraditional + Çin_Ənənəvi + + + + Japanese + Yapon + + + + Korean + Koreya + + + + Thai + Tay + + + + Turkish + Türk + + + + Vietnamese + Vyetnam + + + + File not saved + Fayl saxlanılmadı + + + + + + Line Endings + Sətrin sonu + + + + ReplaceBar + + + Find + Tapmaq + + + + Replace With + Bununla əvəzləmək + + + + Replace + Əvəzləmək + + + + Skip + Ötürmək + + + + Replace Rest + Başqalarını dəyişin + + + + Replace All + Hamısını əvəzləmək + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standard + + + + Customize + Özəlləşdirmək + + + + Normal + Normal + + + + Maximum + Ən çox + + + + Fullscreen + Tam ekran + + + + This shortcut conflicts with system shortcut %1 + Bu qısayol %1 sistem qısayolu ilə ziddiyyətlidir + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Bu qısayol %1 ilə ziddiyyətlidir, bu qısayolu dərhal qüvvəyə mindirmək üçün Əvəzləmək düyməsinə vurun + + + + + The shortcut %1 is invalid, please set another one. + %1 qısayolu işləmir, başqa birini təyin edin. + + + + Cancel + İmtina + + + + Replace + Əvəzləmək + + + + OK + OLDU + + + + StartManager + + + Untitled %1 + Başlıqsız %1 + + + + Tabbar + + + Close tab + Vərəqi bağlamaq + + + + Close other tabs + Digər vərəqləri baölamaq + + + + More options + Daha çox seçimlər + + + + Close tabs to the left + Soldakı vərəqləri bağlamaq + + + + Close tabs to the right + Saödakı vərəqləri bağlamaq + + + + Close unmodified tabs + Dəyişdirilməmiş vərəqləri bağlamaq + + + + TextEdit + + + Undo + Qaytarmaq + + + + Redo + Hazır + + + + Cut + Kəsmək + + + + Copy + Kopyalamaq + + + + Paste + Yerləşdirmək + + + + Delete + Silmək + + + + Select All + Hamısını seçmək + + + + + Find + Tapmaq + + + + + Replace + Əvəzləmək + + + + Go to Line + Sətirə keçin + + + + Turn on Read-Only mode + Yalnız-oxu, rejimini açmaq + + + + Turn off Read-Only mode + Yalnız-oxu, rejimini söndürmək + + + + Fullscreen + Tam ekran + + + + Exit fullscreen + Tam ekrandan çıxış + + + + Display in file manager + Fayl bələdçisində göstərmək + + + + + Add Comment + Şərh əlavə edin + + + + Text to Speech + Mətndən_Nitqə + + + + Stop reading + Oxunuşu saxlamaq + + + + Speech to Text + Nitqdən_Mətnə + + + + Translate + Tərcümə + + + + Column Mode + Sütun rejimi + + + + Add bookmark + Əlfəcin əlavə etmək + + + + Remove Bookmark + Əlfəcini silmək + + + + Previous bookmark + Əvvəlki əlfəcin + + + + Next bookmark + Sonrakı əlfəcin + + + + Remove All Bookmarks + Bütün əlfəcinləri silmək + + + + Fold All + Hamısını bükmək + + + + Fold Current Level + Cari səviyyəni bükmək + + + + Unfold All + Hamısını açmaq + + + + Unfold Current Level + Cari səviyyəni açmaq + + + + Color Mark + Rəng markeri + + + + Clear All Marks + Bütün işarələri qaldırmaq + + + + Clear Last Mark + Sonuncu işarəni qaldırmaq + + + + Mark + İşarələmək + + + + Mark All + Hamısını işarələmək + + + + Remove Comment + Şərhi silmək + + + + Copy failed: not enough memory + Kopyalanmadı: kifayət qədər yaddaş yoxdur + + + + Press ALT and click lines to edit in column mode + Sütun rejimində düzəliş etmək üçün ALT düyməsini basın və sətirə vurun + + + + Change Case + Böyük-kiçik hərfi dəyişdirmək + + + + Upper Case + Böyük hərf + + + + Lower Case + Kiçik hərf + + + + Capitalize + Baş hərflərlə + + + + None + Heç biri + + + + Selected line(s) copied + Seçilmiş sətir(lər) kopyalandı + + + + Current line copied + Cari sətir kopyalandı + + + + Selected line(s) clipped + Seçilmiş sətir(lər) kəsildi + + + + Current line clipped + Cari sətir kəsildi + + + + Paste failed: not enough memory + Yerləşdirilmədi: kifayət qədər yaddaş yoxdur + + + + Read-Only mode is off + Yalnız-oxu, rejimi söndürülüb + + + + + + Read-Only mode is on + Yalnız-ozu, rejimi aktivdir + + + + WarningNotices + + + Reload + Yenidən yükləmək + + + + Window + + + + Save as + Belə saxlayın + + + + New window + Yeni pəncərə + + + + New tab + Yeni vərəq + + + + Open file + Faylı açın + + + + + Save + Saxlamaq + + + + Print + Çap + + + + Switch theme + Mövzunu dəyişmək + + + + + Settings + Ayarlar + + + + + Read-Only + Yalnız-oxumaq + + + + You do not have permission to open %1 + %1 açmaq üçün imtiyazınız yoxdur + + + + Invalid file: %1 + Səhv fayl: %1 + + + + + Do you want to save this file? + Bu faylı saxlamaq istəyirsiniz? + + + + You do not have permission to save %1 + %1 saxlamaq üçün imtiyazınız yoxdur + + + + Saved successfully + Uğurla saxlanıldı + + + + + + Save File + Faylı saxlayın + + + + Encoding + Kodlaşma + + + + Read-Only mode is on + Yalnız-ozu, rejimi aktivdir + + + + Current location remembered + Cari yer yadda saxlanıldı + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Redaktor + + + + Untitled %1 + Başlıqsız %1 + + + + Cancel + İmtina + + + + Discard + Rədd etmək + + + \ No newline at end of file diff --git a/translations/deepin-editor_bg.ts b/translations/deepin-editor_bg.ts new file mode 100644 index 0000000000000000000000000000000000000000..f0f97dee92453a78a7dec70b211df7fa95f8ceb8 --- /dev/null +++ b/translations/deepin-editor_bg.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + Ред + + + + Column + Колона + + + + Characters %1 + Знак %1 + + + + DDropdownMenu + + + + + None + Нищо + + + + EditWrapper + + + File has changed on disk. Reload? + Файлът е променен на диска. Презареждане? + + + + File removed on the disk. Save it now? + Файлът е премахнат на диска. Запазвате ли го? + + + + Do you want to save this file? + Искате ли да запазите този файл? + + + + Discard + Отказ + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + Нямате разрешение да запазите %1 + + + + + INSERT + ВМЪКВАНЕ + + + + OVERWRITE + ПРЕЗАПИСВАНЕ + + + + R/O + R/O + + + + + Cancel + Отказ + + + + + + + Save + Запазване + + + + FindBar + + + Find + Търсене + + + + Next + Следващ + + + + Previous + Предишен + + + + JumpLineBar + + + Go to Line: + Отиди на ред: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + + + + + Text Editor + + + + + QObject + + + File not saved + + + + + Text Editor + + + + + Basic + Основен + + + + Font Style + Стил на шрифт + + + + Font + Щрифт + + + + Font Size + Размер на шрифт + + + + + Keymap + Клавиатурната подредба + + + + Shortcuts + Преки пътища + + + + Forward character + Следваш знак + + + + Backward character + Предишен знак + + + + Transpose character + Транспониращ символ + + + + Add comment + + + + + Remove comment + + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Tab width + ширина на раздела + + + + + + Window + Прозорец + + + + New tab + Нов раздел + + + + New window + Нов прозорец + + + + Save + Запазване + + + + Save as + Запази като + + + + Next tab + Следващ раздел + + + + Previous tab + Предишен раздел + + + + Close tab + Затваряне на раздел + + + + Close other tabs + Затвори другите раздели + + + + Restore tab + Възстанови раздел + + + + Open file + Отваряне на файл + + + + Reset font size + Възстановяване на размера на шрифта + + + + Toggle fullscreen + Превключи на цял екран + + + + Help + + + + + Increment font size + + + + + Decrement font size + + + + + Find + Търсене + + + + Replace + Замяна + + + + Go to line + Отиди на ред + + + + Save cursor position + Запази положението на курсора + + + + Reset cursor position + Възстанови положението на курсора + + + + Exit + Изход + + + + Display shortcuts + Покажи преките пътища + + + + Print + Принтиране + + + + Editor + Редактор + + + + Increase indent + Увеличи отстъпа + + + + Decrease indent + Намали отстъпа + + + + Forward word + Следваща дума + + + + Backward word + Предишна дума + + + + Next line + Следваща линия + + + + Previous line + Предна линия + + + + New line + Нов ред + + + + New line above + Нов ред отгоре + + + + New line below + Нов ред отдолу + + + + Duplicate line + Дублирай ред + + + + Delete to end of line + Изтрий до края на реда + + + + Delete current line + Изтрий текущият ред + + + + Swap line up + Прехвърли реда нагоре + + + + Swap line down + Прехвърли реда надолу + + + + Scroll up one line + Превъртане нагоре с един ред + + + + Scroll down one line + Превъртане надолу с един ред + + + + Page up + Страница нагоре + + + + Page down + Страница надолу + + + + Move to end of line + Преместване до края на реда + + + + Move to start of line + Преместване до началото на реда + + + + Move to end of text + Преместване до края на текста + + + + Move to start of text + Преместване до началото на текста + + + + Move to line indentation + Преместване до отстъпа на реда + + + + Upper case + Големи букви + + + + Lower case + Малки букви + + + + Capitalize + С големи букви + + + + Delete backward word + Изтрий предишна дума + + + + Delete forward word + Изтрий следваща дума + + + + Forward over a pair + Напред през два + + + + Backward over a pair + Назад през два + + + + Select all + Избор на всичко + + + + Copy + Копиране + + + + Cut + Премести + + + + Paste + Прилагане + + + + Mark + Маркиране + + + + Unmark + Размаркиране + + + + Copy line + Копиране на ред + + + + Cut line + Преместване на линия + + + + Merge lines + Сливане на ред + + + + Read-Only mode + Режим "Само за четене" + + + + Word wrap + + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Undo + Поправи + + + + Redo + Повторение + + + + Advanced + За напреднали + + + + Window size + Размер на прозорец + + + + + + + + + Encoding + Кодиране + + + + + + Line Endings + Крайни линии + + + + ReplaceBar + + + Find + Търсене + + + + Replace With + + + + + Replace + Рамени + + + + Skip + Пропусни + + + + Replace Rest + Замени останалото + + + + Replace All + Замени всички: + + + + Settings + + + Standard + Стандартно + + + + Customize + Потребителско + + + + Normal + Нормално + + + + Maximum + Максимум + + + + Fullscreen + На цял екран + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + Отказ + + + + Replace + + + + + OK + + + + + StartManager + + + Untitled %1 + + + + + Tabbar + + + Close tab + Затваряне на раздел + + + + Close other tabs + Затвори другите раздели + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + TextEdit + + + Undo + Поправи + + + + Redo + Повторение + + + + Cut + Премести + + + + Copy + Копиране + + + + Paste + Прилагане + + + + Delete + Изтриване + + + + Select All + Избор на всичко + + + + + Find + Търсене + + + + + Replace + Рамени + + + + Go to Line + Отиди на ред + + + + Turn on Read-Only mode + Включване режим "Само за четене" + + + + Turn off Read-Only mode + Изключване режим "Само за четене" + + + + Fullscreen + На цял екран + + + + Exit fullscreen + Изход от цял екран + + + + Display in file manager + Отвори във файловия диспечер + + + + + Add Comment + + + + + Text to Speech + + + + + Stop reading + + + + + Speech to Text + + + + + Translate + + + + + Column Mode + + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Mark + Маркиране + + + + Mark All + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + Смяна на големината + + + + Upper Case + Големи букви + + + + Lower Case + Малки букви + + + + Capitalize + С големи букви + + + + None + Нищо + + + + Selected line(s) copied + + + + + Current line copied + + + + + Selected line(s) clipped + + + + + Current line clipped + + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + Режим "Само за четене" е изключен + + + + + + Read-Only mode is on + Режим "Само за четене" е включен + + + + WarningNotices + + + Reload + Презареди + + + + Window + + + New window + Нов прозорец + + + + New tab + Нов раздел + + + + Open file + Отваряне на файл + + + + + Save as + Запази като + + + + Print + Принтиране + + + + Switch theme + Смени тема + + + + + Read-Only + Само за четене + + + + Saved successfully + Успешно запазено + + + + Read-Only mode is on + Режим "Само за четене" е включен + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + Отказ + + + + + Settings + Настройки + + + + You do not have permission to open %1 + Нямате разрешение да отворите %1 + + + + Invalid file: %1 + Невалиден файл: %1 + + + + + + Save File + Запази файла + + + + + Do you want to save this file? + Искате ли да запазите този файл? + + + + Encoding + Кодиране + + + + Editor + Редактор + + + + You do not have permission to save %1 + Нямате разрешение да запазите %1 + + + + Untitled %1 + + + + + Current location remembered + + + + + Cancel + Отказ + + + + + Save + Запазване + + + diff --git a/translations/deepin-editor_bo.ts b/translations/deepin-editor_bo.ts new file mode 100644 index 0000000000000000000000000000000000000000..f30e7a68c627efc5c4ca05235091f0ed162b2fd5 --- /dev/null +++ b/translations/deepin-editor_bo.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + འཕྲེད་སྟར། + + + + Column + གཞུང་སྟར། + + + + Characters %1 + ཡིག་འབྲུ། %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + མེད། + + + + EditWrapper + + + + + + Save + ཉར་ཚགས། + + + + Do you want to save this file? + ཁྱེད་ཀྱིས་ཡིག་ཆ་འདི་ཉར་ཚགས་བྱེད་དམ། + + + + + Cancel + འདོར་བ། + + + + Encoding changed. Do you want to save the file now? + ཡིག་ཆའི་ཨང་སྒྲིག་བཟོ་བཅོས་བྱས་ཟིན་པས། སྔོན་ལ་ཉར་ཚགས་བྱེད་དམ། + + + + Discard + མི་ཉར། + + + + You do not have permission to save %1 + ཁྱེད་ལ་%1ཉར་བའི་དབང་ཚད་མེད། + + + + File removed on the disk. Save it now? + སྡུད་སྡེར་ནང་གི་ཐོག་མའི་ཡིག་ཆ་འབུད་ཟིན་པས། དེ་ཉར་རམ། + + + + File has changed on disk. Reload? + སྡུད་སྡེར་ནང་གི་ཐོག་མའི་ཡིག་ཆ་བཟོ་བཅོས་བྱས་ཟིན་པས། བསྐྱར་འཇུག་བྱེད་དམ། + + + + + INSERT + ནང་འཇུག + + + + OVERWRITE + འགེབས་པ། + + + + R/O + ཀློག་ཙམ། + + + + FindBar + + + Find + འཚོལ་བ། + + + + Previous + གོང་མ། + + + + Next + རྗེས་མ། + + + + JumpLineBar + + + Go to Line: + འཕྲེད་སྟར་དུ་མཆོང་བ། + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + ཡིག་ཆ་རྩོམ་སྒྲིག་ཆས་ནི་ཡིག་ཆ་ལྟ་བ་དང་རྩོམ་སྒྲིག་བྱེད་པའི་ཡོ་བྱད་ཞིག་རེད། + + + + Text Editor + ཡིག་ཆ་རྩོམ་སྒྲིག་ཆས། + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + ཡིག་ཆ་རྩོམ་སྒྲུག་ཆས། + + + + + + + + + Encoding + ཨང་སྒྲིག + + + + Basic + རྨང་གཞིའི་སྒྲིག་བཀོད། + + + + Font Style + ཡིག་གཟུགས་དཔེ་དབྱིབས། + + + + Font + ཡིག་གཟུགས། + + + + Font Size + ཡིག་ཨང་། + + + + Shortcuts + མྱུར་མཐེབ། + + + + + Keymap + མྱུར་མཐེབ་རྟེན་འཕྲོ། + + + + + + Window + སྒེའུ་ཁུང་། + + + + New tab + ཁ་བྱང་ངོས་གསར། + + + + New window + སྒེའུ་ཁུང་གསར་པ། + + + + Save + ཉར་ཚགས། + + + + Save as + གཞན་ཉར། + + + + Next tab + ཁ་བྱང་ངོས་རྗེས་མ། + + + + Previous tab + ཁ་བྱང་ངོས་གོང་མ། + + + + Close tab + ཁ་བྱང་ངོས་ཁ་རྒྱག + + + + Close other tabs + ཁ་བྱང་ངོས་གཞན་དག་ཁ་རྒྱག + + + + Restore tab + ཁ་བྱང་ངོས་སླར་གསོ། + + + + Open file + ཡིག་ཆ་ཁ་ཕྱེ། + + + + Increment font size + ཡིག་ཨང་ཆེ་སྒྱུར། + + + + Decrement font size + ཡིག་ཨང་ཆུང་སྒྱུར། + + + + Reset font size + ཡིག་ཨང་སོར་ལོག + + + + Help + རོགས་པ། + + + + Toggle fullscreen + བརྙན་ཡོལ་ཡོངས་ལ་བརྗེ་བ། + + + + Find + འཚོལ་བ། + + + + Replace + བརྗེ་བ། + + + + Go to line + འཕྲེད་སྟར་དུ་མཆོང་བ། + + + + Save cursor position + འོད་རྟགས་གནས་ཡུལ་ཉར་བ། + + + + Reset cursor position + ཉར་བའི་འོད་རྟགས་གནས་ཡུལ་དུ་མཆོང་བ། + + + + Exit + ཕྱིར་འབུད། + + + + Display shortcuts + མྱུར་མཐེབ་འཆར་བ། + + + + Print + པར་འདེབས། + + + + Editor + རྩོམ་སྒྲིག + + + + Increase indent + སྐུམ་ཚད་ཆེར་གཏོང་། + + + + Decrease indent + སྐུམ་ཚད་ཆུང་གཏོང་། + + + + Forward character + གཡས་སུ་ཡིག་རྟགས་གཅིག་སྤོ་བ། + + + + Backward character + གཡོན་ལ་ཡིག་རྟགས་གཅིག་སྤོ་བ། + + + + Forward word + གཡས་སུ་ཚིག་གཅིག་སྤོ་བ། + + + + Backward word + གཡོན་དུ་ཚིག་གཅིག་སྤོ་བ། + + + + Next line + སྟར་པ་རྗེས་མ། + + + + Previous line + སྟར་པ་གོང་མ། + + + + New line + སྟར་པ་བརྗེ་བ། + + + + New line above + གོང་ལ་སྟར་པ་གཅིག་འཇུག་པ། + + + + New line below + འོག་ཏུ་སྟར་པ་གཅིག་འཇུག་པ། + + + + Duplicate line + འདྲ་བཤུ་བྱས་རྗེས་མིག་སྔའི་སྟར་པར་སྦྱར་བ། + + + + Delete to end of line + སྟར་པའི་མཇུག་བར་སུབ་པ། + + + + Delete current line + མིག་སྔའི་སྟར་པ་སུབ་པ། + + + + Swap line up + གོང་དུ་སྟར་པ་གཅིག་སྤོ་བ། + + + + Swap line down + འོག་ཏུ་སྟར་པ་གཅིག་སྤོ་བ། + + + + Scroll up one line + སྟེང་དུ་སྟར་པ་གཅིག་འགྲིལ་བ། + + + + Scroll down one line + འོག་ཏུ་སྟར་པ་གཅིག་འགྲིལ་བ། + + + + Page up + སྟེང་དུ་ཤོག་ལྷེ་གཅིག་འགྲིལ་བ། + + + + Page down + འོག་ཏུ་ཤོག་ལྷེ་གཅིག་འགྲིལ་བ། + + + + Move to end of line + སྟར་པའི་མཇུག་ཏུ་སྤོ་བ། + + + + Move to start of line + སྟར་པའི་མགོ་ལ་སྤོ་བ། + + + + Move to end of text + ཡིག་ཆའི་མཇུག་ཏུ་སྤོ་བ། + + + + Move to start of text + ཡིག་ཆའི་མགོ་ལ་སྤོ་བ། + + + + Move to line indentation + སྟར་པ་སྐུམ་སར་སྤོ་བ། + + + + Upper case + ཆེ་བྲིས་ལ་བརྗེ་བ། + + + + Lower case + ཆུང་བྲིས་ལ་བརྗེ་བ། + + + + Capitalize + མགོ་ཡིག་ཆེ་བྲིས། + + + + Delete backward word + གཡོན་དུ་ཚིག་གཅིག་སུབ་པ། + + + + Delete forward word + གཡས་སུ་ཚིག་གཅིག་སུབ་པ། + + + + Forward over a pair + གཡས་སུ་སྙོམ་སྒྲིག་བྱེད་པ། + + + + Backward over a pair + གཡོན་དུ་སྙོམ་སྒྲིག་བྱེད་པ། + + + + Select all + ཡོངས་འདེམས། + + + + Copy + པར་སློག + + + + Cut + དྲས་གཏུབ། + + + + Paste + སྦྱར་བ། + + + + Transpose character + ཡིག་རྟགས་བརྗེ་བ། + + + + Mark + རྟགས་སྒྲིག་བཀོད། + + + + Unmark + རྟགས་འདོར་བ། + + + + Copy line + སྟར་པ་འདྲ་བཟོ། + + + + Cut line + སྟར་པ་དྲས་པ། + + + + Merge lines + སྟར་པ་སྒྲིལ་བ། + + + + Read-Only mode + ཀློག་ཙམ་དཔེ་དབྱིབས་ལ་བརྗེ་བ། + + + + Add comment + མཆན་སྣོན་པ། + + + + Remove comment + མཆན་འདོར་བ། + + + + Undo + མི་བྱེད། + + + + Redo + བསྐྱར་བྱེད། + + + + Add/Remove bookmark + ཤོག་འཛར་སྣོན་པ།/འདོར་བ། + + + + Move to previous bookmark + ཤོག་འཛར་གོང་དུ་སྤོ་བ། + + + + Move to next bookmark + ཤོག་འཛར་རྗེས་མར་སྤོ་བ། + + + + Advanced + མཐོ་རིམ་སྒྲིག་བཀོད། + + + + Window size + སྒེའུ་ཁུང་རྣམ་པ། + + + + Tab width + Tabཡིག་རྟགས་ཞེང་ཚད། + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + རང་འགུལ་ངང་འཕྲེད་སྟར་བརྗེ་བ། + + + + Code folding flag + ཚབ་རྟགས་ལྟེབ་པའི་མཚོན་རྟགས་གསལ་བ། + + + + Show line numbers + སྟར་ཨང་གསལ་བ། + + + + Show bookmarks icon + ཤོག་འཛར་གྱི་རྟགས་གསལ་བ། + + + + Show whitespaces and tabs + སྟོང་ཆའི་ཡིག་རྟགས།/རེའུ་མིག་བཟོ་རྟགས་གསལ་བ། + + + + Highlight current line + མིག་སྔའི་མཐོ་ཚད་གསལ་བ། + + + + Color mark + ཚོས་གཞིའི་རྟགས། + + + + Unicode + Unicode + + + + WesternEuropean + ཡོ་རོབ་ནུབ་མའི་སྐད་ཁོངས། + + + + CentralEuropean + ཡོ་རོབ་བར་མའི་སྐད་ཁོངས། + + + + Baltic + པོ་ལོའུ་ཏི་ཧའེ་ཡི་སྐད་ཡིག + + + + Cyrillic + ཞི་ལེར་གྱི་ཡི་གེ། + + + + Arabic + ཨ་རབ་ཀྱི་སྐད། + + + + Celtic + ཁའེ་ཐེའི་སྐད། + + + + SouthEasternEuropean + ཡོ་རོབ་ཤར་ལྷོའི་སྐད་ཁོངས། + + + + Greek + གྷི་རིག་གི་སྐད། + + + + Hebrew + ཞི་པོ་ལའེ་ཡི་སྐད། + + + + ChineseSimplified + ཟོར་ཡང་རྒྱ་ཡིག + + + + ChineseTraditional + ཟོར་ལྕིའི་རྒྱ་ཡིག + + + + Japanese + ཉི་ཧོང་སྐད། + + + + Korean + ཁོ་རེ་ཡའི་སྐད། + + + + Thai + ཐེ་ལན་གྱི་སྐད། + + + + Turkish + ཐུར་ཁེའི་སྐད། + + + + Vietnamese + ཝེ་ཐེ་ནམ་གྱི་སྐད། + + + + File not saved + ཡིག་ཆ་ཉར་ཚགས་བྱས་མེད། + + + + + + Line Endings + སྟར་བརྗེ་རྟགས། + + + + ReplaceBar + + + Find + འཚོལ་བ། + + + + Replace With + ལ་བརྗེ་བ། + + + + Replace + བརྗེ་བ། + + + + Skip + མཆོང་བ། + + + + Replace Rest + ལྷག་མ་བརྗེ་བ། + + + + Replace All + ཚང་མ་བརྗེ་བ། + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + ཚད་ལྡན། + + + + Customize + རང་སྒྲུབ། + + + + Normal + རྒྱུན་གཏན་སྒེའུ་ཁུང་། + + + + Maximum + ཆེ་སྒྱུར། + + + + Fullscreen + ཡོལ་གང་། + + + + This shortcut conflicts with system shortcut %1 + མྱུར་མཐེབ་འདི་དང་མ་ལག་གི་མྱུར་མཐེབ་%1འགལ་ཟླ་ཡོད། + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + མྱུར་མཐེབ་འདི་དང་%1འགལ་ཟླ་ཡོད་པས། བརྗེ་པོ་མནན་ནས་མྱུར་མཐེབ་འདི་ལམ་སེང་སྤྱོད་གོ་ཆོད། + + + + + The shortcut %1 is invalid, please set another one. + %1ནི་ནུས་མེད་མྱུར་མཐེབ་ཡིན་པས། ཡང་བསྐྱར་སྒྲིག་བཀོད་གནང་རྒྱུ། + + + + Cancel + འདོར་བ། + + + + Replace + བརྗེ་བ། + + + + OK + གཏན་འཁེལ། + + + + StartManager + + + Untitled %1 + མིང་མེད་པའི་ཡིག་ཚགས་%1 + + + + Tabbar + + + Close tab + ཁ་བྱང་ངོས་ཁ་རྒྱག + + + + Close other tabs + ཁ་བྱང་ངོས་གཞན་དག་ཁ་རྒྱག + + + + More options + ཁ་རྒྱག་ཐབས་དེ་ལས་མང་། + + + + Close tabs to the left + གཡོན་ཕྱོགས་ཀྱི་ཁ་བྱང་ངོས་ཚང་མ་ཁ་རྒྱག + + + + Close tabs to the right + གཡས་ཕྱོགས་ཀྱི་ཁ་བྱང་ངོས་ཚང་མ་ཁ་རྒྱག + + + + Close unmodified tabs + བཟོ་བཅོས་བྱས་མེད་པའི་ཁ་བྱང་ངོས་ཚང་མ་ཁ་རྒྱག + + + + TextEdit + + + Undo + མི་བྱེད། + + + + Redo + བསྐྱར་བྱེད། + + + + Cut + དྲས་གཏུབ། + + + + Copy + པར་སློག + + + + Paste + སྦྱར་བ། + + + + Delete + སུབ་པ། + + + + Select All + ཡོངས་འདེམས། + + + + + Find + འཚོལ་བ། + + + + + Replace + བརྗེ་བ། + + + + Go to Line + འཕྲེད་སྟར་དུ་མཆོང་བ། + + + + Turn on Read-Only mode + ཀློག་ཙམ་དཔེ་དབྱིབས་ཁ་ཕྱེ། + + + + Turn off Read-Only mode + ཀློག་ཙམ་དཔེ་དབྱིབས་ཁ་རྒྱག + + + + Fullscreen + ཡོལ་གང་། + + + + Exit fullscreen + ཡོལ་གང་ནས་ཕྱིར་འབུད་པ། + + + + Display in file manager + ཡིག་ཆ་དོ་དམ་ཆས་ཁྲོད་དུ་མངོན་པ། + + + + + Add Comment + མཆན་སྣོན་པ། + + + + Text to Speech + ཀློག་འདོན་བྱ་རྒྱུ། + + + + Stop reading + ཀློག་མཚམས་འཇོག་པ། + + + + Speech to Text + སྐད་སྒྲའི་དཔོད་བྲིས། + + + + Translate + ཡིག་སྒྱུར། + + + + Column Mode + གཞུང་སྟར་རྩོམ་སྒྲིག་རྣམ་པ། + + + + Add bookmark + ཤོག་འཛར་སྣོན་པ། + + + + Remove Bookmark + ཤོག་འཛར་འདོར་བ། + + + + Previous bookmark + ཤོག་འཛར་གོང་མ། + + + + Next bookmark + ཤོག་འཛར་རྗེས་མ། + + + + Remove All Bookmarks + ཤོག་འཛར་ཚང་མ་འདོར་བ། + + + + Fold All + བང་རིམ་ཚང་མ་ལྟེབ་པ། + + + + Fold Current Level + མིག་སྔའི་བང་རིམ་ལྟེབ་པ། + + + + Unfold All + བང་རིམ་ཚང་མ་བཀྲམ་པ། + + + + Unfold Current Level + མིག་སྔའི་བང་རིམ་བཀྲམ་པ། + + + + Color Mark + ཚོས་གཞིའི་རྟགས། + + + + Clear All Marks + རྟགས་ཚང་མ་གཙང་སེལ། + + + + Clear Last Mark + གོང་གི་རྟགས་གཙང་སེལ། + + + + Mark + རྟགས་སྒྲིག་བཀོད། + + + + Mark All + རྟགས་ཚང་མ། + + + + Remove Comment + མཆན་འདོར་བ། + + + + Copy failed: not enough memory + གཤོང་ཚད་མ་འདང་བས་པར་སློག་བྱེད་ཐབས་བྲལ། + + + + Press ALT and click lines to edit in column mode + ALT+ཙི་གུའི་འདེམས་པ་སྤྱད་ནས་གཞུང་སྟར་རྩོམ་སྒྲིག་རྣམ་པ་བརྗེ་རྒྱུ། + + + + Change Case + ཆེ་བྲིས་ཆུང་བྲིས་བརྗེ་བ། + + + + Upper Case + ཆེ་བྲིས། + + + + Lower Case + ཆུང་བྲིས། + + + + Capitalize + མགོ་ཡིག་ཆེ་བྲིས། + + + + None + མེད། + + + + Selected line(s) copied + བདམས་ཟིན་པའི་སྟར་པ(རུ་སྟར)འདི་དྲས་སྦྱར་པང་དུ་པར་སློག་བྱས་ཟིན། + + + + Current line copied + མིག་སྔའི་སྟར་པ་འདི་དྲས་སྦྱར་པང་དུ་པར་སློག་བྱས་ཟིན། + + + + Selected line(s) clipped + བདམས་ཟིན་པའི་སྟར་པ(རུ་སྟར)འདི་དྲས་སྦྱར་པང་དུ་དྲས་གཏུབ་བྱས་ཟིན། + + + + Current line clipped + མིག་སྔའི་སྟར་པ་འདི་དྲས་སྦྱར་པང་དུ་དྲས་གཏུབ་བྱས་ཟིན། + + + + Paste failed: not enough memory + ཤོང་ཚད་མི་འདང་བས་སྦྱར་མ་ཐུབ། + + + + Read-Only mode is off + ཀློག་ཙམ་དཔེ་དབྱིབས་ཁ་བརྒྱབ་ཟིན། + + + + + + Read-Only mode is on + ཀློག་ཙམ་དཔེ་དབྱིབས་ཁ་ཕྱེ་ཟིན། + + + + WarningNotices + + + Reload + བསྐྱར་འཇུག + + + + Window + + + + Save as + གཞན་ཉར། + + + + New window + སྒེའུ་ཁུང་གསར་པ། + + + + New tab + ཁ་བྱང་ངོས་གསར། + + + + Open file + ཡིག་ཆ་ཁ་ཕྱེ། + + + + + Save + ཉར་ཚགས། + + + + Print + པར་འདེབས། + + + + Switch theme + བརྗོད་བྱ་གཙོ་བོ་བརྗེ་བ། + + + + + Settings + སྒྲིག་བཀོད། + + + + + Read-Only + ཀློག་ཙམ། + + + + You do not have permission to open %1 + ཁྱེད་ལ་%1ཁ་ཕྱེ་བའི་དབང་ཚད་མེད། + + + + Invalid file: %1 + ཕན་མེད་ཡིག་ཆ། %1 + + + + + Do you want to save this file? + ཁྱེད་ཀྱིས་ཡིག་ཆ་འདི་ཉར་ཚགས་བྱེད་དམ། + + + + You do not have permission to save %1 + ཁྱེད་ལ་%1ཉར་བའི་དབང་ཚད་མེད། + + + + Saved successfully + ཡིག་ཆ་ཉར་ཟིན། + + + + + + Save File + ཉར་བ། + + + + Encoding + ཨང་སྒྲིག + + + + Read-Only mode is on + ཀློག་ཙམ་དཔེ་དབྱིབས་ཁ་ཕྱེ་ཟིན། + + + + Current location remembered + མིག་སྔའི་གནས་ས་ངེས་ཟིན། + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + རྩོམ་སྒྲིག + + + + Untitled %1 + མིང་མེད་པའི་ཡིག་ཚགས་%1 + + + + Cancel + འདོར་བ། + + + + Discard + མི་ཉར། + + + \ No newline at end of file diff --git a/translations/deepin-editor_ca.ts b/translations/deepin-editor_ca.ts new file mode 100644 index 0000000000000000000000000000000000000000..104c95a06e5d452acce4f7b03d275b061c3943d6 --- /dev/null +++ b/translations/deepin-editor_ca.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Fila + + + + Column + Columna + + + + Characters %1 + Caràcters %1 + + + + Loading: + Es carrega: + + + + DDropdownMenu + + + + + None + Cap + + + + EditWrapper + + + + + + Save + Desa + + + + Do you want to save this file? + Voleu desar aquest fitxer? + + + + + Cancel + Cancel·la + + + + Encoding changed. Do you want to save the file now? + Ha canviat la codificació. Voleu desar el fitxer ara? + + + + Discard + Descarta + + + + You do not have permission to save %1 + No teniu permís per desar %1 + + + + File removed on the disk. Save it now? + El fitxer s'ha eliminat del disc. El voleu desar ara? + + + + File has changed on disk. Reload? + El fitxer ha canviat al disc. El torno a carregar? + + + + + INSERT + INSEREIX + + + + OVERWRITE + SOBREESCRIU + + + + R/O + N/L + + + + FindBar + + + Find + Troba + + + + Previous + Anterior + + + + Next + Següent + + + + JumpLineBar + + + Go to Line: + Ves a la línia: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + L'Editor de text és és una eina potent per visualitzar i editar fitxers de text. + + + + Text Editor + Editor de text + + + + PathSettingWgt + + + Remember the last used path + Recorda el darrer camí usat. + + + + Same path as the current file + El mateix camí del fitxer actual + + + + Customize the default path + Personalització del camí predeterminat + + + + QObject + + + Text Editor + Editor de text + + + + + + + + + Encoding + Codificació + + + + Basic + Bàsic + + + + Font Style + Estil de la lletra + + + + Font + Lletra + + + + Font Size + Mida de la lletra + + + + Shortcuts + Dreceres + + + + + Keymap + Mapa de tecles + + + + + + Window + Finestra + + + + New tab + Pestanya nova + + + + New window + Finestra nova + + + + Save + Desa + + + + Save as + Desa com a + + + + Next tab + Pestanya següent + + + + Previous tab + Pestanya anterior + + + + Close tab + Tanca la pestanya + + + + Close other tabs + Tanca les altres pestanyes + + + + Restore tab + Restaura la pestanya + + + + Open file + Obre un fitxer + + + + Increment font size + Augmenta la mida de la lletra + + + + Decrement font size + Redueix la mida de la lletra + + + + Reset font size + Restableix la mida de la lletra + + + + Help + Ajuda + + + + Toggle fullscreen + Commuta la pantalla completa + + + + Find + Troba + + + + Replace + Reemplaça + + + + Go to line + Ves a la línia + + + + Save cursor position + Desa la posició del cursor + + + + Reset cursor position + Restableix la posició del cursor + + + + Exit + Surt + + + + Display shortcuts + Mostra les dreceres + + + + Print + Imprimeix + + + + Editor + Editor + + + + Increase indent + Augmenta el sagnat + + + + Decrease indent + Redueix el sagant + + + + Forward character + Caràcter següent + + + + Backward character + Caràcter anterior + + + + Forward word + Paraula següent + + + + Backward word + Paraula anterior + + + + Next line + Línia següent + + + + Previous line + Línia anterior + + + + New line + Línia nova + + + + New line above + Línia nova superior + + + + New line below + Línia nova inferior + + + + Duplicate line + Duplica la línia + + + + Delete to end of line + Suprimeix fins al final de la línia + + + + Delete current line + Suprimeix la línia actual + + + + Swap line up + Intercanvia amb la línia superior + + + + Swap line down + Intercanvia amb la línia inferior + + + + Scroll up one line + Ves una línia amunt + + + + Scroll down one line + Ves una línia avall + + + + Page up + Pàgina amunt + + + + Page down + Pàgina avall + + + + Move to end of line + Mou al final de la línia + + + + Move to start of line + Mou a l'inici de la línia + + + + Move to end of text + Mou al final del text + + + + Move to start of text + Mou a l'inici del text + + + + Move to line indentation + Mou al sagnat de la línia + + + + Upper case + Majúscules + + + + Lower case + Minúscules + + + + Capitalize + Posa en majúscules + + + + Delete backward word + Suprimeix la paraula anterior + + + + Delete forward word + Suprimeix la paraula següent + + + + Forward over a pair + Endavant dues + + + + Backward over a pair + Endarrere dues + + + + Select all + Selecciona-ho tot + + + + Copy + Copia + + + + Cut + Retalla + + + + Paste + Enganyxa + + + + Transpose character + Transposa el caràcter + + + + Mark + Marca + + + + Unmark + Desmarca + + + + Copy line + Copia la línia + + + + Cut line + Retalla la línia + + + + Merge lines + Fusiona les línies + + + + Read-Only mode + Mode només de lectura + + + + Add comment + Afegeix-hi un comentari + + + + Remove comment + Elimina el comentari + + + + Undo + Desfés + + + + Redo + Refés + + + + Add/Remove bookmark + Afegeix / elimina un marcador + + + + Move to previous bookmark + Ves al marcador anterior + + + + Move to next bookmark + Ves al marcador següent + + + + Advanced + Avançat + + + + Window size + Mida de la finestra + + + + Tab width + Amplada de la pestanya + + + + Paste by pressing a middle mouse button + Enganxa prement el botó del mig del ratolí. + + + + Startup + Inici + + + + Reopen last closed tabs + Torna a obrir les darreres pestanyes tancades. + + + + Open/Save Settings + Configuració d'obertura / desament + + + + Word wrap + Ajust de paraules + + + + Code folding flag + Bandera de plec de codi + + + + Show line numbers + Mostra els números de línia + + + + Show bookmarks icon + Mostra la icona dels marcadors + + + + Show whitespaces and tabs + Mostra els espais en blanc i les tabulacions + + + + Highlight current line + Ressalta la línia actual + + + + Color mark + Marca de color + + + + Unicode + Unicode + + + + WesternEuropean + Europeu occidental + + + + CentralEuropean + Centreeuropeu + + + + Baltic + Bàltic + + + + Cyrillic + Cirílic + + + + Arabic + Àrab + + + + Celtic + Celta + + + + SouthEasternEuropean + Sud-est europeu + + + + Greek + Grec + + + + Hebrew + Hebreu + + + + ChineseSimplified + Xinès simplificat + + + + ChineseTraditional + Xinès tradicional + + + + Japanese + Japonès + + + + Korean + Coreà + + + + Thai + Tailandès + + + + Turkish + Turc + + + + Vietnamese + Vietnamita + + + + File not saved + Fitxer no desat + + + + + + Line Endings + Finals de línia + + + + ReplaceBar + + + Find + Troba + + + + Replace With + Reemplaça amb + + + + Replace + Reemplaça + + + + Skip + Omet + + + + Replace Rest + Reemplaça'n la resta + + + + Replace All + Reemplaça-ho tot + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Estàndard + + + + Customize + Personalitza + + + + Normal + Normal + + + + Maximum + Màxim + + + + Fullscreen + Pantalla completa + + + + This shortcut conflicts with system shortcut %1 + Aquesta drecera entra en conflicte amb la drecera del sistema %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Aquesta tecla de drecera té conflicte amb %1. Cliqueu a Reemplaça perquè aquesta drecera tingui efecte immediatament. + + + + + The shortcut %1 is invalid, please set another one. + La drecera %1 no és vàlida. Establiu-ne una altra. + + + + Cancel + Cancel·la + + + + Replace + Reemplaça + + + + OK + D'acord + + + + StartManager + + + Untitled %1 + Sense títol: %1 + + + + Tabbar + + + Close tab + Tanca la pestanya + + + + Close other tabs + Tanca les altres pestanyes + + + + More options + Més opcions + + + + Close tabs to the left + Tanca les pestanyes de l'esquerra + + + + Close tabs to the right + Tanca les pestanyes de la dreta + + + + Close unmodified tabs + Tanca les pestanyes no modificades + + + + TextEdit + + + Undo + Desfés + + + + Redo + Refés + + + + Cut + Retalla + + + + Copy + Copia + + + + Paste + Enganxa + + + + Delete + Suprimeix + + + + Select All + Selecciona-ho tot + + + + + Find + Troba + + + + + Replace + Reemplaça + + + + Go to Line + Ves a la línia + + + + Turn on Read-Only mode + Activa el mode només de lectura + + + + Turn off Read-Only mode + Desactiva el mode només de lectura + + + + Fullscreen + Pantalla completa + + + + Exit fullscreen + Surt de la pantalla completa + + + + Display in file manager + Mostra-ho al gestor de fitxers + + + + + Add Comment + Afegeix-hi un comentari + + + + Text to Speech + Text a veu + + + + Stop reading + Atura la lectura + + + + Speech to Text + Veu a text + + + + Translate + Tradueix + + + + Column Mode + Mode de columna + + + + Add bookmark + Afegeix-hi un marcador + + + + Remove Bookmark + Elimina el marcador + + + + Previous bookmark + Marcador anterior + + + + Next bookmark + Marcador següent + + + + Remove All Bookmarks + Elimina tots els marcadors + + + + Fold All + Plega-ho tot + + + + Fold Current Level + Plega el nivell actual + + + + Unfold All + Desplega-ho tot + + + + Unfold Current Level + Desplega el nivell actual + + + + Color Mark + Marca de color + + + + Clear All Marks + Neteja totes les marques + + + + Clear Last Mark + Neteja la darrera marca + + + + Mark + Marca + + + + Mark All + Marca-ho tot + + + + Remove Comment + Elimina el comentari + + + + Copy failed: not enough memory + La còpia ha fallat: no hi ha prou memòria. + + + + Press ALT and click lines to edit in column mode + Premeu ALT i feu clic a les línies per editar-lo en mode columna + + + + Change Case + Canvia'n la caixa + + + + Upper Case + Majúscules + + + + Lower Case + Minúscules + + + + Capitalize + Posa en majúscules + + + + None + Cap + + + + Selected line(s) copied + S'han copiat les línies seleccionades. + + + + Current line copied + S'ha copiat la línia actual. + + + + Selected line(s) clipped + S'han retallat les línies seleccionades. + + + + Current line clipped + S'ha retallat la línia actual. + + + + Paste failed: not enough memory + Ha fallat l'acció d'enganxar: no hi ha prou memòria. + + + + Read-Only mode is off + Mode de lectura desactivat + + + + + + Read-Only mode is on + Mode de lectura activat + + + + WarningNotices + + + Reload + Torna-ho a carregar + + + + Window + + + + Save as + Desa com a + + + + New window + Finestra nova + + + + New tab + Pestanya nova + + + + Open file + Obre un fitxer + + + + + Save + Desa + + + + Print + Imprimeix + + + + Switch theme + Canvia el tema + + + + + Settings + Paràmetres + + + + + Read-Only + Només de lectura + + + + You do not have permission to open %1 + No teniu permís per obrir %1 + + + + Invalid file: %1 + Fitxer no vàlid: %1 + + + + + Do you want to save this file? + Voleu desar aquest fitxer? + + + + You do not have permission to save %1 + No teniu permís per desar %1 + + + + Saved successfully + S'ha desat correctament + + + + + + Save File + Desa el fitxer + + + + Encoding + Codificació + + + + Read-Only mode is on + Mode de lectura activat + + + + Current location remembered + Es recorda la ubicació actual. + + + + Ctrl+'=' + Ctrl + = + + + + Ctrl+'-' + Ctrl + - + + + + Editor + Editor + + + + Untitled %1 + Sense títol: %1 + + + + Cancel + Cancel·la + + + + Discard + Descarta + + + \ No newline at end of file diff --git a/translations/deepin-editor_cs.ts b/translations/deepin-editor_cs.ts new file mode 100644 index 0000000000000000000000000000000000000000..80e5edc3d14898ff16343a252c9246c3fe9bc69c --- /dev/null +++ b/translations/deepin-editor_cs.ts @@ -0,0 +1,1296 @@ + + + BottomBar + + + Row + Řádek + + + + Column + Sloupec + + + + Characters %1 + Znaků %1 + + + + Loading: + Nahrává se: + + + + DDropdownMenu + + + + + None + Žádné + + + + EditWrapper + + + + + + Save + Uložit + + + + Do you want to save this file? + Chcete tento soubor uložit? + + + + + Cancel + Zrušit + + + + Encoding changed. Do you want to save the file now? + Kódování změněno. Chcete tento soubor uložit nyní? + + + + Discard + Zahodit + + + + You do not have permission to save %1 + Nemáte oprávnění pro uložení %1 + + + + File removed on the disk. Save it now? + Soubor byl mezitím na disku odstraněn. Uložit ho nyní? + + + + File has changed on disk. Reload? + Soubor byl mezitím na disku změněn. Načíst znovu? + + + + + INSERT + VLOŽIT + + + + OVERWRITE + PŘEPSAT + + + + R/O + Pouze pro čtení + + + + The file cannot be read, which may be too large or has been damaged! + Soubor nelze přečíst, může být příliš velký nebo poškozený! + + + + FindBar + + + Find + Najít + + + + Previous + Předchozí + + + + Next + Další + + + + JumpLineBar + + + Go to Line: + Jít na řádek: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Textový editor je mocný nástroj na prohlížení a upravování textových souborů. + + + + Text Editor + Textový editor + + + + PathSettingWgt + + + Remember the last used path + Pamatovat si poslední použitou cestu + + + + Same path as the current file + Stejná cesta jako k nynějšímu souboru + + + + Customize the default path + Přizpůsobit výchozí cestu + + + + QObject + + + Text Editor + Textový editor + + + + + + + + + Encoding + Kódování znaků + + + + Basic + Základní + + + + Font Style + Styl písma + + + + Font + Písmo + + + + Font Size + Velikost písma + + + + Shortcuts + Klávesové zkratky + + + + + Keymap + Přiřazení kláves + + + + + + Window + Okno + + + + New tab + Nová karta + + + + New window + Nové okno + + + + Save + Uložit + + + + Save as + Uložit jako + + + + Next tab + Další karta + + + + Previous tab + Předchozí karta + + + + Close tab + Zavřít kartu + + + + Close other tabs + Zavřít ostatní karty + + + + Restore tab + Obnovit kartu + + + + Open file + Otevřít soubor + + + + Increment font size + Zvětšit velikost písma + + + + Decrement font size + Zmenšit velikost písma + + + + Reset font size + Vrátit velikost písma na výchozí + + + + Help + Nápověda + + + + Toggle fullscreen + Přepnout na celou obrazovku + + + + Find + Najít + + + + Replace + Nahradit + + + + Go to line + Jít na řádek + + + + Save cursor position + Uložit pozici kurzoru + + + + Reset cursor position + Vrátit polohu kurzoru na výchozí + + + + Exit + Ukončit + + + + Display shortcuts + Zobrazit klávesové zkratky + + + + Print + Tisk + + + + Editor + Editor + + + + Increase indent + Zvětšit odsazení + + + + Decrease indent + Zmenšit odsazení + + + + Forward character + O znak dopředu + + + + Backward character + O znak dozadu + + + + Forward word + O slovo dopředu + + + + Backward word + O slovo dozadu + + + + Next line + Další řádek + + + + Previous line + Předchozí řádek + + + + New line + Nový řádek + + + + New line above + Nový řádek nad + + + + New line below + Nový řádek pod + + + + Duplicate line + Zduplikovat řádek + + + + Delete to end of line + Smazat po konec řádku + + + + Delete current line + Smazat stávající řádek + + + + Swap line up + Prohodit řádek s tím nad ním + + + + Swap line down + Prohodit řádek s tím pod ním + + + + Scroll up one line + Posunout se o řádek nahoru + + + + Scroll down one line + Posunout se o řádek dolů + + + + Page up + O stránku nahoru + + + + Page down + O stránku dolů + + + + Move to end of line + Přesunout na konec řádku + + + + Move to start of line + Přesunout na začátek řádku + + + + Move to end of text + Přesunout na konec textu + + + + Move to start of text + Přesunout na začátek textu + + + + Move to line indentation + Přesunout na odsazení řádku + + + + Upper case + Velká písmena + + + + Lower case + Malá písmena + + + + Capitalize + Vše velkými písmeny + + + + Delete backward word + Smazat slovo za kurzorem + + + + Delete forward word + Smazat slovo před kurzorem + + + + Forward over a pair + Dopředu přes dvojici + + + + Backward over a pair + Dozadu přes dvojici + + + + Select all + Vybrat vše + + + + Copy + Kopírovat + + + + Cut + Vyjmout + + + + Paste + Vložit + + + + Transpose character + Přemístit znak + + + + Mark + Označit + + + + Unmark + Odznačit + + + + Copy line + Kopírovat řádek + + + + Cut line + Vyjmout řádek + + + + Merge lines + Sloučit řádky + + + + Read-Only mode + Režim pouze pro čtení + + + + Add comment + Přidat komentář + + + + Remove comment + Odebrat komentář + + + + Undo + Zpět + + + + Redo + Znovu + + + + Add/Remove bookmark + Přidat/Odebrat záložku + + + + Move to previous bookmark + Přesunout na předchozí záložku + + + + Move to next bookmark + Přesunout na další záložku + + + + Advanced + Pokročilé + + + + Window size + Velikost okna + + + + Tab width + Šířka zarážky (tabulátor) + + + + Paste by pressing a middle mouse button + Vložit stisknutím prostředního tlačítka myši + + + + Startup + Spuštění + + + + Reopen last closed tabs + Znovu otevřít naposledy zavřené karty + + + + Open/Save Settings + Nastavení pro otevírání/ukládání + + + + Word wrap + Zalamování slov + + + + Code folding flag + Příznak sbalení kódu + + + + Show line numbers + Zobrazovat čísla řádek + + + + Show bookmarks icon + Zobrazovat ikony záložek + + + + Show whitespaces and tabs + Zobrazovat prázdné znaky a tabulátory + + + + Highlight current line + Zvýraznit stávající řádek + + + + Color mark + Barevná značka + + + + Unicode + Unicode + + + + WesternEuropean + Západoevropské + + + + CentralEuropean + Středoevropské + + + + Baltic + Baltské + + + + Cyrillic + Cyrilice + + + + Arabic + Arabské + + + + Celtic + Keltské + + + + SouthEasternEuropean + Jihovýchodoevropské + + + + Greek + Řecké + + + + Hebrew + Hebrejské + + + + ChineseSimplified + Zjednodušená čínština + + + + ChineseTraditional + Tradiční čínština + + + + Japanese + Japonské + + + + Korean + Korejské + + + + Thai + Thajské + + + + Turkish + Turecké + + + + Vietnamese + Vietnamské + + + + File not saved + Soubor neuložen + + + + + + Line Endings + Konce řádků + + + + ReplaceBar + + + Find + Najít + + + + Replace With + Nahradit za + + + + Replace + Nahradit + + + + Skip + Přeskočit + + + + Replace Rest + Nahradit zbytek + + + + Replace All + Nahradit vše + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standardní + + + + Customize + Přizpůsobit + + + + Normal + Normální + + + + Maximum + Největší + + + + Fullscreen + Na celou obrazovku + + + + This shortcut conflicts with system shortcut %1 + Tato zkratka je v konfliktu se systémovou %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Tato zkratka koliduje s %1 – klepněte na Nahradit, pokud chcete, aby začala platit pro tuto akci + + + + + + The shortcut %1 is invalid, please set another one. + Zkratka %1 není platná – prosím nastavte jinou. + + + + Cancel + Zrušit + + + + Replace + Nahradit + + + + OK + OK + + + + StartManager + + + Untitled %1 + Bez názvu %1 + + + + Tabbar + + + Close tab + Zavřít kartu + + + + Close other tabs + Zavřít ostatní karty + + + + More options + Další volby + + + + Close tabs to the left + Zavřít karty nalevo + + + + Close tabs to the right + Zavřít karty napravo + + + + Close unmodified tabs + Zavřít karty, kterých obsah se nezměnil + + + + TextEdit + + + Undo + Zpět + + + + Redo + Znovu + + + + Cut + Vyjmout + + + + Copy + Zkopírovat + + + + Paste + Vložit + + + + Delete + Smazat + + + + Select All + Vybrat vše + + + + + Find + Najít + + + + + Replace + Nahradit + + + + Go to Line + Jít na řádek + + + + Turn on Read-Only mode + Zapnout režim pouze pro čtení + + + + Turn off Read-Only mode + Vypnout režim pouze pro čtení + + + + Fullscreen + Na celou obrazovku + + + + Exit fullscreen + Opustit zobrazení na celou obrazovku + + + + Display in file manager + Zobrazit ve správci souborů + + + + + Add Comment + Přidat komentář + + + + Text to Speech + Text na řeč + + + + Stop reading + Zastavit předčítání + + + + Speech to Text + Řeč na text + + + + Translate + Přeložit + + + + Column Mode + Sloupcový režim + + + + Add bookmark + Přidat záložku + + + + Remove Bookmark + Odebrat záložku + + + + Previous bookmark + Předchozí záložka + + + + Next bookmark + Další záložka + + + + Remove All Bookmarks + Odebrat veškeré záložky + + + + Fold All + Sbalit vše + + + + Fold Current Level + Sbalit stávající úroveň + + + + Unfold All + Rozbalit vše + + + + Unfold Current Level + Rozbalit stávající úroveň + + + + Color Mark + Barevná značka + + + + Clear All Marks + Vymazat všechny značky + + + + Clear Last Mark + Vymazat poslední značku + + + + Mark + Označit + + + + Mark All + Označit vše + + + + Remove Comment + Odebrat komentář + + + + Copy failed: not enough memory + Kopírování se nezdařilo: nedostatek paměti + + + + Press ALT and click lines to edit in column mode + Pro upravování ve sloupcovém režimu stiskněte ALT a klepejte na řádky + + + + Change Case + Změnit velikost písmen + + + + Upper Case + Velká písmena + + + + Lower Case + Malá písmena + + + + Capitalize + Vše velkými písmeny + + + + None + Žádné + + + + Selected line(s) copied + Vybraný řádek (řádky) zkopírován + + + + Current line copied + Stávající řádek zkopírován + + + + Selected line(s) clipped + Vybraný řádek (řádky) zkrácen + + + + Current line clipped + Stávající řádek zkrácen + + + + Paste failed: not enough memory + Vložení se nezdařilo: nedostatek paměti + + + + Read-Only mode is off + Režim pouze pro čtení je vypnut + + + + + + + + + Read-Only mode is on + Režim pouze pro čtení je zapnut + + + + WarningNotices + + + Reload + Načíst znovu + + + + Window + + + + Save as + Uložit jako + + + + New window + Nové okno + + + + New tab + Nová karta + + + + Open file + Otevřít soubor + + + + + Save + Uložit + + + + Print + Tisk + + + + Switch theme + Přepnout vzhled + + + + + Settings + Nastavení + + + + + Read-Only + Pouze pro čtení + + + + You do not have permission to open %1 + Nemáte oprávnění pro otevření %1 + + + + + Invalid file: %1 + Neplatný soubor: %1 + + + + + Do you want to save this file? + Chcete tento soubor uložit? + + + + You do not have permission to save %1 + Nemáte oprávnění pro uložení %1 + + + + Saved successfully + Úspěšně uloženo + + + + + + Save File + Uložit soubor + + + + Encoding + Kódování znaků + + + + Read-Only mode is on + Režim pouze pro čtení je zapnut + + + + Current location remembered + Stávající pozice zapamatována + + + + Ctrl+'=' + Ctrl + = + + + + Ctrl+'-' + Ctlr + - + + + + Editor + Editor + + + + Untitled %1 + Bez názvu %1 + + + + Cancel + Zrušit + + + + Discard + Zahodit + + + \ No newline at end of file diff --git a/translations/deepin-editor_da.ts b/translations/deepin-editor_da.ts new file mode 100644 index 0000000000000000000000000000000000000000..27972d5416ae4e32cfa12bca4665384bd77a66e7 --- /dev/null +++ b/translations/deepin-editor_da.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + Række + + + + Column + Kolonne + + + + Characters %1 + Tegn %1 + + + + DDropdownMenu + + + + + None + Ingen + + + + EditWrapper + + + File has changed on disk. Reload? + Filen er blevet ændret på disken. Genindlæs? + + + + File removed on the disk. Save it now? + Filen er fjernet fra disken. Gem den nu? + + + + Do you want to save this file? + Vil du gemme filen? + + + + Discard + Forkast + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + Du har ikke tilladelse til at gemme %1 + + + + + INSERT + INDSÆT + + + + OVERWRITE + OVERSKRIV + + + + R/O + SB + + + + + Cancel + Annuller + + + + + + + Save + Gem + + + + FindBar + + + Find + Find + + + + Next + Næste + + + + Previous + Forrige + + + + JumpLineBar + + + Go to Line: + Gå til linje: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Teksteditor er et kraftfuldt værktøj til at vise og redigere tekstfiler. + + + + Text Editor + Teksteditor + + + + QObject + + + File not saved + Filen er ikke gemt + + + + Text Editor + Teksteditor + + + + Basic + Grundlæggende + + + + Font Style + Skriftstil + + + + Font + Skrifttype + + + + Font Size + Skriftstørrelse + + + + + Keymap + Tegnkort + + + + Shortcuts + Genveje + + + + Forward character + Et tegn fremad + + + + Backward character + Et tegn tilbage + + + + Transpose character + Omvendte tegn + + + + Tab width + Tabulatorbredde + + + + Word wrap + + + + + + + Window + Vindue + + + + New tab + Nyt faneblad + + + + New window + Nyt vindue + + + + Save + Gem + + + + Save as + Gem som + + + + Next tab + Næste faneblad + + + + Previous tab + Forrige faneblad + + + + Close tab + Luk faneblad + + + + Close other tabs + Luk andre faneblade + + + + Restore tab + Gendan faneblad + + + + Open file + Åbn fil + + + + Increment font size + Større skriftstørrelse + + + + Decrement font size + Mindre skriftstørrelse + + + + Reset font size + Nulstil skriftstørrelse + + + + Toggle fullscreen + Fuldskærm til/fra + + + + Help + Hjælp + + + + Find + Find + + + + Replace + Erstat + + + + Go to line + Gå til linje + + + + Save cursor position + Gem markørplacering + + + + Reset cursor position + Nulstil markørplacering + + + + Exit + Afslut + + + + Display shortcuts + Vis genveje + + + + Print + Udskriv + + + + Editor + Editor + + + + Increase indent + Større indrykning + + + + Decrease indent + Mindre indrykning + + + + Forward word + Et ord fremad + + + + Backward word + Et ord tilbage + + + + Next line + Næste linje + + + + Previous line + Forrige linje + + + + New line + Ny linje + + + + New line above + Ny linje nedenfor + + + + New line below + Ny linje ovenfor + + + + Duplicate line + Dupliker linje + + + + Delete to end of line + Slet til slutningen af linjen + + + + Delete current line + Slet nuværende linje + + + + Swap line up + Ombyt linje op + + + + Swap line down + Ombyt linje ned + + + + Scroll up one line + Rul en linje op + + + + Scroll down one line + Rul en linje ned + + + + Page up + Side op + + + + Page down + Side ned + + + + Move to end of line + Flyt til slutningen af linjen + + + + Move to start of line + Flyt til begyndelsen af linjen + + + + Move to end of text + Flyt til slutningen af teksten + + + + Move to start of text + Flyt til begyndelsen af teksten + + + + Move to line indentation + Flyt til linjeindrykning + + + + Upper case + Store bogstaver + + + + Lower case + Små bogstaver + + + + Capitalize + Stort begyndelsesbogstav + + + + Delete backward word + Slet et ord tilbage + + + + Delete forward word + Slet et ord fremad + + + + Forward over a pair + Fremad over et par + + + + Backward over a pair + Tilbage over et par + + + + Select all + Markér alt + + + + Copy + Kopiér + + + + Cut + Klip + + + + Paste + Indsæt + + + + Mark + Sæt mærke + + + + Unmark + Fjern mærke + + + + Copy line + Kopiér linje + + + + Cut line + Klip linje + + + + Merge lines + Sammenlæg linjer + + + + Read-Only mode + Skrivebeskyttet tilstand + + + + Add comment + + + + + Remove comment + + + + + Undo + Fortryd + + + + Redo + Omgør + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Advanced + Avanceret + + + + Window size + Vinduesstørrelse + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Color mark + + + + + + + + + + Encoding + Kodning + + + + + + Line Endings + Linjeskift + + + + ReplaceBar + + + Find + Find + + + + Replace With + Erstat med + + + + Replace + Erstat + + + + Skip + Spring over + + + + Replace Rest + Erstat resten + + + + Replace All + Erstat alle + + + + Settings + + + Standard + Standard + + + + Customize + Tilpas + + + + Normal + Normal + + + + Maximum + Maksimum + + + + Fullscreen + Fuldskærm + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + Annuller + + + + Replace + Erstat + + + + OK + + + + + StartManager + + + Untitled %1 + Unavngivet %1 + + + + Tabbar + + + Close tab + Luk faneblad + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + Close other tabs + Luk andre faneblade + + + + TextEdit + + + Undo + Fortryd + + + + Redo + Omgør + + + + Cut + Klip + + + + Copy + Kopiér + + + + Paste + Indsæt + + + + Delete + Slet + + + + Select All + Markér alt + + + + + Find + Find + + + + + Replace + Erstat + + + + Go to Line + Gå til linje + + + + Turn on Read-Only mode + Aktivér skrivebeskyttet tilstand + + + + Turn off Read-Only mode + Deaktivér skrivebeskyttet tilstand + + + + Fullscreen + Fuldskærm + + + + Exit fullscreen + Afslut fuldskærm + + + + Display in file manager + Vis i filhåndtering + + + + + Add Comment + + + + + Column Mode + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Text to Speech + Tekst til tale + + + + Stop reading + Stop læsning + + + + Speech to Text + Tale til tekst + + + + Translate + Oversæt + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Mark All + + + + + Mark + Sæt mærke + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Change Case + Skift store/små bogstaver + + + + Upper Case + Store bogstaver + + + + Lower Case + Små bogstaver + + + + Capitalize + Stort begyndelsesbogstav + + + + None + Ingen + + + + Selected line(s) copied + Valgte linje(r) kopieret + + + + Current line copied + Nuværende linje kopieret + + + + Selected line(s) clipped + Valgte linje(r) beskåret + + + + Current line clipped + Nuværende linje beskåret + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + Skrivebeskyttet tilstand er deaktiveret + + + + + + Read-Only mode is on + Skrivebeskyttet tilstand er aktiveret + + + + WarningNotices + + + Reload + Genindlæs + + + + Window + + + New window + Nyt vindue + + + + New tab + Nyt faneblad + + + + Open file + Åbn fil + + + + + Save as + Gem som + + + + Print + Udskriv + + + + Switch theme + Skift tema + + + + + Read-Only + Skrivebeskyttet + + + + Saved successfully + Gemt + + + + Read-Only mode is on + Skrivebeskyttet tilstand er aktiveret + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + Forkast + + + + + Settings + Indstillinger + + + + You do not have permission to open %1 + Du har ikke tilladelse til at åbne %1 + + + + Invalid file: %1 + Ugyldig fil: %1 + + + + + + Save File + Gem fil + + + + + Do you want to save this file? + Vil du gemme filen? + + + + Encoding + Kodning + + + + Editor + Editor + + + + You do not have permission to save %1 + Du har ikke tilladelse til at gemme %1 + + + + Untitled %1 + Unavngivet %1 + + + + Current location remembered + Nuværende placering husket + + + + Cancel + Annuller + + + + + Save + Gem + + + diff --git a/translations/deepin-editor_de.ts b/translations/deepin-editor_de.ts new file mode 100644 index 0000000000000000000000000000000000000000..20ca555eab143d91a9310ae6191a328114e83a6a --- /dev/null +++ b/translations/deepin-editor_de.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Zeile + + + + Column + Spalte + + + + Characters %1 + Zeichen %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Keines + + + + EditWrapper + + + + + + Save + Speichern + + + + Do you want to save this file? + Möchten Sie diese Datei speichern? + + + + + Cancel + Abbrechen + + + + Encoding changed. Do you want to save the file now? + Kodierung geändert. Wollen Sie die Datei jetzt speichern? + + + + Discard + Verwerfen + + + + You do not have permission to save %1 + Berechtigung zum Speichern von %1 fehlt + + + + File removed on the disk. Save it now? + Die Datei wurde von der Festplatte entfernt. Soll die Datei jetzt gespeichert werden. + + + + File has changed on disk. Reload? + Die Datei wurde verändert.. Soll die Datei neu geladen werden? + + + + + INSERT + EINFÜGEN + + + + OVERWRITE + ÜBERSCHREIBEN + + + + R/O + R/O + + + + FindBar + + + Find + Suchen + + + + Previous + Vorheriges + + + + Next + Nächstes + + + + JumpLineBar + + + Go to Line: + Gehe zu Zeile: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Der Texteditor ist ein leistungsstarkes Tool zum Anzeigen und Bearbeiten von Textdateien. + + + + Text Editor + Texteditor + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Texteditor + + + + + + + + + Encoding + Kodierung + + + + Basic + Basis + + + + Font Style + Schriftstil + + + + Font + Schriftart + + + + Font Size + Schriftgröße + + + + Shortcuts + Tastaturkürzel + + + + + Keymap + Tastaturbelegung + + + + + + Window + Fenster + + + + New tab + Neuer Tab + + + + New window + Neues Fenster + + + + Save + Speichern + + + + Save as + Speichern unter + + + + Next tab + Nächster Tab + + + + Previous tab + Vorheriger Tab + + + + Close tab + Tab schließen + + + + Close other tabs + Andere Tabs schließen + + + + Restore tab + Tab wiederherstellen + + + + Open file + Datei öffnen + + + + Increment font size + Schriftgröße erhöhen + + + + Decrement font size + Schriftgröße verringern + + + + Reset font size + Schriftgröße zurücksetzen + + + + Help + Hilfe + + + + Toggle fullscreen + Vollbildmodus umschalten + + + + Find + Suchen + + + + Replace + Ersetzen + + + + Go to line + Gehe zu Zeile + + + + Save cursor position + Position des Schreibmarkers speichern + + + + Reset cursor position + Position des Schreibmarkers zurücksetzen + + + + Exit + Beenden + + + + Display shortcuts + Tastaturkürzel anzeigen + + + + Print + Drucken + + + + Editor + Editor + + + + Increase indent + Einrückung vergrößern + + + + Decrease indent + Einrückung verringern + + + + Forward character + Ein Zeichen vorwärts + + + + Backward character + Ein Zeichen rückwärts + + + + Forward word + Ein Wort vorwärts + + + + Backward word + Ein Wort rückwärts + + + + Next line + Nächste Zeile + + + + Previous line + Vorherige Zeile + + + + New line + Neue Zeile + + + + New line above + Neue Zeile davor + + + + New line below + Neue Zeile danach + + + + Duplicate line + Zeile duplizieren + + + + Delete to end of line + Ende der Zeile löschen + + + + Delete current line + Aktuelle Zeile entfernen + + + + Swap line up + Zeile nach oben verschieben + + + + Swap line down + Zeile nach unten verschieben + + + + Scroll up one line + Eine Zeile hoch + + + + Scroll down one line + Eine Zeile runter + + + + Page up + Eine Seite nach oben + + + + Page down + Eine Seite nach unten + + + + Move to end of line + Zum Ende der Zeile bewegen + + + + Move to start of line + Zum Anfang der Zeile bewegen + + + + Move to end of text + Zum Ende des Texts bewegen + + + + Move to start of text + Zum Anfang des Texts bewegen + + + + Move to line indentation + Zur Zeileneinrückung bewegen + + + + Upper case + Großbuchstaben + + + + Lower case + Kleinbuchstaben + + + + Capitalize + Großschreibung + + + + Delete backward word + Ein Wort rückwärts entfernen + + + + Delete forward word + Ein Wort vorwärts entfernen + + + + Forward over a pair + Vorwärts über ein Paar + + + + Backward over a pair + Rückwärts über ein Paar + + + + Select all + Alles markieren + + + + Copy + Kopieren + + + + Cut + Ausschneiden + + + + Paste + Einfügen + + + + Transpose character + Zeichen transponieren + + + + Mark + Markieren + + + + Unmark + Markierung aufheben + + + + Copy line + Zeile kopieren + + + + Cut line + Zeile ausschneiden + + + + Merge lines + Zeilen zusammenfügen + + + + Read-Only mode + Nur-Lese-Modus + + + + Add comment + Kommentar hinzufügen + + + + Remove comment + Kommentar entfernen + + + + Undo + Rückgängig + + + + Redo + Wiederherstellen + + + + Add/Remove bookmark + Lesezeichen hinzufügen/entfernen + + + + Move to previous bookmark + Zum vorherigen Lesezeichen wechseln + + + + Move to next bookmark + Zum nächsten Lesezeichen wechseln + + + + Advanced + Erweitert + + + + Window size + Fenstergröße + + + + Tab width + Tabulatorbreite + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Zeilenumbruch + + + + Code folding flag + Code-Einklapp-Schalter + + + + Show line numbers + Zeilennummern anzeigen + + + + Show bookmarks icon + Lesezeichensymbol anzeigen + + + + Show whitespaces and tabs + Leerzeichen und Tabulatoren anzeigen + + + + Highlight current line + Aktuelle Zeile markieren + + + + Color mark + Farbmarkierung + + + + Unicode + Unicode + + + + WesternEuropean + Westeuropäisch + + + + CentralEuropean + Mitteleuropäisch + + + + Baltic + Baltisch + + + + Cyrillic + Kyrillisch + + + + Arabic + Arabisch + + + + Celtic + Keltisch + + + + SouthEasternEuropean + Südosteuropäisch + + + + Greek + Griechisch + + + + Hebrew + Hebräisch + + + + ChineseSimplified + ChinesischVereinfacht + + + + ChineseTraditional + ChinesischTraditionell + + + + Japanese + Japanisch + + + + Korean + Koreanisch + + + + Thai + Thailändisch + + + + Turkish + Türkisch + + + + Vietnamese + Vietnamesisch + + + + File not saved + Datei nicht gespeichert + + + + + + Line Endings + Zeilenenden + + + + ReplaceBar + + + Find + Suchen + + + + Replace With + Ersetzen mit + + + + Replace + Ersetzen + + + + Skip + Überspringen + + + + Replace Rest + Rest ersetzen + + + + Replace All + Alles ersetzen + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standard + + + + Customize + Anpassen + + + + Normal + Normal + + + + Maximum + Maximum + + + + Fullscreen + Vollbild + + + + This shortcut conflicts with system shortcut %1 + Dieses Tastaturkürzel steht im Konflikt mit dem Systemkürzel %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Dieses Tastaturkürzel steht im Konflikt mit %1, klicke auf Ersetzen, um dieses Kürzel sofort wirksam zu machen + + + + + The shortcut %1 is invalid, please set another one. + Das Tastaturkürzel %1 ist ungültig, bitte stelle ein anderes ein. + + + + Cancel + Abbrechen + + + + Replace + Ersetzen + + + + OK + OK + + + + StartManager + + + Untitled %1 + Unbenannt %1 + + + + Tabbar + + + Close tab + Tab schließen + + + + Close other tabs + Schließe restliche Tabs + + + + More options + Weitere Optionen + + + + Close tabs to the left + Tabs nach links schließen + + + + Close tabs to the right + Tabs nach rechts schließen + + + + Close unmodified tabs + Unveränderte Tabs schließen + + + + TextEdit + + + Undo + Rückgängig + + + + Redo + Wiederherstellen + + + + Cut + Ausschneiden + + + + Copy + Kopieren + + + + Paste + Einfügen + + + + Delete + Löschen + + + + Select All + Alles auswählen + + + + + Find + Suchen + + + + + Replace + Ersetzen + + + + Go to Line + Gehe zu Zeile + + + + Turn on Read-Only mode + Nur-Lese-Modus aktivieren + + + + Turn off Read-Only mode + Nur-Lese-Modus deaktivieren + + + + Fullscreen + Vollbild + + + + Exit fullscreen + Vollbild beenden + + + + Display in file manager + Im Dateimanager anzeigen + + + + + Add Comment + Kommentar hinzufügen + + + + Text to Speech + Text zu Sprache + + + + Stop reading + Lesen beenden + + + + Speech to Text + Sprache zu Text + + + + Translate + Übersetzen + + + + Column Mode + Spaltenmodus + + + + Add bookmark + Lesezeichen hinzufügen + + + + Remove Bookmark + Lesezeichen entfernen + + + + Previous bookmark + Vorheriges Lesezeichen + + + + Next bookmark + Nächstes Lesezeichen + + + + Remove All Bookmarks + Alle Lesezeichen entfernen + + + + Fold All + Alles einfalten + + + + Fold Current Level + Aktuelle Ebene einfalten + + + + Unfold All + Alles ausfalten + + + + Unfold Current Level + Aktuelle Ebene ausfalten + + + + Color Mark + Farbmarkierung + + + + Clear All Marks + Alle Markierungen löschen + + + + Clear Last Mark + Letzte Markierung löschen + + + + Mark + Markieren + + + + Mark All + Alles markieren + + + + Remove Comment + Kommentar entfernen + + + + Copy failed: not enough memory + Kopieren fehlgeschlagen: nicht genügend Speicher + + + + Press ALT and click lines to edit in column mode + Drücke ALT und klicke auf Zeilen, um im Spaltenmodus zu bearbeiten + + + + Change Case + Groß-/Kleinschreibung ändern + + + + Upper Case + Großbuchstaben + + + + Lower Case + Kleinbuchstaben + + + + Capitalize + Großschreibung + + + + None + Keines + + + + Selected line(s) copied + Ausgewählte Zeile(n) kopiert + + + + Current line copied + Aktuelle Zeile kopiert + + + + Selected line(s) clipped + Ausgewählte Zeile(n) abgeschnitten + + + + Current line clipped + Aktuelle Zeile abgeschnitten + + + + Paste failed: not enough memory + Einfügen fehlgeschlagen: nicht genügend Speicher + + + + Read-Only mode is off + Nur-Lese-Modus ist ausgeschaltet + + + + + + Read-Only mode is on + Nur-Lese-Modus ist eingeschaltet + + + + WarningNotices + + + Reload + Neu laden + + + + Window + + + + Save as + Speichern unter + + + + New window + Neues Fenster + + + + New tab + Neuer Tab + + + + Open file + Datei öffnen + + + + + Save + Speichern + + + + Print + Drucken + + + + Switch theme + Theme wechseln + + + + + Settings + Einstellungen + + + + + Read-Only + Nur Lesen + + + + You do not have permission to open %1 + Berechtigung zum Öffnen von %1 fehlt + + + + Invalid file: %1 + Ungültige Datei: %1 + + + + + Do you want to save this file? + Möchten Sie diese Datei speichern? + + + + You do not have permission to save %1 + Berechtigung zum Speichern von %1 fehlt + + + + Saved successfully + Erfolgreich gespeichert + + + + + + Save File + Datei speichern + + + + Encoding + Kodierung + + + + Read-Only mode is on + Nur-Lese-Modus ist aktiviert + + + + Current location remembered + Aktueller Standort gespeichert + + + + Ctrl+'=' + Strg+'=' + + + + Ctrl+'-' + Strg+'-' + + + + Editor + Editor + + + + Untitled %1 + Unbenannt %1 + + + + Cancel + Abbrechen + + + + Discard + Verwerfen + + + \ No newline at end of file diff --git a/translations/deepin-editor_es.ts b/translations/deepin-editor_es.ts new file mode 100644 index 0000000000000000000000000000000000000000..07f37bef2f077add7c54575478146bcedacc567b --- /dev/null +++ b/translations/deepin-editor_es.ts @@ -0,0 +1,1291 @@ + + + BottomBar + + + Row + Fila + + + + Column + Columna + + + + Characters %1 + Caracteres %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Ninguno + + + + EditWrapper + + + + + + Save + Guardar + + + + Do you want to save this file? + ¿Desea guardar este archivo? + + + + + Cancel + Cancelar + + + + Encoding changed. Do you want to save the file now? + La codificación ha cambiado. ¿Desea guardar el archivo ahora? + + + + Discard + Descartar + + + + You do not have permission to save %1 + No tienes permisos para guardar %1 + + + + File removed on the disk. Save it now? + Archivo eliminado en el disco. ¿Desea guardarlo? + + + + File has changed on disk. Reload? + El archivo ha cambiado en el disco. ¿Recargar? + + + + + INSERT + INSERTAR + + + + OVERWRITE + SOBRESCRIBIR + + + + R/O + R/O + + + + The file cannot be read, which may be too large or has been damaged! + The file cannot be read, which may be too large or has been damaged! + + + + FindBar + + + Find + Buscar + + + + Previous + Anterior + + + + Next + Siguiente + + + + JumpLineBar + + + Go to Line: + Ir a la línea + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Editor de texto de Deepin es una poderosa herramienta para ver y editar archivos de texto. + + + + Text Editor + Editor de texto + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Editor de texto + + + + + + + + + Encoding + Codificación + + + + Basic + Básico + + + + Font Style + Estilo de fuente + + + + Font + Fuente + + + + Font Size + Tamaño de fuente + + + + Shortcuts + Atajos + + + + + Keymap + Asignación de teclas + + + + + + Window + Ventana + + + + New tab + Nueva pestaña + + + + New window + Nueva ventana + + + + Save + Guardar + + + + Save as + Guardar como + + + + Next tab + Pestaña siguiente + + + + Previous tab + Pestaña anterior + + + + Close tab + Cerrar pestaña + + + + Close other tabs + Cerrar otras pestañas + + + + Restore tab + Restaurar pestaña + + + + Open file + Abrir archivo + + + + Increment font size + Aumentar tamaño de letra + + + + Decrement font size + Disminuir tamaño de letra + + + + Reset font size + Restablecer tamaño de la letra + + + + Help + Ayuda + + + + Toggle fullscreen + Cambiar a pantalla completa + + + + Find + Buscar + + + + Replace + Reemplazar + + + + Go to line + Ir a la línea + + + + Save cursor position + Guardar la posición del cursor + + + + Reset cursor position + Restablecer posición del cursor + + + + Exit + Salir + + + + Display shortcuts + Mostrar atajos + + + + Print + Imprimir + + + + Editor + Editor + + + + Increase indent + Aumentar sangría + + + + Decrease indent + Disminuir sangría + + + + Forward character + Próximo carácter + + + + Backward character + Carácter anterior + + + + Forward word + Próxima palabra + + + + Backward word + Palabra anterior + + + + Next line + Siguiente línea + + + + Previous line + Línea anterior + + + + New line + Nueva línea + + + + New line above + Nueva línea encima + + + + New line below + Nueva línea debajo + + + + Duplicate line + Duplicar línea + + + + Delete to end of line + Borrar hasta el final de la línea + + + + Delete current line + Borrar la línea actual + + + + Swap line up + Subir línea + + + + Swap line down + Bajar línea + + + + Scroll up one line + Desplazar una línea arriba + + + + Scroll down one line + Desplazar una línea abajo + + + + Page up + Página arriba + + + + Page down + Página abajo + + + + Move to end of line + Mover al final de la línea + + + + Move to start of line + Mover al inicio de la línea + + + + Move to end of text + Mover al final del texto + + + + Move to start of text + Mover al inicio del texto + + + + Move to line indentation + Mover a sangría de línea + + + + Upper case + Mayúsculas + + + + Lower case + Minúsculas + + + + Capitalize + Capitalizar + + + + Delete backward word + Borrar palabra anterior + + + + Delete forward word + Borrar siguiente palabra + + + + Forward over a pair + Adelantar sobre un par + + + + Backward over a pair + Retroceder sobre un par + + + + Select all + Seleccionar todo + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Pegar + + + + Transpose character + Transponer carácter + + + + Mark + Resaltar + + + + Unmark + No resaltar + + + + Copy line + Copiar línea + + + + Cut line + Cortar línea + + + + Merge lines + Fusionar líneas + + + + Read-Only mode + Modo solo lectura + + + + Add comment + Añadir comentario + + + + Remove comment + Borrar comentario + + + + Undo + Deshacer + + + + Redo + Rehacer + + + + Add/Remove bookmark + Añadir/quitar marcador + + + + Move to previous bookmark + Mover al marcador anterior + + + + Move to next bookmark + Mover al siguiente marcador + + + + Advanced + Avanzado + + + + Window size + Tamaño de ventana + + + + Tab width + Ancho de la pestaña + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Ajuste de línea + + + + Code folding flag + Marcador para contraer el código + + + + Show line numbers + Mostrar número de línea + + + + Show bookmarks icon + Mostrar iconos de marcadores + + + + Show whitespaces and tabs + Mostrar espacios en blanco y tabulaciones + + + + Highlight current line + Resaltar línea actual + + + + Color mark + Resaltador + + + + Unicode + Unicode + + + + WesternEuropean + Europeo Occidental + + + + CentralEuropean + Centro Europeo + + + + Baltic + Báltico + + + + Cyrillic + Cirílico + + + + Arabic + Árabe + + + + Celtic + Céltico + + + + SouthEasternEuropean + Europeo del Sudeste + + + + Greek + Griego + + + + Hebrew + Hebreo + + + + ChineseSimplified + Chino Simplificado + + + + ChineseTraditional + Chino Tradicional + + + + Japanese + Japonés + + + + Korean + Coreano + + + + Thai + Tailandés + + + + Turkish + Turco + + + + Vietnamese + Vietnamita + + + + File not saved + No se guardó el archivo + + + + + + Line Endings + Finales de línea + + + + ReplaceBar + + + Find + Buscar + + + + Replace With + Reemplazar con + + + + Replace + Reemplazar + + + + Skip + Omitir + + + + Replace Rest + Reemplazar el resto + + + + Replace All + Reemplazar todo + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Estándar + + + + Customize + Personalizar + + + + Normal + Normal + + + + Maximum + Maximizada + + + + Fullscreen + Pantalla completa + + + + This shortcut conflicts with system shortcut %1 + Este atajo entra en conflicto con el atajo del sistema %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Este atajo entra en conflicto con %1, haga clic en Reemplazar para que este atajo sea efectivo inmediatamente + + + + + The shortcut %1 is invalid, please set another one. + El atajo %1 es inválido, por favor ponga otro. + + + + Cancel + Cancelar + + + + Replace + Reemplazar + + + + OK + Aceptar + + + + StartManager + + + Untitled %1 + Sin título %1 + + + + Tabbar + + + Close tab + Cerrar pestaña + + + + Close other tabs + Cerrar otras pestañas + + + + More options + Más opciones + + + + Close tabs to the left + Cerrar las pestañas de la izquierda + + + + Close tabs to the right + Cerrar las pestañas de la derecha + + + + Close unmodified tabs + Cerrar las pestañas sin modificar + + + + TextEdit + + + Undo + Deshacer + + + + Redo + Rehacer + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + Delete + Borrar + + + + Select All + Seleccionar todo + + + + + Find + Buscar + + + + + Replace + Reemplazar + + + + Go to Line + Ir a la línea + + + + Turn on Read-Only mode + Activar modo solo lectura + + + + Turn off Read-Only mode + Desactivar modo solo lectura + + + + Fullscreen + Pantalla completa + + + + Exit fullscreen + Salir de la pantalla completa + + + + Display in file manager + Mostrar en el administrador de archivos + + + + + Add Comment + Añadir comentario + + + + Text to Speech + Texto a voz + + + + Stop reading + Detener lectura + + + + Speech to Text + Voz a texto + + + + Translate + Traducir + + + + Column Mode + Modo de columna + + + + Add bookmark + Añadir marcador + + + + Remove Bookmark + Quitar marcador + + + + Previous bookmark + Marcador anterior + + + + Next bookmark + Marcador siguiente + + + + Remove All Bookmarks + Quitar todos los marcadores + + + + Fold All + Ocultar todo + + + + Fold Current Level + Ocultar el nivel actual + + + + Unfold All + Mostrar todo + + + + Unfold Current Level + Mostrar el nivel actual + + + + Color Mark + Resaltador + + + + Clear All Marks + Borrar todo lo resaltado + + + + Clear Last Mark + Borrar último resalte + + + + Mark + Resaltar + + + + Mark All + Resaltar todo + + + + Remove Comment + Borrar comentario + + + + Copy failed: not enough memory + Copia fallida: no hay suficiente memoria + + + + Press ALT and click lines to edit in column mode + Presiona ALT y haz clic en las líneas para editar en el modo de columna + + + + Change Case + Formato de texto + + + + Upper Case + Mayúsculas + + + + Lower Case + Minúsculas + + + + Capitalize + Capitalizar + + + + None + Ninguno + + + + Selected line(s) copied + Líneas seleccionadas copiadas + + + + Current line copied + Línea actual copiada + + + + Selected line(s) clipped + Líneas seleccionadas cortadas + + + + Current line clipped + Línea actual cortada + + + + Paste failed: not enough memory + Fallo al pegar: no hay suficiente memoria + + + + Read-Only mode is off + Modo solo lectura desactivado + + + + + + Read-Only mode is on + Modo solo lectura activado + + + + WarningNotices + + + Reload + Recargar + + + + Window + + + + Save as + Guardar como + + + + New window + Nueva ventana + + + + New tab + Nueva pestaña + + + + Open file + Abrir archivo + + + + + Save + Guardar + + + + Print + Imprimir + + + + Switch theme + Cambiar el tema + + + + + Settings + Ajustes + + + + + Read-Only + Sólo lectura + + + + You do not have permission to open %1 + No tienes permisos para abrir %1 + + + + Invalid file: %1 + Archivo inválido: %1 + + + + + Do you want to save this file? + ¿Desea guardar este archivo? + + + + You do not have permission to save %1 + No tienes permisos para guardar %1 + + + + Saved successfully + Guardado exitosamente + + + + + + Save File + Guardar el archivo + + + + Encoding + Codificación + + + + Read-Only mode is on + Modo solo lectura activado + + + + Current location remembered + Guardar ubicación actual + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Editor + + + + Untitled %1 + Sin título %1 + + + + Cancel + Cancelar + + + + Discard + Descartar + + + \ No newline at end of file diff --git a/translations/deepin-editor_fa.ts b/translations/deepin-editor_fa.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b654df3de2a843fe208262978fe9bdf305526cd --- /dev/null +++ b/translations/deepin-editor_fa.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + سطر + + + + Column + ستون + + + + Characters %1 + کاراکتر %1 + + + + DDropdownMenu + + + + + None + هیچ یک + + + + EditWrapper + + + File has changed on disk. Reload? + فایل روی دیسک تغییر کرده است. بارگیری مجدد شود؟ + + + + File removed on the disk. Save it now? + فایل بر روی دیسک حذف شد. اکنون آن را ذخیره می کنید؟ + + + + Do you want to save this file? + آیا می خواهید این فایل را ذخیره کنید؟ + + + + Discard + دور انداختن + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + شما اجازه ذخیره %1 را ندارید + + + + + INSERT + الحاق + + + + OVERWRITE + بازنویسی + + + + R/O + R/O + + + + + Cancel + لغو + + + + + + + Save + ذخیره + + + + FindBar + + + Find + یافتن + + + + Next + بعدی + + + + Previous + قبلی + + + + JumpLineBar + + + Go to Line: + برو به خط: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + + + + + Text Editor + + + + + QObject + + + File not saved + + + + + Text Editor + + + + + Basic + ابتدایی + + + + Font Style + سبک فونت + + + + Font + فونت + + + + Font Size + اندازه فونت + + + + + Keymap + نقشه کلید + + + + Shortcuts + میانبرها + + + + Forward character + کاراکتر جلو + + + + Backward character + کاراکتر عقب + + + + Transpose character + انتقال کاراکتر + + + + Add comment + + + + + Remove comment + + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Tab width + عرض زبانه + + + + + + Window + پنجره + + + + New tab + زبانه جدید + + + + New window + پنجره جدید + + + + Save + ذخیره + + + + Save as + ذخیره به عنوان + + + + Next tab + زبانه بعدی + + + + Previous tab + زبانه قبلی + + + + Close tab + بستن زبانه + + + + Close other tabs + بستن بقیه زبانه ها + + + + Restore tab + بازیابی زبانه + + + + Open file + باز کردن فایل + + + + Reset font size + تنظیم مجدد اندازه فونت + + + + Toggle fullscreen + ضامن تمام صفحه + + + + Help + + + + + Increment font size + + + + + Decrement font size + + + + + Find + یافتن + + + + Replace + جایگزین + + + + Go to line + برو به خط + + + + Save cursor position + ذخیره موقعیت مکان نما + + + + Reset cursor position + تنظیم مجدد موقعیت مکان نما + + + + Exit + خروج + + + + Display shortcuts + نمایش میانبرها + + + + Print + چاپ + + + + Editor + ویرایشگر + + + + Increase indent + افزایش تورفتگی + + + + Decrease indent + کاهش تورفتگی + + + + Forward word + کلمه جلو + + + + Backward word + کلمه عقب + + + + Next line + خط بعدی + + + + Previous line + خط قبلی + + + + New line + خط جدید + + + + New line above + خط جدید بالا + + + + New line below + خط جدید پایین + + + + Duplicate line + تکثیر خط + + + + Delete to end of line + حذف تا انتهای خط + + + + Delete current line + حذف خط فعلی + + + + Swap line up + تعویض خط بالا + + + + Swap line down + تعویض خط پایین + + + + Scroll up one line + پیمایش به یک خط بالا + + + + Scroll down one line + پیمایش به یک خط پایین + + + + Page up + Page up + + + + Page down + Page down + + + + Move to end of line + حرکت به انتهای خط + + + + Move to start of line + حرکت به ابتدای خط + + + + Move to end of text + انتقال به انتهای متن + + + + Move to start of text + انتقال به ابتدای متن + + + + Move to line indentation + انتقال به تورفتگی متن + + + + Upper case + حالت بزرگ + + + + Lower case + حالت کوچک + + + + Capitalize + درشت نوشتن + + + + Delete backward word + حذف کلمه عقب + + + + Delete forward word + حذف کلمه جلو + + + + Forward over a pair + جلو یک جفت + + + + Backward over a pair + عقب یک جفت + + + + Select all + انتخاب همه + + + + Copy + کپی + + + + Cut + بریدن + + + + Paste + چسباندن + + + + Mark + علامت + + + + Unmark + بدون علامت + + + + Copy line + کپی خط + + + + Cut line + برش خط + + + + Merge lines + ادغام خطوط + + + + Read-Only mode + حالت فقط خواندن + + + + Word wrap + + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Undo + واچیدن + + + + Redo + مجدد + + + + Advanced + پیشرفته + + + + Window size + اندازه پنجره + + + + + + + + + Encoding + رمزگذاری + + + + + + Line Endings + خط پایان + + + + ReplaceBar + + + Find + یافتن + + + + Replace With + + + + + Replace + جایگزین + + + + Skip + پرش + + + + Replace Rest + جایگزینی بقیه + + + + Replace All + جایگزینی همه + + + + Settings + + + Standard + استاندارد + + + + Customize + شخصی سازی + + + + Normal + طبیعی + + + + Maximum + بیشترین + + + + Fullscreen + تمام صفحه + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + لغو + + + + Replace + جایگزین + + + + OK + + + + + StartManager + + + Untitled %1 + + + + + Tabbar + + + Close tab + بستن زبانه + + + + Close other tabs + بستن بقیه زبانه ها + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + TextEdit + + + Undo + واچیدن + + + + Redo + مجدد + + + + Cut + بریدن + + + + Copy + کپی + + + + Paste + چسباندن + + + + Delete + حذف + + + + Select All + انتخاب همه + + + + + Find + یافتن + + + + + Replace + جایگزین + + + + Go to Line + برو به خط + + + + Turn on Read-Only mode + روشن کردن حالت فقط خواندن + + + + Turn off Read-Only mode + خاموش کردن حالت فقط خواندن + + + + Fullscreen + تمام صفحه + + + + Exit fullscreen + خروج از تمام صفحه + + + + Display in file manager + نمایش در مدیریت کننده فایل + + + + + Add Comment + + + + + Text to Speech + + + + + Stop reading + + + + + Speech to Text + + + + + Translate + + + + + Column Mode + + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Mark + علامت + + + + Mark All + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + تغییر حالت + + + + Upper Case + حالت بزرگ + + + + Lower Case + حالت کوچک + + + + Capitalize + درشت نوشتن + + + + None + هیچ یک + + + + Selected line(s) copied + + + + + Current line copied + + + + + Selected line(s) clipped + + + + + Current line clipped + + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + حالت فقط خواندن خاموش است + + + + + + Read-Only mode is on + حالت فقط خواندن روشن است + + + + WarningNotices + + + Reload + + + + + Window + + + New window + پنجره جدید + + + + New tab + زبانه جدید + + + + Open file + باز کردن فایل + + + + + Save as + ذخیره به عنوان + + + + Print + چاپ + + + + Switch theme + تغییر تم + + + + + Read-Only + فقط خواندنی + + + + Saved successfully + با موفقیت ذخیره شد + + + + Read-Only mode is on + حالت فقط خواندن روشن است + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + دور انداختن + + + + + Settings + تنظیمات + + + + You do not have permission to open %1 + شما اجازه باز کردن %1 را ندارید + + + + Invalid file: %1 + فایل نامعتبر: %1 + + + + + + Save File + ذخیره فایل + + + + + Do you want to save this file? + آیا می خواهید این فایل را ذخیره کنید؟ + + + + Encoding + رمزگذاری + + + + Editor + ویرایشگر + + + + You do not have permission to save %1 + شما اجازه ذخیره %1 را ندارید + + + + Untitled %1 + + + + + Current location remembered + + + + + Cancel + لغو + + + + + Save + ذخیره + + + diff --git a/translations/deepin-editor_fi.ts b/translations/deepin-editor_fi.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e674f3b2879077b471ff4b4652a8c7e0a063155 --- /dev/null +++ b/translations/deepin-editor_fi.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Rivi + + + + Column + Sarake + + + + Characters %1 + Merkit %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Tyhjä + + + + EditWrapper + + + + + + Save + Tallenna + + + + Do you want to save this file? + Haluatko tallentaa tämän tiedoston? + + + + + Cancel + Peru + + + + Encoding changed. Do you want to save the file now? + Koodaus muutettu. Haluatko tallentaa tiedoston nyt? + + + + Discard + Hylkää + + + + You do not have permission to save %1 + Sinulla ei ole lupaa tallentaa %1 + + + + File removed on the disk. Save it now? + Tiedosto on poistettu. Tallenna se nyt? + + + + File has changed on disk. Reload? + Tiedosto on muuttunut. Päivitä? + + + + + INSERT + Lisää + + + + OVERWRITE + Ylikirjoita + + + + R/O + R/O + + + + FindBar + + + Find + Etsi + + + + Previous + Edellinen + + + + Next + Seuraava + + + + JumpLineBar + + + Go to Line: + Siirry riville: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Tekstieditori on tehokas työkalu tekstitiedostojen katselemiseen ja muokkaamiseen. + + + + Text Editor + Tekstieditori + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Tekstieditori + + + + + + + + + Encoding + Koodaus + + + + Basic + Perustiedot + + + + Font Style + Kirjasimen tyyli + + + + Font + Kirjasin + + + + Font Size + Kirjasimen koko + + + + Shortcuts + Pikanäppäimet + + + + + Keymap + Näppäinkartta + + + + + + Window + Ikkuna + + + + New tab + Uusi välilehti + + + + New window + Uusi ikkuna + + + + Save + Tallenna + + + + Save as + Tallenna nimellä + + + + Next tab + Seuraava välilehti + + + + Previous tab + Edellinen välilehti + + + + Close tab + Sulje välilehti + + + + Close other tabs + Sulje välilehdet + + + + Restore tab + Palauta välilehti + + + + Open file + Avaa tiedosto + + + + Increment font size + Kasvata fonttikokoa + + + + Decrement font size + Vähennä fonttikokoa + + + + Reset font size + Nollaa kirjasimen koko + + + + Help + Apua + + + + Toggle fullscreen + Siirry koko näyttöön + + + + Find + Etsi + + + + Replace + Korvaa + + + + Go to line + Siirry riville + + + + Save cursor position + Tallenna kohdistimen sijainti + + + + Reset cursor position + Nollaa kohdistimen sijainti + + + + Exit + Poistu + + + + Display shortcuts + Näytä pikavalinnat + + + + Print + Tulosta + + + + Editor + Editori + + + + Increase indent + Suurenna sisennys + + + + Decrease indent + Pienennä sisennys + + + + Forward character + Merkki eteen + + + + Backward character + Merkki taakse + + + + Forward word + Sanan eteen + + + + Backward word + Sanan taakse + + + + Next line + Seuraava rivi + + + + Previous line + Edellinen rivi + + + + New line + Uusi rivi + + + + New line above + Uusi rivi eteen + + + + New line below + Uusi rivi taakse + + + + Duplicate line + Monista rivi + + + + Delete to end of line + Poista rivin loppuun + + + + Delete current line + Poista nykyinen rivi + + + + Swap line up + Vaihda rivi ylös + + + + Swap line down + Vaihda rivi alas + + + + Scroll up one line + Vieritä rivi ylöspäin + + + + Scroll down one line + Vieritä rivi alaspäin + + + + Page up + Sivu ylös + + + + Page down + Sivu alas + + + + Move to end of line + Siirry rivin loppuun + + + + Move to start of line + Siirry rivin alkuun + + + + Move to end of text + Siirry tekstin loppuun + + + + Move to start of text + Siirry tekstin alkuun + + + + Move to line indentation + Lisää sisennys + + + + Upper case + Isot kirjaimet + + + + Lower case + Pienet kirjaimet + + + + Capitalize + Suuret kirjaimet + + + + Delete backward word + Poista taaksepäin + + + + Delete forward word + Poista eteenpäin + + + + Forward over a pair + Etenevä + + + + Backward over a pair + Takautuva + + + + Select all + Valitse kaikki + + + + Copy + Kopioi + + + + Cut + Leikkaa + + + + Paste + Liitä + + + + Transpose character + Siirrä merkki + + + + Mark + Merkki + + + + Unmark + Poista merkintä + + + + Copy line + Kopioi rivi + + + + Cut line + Leikkaa rivi + + + + Merge lines + Yhdistä rivit + + + + Read-Only mode + Vain lukutila + + + + Add comment + Lisää kommentti + + + + Remove comment + Poista kommentti + + + + Undo + Kumoa + + + + Redo + Uudelleen + + + + Add/Remove bookmark + Lisää/poista kirjanmerkki + + + + Move to previous bookmark + Siirry edelliseen kirjanmerkkiin + + + + Move to next bookmark + Siirry seuraavaan kirjanmerkkiin + + + + Advanced + Edistynyt + + + + Window size + Ikkunan koko + + + + Tab width + Välilehden leveys + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Rivitys + + + + Code folding flag + Koodin taiton merkit + + + + Show line numbers + Näytä rivinumerot + + + + Show bookmarks icon + Näytä kirjanmerkit kuvake + + + + Show whitespaces and tabs + Näytä välilyönnit ja tabulaattorit + + + + Highlight current line + Korosta nykyinen rivi + + + + Color mark + Värimerkki + + + + Unicode + Unicode + + + + WesternEuropean + Länsi-Eurooppa + + + + CentralEuropean + Keski-Eurooppa + + + + Baltic + Baltia + + + + Cyrillic + Kyrillinen + + + + Arabic + Arabia + + + + Celtic + Kelttiläinen + + + + SouthEasternEuropean + Kaakkois-Eurooppa + + + + Greek + Kreikka + + + + Hebrew + Hebrea + + + + ChineseSimplified + Kiina-yksinkertaistettu + + + + ChineseTraditional + Kiina-perinteinen + + + + Japanese + Japani + + + + Korean + Korea + + + + Thai + Thai + + + + Turkish + Turkki + + + + Vietnamese + Vietnami + + + + File not saved + Tiedostoa ei tallennettu + + + + + + Line Endings + Rivin loppu + + + + ReplaceBar + + + Find + Etsi + + + + Replace With + Korvaa + + + + Replace + Korvaa + + + + Skip + Ohita + + + + Replace Rest + Korvaa loput + + + + Replace All + Korvaa kaikki + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standardi + + + + Customize + Muokkaa + + + + Normal + Normaali + + + + Maximum + Maksimi + + + + Fullscreen + Koko näyttö + + + + This shortcut conflicts with system shortcut %1 + Tämä pikanäppäin on ristiriidassa järjestelmän %1 kanssa + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Tämä on ristiriidassa %1 kanssa, valitse Korvaa, jotta tämä pikanäppäin tulee voimaan välittömästi + + + + + The shortcut %1 is invalid, please set another one. + Pikanäppäin %1 on virheellinen, aseta toinen. + + + + Cancel + Peru + + + + Replace + Korvaa + + + + OK + OK + + + + StartManager + + + Untitled %1 + Nimetön %1 + + + + Tabbar + + + Close tab + Sulje välilehti + + + + Close other tabs + Sulje välilehdet + + + + More options + Lisää vaihtoehtoja + + + + Close tabs to the left + Sulje välilehdet vasemmalla + + + + Close tabs to the right + Sulje välilehdet oikealla + + + + Close unmodified tabs + Sulje muuttumattomat välilehdet + + + + TextEdit + + + Undo + Kumoa + + + + Redo + Uudelleen + + + + Cut + Leikkaa + + + + Copy + Kopioi + + + + Paste + Liitä + + + + Delete + Poista + + + + Select All + Valitse kaikki + + + + + Find + Etsi + + + + + Replace + Korvaa + + + + Go to Line + Siirry riville + + + + Turn on Read-Only mode + Vain lukutila + + + + Turn off Read-Only mode + Poista vain lukutila + + + + Fullscreen + Koko näyttö + + + + Exit fullscreen + Poistu koko näytöstä + + + + Display in file manager + Näytä tiedostojenhallinnassa + + + + + Add Comment + Lisää kommentti + + + + Text to Speech + Teksti puheeksi + + + + Stop reading + Lopeta lukeminen + + + + Speech to Text + Puhe tekstiksi + + + + Translate + Kääntäjä + + + + Column Mode + Saraketila + + + + Add bookmark + Lisää kirjanmerkki + + + + Remove Bookmark + Poista kirjanmerkki + + + + Previous bookmark + Edellinen kirjanmerkki + + + + Next bookmark + Seuraava kirjanmerkki + + + + Remove All Bookmarks + Poista kaikki kirjanmerkkit + + + + Fold All + Taita kaikki + + + + Fold Current Level + Taita nykyinen taso + + + + Unfold All + Avaa kaikki + + + + Unfold Current Level + Avaa nykyinen taso + + + + Color Mark + Värimerkki + + + + Clear All Marks + Poista kaikki merkit + + + + Clear Last Mark + Poista viimeinen merkki + + + + Mark + Merkki + + + + Mark All + Merkitse kaikki + + + + Remove Comment + Poista kommentti + + + + Copy failed: not enough memory + Kopiointi epäonnistui: muisti ei riitä + + + + Press ALT and click lines to edit in column mode + Paina ALT-näppäintä ja napsauta riviä, jos haluat muokata sitä saraketilassa + + + + Change Case + Vaihda kirjainkokoa + + + + Upper Case + Isot kirjaimet + + + + Lower Case + Pienet kirjaimet + + + + Capitalize + Suuret kirjaimet + + + + None + Tyhjä + + + + Selected line(s) copied + Valitut rivit kopioitu + + + + Current line copied + Nykyinen rivi kopioitu + + + + Selected line(s) clipped + Valitut rivit leikattu + + + + Current line clipped + Nykyinen rivi leikattu + + + + Paste failed: not enough memory + Liittäminen epäonnistui: muisti ei riitä + + + + Read-Only mode is off + Lukutila on pois päältä + + + + + + Read-Only mode is on + Lukutila on päällä + + + + WarningNotices + + + Reload + Päivitä + + + + Window + + + + Save as + Tallenna nimellä + + + + New window + Uusi ikkuna + + + + New tab + Uusi välilehti + + + + Open file + Avaa tiedosto + + + + + Save + Tallenna + + + + Print + Tulosta + + + + Switch theme + Vaihda teema + + + + + Settings + Asetukset + + + + + Read-Only + Luettavissa + + + + You do not have permission to open %1 + Sinulla ei ole lupaa avata %1 + + + + Invalid file: %1 + Virheellinen tiedosto: %1 + + + + + Do you want to save this file? + Haluatko tallentaa tämän tiedoston? + + + + You do not have permission to save %1 + Sinulla ei ole lupaa tallentaa %1 + + + + Saved successfully + Tallennus onnistui + + + + + + Save File + Tallenna tiedosto + + + + Encoding + Koodaus + + + + Read-Only mode is on + Lukutila on päällä + + + + Current location remembered + Nykyinen sijainti muistetaan + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Editori + + + + Untitled %1 + Nimetön %1 + + + + Cancel + Peru + + + + Discard + Hylkää + + + \ No newline at end of file diff --git a/translations/deepin-editor_fr.ts b/translations/deepin-editor_fr.ts new file mode 100644 index 0000000000000000000000000000000000000000..04f88b22959f4c7e287650c134ae71ccee9c888b --- /dev/null +++ b/translations/deepin-editor_fr.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Ligne + + + + Column + Colonne + + + + Characters %1 + Caractères %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Aucun + + + + EditWrapper + + + + + + Save + Sauvegarder + + + + Do you want to save this file? + Voulez-vous enregistrer ce fichier ? + + + + + Cancel + Annuler + + + + Encoding changed. Do you want to save the file now? + L'encodage a changé. Voulez-vous enregistrer le fichier maintenant ? + + + + Discard + Abandonner + + + + You do not have permission to save %1 + Vous n'avez pas la permission de sauvegarder %1 + + + + File removed on the disk. Save it now? + Fichier supprimé du disque. L'enregistrer maintenant ? + + + + File has changed on disk. Reload? + Le fichier a été modifié sur le disque. Recharger ? + + + + + INSERT + INSÉRER + + + + OVERWRITE + ÉCRASER + + + + R/O + L/S + + + + FindBar + + + Find + Rechercher + + + + Previous + Précédent + + + + Next + Suivant + + + + JumpLineBar + + + Go to Line: + Aller à la ligne : + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + L'éditeur de texte est un outil pour afficher et modifier des fichiers texte. + + + + Text Editor + Éditeur de texte + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Éditeur de texte + + + + + + + + + Encoding + Encodage + + + + Basic + De base + + + + Font Style + Style d'écriture + + + + Font + Police + + + + Font Size + Taille de la police + + + + Shortcuts + Raccourcis + + + + + Keymap + Préréglage + + + + + + Window + Fenêtre + + + + New tab + Nouvel onglet + + + + New window + Nouvelle fenêtre + + + + Save + Enregistrer + + + + Save as + Enregistrer sous + + + + Next tab + Onglet suivant + + + + Previous tab + Onglet précédent + + + + Close tab + Fermer l'onglet + + + + Close other tabs + Fermer les autres onglets + + + + Restore tab + Restaurer l'onglet + + + + Open file + Ouvrir un fichier + + + + Increment font size + Augmenter la taille de police + + + + Decrement font size + Diminuer la taille de police + + + + Reset font size + Réinitialiser la taille de la police + + + + Help + Aide + + + + Toggle fullscreen + Basculer en plein écran + + + + Find + Rechercher + + + + Replace + Remplacer + + + + Go to line + Aller à la ligne + + + + Save cursor position + Sauvegarder position curseur + + + + Reset cursor position + Réinitialiser position curseur + + + + Exit + Quitter + + + + Display shortcuts + Afficher les raccourcis + + + + Print + Imprimer + + + + Editor + Éditeur + + + + Increase indent + Augmenter espace + + + + Decrease indent + Diminuer espace + + + + Forward character + Caractère suivant + + + + Backward character + Caractère précédent + + + + Forward word + Mot suivant + + + + Backward word + Mot précédent + + + + Next line + Ligne suivante + + + + Previous line + Ligne précédente + + + + New line + Nouvelle ligne + + + + New line above + Nouvelle ligne au dessus + + + + New line below + Nouvelle ligne en dessous + + + + Duplicate line + Dupliquer la ligne + + + + Delete to end of line + Supprimer jusqu'à fin ligne + + + + Delete current line + Supprimer la ligne actuelle + + + + Swap line up + Basculer ligne vers haut + + + + Swap line down + Basculer ligne vers bas + + + + Scroll up one line + Faire défiler la ligne vers le haut + + + + Scroll down one line + Faire défiler la ligne vers le bas + + + + Page up + Page précédente + + + + Page down + Page suivante + + + + Move to end of line + Déplacer à la fin ligne + + + + Move to start of line + Déplacer au début ligne + + + + Move to end of text + Basculer à la fin du texte + + + + Move to start of text + Basculer au début du texte + + + + Move to line indentation + Basculer à l'index ligne + + + + Upper case + Majuscule + + + + Lower case + Minuscule + + + + Capitalize + Mettre en majuscule + + + + Delete backward word + Supprimer mot précédent + + + + Delete forward word + Supprimer le mot suivant + + + + Forward over a pair + Basculer à la fin sélection + + + + Backward over a pair + Basculer au début sélection + + + + Select all + Tout sélectionner + + + + Copy + Copier + + + + Cut + Couper + + + + Paste + Coller + + + + Transpose character + Caractère de transposition + + + + Mark + Cocher + + + + Unmark + Décocher + + + + Copy line + Copier la ligne + + + + Cut line + Couper la ligne + + + + Merge lines + Fusionner les lignes + + + + Read-Only mode + Mode lecture seule + + + + Add comment + Ajouter un commentaire + + + + Remove comment + Supprimer le commentaire + + + + Undo + Annuler + + + + Redo + Rétablir + + + + Add/Remove bookmark + Ajouter/Supprimer un signet + + + + Move to previous bookmark + Passer au signet précédent + + + + Move to next bookmark + Passer au signet suivant + + + + Advanced + Avancés + + + + Window size + Taille de la fenêtre + + + + Tab width + Largeur de tabulation + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Retour automatique à la ligne + + + + Code folding flag + Drapeau de pliage de code + + + + Show line numbers + Afficher les numéros de ligne + + + + Show bookmarks icon + Afficher l'icône des signets + + + + Show whitespaces and tabs + Afficher les espaces et les tabulations + + + + Highlight current line + Mettre en évidence la ligne actuelle + + + + Color mark + Marque de couleur + + + + Unicode + Unicode + + + + WesternEuropean + Europe de l'ouest + + + + CentralEuropean + Europe centrale + + + + Baltic + Baltique + + + + Cyrillic + Cyrillique + + + + Arabic + Arabe + + + + Celtic + Celtique + + + + SouthEasternEuropean + Europe du sud-est + + + + Greek + Grec + + + + Hebrew + Hébreu + + + + ChineseSimplified + Chinois simplifié + + + + ChineseTraditional + Chinois traditionnel + + + + Japanese + Japonais + + + + Korean + Coréen + + + + Thai + Thaïlandais + + + + Turkish + Turc + + + + Vietnamese + Vietnamien + + + + File not saved + Fichier non sauvegardé + + + + + + Line Endings + Fin de ligne + + + + ReplaceBar + + + Find + Rechercher + + + + Replace With + Remplacer par + + + + Replace + Remplacer + + + + Skip + Passer + + + + Replace Rest + Remplacer la suite + + + + Replace All + Tout remplacer + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standard + + + + Customize + Personnaliser + + + + Normal + Normal + + + + Maximum + Maximum + + + + Fullscreen + Plein écran + + + + This shortcut conflicts with system shortcut %1 + Ce raccourci entre en conflit avec le raccourci système %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Ce raccourci entre en conflit avec %1, cliquez sur Remplacer pour rendre ce raccourci effectif immédiatement + + + + + The shortcut %1 is invalid, please set another one. + Le raccourci %1 n'est pas valide, veuillez en définir un autre. + + + + Cancel + Annuler + + + + Replace + Remplacer + + + + OK + OK + + + + StartManager + + + Untitled %1 + Sans titre %1 + + + + Tabbar + + + Close tab + Fermer l'onglet + + + + Close other tabs + Fermer les autres onglets + + + + More options + Plus d'options + + + + Close tabs to the left + Fermer les onglets à gauche + + + + Close tabs to the right + Fermer les onglets à droite + + + + Close unmodified tabs + Fermer les onglets non modifiés + + + + TextEdit + + + Undo + Annuler + + + + Redo + Rétablir + + + + Cut + Couper + + + + Copy + Copier + + + + Paste + Coller + + + + Delete + Supprimer + + + + Select All + Tout sélectionner + + + + + Find + Rechercher + + + + + Replace + Remplacer + + + + Go to Line + Aller à la ligne + + + + Turn on Read-Only mode + Activer le mode lecture seule + + + + Turn off Read-Only mode + Désactiver le mode lecture seule + + + + Fullscreen + Plein écran + + + + Exit fullscreen + Quitter le mode plein écran + + + + Display in file manager + Afficher dans l'explorateur de fichiers + + + + + Add Comment + Ajouter un commentaire + + + + Text to Speech + Texte vers voix + + + + Stop reading + Arrêter de lire + + + + Speech to Text + Voix vers texte + + + + Translate + Traduire + + + + Column Mode + Mode colonne + + + + Add bookmark + Ajouter un signet + + + + Remove Bookmark + Supprimer le signet + + + + Previous bookmark + Signet précédent + + + + Next bookmark + Signet suivant + + + + Remove All Bookmarks + Supprimer tous les signets + + + + Fold All + Tout plier + + + + Fold Current Level + Plier le niveau actuel + + + + Unfold All + Tout déplier + + + + Unfold Current Level + Déplier le niveau actuel + + + + Color Mark + Marque de couleur + + + + Clear All Marks + Effacer toutes les marques + + + + Clear Last Mark + Effacer la dernière marque + + + + Mark + Cocher + + + + Mark All + Marquer tout + + + + Remove Comment + Supprimer le commentaire + + + + Copy failed: not enough memory + Copie ratée: pas assez de mémoire + + + + Press ALT and click lines to edit in column mode + Appuyer sur ALT et cliquer sur les lignes pour éditer en mode colonne + + + + Change Case + Changer de case + + + + Upper Case + Mettre en majuscules + + + + Lower Case + Mettre en minuscules + + + + Capitalize + Mettre en majuscules + + + + None + Aucun + + + + Selected line(s) copied + Ligne(s) sélectionnée(s) copiée(s) + + + + Current line copied + Ligne actuelle copiée + + + + Selected line(s) clipped + Ligne(s) sélectionnée(s) coupée(s) + + + + Current line clipped + Ligne actuelle coupée + + + + Paste failed: not enough memory + Échec du collage : mémoire insuffisante + + + + Read-Only mode is off + Le mode lecture seule est désactivé + + + + + + Read-Only mode is on + Le mode lecture seule est activé + + + + WarningNotices + + + Reload + Recharger + + + + Window + + + + Save as + Enregistrer sous + + + + New window + Nouvelle fenêtre + + + + New tab + Nouvel onglet + + + + Open file + Ouvrir un fichier + + + + + Save + Enregistrer + + + + Print + Imprimer + + + + Switch theme + Changer de thème + + + + + Settings + Paramètres + + + + + Read-Only + Lecture seule + + + + You do not have permission to open %1 + Vous n'avez pas la permission d'ouvrir %1 + + + + Invalid file: %1 + Fichier invalide : %1 + + + + + Do you want to save this file? + Voulez-vous enregistrer ce fichier ? + + + + You do not have permission to save %1 + Vous n'avez pas la permission de sauvegarder %1 + + + + Saved successfully + Enregistré avec succès + + + + + + Save File + Sauvegarder le fichier + + + + Encoding + Encodage + + + + Read-Only mode is on + Le mode lecture seule est activé + + + + Current location remembered + Location actuelle sauvegardée + + + + Ctrl+'=' + Ctrl + '=' + + + + Ctrl+'-' + Ctrl + '-' + + + + Editor + Éditeur + + + + Untitled %1 + Sans titre %1 + + + + Cancel + Annuler + + + + Discard + Abandonner + + + \ No newline at end of file diff --git a/translations/deepin-editor_gl_ES.ts b/translations/deepin-editor_gl_ES.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0a4ebecec77f55526b603219f1ddf6308783f3e --- /dev/null +++ b/translations/deepin-editor_gl_ES.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Fila + + + + Column + Columna + + + + Characters %1 + Caracteres %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Ningún + + + + EditWrapper + + + + + + Save + Gardar + + + + Do you want to save this file? + Quere gardar este ficheiro? + + + + + Cancel + Cancelar + + + + Encoding changed. Do you want to save the file now? + A codificación cambiou. Quere gardar o ficheiro agora? + + + + Discard + Descartar + + + + You do not have permission to save %1 + Non tes permiso para gardar% 1 + + + + File removed on the disk. Save it now? + Ficheiro eliminado no disco. Gardalo agora? + + + + File has changed on disk. Reload? + O ficheiro cambiou no disco. Recargar? + + + + + INSERT + INSERTAR + + + + OVERWRITE + SUBSTITUÍR + + + + R/O + R/O + + + + FindBar + + + Find + Atopar + + + + Previous + Anterior + + + + Next + Seguinte + + + + JumpLineBar + + + Go to Line: + Ir á liña: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Editor de texto é unha poderosa ferramenta para ver e editar ficheiros de texto. + + + + Text Editor + Editor de texto + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Editor de texto + + + + + + + + + Encoding + Codificación + + + + Basic + Básico + + + + Font Style + Estilo da fonte + + + + Font + Fonte + + + + Font Size + Tamaño da fonte + + + + Shortcuts + Atallos + + + + + Keymap + Mapa de clave + + + + + + Window + Xanela + + + + New tab + Nova lapela + + + + New window + Nova xanela + + + + Save + Gardar + + + + Save as + Gardar como + + + + Next tab + Nova lapela + + + + Previous tab + Lapela anterior + + + + Close tab + Lapela pechada + + + + Close other tabs + Pechar outras lapelas + + + + Restore tab + Restaurar lapela + + + + Open file + Abrir ficheiro + + + + Increment font size + + + + + Decrement font size + + + + + Reset font size + Restablecer o tamaño da fonte + + + + Help + Axuda + + + + Toggle fullscreen + Alternar pantalla completa + + + + Find + Atopar + + + + Replace + Substituír + + + + Go to line + Ir á liña + + + + Save cursor position + Gardar a posición do cursor + + + + Reset cursor position + Restablecer a posición do cursor + + + + Exit + Saír + + + + Display shortcuts + Amosar atallos + + + + Print + Imprimir + + + + Editor + Editor + + + + Increase indent + Aumentar a sangría + + + + Decrease indent + Diminuír a sangría + + + + Forward character + Caracter adiante + + + + Backward character + Caracter atrás + + + + Forward word + Adiantar a palabra + + + + Backward word + Atrasar a palabra + + + + Next line + Seguinte liña + + + + Previous line + Anterior liña + + + + New line + Nova liña + + + + New line above + Nova liña enriba + + + + New line below + Nova liña embaixo + + + + Duplicate line + Duplicar liña + + + + Delete to end of line + Eliminar o final da liña + + + + Delete current line + Eliminar a liña actual + + + + Swap line up + Intercambiar a liña cara enriba + + + + Swap line down + Intercambiar a liña cara abaixo + + + + Scroll up one line + Desprazarse cara arriba unha liña + + + + Scroll down one line + Desprazarse cara abaixo unha liña + + + + Page up + Mover cara arriba polas páxinas + + + + Page down + Mover cara arriba polas páxinas + + + + Move to end of line + Moverse ata o final da liña + + + + Move to start of line + Moverse ao principio da liña + + + + Move to end of text + Moverse ao final do texto + + + + Move to start of text + Moverse ao principio do texto + + + + Move to line indentation + Mover a sangría da liña + + + + Upper case + Maiúscula + + + + Lower case + Minúscula + + + + Capitalize + Capitalizar + + + + Delete backward word + Eliminar palabras atrás + + + + Delete forward word + Eliminar palabras adiante + + + + Forward over a pair + Adiantar sobre un par + + + + Backward over a pair + Atrás sobre un par + + + + Select all + Seleccionar todo + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Pegar + + + + Transpose character + Caracter transposto + + + + Mark + Marcar + + + + Unmark + Desmarcar + + + + Copy line + Copiar liña + + + + Cut line + Cortar liña + + + + Merge lines + Fusionar liñas + + + + Read-Only mode + Modo só-ler + + + + Add comment + Engadir comentario + + + + Remove comment + Eliminar comentario + + + + Undo + Desfacer + + + + Redo + Refacer + + + + Add/Remove bookmark + Engadir/Eliminar marcador + + + + Move to previous bookmark + Moverse ao anterior marcador + + + + Move to next bookmark + Moverse ao seguinte marcador + + + + Advanced + Avanzado + + + + Window size + Tamaño da xanela + + + + Tab width + Ancho da lapela + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Axuste de liña + + + + Code folding flag + Indicador do dobramento do código + + + + Show line numbers + Ensinar os números das liñas + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + Marcador de cor + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + File not saved + Ficheiro non gardado + + + + + + Line Endings + Finais das liñas + + + + ReplaceBar + + + Find + Atopar + + + + Replace With + Substituír con + + + + Replace + Substituír + + + + Skip + Saltar + + + + Replace Rest + Substituír o resto + + + + Replace All + Substituír todo + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Estándar + + + + Customize + Personalizar + + + + Normal + Normal + + + + Maximum + Máximo + + + + Fullscreen + Pantalla completa + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Este atallo entra en conflito con% 1, prema en Substituír para facer efectivo este atallo inmediatamente + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + Cancelar + + + + Replace + Substituír + + + + OK + + + + + StartManager + + + Untitled %1 + Sen título %1 + + + + Tabbar + + + Close tab + Lapela pechada + + + + Close other tabs + Pechar outras lapelas + + + + More options + Máis opcións + + + + Close tabs to the left + Pechar lapelas á esquerda + + + + Close tabs to the right + Pechar lapelas á dereita + + + + Close unmodified tabs + Pechar lapelas non modificadas + + + + TextEdit + + + Undo + Desfacer + + + + Redo + Refacer + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Pegar + + + + Delete + Eliminar + + + + Select All + Seleccionar todo + + + + + Find + Atopar + + + + + Replace + Substituír + + + + Go to Line + Ir á liña + + + + Turn on Read-Only mode + Activar modo só-ler + + + + Turn off Read-Only mode + Desactivar modo só-ler + + + + Fullscreen + Pantalla completa + + + + Exit fullscreen + Saír da pantalla completa + + + + Display in file manager + Amosar no xestor do ficheiros + + + + + Add Comment + Engadir comentario + + + + Text to Speech + Texto a Voz + + + + Stop reading + + + + + Speech to Text + Voz a Texto + + + + Translate + Traducir + + + + Column Mode + Modo columna + + + + Add bookmark + + + + + Remove Bookmark + Eliminar marcador + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + Eliminar todos os marcadores + + + + Fold All + Dobrar todo + + + + Fold Current Level + Dobrar o nivel actual + + + + Unfold All + Desdobrar todo + + + + Unfold Current Level + Desdobrar o nivel actual + + + + Color Mark + Marcar a cor + + + + Clear All Marks + Borrar todos os marcadores + + + + Clear Last Mark + Borrar o último marcador + + + + Mark + Marcar + + + + Mark All + Marcar todo + + + + Remove Comment + Eliminar comentario + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + Cambiar caso + + + + Upper Case + Maiúscula + + + + Lower Case + Minúscula + + + + Capitalize + Capitalizar + + + + None + Ningún + + + + Selected line(s) copied + Liña(s) seleccionada/s copiada/s + + + + Current line copied + Liña actual copiada + + + + Selected line(s) clipped + Liña(s) selecciona/s enganchada/s + + + + Current line clipped + Liña actual enganchada + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + O modo só-ler está apagado + + + + + + Read-Only mode is on + O modo só-ler está acendido + + + + WarningNotices + + + Reload + Recargar + + + + Window + + + + Save as + Gardar como + + + + New window + Nova xanela + + + + New tab + Nova lapela + + + + Open file + Abrir ficheiro + + + + + Save + Gardar + + + + Print + Imprimir + + + + Switch theme + Cambiar tema + + + + + Settings + Configuracións + + + + + Read-Only + Só-ler + + + + You do not have permission to open %1 + Non tes permiso para abrir% 1 + + + + Invalid file: %1 + Ficheiro non válido: %1 + + + + + Do you want to save this file? + Quere gardar este ficheiro? + + + + You do not have permission to save %1 + Non tes permiso para gardar% 1 + + + + Saved successfully + Gardado con éxito + + + + + + Save File + Gardar ficheiro + + + + Encoding + Codificación + + + + Read-Only mode is on + O modo só-ler está acendido + + + + Current location remembered + Localización actual recordada + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Editor + + + + Untitled %1 + Sen título %1 + + + + Cancel + Cancelar + + + + Discard + Descartar + + + \ No newline at end of file diff --git a/translations/deepin-editor_hi_IN.ts b/translations/deepin-editor_hi_IN.ts new file mode 100644 index 0000000000000000000000000000000000000000..9cad367bd1af0a47b4b9ce0d9b7b5612863ccb3c --- /dev/null +++ b/translations/deepin-editor_hi_IN.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + पंक्ति + + + + Column + स्तंभ + + + + Characters %1 + अक्षर %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + कुछ नहीं + + + + EditWrapper + + + + + + Save + संचित करें + + + + Do you want to save this file? + क्या आप यह फाइल संचित करना चाहते हैं? + + + + + Cancel + रद्द करें + + + + Encoding changed. Do you want to save the file now? + एन्कोडिंग में परिवर्तन हुआ है। क्या आप अब फाइल को संचित करना चाहते हैं? + + + + Discard + निरस्त करें + + + + You do not have permission to save %1 + आपके पास %1 संचित करने की अनुमति नहीं है + + + + File removed on the disk. Save it now? + डिस्क से फाइल हटा दी गई है। अभी संचित करें? + + + + File has changed on disk. Reload? + डिस्क पर फाइल में परिवर्तन हुआ है। पुनः लोड करें? + + + + + INSERT + प्रविष्ट करें + + + + OVERWRITE + अधिलेखित करें + + + + R/O + केवल-रीड योग्य + + + + FindBar + + + Find + खोज + + + + Previous + पिछली आवृत्ति + + + + Next + अगली आवृत्ति + + + + JumpLineBar + + + Go to Line: + इस पंक्ति पर जाएँ : + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + लेख संपादक - टेक्स्ट फाइलों देखने व संपादन हेतु एक सशक्त साधन है। + + + + Text Editor + लेख संपादक + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + लेख संपादक + + + + + + + + + Encoding + एन्कोडिंग + + + + Basic + सामान्य + + + + Font Style + मुद्रलिपि शैली + + + + Font + मुद्रलिपि + + + + Font Size + मुद्रलिपि आकार + + + + Shortcuts + शॉर्टकट + + + + + Keymap + अभिन्यास + + + + + + Window + विंडो + + + + New tab + नवीन टैब + + + + New window + नवीन विंडो + + + + Save + संचित करें + + + + Save as + इस रूप में संचित करें + + + + Next tab + अगला टैब + + + + Previous tab + पिछला टैब + + + + Close tab + टैब बंद करें + + + + Close other tabs + अन्य टैब बंद करें + + + + Restore tab + टैब पुनः स्थापित करें + + + + Open file + फाइल खोलें + + + + Increment font size + मुद्रलिपि आकार बढ़ाएँ + + + + Decrement font size + मुद्रलिपि आकार घटाएँ + + + + Reset font size + मुद्रलिपि आकार पुनः सेट करें + + + + Help + सहायता + + + + Toggle fullscreen + पूर्ण स्क्रीन चालू/बंद + + + + Find + खोज + + + + Replace + बदलें + + + + Go to line + इस पंक्ति पर जाएँ + + + + Save cursor position + कर्सर स्थिति संचित करें + + + + Reset cursor position + कर्सर स्थिति पुनः सेट करें + + + + Exit + बंद करें + + + + Display shortcuts + शॉर्टकट दिखाएँ + + + + Print + प्रिंट करें + + + + Editor + संपादक + + + + Increase indent + पंक्ति आरंभ सूचक का क्षेत्र बढ़ाएँ + + + + Decrease indent + पंक्ति आरंभ सूचक का क्षेत्र घटाएँ + + + + Forward character + अक्षर के आगे कर्सर ले जाएँ + + + + Backward character + अक्षर के पीछे कर्सर ले जाएँ + + + + Forward word + अगले शब्द पर ले जाएँ + + + + Backward word + पिछले शब्द पर ले जाएँ + + + + Next line + अगली पंक्ति + + + + Previous line + पिछली पंक्ति + + + + New line + नवीन पंक्ति + + + + New line above + नवीन पंक्ति ऊपरी ओर + + + + New line below + नवीन पंक्ति निचली ओर + + + + Duplicate line + पंक्ति प्रतिरूपित करें + + + + Delete to end of line + समापन पंक्ति तक की सामग्री हटाएँ + + + + Delete current line + वर्तमान पंक्ति हटाएँ + + + + Swap line up + ऊपरी पंक्ति से बदलें + + + + Swap line down + निचली पंक्ति से बदलें + + + + Scroll up one line + एक पंक्ति ऊपरी ओर स्क्रॉल करें + + + + Scroll down one line + एक पंक्ति निचली ओर स्क्रॉल करें + + + + Page up + पृष्ठ ऊपर करें + + + + Page down + पृष्ठ नीचे करें + + + + Move to end of line + पंक्ति के अंत पर ले जाएँ + + + + Move to start of line + पंक्ति आरंभ पर ले जाएँ + + + + Move to end of text + लेख के अंत पर ले जाएँ + + + + Move to start of text + लेख के आरंभ पर ले जाएँ + + + + Move to line indentation + पंक्ति आरंभ सूचक पर ले जाएँ + + + + Upper case + अपरकेस + + + + Lower case + लोअरकेस + + + + Capitalize + कैपिटल अक्षर में बदलें + + + + Delete backward word + पिछला शब्द हटाएँ + + + + Delete forward word + अगला शब्द हटाएँ + + + + Forward over a pair + कोष्ठक के आगे कर्सर ले जाएँ + + + + Backward over a pair + कोष्ठक के पीछे कर्सर ले जाएँ + + + + Select all + सभी चयनित करें + + + + Copy + कॉपी करें + + + + Cut + कट करें + + + + Paste + पेस्ट करें + + + + Transpose character + अक्षर स्थानांतरण + + + + Mark + चिन्हित + + + + Unmark + अचिन्हित करें + + + + Copy line + पंक्ति कॉपी करें + + + + Cut line + पंक्ति कट करें + + + + Merge lines + पंक्तियों का विलय करें + + + + Read-Only mode + केवल-रीड योग्य मोड + + + + Add comment + टिप्पणी जोड़ें + + + + Remove comment + टिप्पणी हटाएँ + + + + Undo + पूर्ववत करें + + + + Redo + पुनः करें + + + + Add/Remove bookmark + स्मृति-चिन्ह जोड़ें/हटाएँ + + + + Move to previous bookmark + पिछले स्मृति-चिन्ह पर जाएँ + + + + Move to next bookmark + अगले स्मृति-चिन्ह पर जाएँ + + + + Advanced + विस्तृत + + + + Window size + विंडो आकार + + + + Tab width + टैब चौड़ाई + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + विखंडन + + + + Code folding flag + कोड के संक्षिप्त प्रदर्शन हेतु सूचक + + + + Show line numbers + पंक्ति संख्या प्रदर्शित करें + + + + Show bookmarks icon + स्मृति-चिन्ह आइकन दिखाएँ + + + + Show whitespaces and tabs + रिक्त अक्षर व टैब दिखाएँ + + + + Highlight current line + वर्तमान पंक्ति चिन्हित करें + + + + Color mark + रंगीन चिन्ह + + + + Unicode + यूनिकोड + + + + WesternEuropean + पश्चिमी यूरोपीय + + + + CentralEuropean + मध्य यूरोपीय + + + + Baltic + बाल्टिक + + + + Cyrillic + सिरिलिक + + + + Arabic + अरबी + + + + Celtic + सेल्टिक + + + + SouthEasternEuropean + दक्षिण पूर्वी यूरोपीय + + + + Greek + यूनानी + + + + Hebrew + हिब्रू + + + + ChineseSimplified + सरल चीनी + + + + ChineseTraditional + पारंपरिक चीनी + + + + Japanese + जापानी + + + + Korean + कोरियाई + + + + Thai + थाई + + + + Turkish + तुर्क + + + + Vietnamese + वियतनामी + + + + File not saved + फाइल संचय विफल + + + + + + Line Endings + पंक्ति अंत + + + + ReplaceBar + + + Find + खोज + + + + Replace With + इससे बदलें + + + + Replace + बदलें + + + + Skip + निरस्त + + + + Replace Rest + शेष को बदलें + + + + Replace All + सभी को बदलें + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + सामान्य + + + + Customize + अनुकूलन + + + + Normal + सामान्य + + + + Maximum + अधिकतम + + + + Fullscreen + पूर्ण स्क्रीन + + + + This shortcut conflicts with system shortcut %1 + यह शॉर्टकट %1 सिस्टम शॉर्टकट के विरुद्ध है + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + यह शॉर्टकट %1 के विरुद्ध है, बदलें पर क्लिक कर तुरंत प्रभाव से इस शॉर्टकट को क्रियान्वित करें + + + + + The shortcut %1 is invalid, please set another one. + %1 शॉर्टकट अमान्य है, कृपया अन्य सेट करें। + + + + Cancel + रद्द करें + + + + Replace + बदलें + + + + OK + ठीक है + + + + StartManager + + + Untitled %1 + शीर्षक रहित %1 + + + + Tabbar + + + Close tab + टैब बंद करें + + + + Close other tabs + अन्य टैब बंद करें + + + + More options + अधिक विकल्प + + + + Close tabs to the left + बाईं ओर के टैब बंद करें + + + + Close tabs to the right + दाईं ओर के टैब बंद करें + + + + Close unmodified tabs + अपरिवर्तित टैब बंद करें + + + + TextEdit + + + Undo + पूर्ववत करें + + + + Redo + पुनः करें + + + + Cut + कट करें + + + + Copy + कॉपी करें + + + + Paste + पेस्ट करें + + + + Delete + हटाएँ + + + + Select All + सभी चयनित करें + + + + + Find + खोज + + + + + Replace + बदलें + + + + Go to Line + इस पंक्ति पर जाएँ + + + + Turn on Read-Only mode + केवल-रीड योग्य मोड चालू करें + + + + Turn off Read-Only mode + केवल-रीड योग्य मोड बंद करें + + + + Fullscreen + पूर्ण स्क्रीन + + + + Exit fullscreen + पूर्ण स्क्रीन बंद करें + + + + Display in file manager + फाइल प्रबंधक में दिखाएँ + + + + + Add Comment + टिप्पणी जोड़ें + + + + Text to Speech + लेख से वाणी + + + + Stop reading + वाचन बंद करें + + + + Speech to Text + वाणी से लेख + + + + Translate + अनुवाद + + + + Column Mode + स्तंभ मोड + + + + Add bookmark + स्मृति-चिन्ह जोड़ें + + + + Remove Bookmark + स्मृति-चिन्ह हटाएँ + + + + Previous bookmark + पिछला स्मृति-चिन्ह + + + + Next bookmark + अगला स्मृति-चिन्ह + + + + Remove All Bookmarks + सभी स्मृति-चिन्ह हटाएँ + + + + Fold All + सभी संक्षिप्त करें + + + + Fold Current Level + वर्तमान स्तर को संक्षिप्त करें + + + + Unfold All + सभी विस्तृत करें + + + + Unfold Current Level + वर्तमान स्तर को विस्तृत करें + + + + Color Mark + रंगीन चिन्ह + + + + Clear All Marks + सभी चिन्ह हटाएँ + + + + Clear Last Mark + अंतिम चिन्ह हटाएँ + + + + Mark + चिन्हित + + + + Mark All + सभी चिन्हित करें + + + + Remove Comment + टिप्पणी हटाएँ + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + स्तंभ मोड में संपादन हेतु ALT कुंजी दबाकर पंक्तियों पर क्लिक करें + + + + Change Case + केस बदलें + + + + Upper Case + अपरकेस + + + + Lower Case + लोअरकेस + + + + Capitalize + कैपिटल अक्षर में बदलें + + + + None + कुछ नहीं + + + + Selected line(s) copied + चयनित पंक्तियाँ कॉपी की गई + + + + Current line copied + वर्तमान पंक्ति कॉपी की गई + + + + Selected line(s) clipped + चयनित पंक्तियाँ क्लिप की गई + + + + Current line clipped + वर्तमान पंक्ति क्लिप की गई + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + केवल-रीड योग्य मोड निष्क्रिय है + + + + + + Read-Only mode is on + केवल-रीड योग्य मोड सक्रिय है + + + + WarningNotices + + + Reload + पुनः लोड करें + + + + Window + + + + Save as + इस रूप में संचित करें + + + + New window + नवीन विंडो + + + + New tab + नवीन टैब + + + + Open file + फाइल खोलें + + + + + Save + संचित करें + + + + Print + प्रिंट करें + + + + Switch theme + थीम बदलें + + + + + Settings + सेटिंग्स + + + + + Read-Only + केवल-रीड योग्य + + + + You do not have permission to open %1 + आपके पास %1 खोलने की अनुमति नहीं है + + + + Invalid file: %1 + अमान्य फाइल : %1 + + + + + Do you want to save this file? + क्या आप यह फाइल संचित करना चाहते हैं? + + + + You do not have permission to save %1 + आपके पास %1 संचित करने की अनुमति नहीं है + + + + Saved successfully + संचित करना सफल + + + + + + Save File + फाइल संचित करें + + + + Encoding + एन्कोडिंग + + + + Read-Only mode is on + केवल-रीड योग्य मोड सक्रिय है + + + + Current location remembered + वर्तमान स्थान स्मरणित किया + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + संपादक + + + + Untitled %1 + शीर्षक रहित %1 + + + + Cancel + रद्द करें + + + + Discard + निरस्त करें + + + \ No newline at end of file diff --git a/translations/deepin-editor_hu.ts b/translations/deepin-editor_hu.ts new file mode 100644 index 0000000000000000000000000000000000000000..5dae1e8fc6f6a7aecfe570bc70870260d66da950 --- /dev/null +++ b/translations/deepin-editor_hu.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Sor + + + + Column + Oszlop + + + + Characters %1 + %1 karakter + + + + Loading: + Betöltés: + + + + DDropdownMenu + + + + + None + Semmi + + + + EditWrapper + + + + + + Save + Mentés + + + + Do you want to save this file? + El akarja menteni ezt a fájlt? + + + + + Cancel + Mégsem + + + + Encoding changed. Do you want to save the file now? + A kódolás megváltozott. El akarja menteni a fájlt most? + + + + Discard + Elvetés + + + + You do not have permission to save %1 + Nincs engedélye a %1 mentéséhez + + + + File removed on the disk. Save it now? + A fájl eltávolítva a lemezről. Elmenti most? + + + + File has changed on disk. Reload? + A fájl megváltozott a lemezen. Újra betölti? + + + + + INSERT + BESZÚRÁS + + + + OVERWRITE + FELÜLÍRÁS + + + + R/O + Írásvédett + + + + FindBar + + + Find + Találat + + + + Previous + Előző + + + + Next + Következő + + + + JumpLineBar + + + Go to Line: + Ugrás megadott sorra: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + A Szövegszerkesztő egy hatékony eszköz a szöveges fájlok megtekintésére és szerkesztésére. + + + + Text Editor + Szövegszerkesztő + + + + PathSettingWgt + + + Remember the last used path + Emlékezzen az utoljára használt útvonalra + + + + Same path as the current file + Ugyanaz az elérési út, mint az aktuális fájl + + + + Customize the default path + Az alapértelmezett elérési út testreszabása + + + + QObject + + + Text Editor + Szövegszerkesztő + + + + + + + + + Encoding + Kódolás + + + + Basic + Alapvető + + + + Font Style + Betűstílus + + + + Font + Betűtípus + + + + Font Size + Betűméret + + + + Shortcuts + Gyorsbillentyűk + + + + + Keymap + Karakterkiosztás + + + + + + Window + Ablak + + + + New tab + Új lap + + + + New window + Új ablak + + + + Save + Mentés + + + + Save as + Mentés másként + + + + Next tab + Következő lap + + + + Previous tab + Előző lap + + + + Close tab + Lap bezárása + + + + Close other tabs + Többi lap bezárása + + + + Restore tab + Lap visszaállítása + + + + Open file + Fájl megnyitása + + + + Increment font size + Betűméret növelése + + + + Decrement font size + Betűméret csökkentése + + + + Reset font size + Betűméret visszaállítása + + + + Help + Segítség + + + + Toggle fullscreen + Teljes képernyős mód + + + + Find + Találat + + + + Replace + Csere + + + + Go to line + Ugrás megadott sorra + + + + Save cursor position + Kurzor pozíciójának mentése + + + + Reset cursor position + Kurzor pozíciójának visszaállítása + + + + Exit + Kilépés + + + + Display shortcuts + Gyorsbillentyűk megjelenítése + + + + Print + Nyomtatás + + + + Editor + Szerkesztő + + + + Increase indent + Behúzás növelése + + + + Decrease indent + Behúzás csökkentése + + + + Forward character + Előre mutató karakter + + + + Backward character + Visszafelé mutató karakter + + + + Forward word + Szó előre + + + + Backward word + Szó hátra + + + + Next line + Következő sor + + + + Previous line + Előző sor + + + + New line + Új sor + + + + New line above + Új sor felülre + + + + New line below + Új sor alulra + + + + Duplicate line + Sor duplikálása + + + + Delete to end of line + Sorvég törlése + + + + Delete current line + Aktuális sor törlése + + + + Swap line up + Sor cseréje felfelé + + + + Swap line down + Sor cseréje lefelé + + + + Scroll up one line + Egy sorral felfelé + + + + Scroll down one line + Egy sorral lefelé + + + + Page up + Lapozás felfelé + + + + Page down + Lapozás lefelé + + + + Move to end of line + Ugrás a sor végére + + + + Move to start of line + Ugrás a sor elejére + + + + Move to end of text + Ugrás a szöveg végére + + + + Move to start of text + Ugrás a szöveg elejére + + + + Move to line indentation + Ugrás a sorbehúzáshoz + + + + Upper case + Nagybetűs + + + + Lower case + Kisbetűs + + + + Capitalize + Kapitális + + + + Delete backward word + Hátul lévő szó törlése + + + + Delete forward word + Elől lévő szó törlése + + + + Forward over a pair + Előre kettővel + + + + Backward over a pair + Vissza kettővel + + + + Select all + Összes kijelölése + + + + Copy + Másolás + + + + Cut + Kivágás + + + + Paste + Beillesztés + + + + Transpose character + Karakter átalakítása + + + + Mark + Jelölés + + + + Unmark + Jelölés törlése + + + + Copy line + Sor másolása + + + + Cut line + Sor kivágása + + + + Merge lines + Sorok összefűzése + + + + Read-Only mode + Csak olvasható mód + + + + Add comment + Megjegyzés hozzáadása + + + + Remove comment + Megjegyzés eltávolítása + + + + Undo + Visszavonás + + + + Redo + Visszavonás újra + + + + Add/Remove bookmark + Könyvjelző hozzáadása/eltávolítása + + + + Move to previous bookmark + Ugrás az előző könyvjelzőre + + + + Move to next bookmark + Ugrás a következő könyvjelzőre + + + + Advanced + Haladó + + + + Window size + Ablakméret + + + + Tab width + Tabulátor szélesség + + + + Paste by pressing a middle mouse button + Beillesztés az egér középső gombjának megnyomásával + + + + Startup + Üzembe helyezés + + + + Reopen last closed tabs + Nyissa meg újra az utoljára bezárt lapokat + + + + Open/Save Settings + Megnyitási / Mentési beállítások + + + + Word wrap + Sortörés + + + + Code folding flag + Kód hajtogatási zászló + + + + Show line numbers + Sorok számának mutatása + + + + Show bookmarks icon + Könyvjelző ikon megjelenítése + + + + Show whitespaces and tabs + Szóközök és fülek megjelenítése + + + + Highlight current line + Aktuális sor kijelölése + + + + Color mark + Színes jelölő + + + + Unicode + Unicode + + + + WesternEuropean + Nyugat-európai + + + + CentralEuropean + Közép-európai + + + + Baltic + Balti + + + + Cyrillic + Cirill + + + + Arabic + Arab + + + + Celtic + Kelta + + + + SouthEasternEuropean + Délkelet-európai + + + + Greek + Görög + + + + Hebrew + Héber + + + + ChineseSimplified + Egyszerűsített kínai + + + + ChineseTraditional + Tradicionális kínai + + + + Japanese + Japán + + + + Korean + Kóreai + + + + Thai + Thai + + + + Turkish + Török + + + + Vietnamese + Vietnámi + + + + File not saved + A fájl nincs elmentve + + + + + + Line Endings + Sorvégek + + + + ReplaceBar + + + Find + Találat + + + + Replace With + Csere a + + + + Replace + Csere + + + + Skip + Kihagyás + + + + Replace Rest + Aktuális cseréje + + + + Replace All + Összes cseréje + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Alapértelmezett + + + + Customize + Testreszabás + + + + Normal + Normál + + + + Maximum + Maximum + + + + Fullscreen + Teljes képernyő + + + + This shortcut conflicts with system shortcut %1 + Ez a gyorsbillentyű ütközik a %1 rendszer gyorsbillentyűvel + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Ez a gyorsbillentyű ütközik a következővel: %1, kattintson a Csere gombra a gyorsbillentyű azonnali használatához + + + + + The shortcut %1 is invalid, please set another one. + A %1 gyorsbillentyű érvénytelen, kérjük állítson be egy másikat. + + + + Cancel + Mégsem + + + + Replace + Csere + + + + OK + OK + + + + StartManager + + + Untitled %1 + Cím nélküli %1 + + + + Tabbar + + + Close tab + Lap bezárása + + + + Close other tabs + Többi lap bezárása + + + + More options + További beállítások + + + + Close tabs to the left + Lapok balra zárása + + + + Close tabs to the right + Lapok jobbra zárása + + + + Close unmodified tabs + Módosítatlan lapok bezárása + + + + TextEdit + + + Undo + Visszavonás + + + + Redo + Újra visszavonás + + + + Cut + Kivágás + + + + Copy + Másolás + + + + Paste + Beillesztés + + + + Delete + Törlés + + + + Select All + Összes kijelölése + + + + + Find + Találat + + + + + Replace + Csere + + + + Go to Line + Ugrás megadott sorra + + + + Turn on Read-Only mode + Csak olvasható mód bekapcsolása + + + + Turn off Read-Only mode + Csak olvasható mód kikapcsolása + + + + Fullscreen + Teljes képernyő + + + + Exit fullscreen + Kilépés a teljes képernyőből + + + + Display in file manager + Megjelenítés a fájlkezelőben + + + + + Add Comment + Megjegyzés hozzáadása + + + + Text to Speech + Szövegből beszéd + + + + Stop reading + Olvasás megállítása + + + + Speech to Text + Beszédből szöveg + + + + Translate + Fordítás + + + + Column Mode + Oszlop mód + + + + Add bookmark + Könyvjelző hozzáadása + + + + Remove Bookmark + Könyvjelző eltávolítása + + + + Previous bookmark + Előző könyvjelző + + + + Next bookmark + Következő könyvjelző + + + + Remove All Bookmarks + Összes könyvjelző eltávolítása + + + + Fold All + Összes hajtogatása + + + + Fold Current Level + Jelenlegi szint hajtogatása + + + + Unfold All + Összes kihajtogatása + + + + Unfold Current Level + Jelenlegi szint kihajtogatása + + + + Color Mark + Színes jelölő + + + + Clear All Marks + Összes jelölő törlése + + + + Clear Last Mark + Utolsó jelölés törlése + + + + Mark + Jelölő + + + + Mark All + Összes jelölése + + + + Remove Comment + Megjegyzés eltávolítása + + + + Copy failed: not enough memory + A másolás sikertelen: nincs elég memória + + + + Press ALT and click lines to edit in column mode + Nyomja meg az ALT gombot, és kattintson a sorokra az oszlop módban történő szerkesztéshez + + + + Change Case + Kisbetű/nagybetű váltása + + + + Upper Case + Nagybetűs + + + + Lower Case + Kisbetűs + + + + Capitalize + Kapitális + + + + None + Semmi + + + + Selected line(s) copied + A kijelölt sor(ok) átmásolva + + + + Current line copied + A jelenlegi sor átmásolva + + + + Selected line(s) clipped + A kijelölt sor(ok) kivágva + + + + Current line clipped + A jelenlegi sor kivágva + + + + Paste failed: not enough memory + A beillesztés sikertelen: Nincs elegendő memória + + + + Read-Only mode is off + Csak olvasható mód kikapcsolva + + + + + + Read-Only mode is on + Csak olvasható mód bekapcsolva + + + + WarningNotices + + + Reload + Újratöltés + + + + Window + + + + Save as + Mentés másként + + + + New window + Új ablak + + + + New tab + Új lap + + + + Open file + Fájl megnyitása + + + + + Save + Mentés + + + + Print + Nyomtatás + + + + Switch theme + Téma váltása + + + + + Settings + Beállítások + + + + + Read-Only + Csak olvasható + + + + You do not have permission to open %1 + Nincs engedélye a %1 megnyitásához + + + + Invalid file: %1 + Érvénytelen fájl: %1 + + + + + Do you want to save this file? + El akarja menteni ezt a fájlt? + + + + You do not have permission to save %1 + Nincs engedélye a %1 mentéséhez + + + + Saved successfully + A mentés sikeres + + + + + + Save File + Fájl mentése + + + + Encoding + Kódolás + + + + Read-Only mode is on + Csak olvasható mód bekapcsolva + + + + Current location remembered + A jelenlegi hely megjegyezve + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Szerkesztő + + + + Untitled %1 + Cím nélküli %1 + + + + Cancel + Mégsem + + + + Discard + Elvetés + + + \ No newline at end of file diff --git a/translations/deepin-editor_id.ts b/translations/deepin-editor_id.ts new file mode 100644 index 0000000000000000000000000000000000000000..6a5f01396403950cec73640589bd6632c3655ee5 --- /dev/null +++ b/translations/deepin-editor_id.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + Baris + + + + Column + Kolom + + + + Characters %1 + + + + + DDropdownMenu + + + + + None + Tidak ada + + + + EditWrapper + + + File has changed on disk. Reload? + Berkas didisk sudah berubah, muat ulang? + + + + File removed on the disk. Save it now? + Berkas didisk sudah dihapus. Simpan sekarang? + + + + Do you want to save this file? + Apakah anda ingin menyimpan berkas ini? + + + + Discard + Membuang + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + Anda tidak mempunyai ijin untuk simpan %1 + + + + + INSERT + MASUK + + + + OVERWRITE + TULIS ULANG + + + + R/O + R/O + + + + + Cancel + Batal + + + + + + + Save + Simpan + + + + FindBar + + + Find + Cari + + + + Next + Lanjut + + + + Previous + Sebelum + + + + JumpLineBar + + + Go to Line: + Pergi ke Baris: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + + + + + Text Editor + + + + + QObject + + + File not saved + + + + + Text Editor + + + + + Basic + Dasar + + + + Font Style + Gaya Huruf + + + + Font + Huruf + + + + Font Size + Ukuran Huruf + + + + + Keymap + Letak tombol + + + + Shortcuts + Jalan Pintas + + + + Forward character + + + + + Backward character + + + + + Transpose character + + + + + Add comment + + + + + Remove comment + + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Tab width + + + + + + + Window + Jendela + + + + New tab + Tab Baru + + + + New window + Jendela baru + + + + Save + Simpan + + + + Save as + Simpan sebagai + + + + Next tab + Tab lanjut + + + + Previous tab + Tab sebelum + + + + Close tab + Tutup tab + + + + Close other tabs + Tutup tab lainnya + + + + Restore tab + Pulihkan tab + + + + Open file + Buka berkas + + + + Reset font size + Reset ukuran huruf + + + + Toggle fullscreen + Beralih layar penuh + + + + Help + + + + + Increment font size + + + + + Decrement font size + + + + + Find + Cari + + + + Replace + Ganti + + + + Go to line + Pergi ke Baris + + + + Save cursor position + Simpan posisi kursor + + + + Reset cursor position + Reset posisi kursor + + + + Exit + Keluar + + + + Display shortcuts + Tampilkan jalan pintas + + + + Print + Cetak + + + + Editor + Penyunting + + + + Increase indent + Tingkatkan indentasi + + + + Decrease indent + Turunkan indentasi + + + + Forward word + Maju kata + + + + Backward word + Mundur kata + + + + Next line + Baris selanjutnya + + + + Previous line + Baris sebelumnya + + + + New line + Garis baru + + + + New line above + Garis baru diatas + + + + New line below + Garis baru dibawah + + + + Duplicate line + Duplikasi garis + + + + Delete to end of line + Hapus sampai akhir baris + + + + Delete current line + Hapus garis saat ini + + + + Swap line up + Tukar baris atas + + + + Swap line down + Tukar baris bawah + + + + Scroll up one line + Gulir keatas satu baris + + + + Scroll down one line + Gulir kebawah satu baris + + + + Page up + Halaman atas + + + + Page down + Halaman bawah + + + + Move to end of line + Pindah baris akhir + + + + Move to start of line + Pindah keawal baris + + + + Move to end of text + Pindah akhir teks + + + + Move to start of text + Pindah keawal teks + + + + Move to line indentation + Pindah kebaris indentasi + + + + Upper case + Huruf besar + + + + Lower case + Huruf kecil + + + + Capitalize + Kapital + + + + Delete backward word + Hapus kata kebelakang + + + + Delete forward word + Hapus kata kedepan + + + + Forward over a pair + Maju lebih dari satu pasangan + + + + Backward over a pair + Mundur lebih dari satu pasangan + + + + Select all + Pilih semua + + + + Copy + Salin + + + + Cut + Potong + + + + Paste + Tempel + + + + Mark + Tandai + + + + Unmark + Tidak tandai + + + + Copy line + Salin baris + + + + Cut line + Potong baris + + + + Merge lines + Gabung baris + + + + Read-Only mode + Mode Hanya-Baca + + + + Word wrap + + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Undo + Sebelum + + + + Redo + Sesudah + + + + Advanced + Terkini + + + + Window size + Ukur Jendela + + + + + + + + + Encoding + Mengencode + + + + + + Line Endings + Akhir Baris + + + + ReplaceBar + + + Find + Cari + + + + Replace With + + + + + Replace + Ganti + + + + Skip + Lewati + + + + Replace Rest + Ganti sisanya + + + + Replace All + Ganti semua + + + + Settings + + + Standard + Baku + + + + Customize + Kustomisasi + + + + Normal + Normal + + + + Maximum + Maximum + + + + Fullscreen + Layarpenuh + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + Batal + + + + Replace + Ganti + + + + OK + + + + + StartManager + + + Untitled %1 + + + + + Tabbar + + + Close tab + Tutup tab + + + + Close other tabs + Tutup tab lainnya + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + TextEdit + + + Undo + Sebelum + + + + Redo + Sesudah + + + + Cut + Potong + + + + Copy + Salin + + + + Paste + Tempel + + + + Delete + Hapus + + + + Select All + Pilih Semua + + + + + Find + Cari + + + + + Replace + Ganti + + + + Go to Line + Pergi ke baris + + + + Turn on Read-Only mode + Nyalakan mode Hanya-Baca + + + + Turn off Read-Only mode + Matikan mode Hanya-Baca + + + + Fullscreen + Layar Penuh + + + + Exit fullscreen + Keluar Layar Penuh + + + + Display in file manager + + + + + + Add Comment + + + + + Text to Speech + + + + + Stop reading + + + + + Speech to Text + + + + + Translate + + + + + Column Mode + + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Mark + Tandai + + + + Mark All + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + Ganti Huruf + + + + Upper Case + Huruf Besar + + + + Lower Case + Huruf Kecil + + + + Capitalize + Kapital + + + + None + Tidak ada + + + + Selected line(s) copied + + + + + Current line copied + + + + + Selected line(s) clipped + + + + + Current line clipped + + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + Mode Hanya-Baca sudah dimatikan + + + + + + Read-Only mode is on + Mode Hanya-Baca sudah dinyalakan + + + + WarningNotices + + + Reload + + + + + Window + + + New window + Jendela baru + + + + New tab + Tab baru + + + + Open file + Buka berkas + + + + + Save as + Simpan bagai + + + + Print + Cetak + + + + Switch theme + Beralih tema + + + + + Read-Only + Hanya-Baca + + + + Saved successfully + Berhasil disimpan + + + + Read-Only mode is on + Mode Hanya-Baca sudah dinyalakan + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + Membuang + + + + + Settings + Pengaturan + + + + You do not have permission to open %1 + Anda tidak mempunyai ijin untuk buka %1 + + + + Invalid file: %1 + Berkas tidak valid: %1 + + + + + + Save File + Simpan Berkas + + + + + Do you want to save this file? + Apakah anda ingin menyimpan berkas ini? + + + + Encoding + Mengencode + + + + Editor + Penyunting + + + + You do not have permission to save %1 + Anda tidak mempunyai ijin untuk simpan %1 + + + + Untitled %1 + + + + + Current location remembered + + + + + Cancel + Batal + + + + + Save + Simpan + + + diff --git a/translations/deepin-editor_it.ts b/translations/deepin-editor_it.ts new file mode 100644 index 0000000000000000000000000000000000000000..f04a696c2ba9a7e23023341aaa1d93ea0308f0da --- /dev/null +++ b/translations/deepin-editor_it.ts @@ -0,0 +1,1288 @@ + + + BottomBar + + + Row + Riga + + + + Column + Colonna + + + + Characters %1 + Caratteri %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + No + + + + EditWrapper + + + + + + Save + Salva + + + + Do you want to save this file? + Desideri salvare questo file? + + + + + Cancel + Annulla + + + + Encoding changed. Do you want to save the file now? +   +La codifica è cambiata. Vuoi salvare il file ora? + + + + Discard + Scarta + + + + You do not have permission to save %1 + Non hai i permessi per salvare %1 + + + + File removed on the disk. Save it now? + File rimosso dal disco, salvarlo ora? + + + + File has changed on disk. Reload? + File modificato sul Disco, ricaricarlo? + + + + + INSERT + INSERT + + + + OVERWRITE + OVERWRITE + + + + R/O + R/O + + + + FindBar + + + Find + Trova + + + + Previous + Precedente + + + + Next + Prossima + + + + JumpLineBar + + + Go to Line: + Vai alla linea: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Editor di Testo è uno strumento utile a visualizzare ed editare testi. +Localizzazione italiana a cura di Massimo A. Carofano. + + + + Text Editor + Editor di Testo + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Editor di Testo + + + + + + + + + Encoding + Codifica + + + + Basic + Base + + + + Font Style + Stile Font + + + + Font + Font + + + + Font Size + Dimensione Font + + + + Shortcuts + Scorciatoie + + + + + Keymap + Mappa caratteri + + + + + + Window + Finestra + + + + New tab + Nuova scheda + + + + New window + Nuova finestra + + + + Save + Salva + + + + Save as + Salva con nome + + + + Next tab + Prossima scheda + + + + Previous tab + Scheda precedente + + + + Close tab + Chiudi scheda + + + + Close other tabs + Chiudi le altre schede + + + + Restore tab + Ripristina scheda + + + + Open file + Apri file + + + + Increment font size + Aumenta dimensione font + + + + Decrement font size + Diminuisci dimensione font + + + + Reset font size + Ripristina dimensione font + + + + Help + Aiuto + + + + Toggle fullscreen + Passa a schermo intero + + + + Find + Trova + + + + Replace + Sostituisci + + + + Go to line + Vai alla linea + + + + Save cursor position + Salva la posizione del cursore + + + + Reset cursor position + Ripristina la posizione del cursore + + + + Exit + Esci + + + + Display shortcuts + Mostra scorciatoie + + + + Print + Stampa + + + + Editor + Editor + + + + Increase indent + Aumenta il rientro + + + + Decrease indent + Diminuisci il rientro + + + + Forward character + Prossimo carattere + + + + Backward character + Carattere precedente + + + + Forward word + Parola successiva + + + + Backward word + Parola precedente + + + + Next line + Prossima linea + + + + Previous line + Linea precedente + + + + New line + Nuova riga + + + + New line above + Nuova riga sopra + + + + New line below + Nuova riga sotto + + + + Duplicate line + Duplica riga + + + + Delete to end of line + Elimina dalla fine della riga + + + + Delete current line + Elimina riga corrente + + + + Swap line up + Inverti riga superiore + + + + Swap line down + Inverti riga inferiore + + + + Scroll up one line + Passa alla riga sopra + + + + Scroll down one line + Passa alla riga sotto + + + + Page up + Pagina su + + + + Page down + Pagina giu + + + + Move to end of line + Muovi alla fine della riga + + + + Move to start of line + Muovi all'inizio della riga + + + + Move to end of text + Muovi alla fine del testo + + + + Move to start of text + Muovi all'inizio del testo + + + + Move to line indentation + Muovi al rientro di riga + + + + Upper case + Lettere maiuscole + + + + Lower case + Lettere minuscole + + + + Capitalize + Maiuscola + + + + Delete backward word + Elimina parola precedente + + + + Delete forward word + Elimina parola successiva + + + + Forward over a pair + Avanti paritario + + + + Backward over a pair + Indietro paritario + + + + Select all + Seleziona tutto + + + + Copy + Copia + + + + Cut + Taglia + + + + Paste + Incolla + + + + Transpose character + Trasponi caratteri + + + + Mark + Evidenzia + + + + Unmark + Non in evidenza + + + + Copy line + Copia riga + + + + Cut line + Taglia riga + + + + Merge lines + Unisci righe + + + + Read-Only mode + Modalità sola lettura + + + + Add comment + Aggiungi commento + + + + Remove comment + Rimuovi commento + + + + Undo + Annulla + + + + Redo + Riapplica + + + + Add/Remove bookmark + Aggiungi/rimuovi segnalibro + + + + Move to previous bookmark + Torna al segnalibro precedente + + + + Move to next bookmark + Vai al prossimo segnalibro + + + + Advanced + Avanzate + + + + Window size + Dimensione finestra + + + + Tab width + Larghezza scheda + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + A capo automatico + + + + Code folding flag + Opzioni di collasso del codice + + + + Show line numbers + Mostra numero riga + + + + Show bookmarks icon + Mostra icona segnalibri + + + + Show whitespaces and tabs + Mostra spazi bianchi e schede + + + + Highlight current line + Evidenzia la riga corrente + + + + Color mark + Colori come marcatori + + + + Unicode + Unicode + + + + WesternEuropean + Europa occidentale + + + + CentralEuropean + Europa centrale + + + + Baltic + Baltici + + + + Cyrillic + Cirillico + + + + Arabic + Arabic + + + + Celtic + Celtico + + + + SouthEasternEuropean + Sud est Europa + + + + Greek + Greek + + + + Hebrew + Hebrew + + + + ChineseSimplified + Cinese Semplificato + + + + ChineseTraditional + Cinese Tradizionale + + + + Japanese + Japanese + + + + Korean + Korean + + + + Thai + Thai + + + + Turkish + Turkish + + + + Vietnamese + Vietnamese + + + + File not saved + File non salvato + + + + + + Line Endings + Fine delle righe + + + + ReplaceBar + + + Find + Trova + + + + Replace With + Sostituisci con + + + + Replace + Sostituisci + + + + Skip + Salta + + + + Replace Rest + Sostituisci il resto + + + + Replace All + Sostituisci tutto + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standard + + + + Customize + Personalizzato + + + + Normal + Normale + + + + Maximum + Massimo + + + + Fullscreen + Pieno schermo + + + + This shortcut conflicts with system shortcut %1 + Questa scorciatoia è in conflitto con la scorciatoia di sistema %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Questa scorciatoia è in conflitto con %1, clicca su Sostituisci per rendere questa come effettiva + + + + + The shortcut %1 is invalid, please set another one. + La scorciatoia %1 non è valida, inseriscine una nuova. + + + + Cancel + Annulla + + + + Replace + Sostituisci + + + + OK + OK + + + + StartManager + + + Untitled %1 + %1 senza titolo + + + + Tabbar + + + Close tab + Chiudi scheda + + + + Close other tabs + Chiudi le altre schede + + + + More options + Ulteriori opzioni + + + + Close tabs to the left + Chiudi le schede sulla sinistra + + + + Close tabs to the right + Chiudi le schede sulla destra + + + + Close unmodified tabs + Chiudi schede non modificate + + + + TextEdit + + + Undo + Annulla + + + + Redo + Ripeti + + + + Cut + Taglia + + + + Copy + Copia + + + + Paste + Incolla + + + + Delete + Elimina + + + + Select All + Seleziona tutto + + + + + Find + Trova + + + + + Replace + Sostituisci + + + + Go to Line + Vai alla linea + + + + Turn on Read-Only mode + Attiva la modalità Sola Lettura + + + + Turn off Read-Only mode + Disattiva la modalità Sola Lettura + + + + Fullscreen + Schermo intero + + + + Exit fullscreen + Esci dallo schermo intero + + + + Display in file manager + Visualizza nel gestore file + + + + + Add Comment + Aggiungi commento + + + + Text to Speech + Da testo a voce + + + + Stop reading + Interrompi lettura + + + + Speech to Text + Da voce a testo + + + + Translate + Traduci + + + + Column Mode + Modlità colonna + + + + Add bookmark + Aggiungi segnalibro + + + + Remove Bookmark + Rimuovi segnalibro + + + + Previous bookmark + Segnalibro precedente + + + + Next bookmark + Prossimo segnalibro + + + + Remove All Bookmarks + Rimuovi tutti i segnalibri + + + + Fold All + Collassa tutti i livelli + + + + Fold Current Level + Collassa l'attuale livello + + + + Unfold All + Espandi tutti i livelli + + + + Unfold Current Level + Espandi il livello corrente + + + + Color Mark + Colori come marcatori + + + + Clear All Marks + Rimuovi le evidenziazioni + + + + Clear Last Mark + Rimuovi ultima evidenziazione + + + + Mark + Evidenzia + + + + Mark All + Evidenzia tutto + + + + Remove Comment + Rimuovi commenti + + + + Copy failed: not enough memory + Copia fallita: memoria non sufficiente + + + + Press ALT and click lines to edit in column mode + Premi ALT e clicca sulle linee per editare in modalità colonna + + + + Change Case + Cambia maiuscole + + + + Upper Case + Maiuscolo + + + + Lower Case + Minuscolo + + + + Capitalize + Maiuscola iniziale + + + + None + No + + + + Selected line(s) copied + Linea(e) selezionate copiate + + + + Current line copied + Linea corrente copiata + + + + Selected line(s) clipped + Linea(e) selezionate copiate negli appunti + + + + Current line clipped + Linea corrente copiata negli appunti + + + + Paste failed: not enough memory + Copia fallita: memoria non sufficiente + + + + Read-Only mode is off + La modalità sola lettura è disattivata + + + + + + Read-Only mode is on + La modalità sola lettura è attiva + + + + WarningNotices + + + Reload + Ricarica + + + + Window + + + + Save as + Salva con nome + + + + New window + Nuova finestra + + + + New tab + Nuova scheda + + + + Open file + Apri file + + + + + Save + Salva + + + + Print + Stampa + + + + Switch theme + Cambia tema + + + + + Settings + Impostazioni + + + + + Read-Only + Sola lettura + + + + You do not have permission to open %1 + Non hai i permessi per aprire %1 + + + + Invalid file: %1 + File non valido: %1 + + + + + Do you want to save this file? + Desideri salvare questo file? + + + + You do not have permission to save %1 + Non hai i permessi per salvare %1 + + + + Saved successfully + Salvato con successo + + + + + + Save File + Salva file + + + + Encoding + Codifica + + + + Read-Only mode is on + La modalità sola lettura è attiva + + + + Current location remembered + Locazione corrente memorizzata + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Editor + + + + Untitled %1 + %1 senza titolo + + + + Cancel + Annulla + + + + Discard + Scarta + + + \ No newline at end of file diff --git a/translations/deepin-editor_ko.ts b/translations/deepin-editor_ko.ts new file mode 100644 index 0000000000000000000000000000000000000000..ff5daa3e91b1a15140e3abce3e81b563934d9c91 --- /dev/null +++ b/translations/deepin-editor_ko.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + + + + + Column + + + + + Characters %1 + 문자 %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + 없음 + + + + EditWrapper + + + + + + Save + 저장 + + + + Do you want to save this file? + 이 파일을 저장하시겠습니까? + + + + + Cancel + 취소 + + + + Encoding changed. Do you want to save the file now? + 인코딩이 변경되었습니다. 지금 파일을 저장하시겠습니까? + + + + Discard + 폐기 + + + + You do not have permission to save %1 + %1을(를) 저장할 권한이 없습니다 + + + + File removed on the disk. Save it now? + 디스크에서 파일이 제거되었습니다. 지금 저장 하시겠습니까? + + + + File has changed on disk. Reload? + 디스크의 파일이 변경되었습니다. 다시 불러오시겠습니까? + + + + + INSERT + 삽입 + + + + OVERWRITE + 덮어쓰기 + + + + R/O + 읽기 전용 + + + + FindBar + + + Find + 찾기 + + + + Previous + 이전 + + + + Next + 다음 + + + + JumpLineBar + + + Go to Line: + 줄로 이동: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + 텍스트 편집기는 텍스트 파일을 보고 편집할 수 있는 강력한 도구입니다. + + + + Text Editor + 텍스트 편집기 + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + 텍스트 편집기 + + + + + + + + + Encoding + 인코딩 + + + + Basic + 기본 + + + + Font Style + 글꼴 유형 + + + + Font + 글꼴 + + + + Font Size + 글꼴 크기 + + + + Shortcuts + 단축키 + + + + + Keymap + 키맵 + + + + + + Window + + + + + New tab + 새 탭 + + + + New window + 새 창 + + + + Save + 저장 + + + + Save as + 다른 이름으로 저장 + + + + Next tab + 다음 탭 + + + + Previous tab + 이전 탭 + + + + Close tab + 탭 닫기 + + + + Close other tabs + 다른 탭 닫기 + + + + Restore tab + 복원 탭 + + + + Open file + 파일 열기 + + + + Increment font size + + + + + Decrement font size + + + + + Reset font size + 글꼴 크기 재설정 + + + + Help + 도움말 + + + + Toggle fullscreen + 전체 화면 전환 + + + + Find + 찾기 + + + + Replace + 바꾸기 + + + + Go to line + 줄로 이동 + + + + Save cursor position + 커서 위치 저장 + + + + Reset cursor position + 커서 위치 재설정 + + + + Exit + 종료 + + + + Display shortcuts + 단축키 표시 + + + + Print + 인쇄 + + + + Editor + 편집기 + + + + Increase indent + 들여쓰기 늘리기 + + + + Decrease indent + 들여쓰기 줄이기 + + + + Forward character + 정방향 문자 + + + + Backward character + 역방향 문자 + + + + Forward word + 정방향 단어 + + + + Backward word + 역방향 단어 + + + + Next line + 다음 줄 + + + + Previous line + 이전 줄 + + + + New line + 새 줄 + + + + New line above + 위로 새 줄 + + + + New line below + 아래로 새 줄 + + + + Duplicate line + 줄 복제 + + + + Delete to end of line + 현재 위치에서 줄의 끝까지 삭제 + + + + Delete current line + 현재 줄 삭제 + + + + Swap line up + 줄 위로 올리기 + + + + Swap line down + 줄 아래로 내리기 + + + + Scroll up one line + 한 줄 위로 스크롤 + + + + Scroll down one line + 한 줄 아래로 스크롤 + + + + Page up + 페이지 위로 + + + + Page down + 페이지 아래로 + + + + Move to end of line + 줄의 끝으로 이동 + + + + Move to start of line + 줄의 시작으로 이동 + + + + Move to end of text + 텍스트의 끝으로 이동 + + + + Move to start of text + 텍스트의 시작으로 이동 + + + + Move to line indentation + 줄 들여쓰기로 이동 + + + + Upper case + 대문자 + + + + Lower case + 소문자 + + + + Capitalize + 대문자로 쓰기 + + + + Delete backward word + 뒤의 단어 삭제 + + + + Delete forward word + 앞의 단어 삭제 + + + + Forward over a pair + 한 쌍이상 앞으로 + + + + Backward over a pair + 한 쌍이상 뒤로 + + + + Select all + 모두 선택 + + + + Copy + 복사하기 + + + + Cut + 잘라내기 + + + + Paste + 붙여넣기 + + + + Transpose character + 글자 바꾸기 + + + + Mark + 선택표시 시작 + + + + Unmark + 선택표시 시작점 이동 + + + + Copy line + 줄 복사하기 + + + + Cut line + 줄 잘라내기 + + + + Merge lines + 줄 합치기 + + + + Read-Only mode + 읽기 전용 모드 + + + + Add comment + 주석 추가하기 + + + + Remove comment + 주석 지우기 + + + + Undo + 되돌리기 + + + + Redo + 재실행 + + + + Add/Remove bookmark + 책갈피 추가/제거 + + + + Move to previous bookmark + 이전 책갈피로 이동 + + + + Move to next bookmark + 다음 책갈피로 이동 + + + + Advanced + 고급 + + + + Window size + 창 크기 + + + + Tab width + 탭 너비 + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + 단어 넘김 + + + + Code folding flag + 접을 수 있는 코드 표시하기 + + + + Show line numbers + 줄 번호 표시 + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + 색상 표시 + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + File not saved + 파일이 저장되지 않음 + + + + + + Line Endings + 줄 끝 + + + + ReplaceBar + + + Find + 찾기 + + + + Replace With + 바꿀 대상 + + + + Replace + 바꾸기 + + + + Skip + 건너뛰기 + + + + Replace Rest + 나머지 바꾸기 + + + + Replace All + 모두 바꾸기 + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + 표준 + + + + Customize + 사용자 정의 + + + + Normal + 보통 + + + + Maximum + 최대 + + + + Fullscreen + 전체 화면 + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + 이 단축키는 %1과 충돌합니다. 이 단축키를 즉시 적용하려면 바꾸기를 클릭하십시오. + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + 취소 + + + + Replace + 바꾸기 + + + + OK + + + + + StartManager + + + Untitled %1 + 제목 없음 %1 + + + + Tabbar + + + Close tab + 탭 닫기 + + + + Close other tabs + 다른 탭 닫기 + + + + More options + 더보기 + + + + Close tabs to the left + 왼쪽으로 탭 닫기 + + + + Close tabs to the right + 오른쪽으로 탭 닫기 + + + + Close unmodified tabs + 수정되지 않은 탭 닫기 + + + + TextEdit + + + Undo + 되돌리기 + + + + Redo + 재실행 + + + + Cut + 잘라내기 + + + + Copy + 복사하기 + + + + Paste + 붙여넣기 + + + + Delete + 삭제하기 + + + + Select All + 모두 선택 + + + + + Find + 찾기 + + + + + Replace + 바꾸기 + + + + Go to Line + 줄로 이동 + + + + Turn on Read-Only mode + 읽기 전용 모드 켜기 + + + + Turn off Read-Only mode + 읽기 전용 모드 끄기 + + + + Fullscreen + 전체 화면 + + + + Exit fullscreen + 전체 화면 종료 + + + + Display in file manager + 파일 관리자에 표시 + + + + + Add Comment + 주석 추가하기 + + + + Text to Speech + 텍스트 음성 변환 + + + + Stop reading + + + + + Speech to Text + 음성 텍스트 변환 + + + + Translate + 번역 + + + + Column Mode + 열 모드 + + + + Add bookmark + + + + + Remove Bookmark + 책갈피 제거 + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + 모든 책갈피 제거 + + + + Fold All + 모두 접기 + + + + Fold Current Level + 현재 레벨 접기 + + + + Unfold All + 모두 펼치기 + + + + Unfold Current Level + 현재 레벨 펼치기 + + + + Color Mark + 색상 표시 + + + + Clear All Marks + 모든 표시 지우기 + + + + Clear Last Mark + 마지막 표시 지우기 + + + + Mark + 선택표시 시작 + + + + Mark All + 모두 표시하기 + + + + Remove Comment + 주석 제거하기 + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + 대/소문자 변경 + + + + Upper Case + 대문자 + + + + Lower Case + 소문자 + + + + Capitalize + 대문자로 쓰기 + + + + None + 없음 + + + + Selected line(s) copied + 선택된 줄 복사됨 + + + + Current line copied + 현재 줄 복사됨 + + + + Selected line(s) clipped + 선택된 줄 복사됨 + + + + Current line clipped + 현재 줄 복사됨 + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + 읽기 전용 모드가 꺼져 있음 + + + + + + Read-Only mode is on + 읽기 전용 모드가 켜져 있음 + + + + WarningNotices + + + Reload + 새로고침 + + + + Window + + + + Save as + 다른 이름으로 저장 + + + + New window + 새 창 + + + + New tab + 새 탭 + + + + Open file + 파일 열기 + + + + + Save + 저장 + + + + Print + 인쇄 + + + + Switch theme + 테마 전환 + + + + + Settings + 설정 + + + + + Read-Only + 읽기 전용 + + + + You do not have permission to open %1 + %1을(를) 열 수 있는 권한이 없음 + + + + Invalid file: %1 + 잘못된 파일: %1 + + + + + Do you want to save this file? + 이 파일을 저장하시겠습니까? + + + + You do not have permission to save %1 + %1을(를) 저장할 권한이 없습니다 + + + + Saved successfully + 성공적으로 저장됨 + + + + + + Save File + 파일 저장 + + + + Encoding + 인코딩 + + + + Read-Only mode is on + 읽기 전용 모드가 켜져 있음 + + + + Current location remembered + 기억된 현재 위치 + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + 편집기 + + + + Untitled %1 + 제목 없음 %1 + + + + Cancel + 취소 + + + + Discard + 폐기 + + + \ No newline at end of file diff --git a/translations/deepin-editor_lt.ts b/translations/deepin-editor_lt.ts new file mode 100644 index 0000000000000000000000000000000000000000..6eda3f55394d5e18003eabb4c87d853f874f0e00 --- /dev/null +++ b/translations/deepin-editor_lt.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + Eilutė + + + + Column + Stulpelis + + + + Characters %1 + Simboliai %1 + + + + DDropdownMenu + + + + + None + Nėra + + + + EditWrapper + + + File has changed on disk. Reload? + Failas diske pasikeitė. Įkelti jį iš naujo? + + + + File removed on the disk. Save it now? + Failas diske buvo pašalintas. Įrašyti jį dabar? + + + + Do you want to save this file? + Ar norite įrašyti šį failą? + + + + Discard + Atmesti + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + Jūs neturite leidimo įrašyti %1 + + + + + INSERT + ĮTERPTI + + + + OVERWRITE + PERRAŠYTI + + + + R/O + TIK SKAITYMUI + + + + + Cancel + Atsisakyti + + + + + + + Save + Įrašyti + + + + FindBar + + + Find + Rasti + + + + Next + Kitas + + + + Previous + Ankstesnis + + + + JumpLineBar + + + Go to Line: + Pereiti į eilutę: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Tekstų redaktorius yra galingas įrankis, skirtas rodyti ir redaguoti tekstinius failus. + + + + Text Editor + Tekstų redaktorius + + + + QObject + + + File not saved + + + + + Text Editor + Tekstų redaktorius + + + + Basic + Pagrindiniai + + + + Font Style + Šrifto stilius + + + + Font + Šriftas + + + + Font Size + Šrifto dydis + + + + + Keymap + Klavišų išdėstymas + + + + Shortcuts + Trumpiniai + + + + Forward character + Kitas simbolis + + + + Backward character + Ankstesnis simbolis + + + + Transpose character + Apkeisti simbolius vietomis + + + + Add comment + + + + + Remove comment + + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Tab width + Tabuliacijos plotis + + + + + + Window + Langas + + + + New tab + Nauja kortelė + + + + New window + Naujas langas + + + + Save + Įrašyti + + + + Save as + Įrašyti kaip + + + + Next tab + Kita kortelė + + + + Previous tab + Ankstesnė kortelė + + + + Close tab + Užverti kortelę + + + + Close other tabs + Užverti kitas korteles + + + + Restore tab + Atkurti kortelę + + + + Open file + Atverti failą + + + + Reset font size + Atstatyti šrifto dydį + + + + Toggle fullscreen + Perjungti visą ekraną + + + + Help + Žinynas + + + + Increment font size + + + + + Decrement font size + + + + + Find + Rasti + + + + Replace + Pakeisti + + + + Go to line + Pereiti į eilutę + + + + Save cursor position + Įrašyti žymeklio vietą + + + + Reset cursor position + Atstatyti žymeklio vietą + + + + Exit + Išeiti + + + + Display shortcuts + Rodyti trumpinius + + + + Print + Spausdinti + + + + Editor + Redaktorius + + + + Increase indent + Padidinti įtrauką + + + + Decrease indent + Sumažinti įtrauką + + + + Forward word + Kitas žodis + + + + Backward word + Ankstesnis žodis + + + + Next line + Kita eilutė + + + + Previous line + Ankstesnė eilutė + + + + New line + Nauja eilutė + + + + New line above + Nauja eilutė aukščiau + + + + New line below + Nauja eilutė žemiau + + + + Duplicate line + Dubliuoti eilutę + + + + Delete to end of line + Ištrinti iki eilutės galo + + + + Delete current line + Ištrinti esamą eilutę + + + + Swap line up + Pakelti eilutę + + + + Swap line down + Nuleisti eilutę + + + + Scroll up one line + Slinkti viena eilute aukštyn + + + + Scroll down one line + Slinkti viena eilute žemyn + + + + Page up + Ankstesnis puslapis + + + + Page down + Kitas puslapis + + + + Move to end of line + Perkelti į eilutės galą + + + + Move to start of line + Perkelti į eilutės pradžią + + + + Move to end of text + Perkelti į teksto galą + + + + Move to start of text + Perkelti į teksto pradžią + + + + Move to line indentation + Pereiti į eilutės įtrauką + + + + Upper case + Didžiosios raidės + + + + Lower case + Mažosios raidės + + + + Capitalize + Iš didžiosios raidės + + + + Delete backward word + Ištrinti ankstesnį žodį + + + + Delete forward word + Ištrinti kitą žodį + + + + Forward over a pair + Kiti skliaustai + + + + Backward over a pair + Ankstesni skliaustai + + + + Select all + Žymėti viską + + + + Copy + Kopijuoti + + + + Cut + Iškirpti + + + + Paste + Įdėti + + + + Mark + Žymėti + + + + Unmark + Nuimti žymėjimą + + + + Copy line + Kopijuoti eilutę + + + + Cut line + Iškirpti eilutę + + + + Merge lines + Sulieti eilutes + + + + Read-Only mode + Tik skaitymo veiksena + + + + Word wrap + + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Undo + Atšaukti + + + + Redo + Grąžinti + + + + Advanced + Išplėstiniai + + + + Window size + Lango dydis + + + + + + + + + Encoding + Koduotė + + + + + + Line Endings + Eilučių pabaigos + + + + ReplaceBar + + + Find + Rasti + + + + Replace With + Kuo pakeisti + + + + Replace + Pakeisti + + + + Skip + Praleisti + + + + Replace Rest + Pakeisti likusius + + + + Replace All + Pakeisti visus + + + + Settings + + + Standard + Standartinis + + + + Customize + Tinkinti + + + + Normal + Normalus + + + + Maximum + Didžiausias + + + + Fullscreen + Visas ekranas + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + Atsisakyti + + + + Replace + Pakeisti + + + + OK + + + + + StartManager + + + Untitled %1 + Be pavadinimo %1 + + + + Tabbar + + + Close tab + Užverti kortelę + + + + Close other tabs + Užverti kitas korteles + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + TextEdit + + + Undo + Atšaukti + + + + Redo + Grąžinti + + + + Cut + Iškirpti + + + + Copy + Kopijuoti + + + + Paste + Įdėti + + + + Delete + Ištrinti + + + + Select All + Žymėti viską + + + + + Find + Rasti + + + + + Replace + Pakeisti + + + + Go to Line + Pereiti į eilutę + + + + Turn on Read-Only mode + Įjungti tik skaitymo veikseną + + + + Turn off Read-Only mode + Išjungti tik skaitymo veikseną + + + + Fullscreen + Visas ekranas + + + + Exit fullscreen + Išeiti iš viso ekrano + + + + Display in file manager + Rodyti failų tvarkytuvėje + + + + + Add Comment + + + + + Text to Speech + + + + + Stop reading + + + + + Speech to Text + + + + + Translate + + + + + Column Mode + + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Mark + Žymėti + + + + Mark All + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + Keisti raidžių dydį + + + + Upper Case + Didžiosios raidės + + + + Lower Case + Mažosios raidės + + + + Capitalize + Iš didžiosios raidės + + + + None + Nėra + + + + Selected line(s) copied + + + + + Current line copied + Dabartinė eilutė nukopijuota + + + + Selected line(s) clipped + + + + + Current line clipped + + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + Tik skaitymo veiksena yra išjungta + + + + + + Read-Only mode is on + Tik skaitymo veiksena yra įjungta + + + + WarningNotices + + + Reload + Įkelti iš naujo + + + + Window + + + New window + Naujas langas + + + + New tab + Nauja kortelė + + + + Open file + Atverti failą + + + + + Save as + Įrašyti kaip + + + + Print + Spausdinti + + + + Switch theme + Perjungti temą + + + + + Read-Only + Tik skaitymui + + + + Saved successfully + Sėkmingai įrašyta + + + + Read-Only mode is on + Tik skaitymo veiksena yra įjungta + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + Atmesti + + + + + Settings + Nustatymai + + + + You do not have permission to open %1 + Jūs neturite leidimo atverti %1 + + + + Invalid file: %1 + Neteisingas failas: %1 + + + + + + Save File + Įrašyti failą + + + + + Do you want to save this file? + Ar norite įrašyti šį failą? + + + + Encoding + Koduotė + + + + Editor + Redaktorius + + + + You do not have permission to save %1 + Jūs neturite leidimo įrašyti %1 + + + + Untitled %1 + Be pavadinimo %1 + + + + Current location remembered + + + + + Cancel + Atsisakyti + + + + + Save + Įrašyti + + + diff --git a/translations/deepin-editor_ms.ts b/translations/deepin-editor_ms.ts new file mode 100644 index 0000000000000000000000000000000000000000..36ba89f7b19226fd99a7c721a602b881e048e185 --- /dev/null +++ b/translations/deepin-editor_ms.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Baris + + + + Column + Lajur + + + + Characters %1 + Aksara %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Tiada + + + + EditWrapper + + + + + + Save + Simpan + + + + Do you want to save this file? + Anda mahu menyimpan fail ini? + + + + + Cancel + Batal + + + + Encoding changed. Do you want to save the file now? + Pengekodan berubah. Anda mahu menyimpan fail sekarang? + + + + Discard + Singkir + + + + You do not have permission to save %1 + Anda tidak mempunyai keizinan untuk menyimpan %1 + + + + File removed on the disk. Save it now? + Fail dalam cakera telah dibuang. Simpan ia sekarang? + + + + File has changed on disk. Reload? + Fail telah berubah di dalam cakera. Muat semula? + + + + + INSERT + SISIP + + + + OVERWRITE + TULISGANTI + + + + R/O + R/O + + + + FindBar + + + Find + Cari + + + + Previous + Terdahulu + + + + Next + Berikutnya + + + + JumpLineBar + + + Go to Line: + Pergi ke Baris: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Penyunting Teks ialah sebuah alat melihat dan menyunting fail teks yang hebat. + + + + Text Editor + Penyunting Teks + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Penyunting Teks + + + + + + + + + Encoding + Pengekodan + + + + Basic + Asas + + + + Font Style + Gaya Fon + + + + Font + Fon + + + + Font Size + Saiz Fon + + + + Shortcuts + Pintasan + + + + + Keymap + Peta Kunci + + + + + + Window + Tetingkap + + + + New tab + Tab baharu + + + + New window + Tetingkap baharu + + + + Save + Simpan + + + + Save as + Simpan sebagai + + + + Next tab + Tab berikutnya + + + + Previous tab + Tab terdahulu + + + + Close tab + Tutup tab + + + + Close other tabs + Tutup tab lain + + + + Restore tab + Pulihkan tab + + + + Open file + Buka fail + + + + Increment font size + Tingkatkan saiz fon + + + + Decrement font size + Kurangkan saiz fon + + + + Reset font size + Tetap semula saiz fon + + + + Help + Bantuan + + + + Toggle fullscreen + Togol skrin penuh + + + + Find + Cari + + + + Replace + Ganti + + + + Go to line + Pergi ke baris + + + + Save cursor position + Simpan kedudukan kursor + + + + Reset cursor position + Tetap semula kedudukan kursor + + + + Exit + Keluar + + + + Display shortcuts + Papar pintasan + + + + Print + Cetak + + + + Editor + Penyunting + + + + Increase indent + Tingkatkan inden + + + + Decrease indent + Kurangkan inden + + + + Forward character + Aksara maju + + + + Backward character + Aksara undur + + + + Forward word + Maju perkataan + + + + Backward word + Undur perkataan + + + + Next line + Baris berikutnya + + + + Previous line + Baris terdahulu + + + + New line + Baris baharu + + + + New line above + Baris baharu di atas + + + + New line below + Baris baharu di bawah + + + + Duplicate line + Gandakan baris + + + + Delete to end of line + Padam ke penghujung baris + + + + Delete current line + Padam baris semasa + + + + Swap line up + Silih baris ke atas + + + + Swap line down + Silih baris ke bawah + + + + Scroll up one line + Tatal ke atas satu baris + + + + Scroll down one line + Tatal ke bawah satu baris + + + + Page up + Halaman ke atas + + + + Page down + Halaman ke bawah + + + + Move to end of line + Gerak ke penghujung baris + + + + Move to start of line + Gerak ke permulaan baris + + + + Move to end of text + Gerak ke penghujung teks + + + + Move to start of text + Gerak ke permulaan teks + + + + Move to line indentation + Alih ke indentasi baris + + + + Upper case + Huruf besar + + + + Lower case + Huruf kecil + + + + Capitalize + Huruf Besarkan + + + + Delete backward word + Padam perkataan mengundur + + + + Delete forward word + Padam perkataan ke hadapan + + + + Forward over a pair + Majukan melangkaui pasangan + + + + Backward over a pair + Undur melangkaui pasangan + + + + Select all + Pilih semua + + + + Copy + Salin + + + + Cut + Potong + + + + Paste + Tampal + + + + Transpose character + Transposisi aksara + + + + Mark + Tanda + + + + Unmark + Nyahtanda + + + + Copy line + Salin baris + + + + Cut line + Potong baris + + + + Merge lines + Gabung baris + + + + Read-Only mode + Mod Baca-Sahaja + + + + Add comment + Tambah ulasan + + + + Remove comment + Buang ulasan + + + + Undo + Buat Asal + + + + Redo + Buat Semula + + + + Add/Remove bookmark + Tambah/Buang tanda buku + + + + Move to previous bookmark + Alih ke tanda buku terdahulu + + + + Move to next bookmark + Alih ke tanda buku berikutnya + + + + Advanced + Lanjutan + + + + Window size + Saiz tetingkap + + + + Tab width + Lebar tab + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Lilit perkataan + + + + Code folding flag + Bendera melipat kod + + + + Show line numbers + Tunjuk nombor baris + + + + Show bookmarks icon + Tunjuk ikon tanda buku + + + + Show whitespaces and tabs + Tunjuk jarak dan tab + + + + Highlight current line + Sorot baris semasa + + + + Color mark + Tanda warna + + + + Unicode + Unikod + + + + WesternEuropean + Eropah Barat + + + + CentralEuropean + Eropah Tengah + + + + Baltic + Baltik + + + + Cyrillic + Cyril + + + + Arabic + Arab + + + + Celtic + Celt + + + + SouthEasternEuropean + Eropah Tenggara + + + + Greek + Yunani + + + + Hebrew + Ibrani + + + + ChineseSimplified + Cina Ringkas + + + + ChineseTraditional + Cina Tradisional + + + + Japanese + Jepun + + + + Korean + Korea + + + + Thai + Siam + + + + Turkish + Turki + + + + Vietnamese + Vietnam + + + + File not saved + Fail tidak disimpan + + + + + + Line Endings + Penghujung Baris + + + + ReplaceBar + + + Find + Cari + + + + Replace With + Ganti Dengan + + + + Replace + Ganti + + + + Skip + Langkau + + + + Replace Rest + Ganti Selebihnya + + + + Replace All + Ganti Semua + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Piawai + + + + Customize + Suai + + + + Normal + Biasa + + + + Maximum + Maksimum + + + + Fullscreen + Skrin Penuh + + + + This shortcut conflicts with system shortcut %1 + Pintasan ini berkonflik dengan pintasan sistem %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Pintasan ini berkonflik dengan %1, klik Ganti untuk menjadikan pintasan ini berkesan serta-merta + + + + + The shortcut %1 is invalid, please set another one. + Pintasan %1 tidak sah, sila tetapkan yang lain. + + + + Cancel + Batal + + + + Replace + Ganti + + + + OK + OK + + + + StartManager + + + Untitled %1 + %1 Tidak Bertajuk + + + + Tabbar + + + Close tab + Tutup tab + + + + Close other tabs + Tutup tab lain + + + + More options + Lagi pilihan + + + + Close tabs to the left + Tutup tab di sebelah kiri + + + + Close tabs to the right + Tutup tab di sebelah kanan + + + + Close unmodified tabs + Tutup tab yang tidak diubah suai + + + + TextEdit + + + Undo + Buat Asal + + + + Redo + Buat Semula + + + + Cut + Potong + + + + Copy + Salin + + + + Paste + Tampal + + + + Delete + Padam + + + + Select All + Pilih Semua + + + + + Find + Cari + + + + + Replace + Ganti + + + + Go to Line + Pergi ke Baris + + + + Turn on Read-Only mode + Hidupkan mod Baca-Sahaja + + + + Turn off Read-Only mode + Matikan mod Baca-Sahaja + + + + Fullscreen + Skrin Penuh + + + + Exit fullscreen + Keluar dari skrin penuh + + + + Display in file manager + Papar dalam pengurus fail + + + + + Add Comment + Tambah Ulasan + + + + Text to Speech + Teks ke Pertuturan + + + + Stop reading + Berhenti membaca + + + + Speech to Text + Pertuturan ke Teks + + + + Translate + Terjemah + + + + Column Mode + Mod Lajur + + + + Add bookmark + Tambah tanda buku + + + + Remove Bookmark + Buang Tanda Buku + + + + Previous bookmark + Tanda buku terdahulu + + + + Next bookmark + Tanda buku berikutnya + + + + Remove All Bookmarks + Buang Semua Tanda Buku + + + + Fold All + Lipat Semua + + + + Fold Current Level + Lipat Aras Semasa + + + + Unfold All + Nyahlipat Semua + + + + Unfold Current Level + Nyahlipat Aras Semasa + + + + Color Mark + Tanda Warna + + + + Clear All Marks + Kosongkan Semua Tanda + + + + Clear Last Mark + Kosongkan Tanda Terakhir + + + + Mark + Tanda + + + + Mark All + Tanda Semua + + + + Remove Comment + Buang Ulasan + + + + Copy failed: not enough memory + Gagal salin: ingatan tidak mencukupi + + + + Press ALT and click lines to edit in column mode + Tekan ALT dan klik baris untuk menyunting dalam mod lajur + + + + Change Case + Ubah Kata + + + + Upper Case + Huruf Besar + + + + Lower Case + Huruf Kecil + + + + Capitalize + Huruf Besarkan + + + + None + Tiada + + + + Selected line(s) copied + Baris terpilih disalin + + + + Current line copied + Baris semasa disalin + + + + Selected line(s) clipped + Baris terpilih dikerat + + + + Current line clipped + Baris semasa dikerat + + + + Paste failed: not enough memory + Gagal tampal: ingatan tidak mencukupi + + + + Read-Only mode is off + Mod Baca-Sahaja dimatikan + + + + + + Read-Only mode is on + Mod Baca-Sahaja dihidupkan + + + + WarningNotices + + + Reload + Muat Semula + + + + Window + + + + Save as + Simpan sebagai + + + + New window + Tetingkap baharu + + + + New tab + Tab baharu + + + + Open file + Buka fail + + + + + Save + Simpan + + + + Print + Cetak + + + + Switch theme + Tukar tema + + + + + Settings + Tetapan + + + + + Read-Only + Baca-Sahaja + + + + You do not have permission to open %1 + Anda tidak mempunyai keizinan untuk membuka %1 + + + + Invalid file: %1 + Fail tidak sah: %1 + + + + + Do you want to save this file? + Anda mahu menyimpan fail ini? + + + + You do not have permission to save %1 + Anda tidak mempunyai keizinan untuk menyimpan %1 + + + + Saved successfully + Berjaya disimpan + + + + + + Save File + Simpan Fail + + + + Encoding + Pengekodan + + + + Read-Only mode is on + Mod Baca-Sahaja dihidupkan + + + + Current location remembered + Lokasi semasa diingati + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Penyunting + + + + Untitled %1 + %1 Tidak Bertajuk + + + + Cancel + Batal + + + + Discard + Singkir + + + \ No newline at end of file diff --git a/translations/deepin-editor_ne.ts b/translations/deepin-editor_ne.ts new file mode 100644 index 0000000000000000000000000000000000000000..5f7f49ce22a5cf2b4b364b57dbe1f6f2caaf48ef --- /dev/null +++ b/translations/deepin-editor_ne.ts @@ -0,0 +1,1236 @@ + + + + + BottomBar + + + Row + पंक्ति + + + + Column + स्तम्भ + + + + Characters %1 + क्यारेक्टर% 1 + + + + DDropdownMenu + + + + + None + कुनै पनि होइन + + + + EditWrapper + + + File has changed on disk. Reload? + डिस्कमा फाइल परिवर्तन भएको छ। पुन: लोड गर्नुहोस? + + + + File removed on the disk. Save it now? + डिस्कबाट फाइल हटाइयो सुरक्षित गर्नुहोस्। + + + + Do you want to save this file? + के तपाइँ यो फाईल सुरक्षित गर्न चाहनुहुन्छ? + + + + Discard + त्याग्नुहोस् + + + + Encoding changed. Do you want to save the file now? + + + + + You do not have permission to save %1 + तपाईंसँग% 1 सुरक्षित गर्न अनुमति छैन + + + + + INSERT + हाल्नु + + + + OVERWRITE + त्योमाथि + + + + R/O + आर / ओ + + + + + Cancel + रद्द गर्नुहोस् + + + + + + + Save + सुरक्षित गर्नु + + + + FindBar + + + Find + खोज्नुहोस् + + + + Next + अर्को + + + + Previous + अघिल्लो + + + + JumpLineBar + + + Go to Line: + रेखामा जानुहोस् + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + पाठ सम्पादक हेर्न र सम्पादन गर्न पाठ फाइलहरू एक शक्तिशाली उपकरण हो। + + + + Text Editor + पाठ सम्पादक + + + + QObject + + + File not saved + फाइल बचत भएन + + + + Text Editor + पाठ सम्पादक + + + + Basic + आधारभूत + + + + Font Style + फन्टको शैली + + + + Font + फन्ट + + + + Font Size + फन्टको आकार + + + + + Keymap + किम्याप + + + + Shortcuts + सर्टकटहरू + + + + Forward character + फर्वार्ड क्यारेक्टर + + + + Backward character + पछाडि क्यारेक्टर + + + + Transpose character + रूपान्तरण अक्षर + + + + Add comment + + + + + Remove comment + + + + + Add/Remove bookmark + + + + + Move to previous bookmark + + + + + Move to next bookmark + + + + + Tab width + ट्याब चौडाइ + + + + + + Window + विन्डो + + + + New tab + नयाँ ट्याब + + + + New window + नयाँ विन्डो + + + + Save + सुरक्षित गर्नु + + + + Save as + यसरी राख + + + + Next tab + अर्को ट्याब + + + + Previous tab + अघिल्लो ट्याब + + + + Close tab + ट्याब बन्द गर्नुहोस् + + + + Close other tabs + अन्य ट्याबहरू बन्द गर्नुहोस् + + + + Restore tab + ट्याब पुनर्स्थापित गर्नुहोस् + + + + Open file + फाईल खोल्नुहोस् + + + + Reset font size + फन्ट साइज रिसेट गर्नुहोस् + + + + Toggle fullscreen + पूरा स्क्रिन टगल गर्नुहोस् + + + + Help + मद्दत + + + + Increment font size + + + + + Decrement font size + + + + + Find + खोज्नुहोस + + + + Replace + बदल्नुहोस् + + + + Go to line + रेखामा जानुहोस् + + + + Save cursor position + कर्सरको स्थिति बचत गर्नुहोस् + + + + Reset cursor position + कर्सरको स्थिति रिसेट गर्नुहोस् + + + + Exit + बाहिर निस्कनुहोस् + + + + Display shortcuts + सर्टकटहरू प्रदर्शन गर्नुहोस् + + + + Print + प्रिन्ट गर्नुहोस् + + + + Editor + संपादक + + + + Increase indent + इन्डेन्ट बढाउनुहोस् + + + + Decrease indent + इन्डेन्ट घटाउनुहोस् + + + + Forward word + फर्वार्ड शब्द + + + + Backward word + पछाडि शब्द + + + + Next line + अर्को रेखा जानुहोस् + + + + Previous line + अघिल्लो रेखा + + + + New line + नयाँ रेखा + + + + New line above + माथि नयाँ रेखा + + + + New line below + तल नयाँ रेखा + + + + Duplicate line + डुप्लिकेट रेखा + + + + Delete to end of line + रेखाको अन्त्य मेटाउनुहोस् + + + + Delete current line + हालको रेखा मेट्नुहोस् + + + + Swap line up + स्वाइप रेखा माथि + + + + Swap line down + स्वाइप रेखा तल + + + + Scroll up one line + एक रेखा माथि स्क्रोल गर्नुहोस् + + + + Scroll down one line + एक रेखा तल स्क्रोल गर्नुहोस् + + + + Page up + पृष्ठ माथि + + + + Page down + पृष्ठ तल + + + + Move to end of line + रेखाको अन्त्यमा सार्नुहोस् + + + + Move to start of line + रेखाको सुरूमा सार्नुहोस् + + + + Move to end of text + पाठको अन्त्यमा सार्नुहोस् + + + + Move to start of text + पाठको सुरुमा सार्नुहोस् + + + + Move to line indentation + रेखाको इन्डेन्टेशनमा सार्नुहोस् + + + + Upper case + माथिल्लो केस + + + + Lower case + तल्लो केस + + + + Capitalize + क्यापिटलिज गर्नुहोस् + + + + Delete backward word + पछाडिको शब्द मेटाउनुहोस् + + + + Delete forward word + अगाडिको शब्द मेटाउनुहोस् + + + + Forward over a pair + एउटा जोडा माथि फर्वार्ड गर्नुहोस् + + + + Backward over a pair + एक जोडा माथि पछाडि गर्नुहोस् + + + + Select all + सबै छान्नु + + + + Copy + कपी + + + + Cut + काट्नुहोस् + + + + Paste + टाँस्नुहोस् + + + + Mark + चिन्ह लगाउनुहोस् + + + + Unmark + चिन्ह हटाउनुहोस + + + + Copy line + लाइन प्रतिलिपि गर्नुहोस् + + + + Cut line + रेखा कटौती गर्नुहोस् + + + + Merge lines + रेखा जोड्नुहोस् + + + + Read-Only mode + पढ्ने मात्र मोड + + + + Word wrap + + + + + Code folding flag + + + + + Show line numbers + + + + + Show bookmarks icon + + + + + Show whitespaces and tabs + + + + + Highlight current line + + + + + Color mark + + + + + Unicode + + + + + WesternEuropean + + + + + CentralEuropean + + + + + Baltic + + + + + Cyrillic + + + + + Arabic + + + + + Celtic + + + + + SouthEasternEuropean + + + + + Greek + + + + + Hebrew + + + + + ChineseSimplified + + + + + ChineseTraditional + + + + + Japanese + + + + + Korean + + + + + Thai + + + + + Turkish + + + + + Vietnamese + + + + + Undo + पूर्ववत गर्नुहोस् + + + + Redo + फेरि गर्नुहोस् + + + + Advanced + उच्च + + + + Window size + विन्डोको आकार + + + + + + + + + Encoding + सङ्केतन + + + + + + Line Endings + रेखा समाप्ति + + + + ReplaceBar + + + Find + खोज्नुहोस् + + + + Replace With + संग बदल्नुहोस् + + + + Replace + बदल्नुहोस् + + + + Skip + छोड्नुहोस् + + + + Replace Rest + पुन: बदल्नुहोस् + + + + Replace All + सबै बदल्नुहोस् + + + + Settings + + + Standard + स्तर + + + + Customize + अनुकूलन गर्नुहोस् + + + + Normal + साधारण + + + + Maximum + अधिकतम + + + + Fullscreen + पूरा स्क्रीन + + + + This shortcut conflicts with system shortcut %1 + + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + + + + + + The shortcut %1 is invalid, please set another one. + + + + + Cancel + रद्द गर्नुहोस् + + + + Replace + बदल्नुहोस् + + + + OK + + + + + StartManager + + + Untitled %1 + शीर्षकविहिन% 1 + + + + Tabbar + + + Close tab + ट्याब बन्द गर्नुहोस् + + + + Close other tabs + अन्य ट्याबहरू बन्द गर्नुहोस् + + + + More options + + + + + Close tabs to the left + + + + + Close tabs to the right + + + + + Close unmodified tabs + + + + + TextEdit + + + Undo + पूर्ववत गर्नुहोस् + + + + Redo + फेरि गर्नुहोस् + + + + Cut + काट्नुहोस् + + + + Copy + कपी + + + + Paste + टाँस्नुहोस् + + + + Delete + मेटाउनुहोस् + + + + Select All + सबै छान्नु + + + + + Find + खोज्नुहोस् + + + + + Replace + बदल्नुहोस् + + + + Go to Line + रेखामा जानुहोस् + + + + Turn on Read-Only mode + पढ्ने-मात्र मोड खोल्नुहोस् + + + + Turn off Read-Only mode + पढ्ने-मात्र मोड बन्द गर्नुहोस् + + + + Fullscreen + पूरा स्क्रीन + + + + Exit fullscreen + पूरा स्क्रिनबाट निस्कनुहोस् + + + + Display in file manager + फाईल प्रबन्धकमा प्रदर्शन गर्नुहोस् + + + + + Add Comment + + + + + Text to Speech + टेक्स्ट तु स्पीच + + + + Stop reading + + + + + Speech to Text + स्पीच तु टेक्स्ट + + + + Translate + + + + + Column Mode + + + + + Add bookmark + + + + + Remove Bookmark + + + + + Previous bookmark + + + + + Next bookmark + + + + + Remove All Bookmarks + + + + + Fold All + + + + + Fold Current Level + + + + + Unfold All + + + + + Unfold Current Level + + + + + Color Mark + + + + + Clear All Marks + + + + + Clear Last Mark + + + + + Mark + चिन्ह लगाउनुहोस् + + + + Mark All + + + + + Remove Comment + + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + + + + + Change Case + केस परिवर्तन गर्नुहोस् + + + + Upper Case + माथिल्लो केस + + + + Lower Case + तल्लो केस + + + + Capitalize + क्यापिटलिज गर्नुहोस् + + + + None + कुनै पनि होइन + + + + Selected line(s) copied + चयनित लाइन (हरू) प्रतिलिपि गरियो + + + + Current line copied + हालको लाइन प्रतिलिपि गरियो + + + + Selected line(s) clipped + चयनित लाइन (हरू) क्लिप गरियो + + + + Current line clipped + हालको लाइन क्लिप गरियो + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + पढ्ने मात्र मोड बन्द छ + + + + + + Read-Only mode is on + पढ्ने मात्र मोड चालू छ + + + + WarningNotices + + + Reload + पुन: लोड गर्नुहोस् + + + + Window + + + New window + नयाँ विन्डो + + + + New tab + नयाँ ट्याब + + + + Open file + फाईल खोल्नुहोस् + + + + + Save as + यसरी राख + + + + Print + प्रिन्ट गर्नुहोस् + + + + Switch theme + स्विच थेम + + + + + Read-Only + पढ्ने मात्र + + + + Saved successfully + सफलतापूर्वक सुरक्षित गरियो + + + + Read-Only mode is on + पढ्ने मात्र मोड चालू छ + + + + Ctrl+'=' + + + + + Ctrl+'-' + + + + + Discard + त्याग्नुहोस् + + + + + Settings + सेटिङ्हरू + + + + You do not have permission to open %1 + तपाईंसँग% 1 खोल्न अनुमति छैन + + + + Invalid file: %1 + अमान्य फाइल:% 1 + + + + + + Save File + फाइल सुरक्षित गर्नु + + + + + Do you want to save this file? + के तपाइँ यो फाईल सुरक्षित गर्न चाहनुहुन्छ? + + + + Encoding + सङ्केतन + + + + Editor + संपादक + + + + You do not have permission to save %1 + तपाईंसँग% 1 सुरक्षित गर्न अनुमति छैन + + + + Untitled %1 + शीर्षकविहिन% 1 + + + + Current location remembered + हालको स्थान सम्झियो + + + + Cancel + रद्द गर्नुहोस् + + + + + Save + सुरक्षित गर्नु + + + diff --git a/translations/deepin-editor_nl.ts b/translations/deepin-editor_nl.ts new file mode 100644 index 0000000000000000000000000000000000000000..59d066012fc5693a345c6b369cf518ac0bd6c26c --- /dev/null +++ b/translations/deepin-editor_nl.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Rij + + + + Column + Kolom + + + + Characters %1 + %1 tekens + + + + Loading: + Bezig met laden van + + + + DDropdownMenu + + + + + None + Geen + + + + EditWrapper + + + + + + Save + Opslaan + + + + Do you want to save this file? + Wil je dit bestand opslaan? + + + + + Cancel + Annuleren + + + + Encoding changed. Do you want to save the file now? + De tekencodering is aangepast. Wil je het bestand opslaan? + + + + Discard + Verwerpen + + + + You do not have permission to save %1 + Je bent niet gemachtigd om %1 op te slaan + + + + File removed on the disk. Save it now? + Het bestand is verwijderd van de schijf. Wil je het opslaan? + + + + File has changed on disk. Reload? + Het bestand is aangepast op de schijf. Wil je het opnieuw laden? + + + + + INSERT + INSERT + + + + OVERWRITE + OVERSCHRIJVEN + + + + R/O + ALLEEN-LEZEN + + + + FindBar + + + Find + Zoeken + + + + Previous + Vorige + + + + Next + Volgende + + + + JumpLineBar + + + Go to Line: + Ga naar regel: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Tekstbewerker is een programma vol functies om platte tekst te bekijken en bewerken. + + + + Text Editor + Tekstbewerker + + + + PathSettingWgt + + + Remember the last used path + Laatstgebruikte locatie onthouden + + + + Same path as the current file + Dezelfde locatie als huidig bestand + + + + Customize the default path + Standaardlocatie wijzigen + + + + QObject + + + Text Editor + Tekstbewerker + + + + + + + + + Encoding + Tekencodering + + + + Basic + Algemeen + + + + Font Style + Lettertypestijl + + + + Font + Lettertype + + + + Font Size + Lettergrootte + + + + Shortcuts + Sneltoetsen + + + + + Keymap + Sneltoetsoverzicht + + + + + + Window + Venster + + + + New tab + Nieuw tabblad + + + + New window + Nieuw venster + + + + Save + Opslaan + + + + Save as + Opslaan als + + + + Next tab + Volgend tabblad + + + + Previous tab + Vorig tabblad + + + + Close tab + Tabblad sluiten + + + + Close other tabs + Overige tabbladen sluiten + + + + Restore tab + Tabblad herstellen + + + + Open file + Bestand openen + + + + Increment font size + Lettertype vergroten + + + + Decrement font size + Lettertype verkleinen + + + + Reset font size + Lettergrootte herstellen + + + + Help + Hulp + + + + Toggle fullscreen + Beeldvullende modus in-/uitschakelen + + + + Find + Zoeken + + + + Replace + Vervangen + + + + Go to line + Ga naar regel + + + + Save cursor position + Cursorpositie opslaan + + + + Reset cursor position + Cursorpositie herstellen + + + + Exit + Afsluiten + + + + Display shortcuts + Sneltoetsen tonen + + + + Print + Afdrukken + + + + Editor + Bewerker + + + + Increase indent + Inspringing vergroten + + + + Decrease indent + Inspringing verkleinen + + + + Forward character + Teken vooruit + + + + Backward character + Teken achteruit + + + + Forward word + Woord vooruit + + + + Backward word + Woord achteruit + + + + Next line + Volgende regel + + + + Previous line + Vorige regel + + + + New line + Nieuwe regel + + + + New line above + Nieuwe regel erboven + + + + New line below + Nieuwe regel eronder + + + + Duplicate line + Regel dupliceren + + + + Delete to end of line + Wissen tot einde van regel + + + + Delete current line + Huidige regel wissen + + + + Swap line up + Regel omhoog verwisselen + + + + Swap line down + Regel omlaag verwisselen + + + + Scroll up one line + Eén regel omhoog scrollen + + + + Scroll down one line + Eén regel omlaag scrollen + + + + Page up + Pagina omhoog + + + + Page down + Pagina omlaag + + + + Move to end of line + Verplaatsen naar einde van regel + + + + Move to start of line + Verplaatsen naar begin van regel + + + + Move to end of text + Verplaatsen naar einde van tekst + + + + Move to start of text + Verplaatsen naar begin van tekst + + + + Move to line indentation + Verplaatsen naar regelinspringing + + + + Upper case + Hoofdletters + + + + Lower case + Kleine letters + + + + Capitalize + Omzetten naar hoofdletters + + + + Delete backward word + Woord achterwaarts wissen + + + + Delete forward word + Woord voorwaarts wissen + + + + Forward over a pair + Voorwaarts over een stel + + + + Backward over a pair + Achterwaarts over een stel + + + + Select all + Alles selecteren + + + + Copy + Kopiëren + + + + Cut + Knippen + + + + Paste + Plakken + + + + Transpose character + Teken omzetten + + + + Mark + Markeren + + + + Unmark + Demarkeren + + + + Copy line + Regel kopiëren + + + + Cut line + Regel knippen + + + + Merge lines + Regels samenvoegen + + + + Read-Only mode + Alleen-lezenmodus + + + + Add comment + Opmerking toevoegen + + + + Remove comment + Opmerking verwijderen + + + + Undo + Ongedaan maken + + + + Redo + Opnieuw + + + + Add/Remove bookmark + Bladwijzer toevoegen/verwijderen + + + + Move to previous bookmark + Naar vorige bladwijzer + + + + Move to next bookmark + Naar volgende bladwijzer + + + + Advanced + Geavanceerd + + + + Window size + Venstergrootte + + + + Tab width + Tabbreedte + + + + Paste by pressing a middle mouse button + Plakken met middelste muisknop + + + + Startup + Opstarten + + + + Reopen last closed tabs + Vorige tabbladen heropenen + + + + Open/Save Settings + Openen/Opslaan + + + + Word wrap + Regelafbreking + + + + Code folding flag + Codefloodvlag + + + + Show line numbers + Regelnummers tonen + + + + Show bookmarks icon + Bladwijzerpictogram tonen + + + + Show whitespaces and tabs + Witruimtes en tabs tonen + + + + Highlight current line + Huidige regel markeren + + + + Color mark + Markeerkleur + + + + Unicode + Unicode + + + + WesternEuropean + West-Europees + + + + CentralEuropean + Centraal-Europees + + + + Baltic + Baltisch + + + + Cyrillic + Cyrillisch + + + + Arabic + Arabisch + + + + Celtic + Keltisch + + + + SouthEasternEuropean + Zuidoost-Europees + + + + Greek + Grieks + + + + Hebrew + Hebreeuws + + + + ChineseSimplified + Chinees (Vereenvoudigd) + + + + ChineseTraditional + Chinees (Traditioneel) + + + + Japanese + Japans + + + + Korean + Koreaans + + + + Thai + Thais + + + + Turkish + Turks + + + + Vietnamese + Vietnamees + + + + File not saved + Bestand is niet opgeslagen + + + + + + Line Endings + Regeleindes + + + + ReplaceBar + + + Find + Zoeken + + + + Replace With + Vervangen door + + + + Replace + Vervangen + + + + Skip + Overslaan + + + + Replace Rest + Overige vervangen + + + + Replace All + Alles vervangen + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standaard + + + + Customize + Aanpassen + + + + Normal + Normaal + + + + Maximum + Maximaal + + + + Fullscreen + Beeldvullende modus + + + + This shortcut conflicts with system shortcut %1 + Deze sneltoets is wordt al gebruikt door de algemene sneltoets %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Deze sneltoets is al in gebruik door %1 - klik om deze sneltoets in plaats daarvan te gebruiken + + + + + The shortcut %1 is invalid, please set another one. + De sneltoets '%1' is ongeldig. Stel een andere in. + + + + Cancel + Annuleren + + + + Replace + Vervangen + + + + OK + Oké + + + + StartManager + + + Untitled %1 + Naamloos %1 + + + + Tabbar + + + Close tab + Tabblad sluiten + + + + Close other tabs + Overige tabbladen sluiten + + + + More options + Meer opties + + + + Close tabs to the left + Tabbladen links sluiten + + + + Close tabs to the right + Tabbladen rechts sluiten + + + + Close unmodified tabs + Onaangepaste tabbladen sluiten + + + + TextEdit + + + Undo + Ongedaan maken + + + + Redo + Opnieuw + + + + Cut + Knippen + + + + Copy + Kopiëren + + + + Paste + Plakken + + + + Delete + Verwijderen + + + + Select All + Alles selecteren + + + + + Find + Zoeken + + + + + Replace + Vervangen + + + + Go to Line + Ga naar regel + + + + Turn on Read-Only mode + Alleen-lezenmodus inschakelen + + + + Turn off Read-Only mode + Alleen-lezenmodus uitschakelen + + + + Fullscreen + Beeldvullende modus + + + + Exit fullscreen + Beeldvullende modus verlaten + + + + Display in file manager + Tonen in bestandsbeheerder + + + + + Add Comment + Opmerking toevoegen + + + + Text to Speech + Tekst-naar-spraak + + + + Stop reading + Stoppen met lezen + + + + Speech to Text + Spraak-naar-tekst + + + + Translate + Vertalen + + + + Column Mode + Kolommodus + + + + Add bookmark + Bladwijzer toevoegen + + + + Remove Bookmark + Bladwijzer verwijderen + + + + Previous bookmark + Vorige bladwijzer + + + + Next bookmark + Volgende bladwijzer + + + + Remove All Bookmarks + Alle bladwijzers verwijderen + + + + Fold All + Alles inklappen + + + + Fold Current Level + Huidig niveau inklappen + + + + Unfold All + Alles uitklappen + + + + Unfold Current Level + Huidig niveau uitklappen + + + + Color Mark + Markeerkleur + + + + Clear All Marks + Alle markeringen missen + + + + Clear Last Mark + Recentste markering demarkeren + + + + Mark + Markeren + + + + Mark All + Alles markeren + + + + Remove Comment + Opmerking verwijderen + + + + Copy failed: not enough memory + Het kopiëren is mislukt omdat er onvoldoende vrij geheugen is + + + + Press ALT and click lines to edit in column mode + Druk op Alt en klik op regels om te bewerken in kolommodus + + + + Change Case + Hoofdletters/Kleine letters + + + + Upper Case + Hoofdletters + + + + Lower Case + Kleine letters + + + + Capitalize + Omzetten naar hoofdletters + + + + None + Geen + + + + Selected line(s) copied + De geselecteerde regel(s) is (zijn) gekopieerd + + + + Current line copied + De huidige regel is gekopieerd + + + + Selected line(s) clipped + De geselecteerde regel(s) is (zijn) ingekort + + + + Current line clipped + De huidige regel is ingekort + + + + Paste failed: not enough memory + Het plakken is mislukt omdat er onvoldoende vrij geheugen is + + + + Read-Only mode is off + Alleen-lezenmodus is uitgeschakeld + + + + + + Read-Only mode is on + Alleen-lezenmodus is ingeschakeld + + + + WarningNotices + + + Reload + Opnieuw laden + + + + Window + + + + Save as + Opslaan als + + + + New window + Nieuw venster + + + + New tab + Nieuw tabblad + + + + Open file + Bestand openen + + + + + Save + Opslaan + + + + Print + Afdrukken + + + + Switch theme + Thema wijzigen + + + + + Settings + Instellingen + + + + + Read-Only + Alleen-lezen + + + + You do not have permission to open %1 + Je bent niet gemachtigd om %1 te openen + + + + Invalid file: %1 + Ongeldig bestand: %1 + + + + + Do you want to save this file? + Wil je dit bestand opslaan? + + + + You do not have permission to save %1 + Je bent niet gemachtigd om %1 op te slaan + + + + Saved successfully + Opgeslagen + + + + + + Save File + Bestand opslaan + + + + Encoding + Tekencodering + + + + Read-Only mode is on + Alleen-lezenmodus is ingeschakeld + + + + Current location remembered + De huidige locatie wordt onthouden + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Bewerker + + + + Untitled %1 + Naamloos %1 + + + + Cancel + Annuleren + + + + Discard + Verwerpen + + + \ No newline at end of file diff --git a/translations/deepin-editor_pl.ts b/translations/deepin-editor_pl.ts new file mode 100644 index 0000000000000000000000000000000000000000..ef235a1281179eb6ed7f7ac0adea3ee66178eff1 --- /dev/null +++ b/translations/deepin-editor_pl.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Wiersz + + + + Column + Kolumna + + + + Characters %1 + Znaki %1 + + + + Loading: + Wczytywanie: + + + + DDropdownMenu + + + + + None + Brak + + + + EditWrapper + + + + + + Save + Zapisz + + + + Do you want to save this file? + Czy chcesz zapisać plik? + + + + + Cancel + Anuluj + + + + Encoding changed. Do you want to save the file now? + Kodowanie zostało zmienione. Czy chcesz teraz zapisać plik? + + + + Discard + Odrzuć + + + + You do not have permission to save %1 + Nie posiadasz uprawnień do zapisania %1 + + + + File removed on the disk. Save it now? + Plik został usunięty z dysku. Czy chcesz go zapisać? + + + + File has changed on disk. Reload? + Plik został zmieniony na dysku. Czy chcesz go ponownie wczytać? + + + + + INSERT + WSTAWIANIE + + + + OVERWRITE + NADPISYWANIE + + + + R/O + TYLKO DO ODCZYTU + + + + FindBar + + + Find + Znajdź + + + + Previous + Poprzednie + + + + Next + Następne + + + + JumpLineBar + + + Go to Line: + Przejdź do wiersza: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Edytor Tekstu to potężne narzędzie do przeglądania i edycji plików tekstowych. + + + + Text Editor + Edytor tekstu + + + + PathSettingWgt + + + Remember the last used path + Zapamiętaj ostatnio użytą ścieżkę + + + + Same path as the current file + Taka sama ścieżka jak bieżącego pliku + + + + Customize the default path + Dostosuj ścieżkę domyślną + + + + QObject + + + Text Editor + Edytor tekstu + + + + + + + + + Encoding + Kodowanie + + + + Basic + Podstawowe + + + + Font Style + Styl czcionki + + + + Font + Czcionka + + + + Font Size + Rozmiar czcionki + + + + Shortcuts + Skróty + + + + + Keymap + Mapowanie klawiszy + + + + + + Window + Okno + + + + New tab + Nowa karta + + + + New window + Nowe okno + + + + Save + Zapisz + + + + Save as + Zapisz jako + + + + Next tab + Następna karta + + + + Previous tab + Poprzednia karta + + + + Close tab + Zamknij kartę + + + + Close other tabs + Zamknij pozostałe karty + + + + Restore tab + Przywróć kartę + + + + Open file + Otwórz plik + + + + Increment font size + Zwiększ rozmiar czcionki + + + + Decrement font size + Zmniejsz rozmiar czcionki + + + + Reset font size + Zresetuj rozmiar czcionki + + + + Help + Pomoc + + + + Toggle fullscreen + Przełącz pełny ekran + + + + Find + Znajdź + + + + Replace + Zamień + + + + Go to line + Przejdź do wiersza + + + + Save cursor position + Zapisz pozycję kursora + + + + Reset cursor position + Zresetuj pozycję kursora + + + + Exit + Wyjście + + + + Display shortcuts + Wyświetl skróty + + + + Print + Drukuj + + + + Editor + Edytor + + + + Increase indent + Zwiększ wcięcie + + + + Decrease indent + Zmniejsz wcięcie + + + + Forward character + Znak do przodu + + + + Backward character + Znak do tyłu + + + + Forward word + Następne słowo + + + + Backward word + Poprzednie słowo + + + + Next line + Następny wiersz + + + + Previous line + Poprzedni wiersz + + + + New line + Nowy wiersz + + + + New line above + Nowy wiersz powyżej + + + + New line below + Nowy wiersz poniżej + + + + Duplicate line + Duplikuj wiersz + + + + Delete to end of line + Usuń do końca wiersza + + + + Delete current line + Usuń bieżący wiersz + + + + Swap line up + Zamień wiersz z powyższym + + + + Swap line down + Zamień wiersz z poniższym + + + + Scroll up one line + Przewiń jeden wiersz w górę + + + + Scroll down one line + Przewiń jeden wiersz w dół + + + + Page up + Strona w górę + + + + Page down + Strona w dół + + + + Move to end of line + Przejdź do końca wiersza + + + + Move to start of line + Przejdź do początku wiersza + + + + Move to end of text + Przejdź do końca tekstu + + + + Move to start of text + Przejdź do początku tekstu + + + + Move to line indentation + Przejdź do wcięcia wiersza + + + + Upper case + Wielkie litery + + + + Lower case + Małe litery + + + + Capitalize + Wielka litera + + + + Delete backward word + Usuń poprzedzające słowo + + + + Delete forward word + Usuń następujące słowo + + + + Forward over a pair + Przenieś się za nawias + + + + Backward over a pair + Przenieś się przed nawias + + + + Select all + Zaznacz wszystko + + + + Copy + Kopiuj + + + + Cut + Wytnij + + + + Paste + Wklej + + + + Transpose character + Przenieś znak + + + + Mark + Oznacz + + + + Unmark + Odznacz + + + + Copy line + Kopiuj wiersz + + + + Cut line + Wytnij wiersz + + + + Merge lines + Połącz wiersze + + + + Read-Only mode + Tryb tylko-do-odczytu + + + + Add comment + Dodaj komentarz + + + + Remove comment + Usuń komentarz + + + + Undo + Cofnij + + + + Redo + Ponów + + + + Add/Remove bookmark + Dodaj/Usuń zakładkę + + + + Move to previous bookmark + Przejdź do poprzedniej zakładki + + + + Move to next bookmark + Przejdź do następnej zakładki + + + + Advanced + Zaawansowane + + + + Window size + Rozmiar okna + + + + Tab width + Szerokość zakładki + + + + Paste by pressing a middle mouse button + Wklej przy użyciu środkowego przycisku myszy + + + + Startup + Uruchamianie + + + + Reopen last closed tabs + Otwórz ostatnio zamknięte karty + + + + Open/Save Settings + Otwórz/Zapisz ustawienia + + + + Word wrap + Zawijanie tekstu + + + + Code folding flag + Pokaż strzałki zawijające kod + + + + Show line numbers + Pokaż numery wierszy + + + + Show bookmarks icon + Pokaż ikonę zakładek + + + + Show whitespaces and tabs + Pokaż spacje i tabulatory + + + + Highlight current line + Podkreśl bieżący wiersz + + + + Color mark + Kolor oznaczenia + + + + Unicode + Unicode + + + + WesternEuropean + Zachodnio Europejski + + + + CentralEuropean + Europa Centralna + + + + Baltic + Bałtycki + + + + Cyrillic + Cyrylica + + + + Arabic + Arabski + + + + Celtic + Celtycki + + + + SouthEasternEuropean + Południowo-Wschodnia Europa + + + + Greek + Grecki + + + + Hebrew + Hebrajski + + + + ChineseSimplified + Chiński uproszczony + + + + ChineseTraditional + Chiński tradycyjny + + + + Japanese + Japoński + + + + Korean + Koreański + + + + Thai + Tajlandzki + + + + Turkish + Turecki + + + + Vietnamese + Wietnamski + + + + File not saved + Plik nie został zapisany + + + + + + Line Endings + Zakończenia wiersza + + + + ReplaceBar + + + Find + Znajdź + + + + Replace With + Zamień na + + + + Replace + Zastąp + + + + Skip + Pomiń + + + + Replace Rest + Zastąp pozostałe + + + + Replace All + Zastąp wszystkie + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standardowe + + + + Customize + Dostosuj + + + + Normal + Normalny + + + + Maximum + Maksymalny + + + + Fullscreen + Pełny ekran + + + + This shortcut conflicts with system shortcut %1 + Ten skrót jest w konflikcie ze skrótem systemowym %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Ten skrót jest w konflikcie z %1, kliknij Zamień, aby skrót zaczął działać od razu + + + + + The shortcut %1 is invalid, please set another one. + Skrót %1 jest nieprawidłowy, ustaw inny. + + + + Cancel + Anuluj + + + + Replace + Zamień + + + + OK + OK + + + + StartManager + + + Untitled %1 + Bez tytułu %1 + + + + Tabbar + + + Close tab + Zamknij kartę + + + + Close other tabs + Zamknij pozostałe karty + + + + More options + Więcej opcji + + + + Close tabs to the left + Zamknij karty po lewej stronie + + + + Close tabs to the right + Zamknij karty po prawej stronie + + + + Close unmodified tabs + Zamknij niezmodyfikowane karty + + + + TextEdit + + + Undo + Cofnij + + + + Redo + Ponów + + + + Cut + Wytnij + + + + Copy + Kopiuj + + + + Paste + Wklej + + + + Delete + Usuń + + + + Select All + Zaznacz wszystko + + + + + Find + Znajdź + + + + + Replace + Zamień + + + + Go to Line + Przejdź do wiersza + + + + Turn on Read-Only mode + Włącz tryb tylko-do-odczytu + + + + Turn off Read-Only mode + Wyłącz tryb tylko-do-odczytu + + + + Fullscreen + Pełny ekran + + + + Exit fullscreen + Opuść pełny ekran + + + + Display in file manager + Wyświetl w Menedżerze plików + + + + + Add Comment + Dodaj komentarz + + + + Text to Speech + Tekst na mowę + + + + Stop reading + Przestań czytać + + + + Speech to Text + Mowa na tekst + + + + Translate + Przetłumacz + + + + Column Mode + Tryb kolumnowy + + + + Add bookmark + Dodaj zakładkę + + + + Remove Bookmark + Usuń zakładkę + + + + Previous bookmark + Poprzednia zakładka + + + + Next bookmark + Następna zakładka + + + + Remove All Bookmarks + Usuń wszystkie zakładki + + + + Fold All + Zwiń wszystko + + + + Fold Current Level + Zwiń bieżący poziom + + + + Unfold All + Rozwiń wszystko + + + + Unfold Current Level + Rozwiń bieżący poziom + + + + Color Mark + Kolor oznaczenia + + + + Clear All Marks + Wyczyść wszystkie oznaczenia + + + + Clear Last Mark + Wyczyść ostatnie oznaczenie + + + + Mark + Oznacz + + + + Mark All + Oznacz wszystko + + + + Remove Comment + Usuń komentarz + + + + Copy failed: not enough memory + Kopiowanie nieudane: niewystarczająca ilość pamięci + + + + Press ALT and click lines to edit in column mode + Naciśnij ALT i kliknij wiersz, aby edytować w trybie kolumnowym + + + + Change Case + Zmień wielkość znaków + + + + Upper Case + Wielkie litery + + + + Lower Case + Małe litery + + + + Capitalize + Wielka litera + + + + None + Brak + + + + Selected line(s) copied + Skopiowano zaznaczone wiersz(e) + + + + Current line copied + Skopiowano bieżący wiersz + + + + Selected line(s) clipped + Wycięto zaznaczone wiersz(e) + + + + Current line clipped + Wycięto bieżący wiersz + + + + Paste failed: not enough memory + Wklejanie nieudane: niewystarczająca ilość pamięci + + + + Read-Only mode is off + Tryb tylko-do-odczytu jest nieaktywny + + + + + + Read-Only mode is on + Tryb tylko-do-odczytu jest włączony + + + + WarningNotices + + + Reload + Przeładuj + + + + Window + + + + Save as + Zapisz jako + + + + New window + Nowe okno + + + + New tab + Nowa karta + + + + Open file + Otwórz plik + + + + + Save + Zapisz + + + + Print + Drukuj + + + + Switch theme + Przełącz motyw + + + + + Settings + Ustawienia + + + + + Read-Only + Tylko-do-odczytu + + + + You do not have permission to open %1 + Nie posiadasz uprawnień do otwarcia %1 + + + + Invalid file: %1 + Nieprawidłowy plik: %1 + + + + + Do you want to save this file? + Czy chcesz zapisać ten plik? + + + + You do not have permission to save %1 + Nie posiadasz uprawnień do zapisania %1 + + + + Saved successfully + Zapisano pomyślnie + + + + + + Save File + Zapisz plik + + + + Encoding + Kodowanie + + + + Read-Only mode is on + Tryb tylko-do-odczytu jest włączony + + + + Current location remembered + Bieżąca pozycja kursora została zapamiętana + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Edytor + + + + Untitled %1 + Bez tytułu %1 + + + + Cancel + Anuluj + + + + Discard + Odrzuć + + + \ No newline at end of file diff --git a/translations/deepin-editor_pt.ts b/translations/deepin-editor_pt.ts new file mode 100644 index 0000000000000000000000000000000000000000..599c9b6f0687e1a5aedb4483897adc3914b412ff --- /dev/null +++ b/translations/deepin-editor_pt.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Linha + + + + Column + Coluna + + + + Characters %1 + Caracteres %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Nenhum + + + + EditWrapper + + + + + + Save + Guardar + + + + Do you want to save this file? + Quer guardar este ficheiro? + + + + + Cancel + Cancelar + + + + Encoding changed. Do you want to save the file now? + A codificação foi alterada. Deseja guardar o ficheiro agora? + + + + Discard + Descartar + + + + You do not have permission to save %1 + Não possui permissões para guardar %1 + + + + File removed on the disk. Save it now? + Ficheiro removido no disco. Guardar agora? + + + + File has changed on disk. Reload? + Ficheiro foi alterado no disco. Recarregar? + + + + + INSERT + INSERIR + + + + OVERWRITE + SOBRESCREVER + + + + R/O + A/L + + + + FindBar + + + Find + Procurar + + + + Previous + Anterior + + + + Next + Seguinte + + + + JumpLineBar + + + Go to Line: + Ir para linha: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + O Editor de texto é uma ferramenta poderosa para visualizar e editar ficheiros de texto. + + + + Text Editor + Editor de texto + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Editor de texto + + + + + + + + + Encoding + Codificação + + + + Basic + Básico + + + + Font Style + Estilo de fonte + + + + Font + Fonte + + + + Font Size + Tamanho da fonte + + + + Shortcuts + Atalhos + + + + + Keymap + Esquema de teclado + + + + + + Window + Janela + + + + New tab + Novo separador + + + + New window + Nova janela + + + + Save + Guardar + + + + Save as + Guardar como + + + + Next tab + Separador seguinte + + + + Previous tab + Separador anterior + + + + Close tab + Fechar separador + + + + Close other tabs + Fechar outros separadores + + + + Restore tab + Restaurar separador + + + + Open file + Abrir ficheiro + + + + Increment font size + Aumentar tamanho da fonte + + + + Decrement font size + Diminuir tamanho da fonte + + + + Reset font size + Redefinir tamanho da fonte + + + + Help + Ajuda + + + + Toggle fullscreen + Ativar/Desativar ecrã inteiro + + + + Find + Procurar + + + + Replace + Substituir + + + + Go to line + Ir para linha + + + + Save cursor position + Guardar posição do cursor + + + + Reset cursor position + Redefinir posição do cursor + + + + Exit + Sair + + + + Display shortcuts + Mostrar atalhos + + + + Print + Imprimir + + + + Editor + Editor + + + + Increase indent + Aumentar indentação + + + + Decrease indent + Diminuir indentação + + + + Forward character + Avançar caracter + + + + Backward character + Recuar caracter + + + + Forward word + Avançar palavra + + + + Backward word + Recuar palavra + + + + Next line + Linha seguinte + + + + Previous line + Linha anterior + + + + New line + Nova linha + + + + New line above + Nova linha acima + + + + New line below + Nova linha abaixo + + + + Duplicate line + Duplicar linha + + + + Delete to end of line + Eliminar até ao fim da linha + + + + Delete current line + Eliminar esta linha + + + + Swap line up + Trocar para linha acima + + + + Swap line down + Trocar para linha abaixo + + + + Scroll up one line + Rolar uma linha para cima + + + + Scroll down one line + Rolar uma linha para baixo + + + + Page up + Página acima + + + + Page down + Página abaixo + + + + Move to end of line + Mover para o fim da linha + + + + Move to start of line + Mover para o início da linha + + + + Move to end of text + Mover para o fim do texto + + + + Move to start of text + Mover para o início do texto + + + + Move to line indentation + Mover para indentação da linha + + + + Upper case + Maiúsculas + + + + Lower case + Minúsculas + + + + Capitalize + Maiúsculas + + + + Delete backward word + Eliminar palavra anterior + + + + Delete forward word + Eliminar palavra seguinte + + + + Forward over a pair + Avançar em pares + + + + Backward over a pair + Recuar em pares + + + + Select all + Selecionar tudo + + + + Copy + Copiar + + + + Cut + Cortar + + + + Paste + Colar + + + + Transpose character + Transpor caracter + + + + Mark + Marcar + + + + Unmark + Desmarcar + + + + Copy line + Copiar linha + + + + Cut line + Cortar linha + + + + Merge lines + Juntar linhas + + + + Read-Only mode + Modo de Apenas-Leitura + + + + Add comment + Adicionar comentário + + + + Remove comment + Remover comentário + + + + Undo + Anular + + + + Redo + Refazer + + + + Add/Remove bookmark + Adicionador/Remover marcador + + + + Move to previous bookmark + Mover para o marcador anterior + + + + Move to next bookmark + Mover para o marcador seguinte + + + + Advanced + Avançado + + + + Window size + Tamanho da janela + + + + Tab width + Largura do separador + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Quebra de linha + + + + Code folding flag + Marcador de código minimizado + + + + Show line numbers + Mostrar números de linha + + + + Show bookmarks icon + Mostrar ícone de marcadores + + + + Show whitespaces and tabs + Mostrar espaços em branco e separadores + + + + Highlight current line + Destacar a linha atual + + + + Color mark + Marca de cor + + + + Unicode + Unicode + + + + WesternEuropean + EuropeuOcidental + + + + CentralEuropean + CentroEuropeu + + + + Baltic + Báltico + + + + Cyrillic + Cirílico + + + + Arabic + Árabe + + + + Celtic + Celta + + + + SouthEasternEuropean + SudesteEuropeu + + + + Greek + Grego + + + + Hebrew + Hebraico + + + + ChineseSimplified + ChinêsSimplificado + + + + ChineseTraditional + ChinêsTradicional + + + + Japanese + Japonês + + + + Korean + Coreano + + + + Thai + Tailandês + + + + Turkish + Turco + + + + Vietnamese + Vietnamita + + + + File not saved + Ficheiro não guardado + + + + + + Line Endings + Terminações de linha + + + + ReplaceBar + + + Find + Localizar + + + + Replace With + Substituir por + + + + Replace + Substituir + + + + Skip + Ignorar + + + + Replace Rest + Substituir restantes + + + + Replace All + Substituir todos + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Predefinição + + + + Customize + Personalizar + + + + Normal + Normal + + + + Maximum + Máximo + + + + Fullscreen + Ecrã Inteiro + + + + This shortcut conflicts with system shortcut %1 + Este atalho entra em conflito com o atalho do sistema %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Esta tecla de atalho entra em conflito com %1, clique em Substituir para que esta tecla de atalho entre em vigor imediatamente + + + + + The shortcut %1 is invalid, please set another one. + O atalho %1 é inválido, defina outro. + + + + Cancel + Cancelar + + + + Replace + Substituir + + + + OK + Aceitar + + + + StartManager + + + Untitled %1 + Sem título %1 + + + + Tabbar + + + Close tab + Fechar separador + + + + Close other tabs + Fechar outros separadores + + + + More options + Mais opções + + + + Close tabs to the left + Fechar separadores à esquerda + + + + Close tabs to the right + Fechar separadores à direita + + + + Close unmodified tabs + Fechar separadores não modificados + + + + TextEdit + + + Undo + Anular + + + + Redo + Refazer + + + + Cut + Cortar + + + + Copy + Copiar + + + + Paste + Colar + + + + Delete + Eliminar + + + + Select All + Selecionar tudo + + + + + Find + Procurar + + + + + Replace + Substituir + + + + Go to Line + Ir para linha + + + + Turn on Read-Only mode + Ativar modo de Apenas-Leitura + + + + Turn off Read-Only mode + Desativar modo de Apenas-Leitura + + + + Fullscreen + Ecrã inteiro + + + + Exit fullscreen + Sair de ecrã inteiro + + + + Display in file manager + Mostrar no gestor de ficheiros + + + + + Add Comment + Adicionar comentário + + + + Text to Speech + Texto para voz + + + + Stop reading + Parar a leitura + + + + Speech to Text + Voz para texto + + + + Translate + Traduzir + + + + Column Mode + Modo de coluna + + + + Add bookmark + Adicionador marcador + + + + Remove Bookmark + Remover marcador + + + + Previous bookmark + Marcador anterior + + + + Next bookmark + Marcador seguinte + + + + Remove All Bookmarks + Remover todos os marcadores + + + + Fold All + Minimizar tudo + + + + Fold Current Level + Minimizar nível atual + + + + Unfold All + Mostrar tudo + + + + Unfold Current Level + Mostrar nível atual + + + + Color Mark + Marca de cor + + + + Clear All Marks + Limpar selecionados + + + + Clear Last Mark + Limpar último selecionado + + + + Mark + Marcar + + + + Mark All + Marcar tudo + + + + Remove Comment + Remover comentário + + + + Copy failed: not enough memory + Falha ao copiar: não há memória suficiente + + + + Press ALT and click lines to edit in column mode + Prima ALT e clique em linhas para editar em modo de coluna + + + + Change Case + Maiúsculas e Minúsculas + + + + Upper Case + Maiúsculas + + + + Lower Case + Minúsculas + + + + Capitalize + Maiúsculas + + + + None + Nenhum + + + + Selected line(s) copied + Linha(s) selecionada(s) copiada(s) + + + + Current line copied + Linha atual copiada + + + + Selected line(s) clipped + Linha(s) selecionada(s) cortada(s) + + + + Current line clipped + Linha atual cortada + + + + Paste failed: not enough memory + Falha ao colar: memória insuficiente + + + + Read-Only mode is off + O modo de Apenas-Leitura está desligado + + + + + + Read-Only mode is on + O modo de Apenas-Leitura está ligado + + + + WarningNotices + + + Reload + Recarregar + + + + Window + + + + Save as + Guardar como + + + + New window + Nova janela + + + + New tab + Novo separador + + + + Open file + Abrir ficheiro + + + + + Save + Guardar + + + + Print + Imprimir + + + + Switch theme + Alterar tema + + + + + Settings + Definições + + + + + Read-Only + Apenas-Leitura + + + + You do not have permission to open %1 + Não possui permissões para abrir %1 + + + + Invalid file: %1 + Ficheiro inválido: %1 + + + + + Do you want to save this file? + Quer guardar este ficheiro? + + + + You do not have permission to save %1 + Não possui permissões para guardar %1 + + + + Saved successfully + Gravado com sucesso + + + + + + Save File + Guardar ficheiro + + + + Encoding + Codificação + + + + Read-Only mode is on + O modo de Apenas-Leitura está ligado + + + + Current location remembered + Localização atual memorizada + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Editor + + + + Untitled %1 + Sem título %1 + + + + Cancel + Cancelar + + + + Discard + Descartar + + + \ No newline at end of file diff --git a/translations/deepin-editor_pt_BR.ts b/translations/deepin-editor_pt_BR.ts new file mode 100644 index 0000000000000000000000000000000000000000..7496a1f58ea8214f470b4bdbf3940c788975c075 --- /dev/null +++ b/translations/deepin-editor_pt_BR.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Linha + + + + Column + Coluna + + + + Characters %1 + %1 Caracteres + + + + Loading: + + + + + DDropdownMenu + + + + + None + Nenhum + + + + EditWrapper + + + + + + Save + Salvar + + + + Do you want to save this file? + Salvar este arquivo? + + + + + Cancel + Cancelar + + + + Encoding changed. Do you want to save the file now? + Codificação alterada. Salvar? + + + + Discard + Descartar + + + + You do not have permission to save %1 + Você não tem permissão para salvar %1 + + + + File removed on the disk. Save it now? + Arquivo removido no disco. Salvar agora? + + + + File has changed on disk. Reload? + O arquivo foi alterado no disco. Recarregar? + + + + + INSERT + INSERIR + + + + OVERWRITE + SOBRESCREVER + + + + R/O + R/O + + + + FindBar + + + Find + Localizar + + + + Previous + Anterior + + + + Next + Próximo + + + + JumpLineBar + + + Go to Line: + Ir para Linha: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + O Editor de Textos é uma ferramenta poderosa para visualizar e editar arquivos de texto. + + + + Text Editor + Editor de Textos + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Editor de Textos + + + + + + + + + Encoding + Codificação + + + + Basic + Básico + + + + Font Style + Estilo de Fonte + + + + Font + Fonte + + + + Font Size + Tamanho da Fonte + + + + Shortcuts + Atalhos + + + + + Keymap + Mapear Teclado + + + + + + Window + Janela + + + + New tab + Nova Aba + + + + New window + Nova janela + + + + Save + Salvar + + + + Save as + Salvar como + + + + Next tab + Próxima aba + + + + Previous tab + Aba anterior + + + + Close tab + Fechar Aba + + + + Close other tabs + Fechar outras abas + + + + Restore tab + Restaurar aba + + + + Open file + Abrir arquivo + + + + Increment font size + Aumentar o tamanho da fonte + + + + Decrement font size + Reduzir o tamanho da fonte + + + + Reset font size + Redefinir o tamanho da fonte + + + + Help + Ajuda + + + + Toggle fullscreen + Alternar para a tela cheia + + + + Find + Localizar + + + + Replace + Substituir + + + + Go to line + Ir para linha + + + + Save cursor position + Salvar a posição do cursor + + + + Reset cursor position + Redefinir a posição do cursor + + + + Exit + Sair + + + + Display shortcuts + Exibir atalhos + + + + Print + Imprimir + + + + Editor + Editor de Textos + + + + Increase indent + Aumentar recuo + + + + Decrease indent + Reduzir recuo + + + + Forward character + Caractere à Frente + + + + Backward character + Caractere Atrás + + + + Forward word + Palavra à frente + + + + Backward word + Palavra para trás + + + + Next line + Próxima linha + + + + Previous line + Linha anterior + + + + New line + Nova linha + + + + New line above + Nova linha acima + + + + New line below + Nova linha inferior + + + + Duplicate line + Duplicar Linha + + + + Delete to end of line + Excluir até o final da linha + + + + Delete current line + Excluir a linha atual + + + + Swap line up + Inverter com a linha superior + + + + Swap line down + Inverter com a linha inferior + + + + Scroll up one line + Subir uma linha + + + + Scroll down one line + Rolar uma Linha para Baixo + + + + Page up + Página acima + + + + Page down + Uma página abaixo + + + + Move to end of line + Ir para o Final da Linha + + + + Move to start of line + Mover para o início da linha + + + + Move to end of text + Mover para o final do texto + + + + Move to start of text + Mover para o início do texto + + + + Move to line indentation + Ir à indentação da linha + + + + Upper case + Maiúscula + + + + Lower case + Minúscula + + + + Capitalize + Autocapitalizar + + + + Delete backward word + Excluir a palavra anterior + + + + Delete forward word + Excluir a palavra seguinte + + + + Forward over a pair + Ir um par à frente + + + + Backward over a pair + Ir um par para trás + + + + Select all + Selecionar tudo + + + + Copy + Copiar + + + + Cut + Recortar + + + + Paste + Colar + + + + Transpose character + Inverter caractere + + + + Mark + Marcar + + + + Unmark + Desmarcar + + + + Copy line + Copiar Linha + + + + Cut line + Cortar Linha + + + + Merge lines + Mesclar linhas + + + + Read-Only mode + Modo Somente Leitura + + + + Add comment + Adicionar comentário + + + + Remove comment + Remover comentário + + + + Undo + Desfazer + + + + Redo + Refazer + + + + Add/Remove bookmark + Adicionar/Remover marcador + + + + Move to previous bookmark + Mover para o marcador anterior + + + + Move to next bookmark + Mover para o próximo marcador + + + + Advanced + Avançado + + + + Window size + Tamanho da janela + + + + Tab width + Largura da Guia + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Quebra de linha + + + + Code folding flag + Bandeira de código dobrável + + + + Show line numbers + Exibir os números das linhas + + + + Show bookmarks icon + Exibir o ícone dos marcadores + + + + Show whitespaces and tabs + Exibir os espaços em branco e as abas + + + + Highlight current line + Destacar a linha atual + + + + Color mark + Marca colorida + + + + Unicode + Unicode + + + + WesternEuropean + Europa Ocidental + + + + CentralEuropean + Europa Central + + + + Baltic + Báltico + + + + Cyrillic + Cirílico + + + + Arabic + Árabe + + + + Celtic + Celta + + + + SouthEasternEuropean + Sudeste Europeu + + + + Greek + Grego + + + + Hebrew + Hebraico + + + + ChineseSimplified + Chinês Simplificado + + + + ChineseTraditional + Chinês Tradicional + + + + Japanese + Japonês + + + + Korean + Coreano + + + + Thai + Tailandês + + + + Turkish + Turco + + + + Vietnamese + Vietnamita + + + + File not saved + Arquivo não salvo + + + + + + Line Endings + Terminações de Linha + + + + ReplaceBar + + + Find + Localizar + + + + Replace With + Substituir com + + + + Replace + Substituir + + + + Skip + Ignorar + + + + Replace Rest + Substituir o Restante + + + + Replace All + Substituir Tudo + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Padrão + + + + Customize + Personalizar + + + + Normal + Normal + + + + Maximum + Maximizado + + + + Fullscreen + Tela Cheia + + + + This shortcut conflicts with system shortcut %1 + Este atalho entra em conflito com o atalho %1 do sistema + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Este atalho entra em conflito com %1; clique em Substituir para efetivar esse atalho imediatamente + + + + + The shortcut %1 is invalid, please set another one. + O atalho %1 é inválido; defina outro. + + + + Cancel + Cancelar + + + + Replace + Substituir + + + + OK + Ok + + + + StartManager + + + Untitled %1 + Sem título %1 + + + + Tabbar + + + Close tab + Fechar Aba + + + + Close other tabs + Fechar outras abas + + + + More options + Mais opções + + + + Close tabs to the left + Fechar as abas à esquerda + + + + Close tabs to the right + Fechar as abas à direita + + + + Close unmodified tabs + Fechar as abas não modificadas + + + + TextEdit + + + Undo + Desfazer + + + + Redo + Refazer + + + + Cut + Recortar + + + + Copy + Copiar + + + + Paste + Colar + + + + Delete + Excluir + + + + Select All + Selecionar Tudo + + + + + Find + Localizar + + + + + Replace + Substituir + + + + Go to Line + Ir para Linha + + + + Turn on Read-Only mode + Ativar o modo Somente Leitura + + + + Turn off Read-Only mode + Desativar o modo Somente Leitura + + + + Fullscreen + Tela Cheia + + + + Exit fullscreen + Sair da tela cheia + + + + Display in file manager + Exibir no Gerenciador de Arquivos + + + + + Add Comment + Adicionar Comentário + + + + Text to Speech + Texto em Voz + + + + Stop reading + Parar a leitura + + + + Speech to Text + Voz em Texto + + + + Translate + Traduzir + + + + Column Mode + Modo de Coluna + + + + Add bookmark + Adicionar marcador + + + + Remove Bookmark + Remover Marcador + + + + Previous bookmark + Marcador anterior + + + + Next bookmark + Próximo marcador + + + + Remove All Bookmarks + Remover Todos os Marcadores + + + + Fold All + Dobrar Tudo + + + + Fold Current Level + Dobrar o Nível Atual + + + + Unfold All + Desdobrar Tudo + + + + Unfold Current Level + Desdobrar o Nível Atual + + + + Color Mark + Marca Colorida + + + + Clear All Marks + Limpar Todas as Marcações + + + + Clear Last Mark + Limpar a Última Marcação + + + + Mark + Marcar + + + + Mark All + Marcar Tudo + + + + Remove Comment + Remover Comentário + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + Pressione ALT e clique nas linhas para editar no modo de coluna + + + + Change Case + Alterar entre Maiúscula e Minúscula + + + + Upper Case + Maiúscula + + + + Lower Case + Minúscula + + + + Capitalize + Autocapitalizar + + + + None + Nenhum + + + + Selected line(s) copied + Linha(s) selecionada(s) copiada(s) + + + + Current line copied + Linha atual copiada + + + + Selected line(s) clipped + Linha(s) selecionada(s) recortada(s) + + + + Current line clipped + Linha atual recortada + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + O modo Somente Leitura está desativado + + + + + + Read-Only mode is on + O modo Somente Leitura está ativado + + + + WarningNotices + + + Reload + Recarregar + + + + Window + + + + Save as + Salvar como + + + + New window + Nova janela + + + + New tab + Nova aba + + + + Open file + Abrir arquivo + + + + + Save + Salvar + + + + Print + Imprimir + + + + Switch theme + Alternar tema + + + + + Settings + Configurações + + + + + Read-Only + Somente-Leitura + + + + You do not have permission to open %1 + Você não tem permissão para abrir %1 + + + + Invalid file: %1 + Arquivo Inválido: %1 + + + + + Do you want to save this file? + Salvar este arquivo? + + + + You do not have permission to save %1 + Você não tem permissão para salvar %1 + + + + Saved successfully + Salvo + + + + + + Save File + Salvar Arquivo + + + + Encoding + Codificação + + + + Read-Only mode is on + O modo Somente Leitura está ativado + + + + Current location remembered + Lembrar o local atual + + + + Ctrl+'=' + Ctrl + = + + + + Ctrl+'-' + Ctrl + - + + + + Editor + Editor de Textos + + + + Untitled %1 + Sem título %1 + + + + Cancel + Cancelar + + + + Discard + Descartar + + + \ No newline at end of file diff --git a/translations/deepin-editor_ru.ts b/translations/deepin-editor_ru.ts new file mode 100644 index 0000000000000000000000000000000000000000..b34f56aba3d653e2ccd03960077c01d7681b2a99 --- /dev/null +++ b/translations/deepin-editor_ru.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Строка + + + + Column + Столбец + + + + Characters %1 + Символы %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Ничего + + + + EditWrapper + + + + + + Save + Сохранить + + + + Do you want to save this file? + Вы хотите сохранить этот документ? + + + + + Cancel + Отмена + + + + Encoding changed. Do you want to save the file now? + Кодирование изменилось. Вы хотите сохранить файл сейчас? + + + + Discard + Забыть + + + + You do not have permission to save %1 + Вы не имеете разрешения на сохранение %1 + + + + File removed on the disk. Save it now? + Файл удален на диске. Сохранить его сейчас? + + + + File has changed on disk. Reload? + Файл изменился на диске. Обновить? + + + + + INSERT + ВСТАВИТЬ + + + + OVERWRITE + ПЕРЕЗАПИСАТЬ + + + + R/O + Т/Ч + + + + FindBar + + + Find + Найти + + + + Previous + Предыдущий + + + + Next + Следующий + + + + JumpLineBar + + + Go to Line: + Перейти к Строке: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Текстовый редактор - это мощный инструмент для просмотра и редактирования текстовых файлов. + + + + Text Editor + Текстовый Редактор + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Текстовый редактор + + + + + + + + + Encoding + Кодировка + + + + Basic + Основной + + + + Font Style + Стиль Шрифта + + + + Font + Шрифт + + + + Font Size + Размер Шрифта + + + + Shortcuts + Горячие Клавиши + + + + + Keymap + Раскладка + + + + + + Window + Окно + + + + New tab + Новая вкладка + + + + New window + Новое окно + + + + Save + Сохранить + + + + Save as + Сохранить как + + + + Next tab + Следующая вкладка + + + + Previous tab + Предыдущая вкладка + + + + Close tab + Закрыть вкладку + + + + Close other tabs + Закрыть другие вкладки + + + + Restore tab + Восстановить вкладки + + + + Open file + Открыть файл + + + + Increment font size + Увеличить размер шрифта + + + + Decrement font size + Уменьшить размер шрифта + + + + Reset font size + Сбросить размер шрифта + + + + Help + Помощь + + + + Toggle fullscreen + Включить полноэкранный режим + + + + Find + Найти + + + + Replace + Заменить + + + + Go to line + Перейти к строке + + + + Save cursor position + Сохранить позицию курсора + + + + Reset cursor position + Сбросить позицию курсора + + + + Exit + Выйти + + + + Display shortcuts + Показать горячие клавиши + + + + Print + Печать + + + + Editor + Редактор + + + + Increase indent + Показать ярлыки + + + + Decrease indent + Уменьшить отступ + + + + Forward character + Символ спереди + + + + Backward character + Символ задом наперёд + + + + Forward word + Начальное слово + + + + Backward word + Последнее слово + + + + Next line + Следующая строка + + + + Previous line + Предыдущая строка + + + + New line + Новая строка + + + + New line above + Новая строка выше + + + + New line below + Новая строка ниже + + + + Duplicate line + Дублированная строка + + + + Delete to end of line + Удалить конец строки + + + + Delete current line + Удалить текущую строку + + + + Swap line up + заменить верхнюю строку + + + + Swap line down + Заменить нижнюю строку + + + + Scroll up one line + Прокрутка вверх на одну строку + + + + Scroll down one line + Прокрутка вниз на одну строку + + + + Page up + Страница вверх + + + + Page down + Страница вниз + + + + Move to end of line + Переход к конецу строки + + + + Move to start of line + Переход к началу строки + + + + Move to end of text + Переход к концу текста + + + + Move to start of text + Переход к началу текста + + + + Move to line indentation + Переход к строке отступа + + + + Upper case + Верхний регистр + + + + Lower case + Нижний регистр + + + + Capitalize + Прописной + + + + Delete backward word + Удалить слово с конца + + + + Delete forward word + Удалить слово с начала + + + + Forward over a pair + Вперед по паре + + + + Backward over a pair + Назад по паре + + + + Select all + Выбрать всё + + + + Copy + Копировать + + + + Cut + Вырезать + + + + Paste + Вставить + + + + Transpose character + Перемещаемый символ + + + + Mark + Пометить + + + + Unmark + Снять отметку + + + + Copy line + Копировать строку + + + + Cut line + Вырезать строку + + + + Merge lines + Совместить строки + + + + Read-Only mode + Режим Только Чтение + + + + Add comment + Добавить комментарий + + + + Remove comment + Удалить комментарий + + + + Undo + Отменить + + + + Redo + Готово + + + + Add/Remove bookmark + Добавить/удалить закладку + + + + Move to previous bookmark + К предыдущей закладке + + + + Move to next bookmark + К следующей закладке + + + + Advanced + Расширенные + + + + Window size + Размер окна + + + + Tab width + Ширина вкладки + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Перенос cлова + + + + Code folding flag + Флаг сворачивания кода + + + + Show line numbers + Показать номера строк + + + + Show bookmarks icon + Показать значок закладок + + + + Show whitespaces and tabs + Показать пробелы и табуляции + + + + Highlight current line + Выделить текущую строку + + + + Color mark + Цветная метка + + + + Unicode + Unicode + + + + WesternEuropean + Западноевропейский + + + + CentralEuropean + Центральноевропейский + + + + Baltic + Балтийский + + + + Cyrillic + Кириллица + + + + Arabic + Арабский + + + + Celtic + Кельтский + + + + SouthEasternEuropean + Юго-Восточная Европа + + + + Greek + Греческий + + + + Hebrew + Еврейский + + + + ChineseSimplified + Китайский упрощенный + + + + ChineseTraditional + Китайский традиционный + + + + Japanese + Японский + + + + Korean + Корейский + + + + Thai + Тайландский + + + + Turkish + Турецкий + + + + Vietnamese + Вьетнамский + + + + File not saved + Файл не сохранен + + + + + + Line Endings + Окончание строк + + + + ReplaceBar + + + Find + Найти + + + + Replace With + Заменить На + + + + Replace + Заменить: + + + + Skip + Пропустить + + + + Replace Rest + Заменить Остальное + + + + Replace All + Заменить Всё + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Стандартный + + + + Customize + Настроить + + + + Normal + Обычный + + + + Maximum + Максимум + + + + Fullscreen + Полный экран + + + + This shortcut conflicts with system shortcut %1 + Это сочетание конфликтует с системным сочитанием %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Это сочетание конфликтует с %1, нажмите Заменить, чтобы это сочетание вступило в силу немедленно + + + + + The shortcut %1 is invalid, please set another one. + Сочетание %1 недействительно, установите другое. + + + + Cancel + Отмена + + + + Replace + Заменить + + + + OK + OK + + + + StartManager + + + Untitled %1 + Без названия %1 + + + + Tabbar + + + Close tab + Закрыть вкладку + + + + Close other tabs + Закрыть другие вкладки + + + + More options + Больше вариантов + + + + Close tabs to the left + Закрыть вкладки слева + + + + Close tabs to the right + Закрыть вкладки справа + + + + Close unmodified tabs + Закрыть не изменённые вкладки + + + + TextEdit + + + Undo + Отменить + + + + Redo + Готово + + + + Cut + Вырезать + + + + Copy + Копировать + + + + Paste + Вставить + + + + Delete + Удалить + + + + Select All + Выбрать всё + + + + + Find + Найти + + + + + Replace + Заменить + + + + Go to Line + Перейти к строке + + + + Turn on Read-Only mode + Включить режим Только Чтение + + + + Turn off Read-Only mode + Отключить режим Только Чтение + + + + Fullscreen + Полноэкранный режим + + + + Exit fullscreen + Выйти из полноэкранного режима + + + + Display in file manager + Показать в файловом менеджере + + + + + Add Comment + Добавить комментарий + + + + Text to Speech + Текст в речь + + + + Stop reading + Прекратить читать + + + + Speech to Text + Речь в текст + + + + Translate + Перевести + + + + Column Mode + Режим колонки + + + + Add bookmark + Добавить закладку + + + + Remove Bookmark + Удалить закладку + + + + Previous bookmark + Предыдущая закладка + + + + Next bookmark + Следующая закладка + + + + Remove All Bookmarks + Удалить все закладки + + + + Fold All + Свернуть всё + + + + Fold Current Level + Свернуть текущий уровень + + + + Unfold All + Развернуть всё + + + + Unfold Current Level + Развернуть текущий уровень + + + + Color Mark + Цветная метка + + + + Clear All Marks + Очистить все метки + + + + Clear Last Mark + Очистить последнюю метку + + + + Mark + Пометить + + + + Mark All + Пометить всё + + + + Remove Comment + Удалить комментарий + + + + Copy failed: not enough memory + Копирование не удалось: недостаточно памяти + + + + Press ALT and click lines to edit in column mode + Нажмите ALT и щелкните строки для редактирования в режиме колонки + + + + Change Case + Изменить регистр + + + + Upper Case + Верхний регистр + + + + Lower Case + Нижний регистр + + + + Capitalize + Заглавные буквы + + + + None + Ничего + + + + Selected line(s) copied + Выбранные строки скопированы + + + + Current line copied + Текущая строка скопирована + + + + Selected line(s) clipped + Выбранные строки обрезаны + + + + Current line clipped + Текущая строка отрезана + + + + Paste failed: not enough memory + Вставка не удалось: недостаточно памяти + + + + Read-Only mode is off + Режим Только Чтение отключён + + + + + + Read-Only mode is on + Режим Только Чтение включён + + + + WarningNotices + + + Reload + Обновить + + + + Window + + + + Save as + Сохранить как + + + + New window + Новое окно + + + + New tab + Новая вкладка + + + + Open file + Открыть файл + + + + + Save + Сохранить + + + + Print + Печать + + + + Switch theme + Переключить тему + + + + + Settings + Настройки + + + + + Read-Only + Только Чтение + + + + You do not have permission to open %1 + Вы не имеете разрешения на открытие %1 + + + + Invalid file: %1 + Недопустимый файл: %1 + + + + + Do you want to save this file? + Вы хотите сохранить этот документ? + + + + You do not have permission to save %1 + Вы не имеете разрешения на сохранение %1 + + + + Saved successfully + Успешно сохранено + + + + + + Save File + Сохранить Файл + + + + Encoding + Кодировка + + + + Read-Only mode is on + Режим Только Чтение включён + + + + Current location remembered + Текущее местоположение запомнилось + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Редактор + + + + Untitled %1 + Без названия %1 + + + + Cancel + Отмена + + + + Discard + Отмена + + + \ No newline at end of file diff --git a/translations/deepin-editor_sl.ts b/translations/deepin-editor_sl.ts new file mode 100644 index 0000000000000000000000000000000000000000..6a4b80fbc730bb8d58aec35ea689f403a46b5e63 --- /dev/null +++ b/translations/deepin-editor_sl.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Vrsta + + + + Column + Stolp + + + + Characters %1 + Znakov %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + brez + + + + EditWrapper + + + + + + Save + Shrani + + + + Do you want to save this file? + Bi radi shranili to datoteko? + + + + + Cancel + Prekini + + + + Encoding changed. Do you want to save the file now? + Kodiranje je bilo spremenjeno. Želite sedaj shraniti to datoteko? + + + + Discard + Opusti + + + + You do not have permission to save %1 + Nimate pravic za shranjevanje %1 + + + + File removed on the disk. Save it now? + Datoteka je bila odstranjena z diska. Shranim sedaj? + + + + File has changed on disk. Reload? + Datoteka je bila spremenjena na disku. Ponovno naložim? + + + + + INSERT + VSTAVI + + + + OVERWRITE + PREPIŠI + + + + R/O + S/B + + + + FindBar + + + Find + Najdi + + + + Previous + Nazaj + + + + Next + Naprej + + + + JumpLineBar + + + Go to Line: + Skok na vrstico: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Urejevalnik besedil je močno orodje za pregledovanje in urejanje besedilnih datotek. + + + + Text Editor + Urejevalnik besedil + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Urejevalnik besedil + + + + + + + + + Encoding + Kodiranje + + + + Basic + Osnovno + + + + Font Style + Slog pisave + + + + Font + Pisava + + + + Font Size + Velikost pisave + + + + Shortcuts + Bljižnica + + + + + Keymap + Razpored tipk + + + + + + Window + Okno + + + + New tab + Nov zavihek + + + + New window + Novo okno + + + + Save + ShraniShrani + + + + Save as + Shrani kot + + + + Next tab + Naslednji zavihek + + + + Previous tab + Prejšnji zavihek + + + + Close tab + Zapri zavihek + + + + Close other tabs + Zapri ostale zavihke + + + + Restore tab + Obnovi zavihek + + + + Open file + Odpir datoteko + + + + Increment font size + Povečaj velikost pisave + + + + Decrement font size + Zmanjšaj velikost pisave + + + + Reset font size + Ponastavi velikost pisave + + + + Help + Pomoč + + + + Toggle fullscreen + Preklopi celozaslonski prikaz + + + + Find + Najdi + + + + Replace + Zamenjaj + + + + Go to line + Skok na vrstico + + + + Save cursor position + Shrani položaj kurzorja + + + + Reset cursor position + Ponastavi položaj kurzorja + + + + Exit + Izhod + + + + Display shortcuts + Prikaži bljižnice + + + + Print + Tiskanje + + + + Editor + Urejevalnik + + + + Increase indent + Povečaj zamik + + + + Decrease indent + Zmanjšaj zamik + + + + Forward character + Znak naprej + + + + Backward character + Znak nazaj + + + + Forward word + Besedo naprej + + + + Backward word + Besedo nazaj + + + + Next line + Naslednja vrstica + + + + Previous line + Prejšnja vrstica + + + + New line + Nova vrstica + + + + New line above + Nova vrstica zograj + + + + New line below + Nova vrstica spodaj + + + + Duplicate line + Podvoji vrstico + + + + Delete to end of line + Izbriši do konca vrstice + + + + Delete current line + Izbriši trenutno vrstico + + + + Swap line up + Zamenja vrstico navzgor + + + + Swap line down + Zamenjaj vrstico navzdol + + + + Scroll up one line + Pomakni eno vrstico navzgor + + + + Scroll down one line + Pomakni eno vrstico navzdol + + + + Page up + Prejšnja stran + + + + Page down + Naslednja stran + + + + Move to end of line + Na konec vrstice + + + + Move to start of line + Na začetek vrstice + + + + Move to end of text + Na konec besedila + + + + Move to start of text + Na začetek besedila + + + + Move to line indentation + Na zamik vrstice + + + + Upper case + Velike črke + + + + Lower case + Male črke + + + + Capitalize + Velika začetnica + + + + Delete backward word + Izbriši prejšnjo besedo + + + + Delete forward word + briši naslednjo besedo + + + + Forward over a pair + Naprej preko para + + + + Backward over a pair + Nazaj preko para + + + + Select all + Izberi vse + + + + Copy + Kopiraj + + + + Cut + Izreži + + + + Paste + Prilepi + + + + Transpose character + Spremeni velikost znaka + + + + Mark + Označi + + + + Unmark + Odznači + + + + Copy line + Kopiraj vrstico + + + + Cut line + Izreži vrstico + + + + Merge lines + Združi vrstice + + + + Read-Only mode + Samo branje + + + + Add comment + Dodaj komentar + + + + Remove comment + Odstrani komentar + + + + Undo + razveljavi + + + + Redo + Uveljavi + + + + Add/Remove bookmark + Dodaj/odstrani zaznamek + + + + Move to previous bookmark + Na prejšnji zaznamek + + + + Move to next bookmark + Na naslednji zaznamek + + + + Advanced + Napredno + + + + Window size + Velikost okna + + + + Tab width + Širina zavihka + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Deljenje besed + + + + Code folding flag + Zastavica za zlaganje kode + + + + Show line numbers + Prikaži teilko vrstice + + + + Show bookmarks icon + Prikaži ikone zaznamkov + + + + Show whitespaces and tabs + Prikaži presledke in tabulatorje + + + + Highlight current line + Osvetli trenutno vrstico + + + + Color mark + barvna oznaka + + + + Unicode + Unicode + + + + WesternEuropean + Zahodnoevropski + + + + CentralEuropean + Srednjeevropski + + + + Baltic + Baltik + + + + Cyrillic + Cirilica + + + + Arabic + Arabsko + + + + Celtic + Keltsko + + + + SouthEasternEuropean + JugovzhodnaEvropa + + + + Greek + Grško + + + + Hebrew + Hebrejsko + + + + ChineseSimplified + KitajščinaPoenostavljena + + + + ChineseTraditional + KitajščinaTradicionalna + + + + Japanese + Japonsko + + + + Korean + Korejsko + + + + Thai + Tajsko + + + + Turkish + Turško + + + + Vietnamese + Vietnamsko + + + + File not saved + Datoteka ni bila shranjena + + + + + + Line Endings + Zaključki vrstic + + + + ReplaceBar + + + Find + Najdi + + + + Replace With + Zamenjaj z + + + + Replace + Zamenjaj + + + + Skip + Preskoči + + + + Replace Rest + Zamenjaj ostalo + + + + Replace All + Zamenjaj vse + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standardno + + + + Customize + Prilagodi + + + + Normal + Normalno + + + + Maximum + Maksimalno + + + + Fullscreen + Celozaslonsko + + + + This shortcut conflicts with system shortcut %1 + Ta bljižnica je enaka sistemski bližnjici %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Ta bližnjica je enaka kot %1. Kliknite na Zamenjaj, da jo nemudoma vklopite + + + + + The shortcut %1 is invalid, please set another one. + Bližnjica %1 ni veljavna. Določite drugo. + + + + Cancel + Prekini + + + + Replace + Zamenjaj + + + + OK + V redu + + + + StartManager + + + Untitled %1 + Neimenovano %1 + + + + Tabbar + + + Close tab + Zapri zavihek + + + + Close other tabs + Zapri ostale zavihke + + + + More options + Več možnosti + + + + Close tabs to the left + Zapri zavihke na levi + + + + Close tabs to the right + Zapri zavihke na desni + + + + Close unmodified tabs + Zapri nespremenjene zavihke + + + + TextEdit + + + Undo + razveljavi + + + + Redo + Uveljavi + + + + Cut + Izreži + + + + Copy + Kopiraj + + + + Paste + Prilepi + + + + Delete + Izbriši + + + + Select All + Označi vse + + + + + Find + Najdi + + + + + Replace + Zamenjaj + + + + Go to Line + Skok na vrstico + + + + Turn on Read-Only mode + Vklopi samo branje + + + + Turn off Read-Only mode + Izklopi samo branje + + + + Fullscreen + Celozaslonsko + + + + Exit fullscreen + Zapri celozaslonski način + + + + Display in file manager + Prikaži v upravljalniku datotek + + + + + Add Comment + Dodaj komentar + + + + Text to Speech + Besedilo v govor + + + + Stop reading + Zaustavi branje + + + + Speech to Text + Govor v besedilo + + + + Translate + Prevedi + + + + Column Mode + Stolpčni način + + + + Add bookmark + Dodaj zaznamek + + + + Remove Bookmark + Odstrani zaznamek + + + + Previous bookmark + Prejšnji zaznamek + + + + Next bookmark + Naslednji zaznamek + + + + Remove All Bookmarks + Odstrani vse zaznamke + + + + Fold All + Zloži vse + + + + Fold Current Level + Zloži trenutni nivo + + + + Unfold All + Razpri vse + + + + Unfold Current Level + Razpri trenutni nivo + + + + Color Mark + Barvna oznaka + + + + Clear All Marks + Odstrani vse oznake + + + + Clear Last Mark + Odstrani zadnjo oznako + + + + Mark + Označi + + + + Mark All + Označi vse + + + + Remove Comment + Odstrani komentar + + + + Copy failed: not enough memory + Kopiranje ni uspelo: ni dovolj pomnilnika + + + + Press ALT and click lines to edit in column mode + Pritisnite ALT in kliknite na vrstice za urejanje v stolpcu + + + + Change Case + Spremeni velikost črk + + + + Upper Case + Velike črke + + + + Lower Case + Male črke + + + + Capitalize + Velika začetnica + + + + None + brez + + + + Selected line(s) copied + Izbrane vrstice so bile kopirane + + + + Current line copied + Trenutna vrstica je bila skopirana + + + + Selected line(s) clipped + Izbrane vrstice so bile porezane + + + + Current line clipped + Trenutna vrstica je bila porezana + + + + Paste failed: not enough memory + Kopiranje ni uspelo: ni dovolj pomnilnika + + + + Read-Only mode is off + Samo branje je izklopljeno + + + + + + Read-Only mode is on + Vklopljeno je samo branje + + + + WarningNotices + + + Reload + Ponovno naloži + + + + Window + + + + Save as + Shrani kot + + + + New window + Novo okno + + + + New tab + Nov zavihek + + + + Open file + Odpir datoteko + + + + + Save + Shrani + + + + Print + Tiskanje + + + + Switch theme + Zamenjaj temo + + + + + Settings + nastavitve + + + + + Read-Only + Samo branje + + + + You do not have permission to open %1 + Nimate pravic za odpiranje %1 + + + + Invalid file: %1 + Napačna datoteka: %1 + + + + + Do you want to save this file? + Bi radi shranili to datoteko? + + + + You do not have permission to save %1 + Nimate pravic za shranjevanje %1 + + + + Saved successfully + Uspešno shranjeno + + + + + + Save File + Shrani datoteko + + + + Encoding + Kodiranje + + + + Read-Only mode is on + Vklopljeno je samo branje + + + + Current location remembered + Trenutni položaj je shranjen + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Urejevalnik + + + + Untitled %1 + Neimenovano %1 + + + + Cancel + Prekini + + + + Discard + Opusti + + + \ No newline at end of file diff --git a/translations/deepin-editor_sq.ts b/translations/deepin-editor_sq.ts new file mode 100644 index 0000000000000000000000000000000000000000..20d52fcdeb11114088cd4044b1e195686eff7083 --- /dev/null +++ b/translations/deepin-editor_sq.ts @@ -0,0 +1,1296 @@ + + + BottomBar + + + Row + Rresht + + + + Column + Shtyllë + + + + Characters %1 + Shenja %1 + + + + Loading: + Po ngarkohet: + + + + DDropdownMenu + + + + + None + Asnjë + + + + EditWrapper + + + + + + Save + Ruaje + + + + Do you want to save this file? + Doni të ruhet kjo kartelë? + + + + + Cancel + Anuloje + + + + Encoding changed. Do you want to save the file now? + Kodimi ndryshoi. Doni të ruhet kartela tani? + + + + Discard + Hidhe Tej + + + + You do not have permission to save %1 + S’keni leje të ruani %1 + + + + File removed on the disk. Save it now? + Kartela u hoq nga disku. Të ruhet tani? + + + + File has changed on disk. Reload? + Kartela ka ndryshuar në disk. Të ringarkohet? + + + + + INSERT + FUTE + + + + OVERWRITE + MBISHKRUAJE + + + + R/O + + + + + The file cannot be read, which may be too large or has been damaged! + Kartela s’mund të lexohet, ngaqë mund të jetë shumë e madhe, ose është dëmtuar! + + + + FindBar + + + Find + Gjej + + + + Previous + E mëparshmja + + + + Next + Pasuesja + + + + JumpLineBar + + + Go to Line: + Shko te Rreshti: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Përpunuesi i Teksteve është një mjet i fuqishëm për parje dhe përpunim kartelash tekst. + + + + Text Editor + Përpunues Tekstesh + + + + PathSettingWgt + + + Remember the last used path + Mbaj mend shtegun e përdorur së fundi + + + + Same path as the current file + I njëjti shteg me kartelën e tanishme + + + + Customize the default path + Përshtatni shtegun parazgjedhje + + + + QObject + + + Text Editor + Përpunues Tekstesh + + + + + + + + + Encoding + Kodim + + + + Basic + Elementare + + + + Font Style + Stil Shkronjash + + + + Font + Shkronja + + + + Font Size + Madhësi Shkronjash + + + + Shortcuts + Shkurtore + + + + + Keymap + Skemë tastiere + + + + + + Window + Dritare + + + + New tab + Skedë e re + + + + New window + Dritare e re + + + + Save + Ruaje + + + + Save as + Ruaje si + + + + Next tab + Skeda pasuese + + + + Previous tab + Skeda e mëparshme + + + + Close tab + Mbylle skedën + + + + Close other tabs + Mbylli skedat e tjera + + + + Restore tab + Riktheje skedën + + + + Open file + Hap kartelë + + + + Increment font size + Rritje madhësie shkronjash + + + + Decrement font size + Zvogëlim madhësie shkronjash + + + + Reset font size + Ktheje madhësinë e shkronjave te parazgjedhja + + + + Help + Ndihmë + + + + Toggle fullscreen + Aktivizo/Çaktivizo mënyrën “sa krejt ekrani” + + + + Find + Gjej + + + + Replace + Zëvendësoje + + + + Go to line + Shko te rreshti + + + + Save cursor position + Ruaj pozicionin e kursorit + + + + Reset cursor position + Zero pozicionin e kursorit + + + + Exit + Dil + + + + Display shortcuts + Shfaq shkurtore + + + + Print + Shtype + + + + Editor + Përpunues + + + + Increase indent + Rrit hapësirë kryeradhe + + + + Decrease indent + Zvogëlo hapësirë kryeradhe + + + + Forward character + + + + + Backward character + + + + + Forward word + Fjala përpara + + + + Backward word + Fjala prapa + + + + Next line + Rreshti pasues + + + + Previous line + Rreshti i mëparshëm + + + + New line + Rresht i ri + + + + New line above + Rresht i ri sipër + + + + New line below + Rresht i ri poshtë + + + + Duplicate line + Përsëdyte rreshtin + + + + Delete to end of line + Fshije deri në fund të rreshtit + + + + Delete current line + Fshi rreshtin e tanishëm + + + + Swap line up + Këmbeje me rreshtin sipër + + + + Swap line down + Këmbeje me rreshtin poshtë + + + + Scroll up one line + Ngjitu një rresht më sipër + + + + Scroll down one line + Zbrit një rresht më poshtë + + + + Page up + Një faqe sipër + + + + Page down + Një faqe poshtë + + + + Move to end of line + Kalo te fund rreshti + + + + Move to start of line + Kalo në fillim rreshti + + + + Move to end of text + Kalo në fund të tekstit + + + + Move to start of text + Kalo në fillim të tekstit + + + + Move to line indentation + Kalo te kryeradhë rreshti + + + + Upper case + Shkronja të mëdha + + + + Lower case + Shkronja të vogla + + + + Capitalize + Kaloje Në Shkronjë të Madhe + + + + Delete backward word + Fshi fjalën prapa + + + + Delete forward word + Fshi fjalën përpara + + + + Forward over a pair + Përpara tej një dysheje + + + + Backward over a pair + Mbrapsht tej një dysheje + + + + Select all + Përzgjidhe krejt + + + + Copy + Kopjoje + + + + Cut + Prije + + + + Paste + Ngjite + + + + Transpose character + Ndërkëmbe shenjën + + + + Mark + Vëri shenjë + + + + Unmark + Hiqja shenjën + + + + Copy line + Kopjo rreshtin + + + + Cut line + Prije rreshtin + + + + Merge lines + Përzje rreshta + + + + Read-Only mode + Mënyrë “Vetëm Për Lexim” + + + + Add comment + Shtoni koment + + + + Remove comment + Hiqe komentin + + + + Undo + Zhbëje + + + + Redo + Ribëje + + + + Add/Remove bookmark + Shtoni/Hiqni faqerojtës + + + + Move to previous bookmark + Kalo te faqerojtësi i mëparshëm + + + + Move to next bookmark + Kalo te faqerojtësi pasues + + + + Advanced + Të mëtejshme + + + + Window size + Madhësi dritareje + + + + Tab width + Gjerësi tabulacioni + + + + Paste by pressing a middle mouse button + Ngjiteni duke shtypur butonin e mesit të miut + + + + Startup + + + + + Reopen last closed tabs + Rihap skedat e mbyllura në fund + + + + Open/Save Settings + Hapni/Ruani Rregullimet + + + + Word wrap + Mbështjellje fjale + + + + Code folding flag + Shenjë për mbështjellje kodi + + + + Show line numbers + Shfaq numra rreshtash + + + + Show bookmarks icon + Shfaq ikonë faqerojtësish + + + + Show whitespaces and tabs + Shfaq hapësira të zbrazëta dhe tabulacione + + + + Highlight current line + Thekso rreshtin e tanishëm + + + + Color mark + Shenjë ngjyre + + + + Unicode + Unikod + + + + WesternEuropean + Evropiane Perëndimore + + + + CentralEuropean + Evropiane Qendrore + + + + Baltic + Baltike + + + + Cyrillic + Cirilike + + + + Arabic + Arabe + + + + Celtic + Kelte + + + + SouthEasternEuropean + Evropiane Juglindore + + + + Greek + Greke + + + + Hebrew + Hebraishte + + + + ChineseSimplified + Kineze të Thjeshtuara + + + + ChineseTraditional + Kineze Tradicionale + + + + Japanese + Japoneze + + + + Korean + Koreane + + + + Thai + Tajlandeze + + + + Turkish + Turke + + + + Vietnamese + Vietnameze + + + + File not saved + Kartela s’u ruajt + + + + + + Line Endings + Funde Rreshtash + + + + ReplaceBar + + + Find + Gjej + + + + Replace With + Zëvendësoje Me + + + + Replace + Zëvendësoje + + + + Skip + Anashkaloje + + + + Replace Rest + + + + + Replace All + Zëvendësoji Krejt + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standarde + + + + Customize + Përshtateni + + + + Normal + Normale + + + + Maximum + Maksimum + + + + Fullscreen + Sa krejt ekrani + + + + This shortcut conflicts with system shortcut %1 + Kjo shkurtore përplaset me shkurtoren e sistemit %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Kjo shkurtore përplaset me %1, klikoni mbi “Zëvendësoje” për ta bërë këtë shkurtore të hyjë në fuqi menjëherë + + + + + + The shortcut %1 is invalid, please set another one. + Shkurtorja %1 është e pavlefshme, ju lutemi, caktoni një tjetër. + + + + Cancel + Anuloje + + + + Replace + Zëvendësoje + + + + OK + OK + + + + StartManager + + + Untitled %1 + %1 pa titull + + + + Tabbar + + + Close tab + Mbylle skedën + + + + Close other tabs + Mbylli skedat e tjera + + + + More options + Më tepër mundësi + + + + Close tabs to the left + Mbylli skedat në të majtë + + + + Close tabs to the right + Mbylli skedat në të djathtë + + + + Close unmodified tabs + Mbylli skedat e paprekura + + + + TextEdit + + + Undo + Zhbëje + + + + Redo + Ribëje + + + + Cut + Prije + + + + Copy + Kopjoje + + + + Paste + Ngjite + + + + Delete + Fshije + + + + Select All + Përzgjidhi Krejt + + + + + Find + Gjej + + + + + Replace + Zëvendësoje + + + + Go to Line + Shko te Rreshti + + + + Turn on Read-Only mode + Aktivizo mënyrën “Vetëm Për Lexim” + + + + Turn off Read-Only mode + Çaktivizo mënyrën “Vetëm Për Lexim” + + + + Fullscreen + Sa krejt ekrani + + + + Exit fullscreen + Dil nga mënyra sa krejt ekrani + + + + Display in file manager + Shfaqe në përgjegjës kartelash + + + + + Add Comment + Shtoni Koment + + + + Text to Speech + Nga Tekst Në të Folur + + + + Stop reading + Ndale leximin + + + + Speech to Text + Nga e Folur Në Tekst + + + + Translate + Përkthejeni + + + + Column Mode + Mënyrë Shtylla + + + + Add bookmark + Shtoni faqerojtës + + + + Remove Bookmark + Hiqe Faqerojtësin + + + + Previous bookmark + Faqerojtësi i mëparshëm + + + + Next bookmark + Faqerojtësi pasues + + + + Remove All Bookmarks + Hiqi Krejt Faqerojtësit + + + + Fold All + Palosi Krejt + + + + Fold Current Level + Palos Nivelin e Tanishëm + + + + Unfold All + Shpalosi Krejt + + + + Unfold Current Level + Shpalos Nivelin e Tanishëm + + + + Color Mark + Shenjë Ngjyre + + + + Clear All Marks + Hiqi Krejt Shenjat + + + + Clear Last Mark + Spastro Shenjën e Fundit + + + + Mark + Vëri shenjë + + + + Mark All + Vëru Shenjë të Tërëve + + + + Remove Comment + Hiqe Komentin + + + + Copy failed: not enough memory + Kopjimi dështoi: s’ka kujtesë të mjaftueshme + + + + Press ALT and click lines to edit in column mode + Shtypni tastin ALT dhe klikoni mbi rreshtat që të përpunohen nën mënyrën shtyllë + + + + Change Case + Ndryshoni Shkronjë të Madhe/të Vogël + + + + Upper Case + Kaloje në Shkronja të Mëdha + + + + Lower Case + Shkronja të Vogla + + + + Capitalize + Kaloje Në Shkronjë të Madhe + + + + None + Asnjë + + + + Selected line(s) copied + U kopjua rreshti(at) i përzgjedhur + + + + Current line copied + U kopjua rreshti i tanishëm + + + + Selected line(s) clipped + Rreshti(at) i përzgjedhur u qeth + + + + Current line clipped + Rreshti i tanishëm u qeth + + + + Paste failed: not enough memory + Ngjitja dështoi: kujtesë e pamjaftueshme + + + + Read-Only mode is off + Mënyra “Vetëm Për Lexim” është e çaktivizuar + + + + + + + + + Read-Only mode is on + Mënyra “Vetëm Për Lexim” është e aktivizuar + + + + WarningNotices + + + Reload + Ringarkoje + + + + Window + + + + Save as + Ruaje si + + + + New window + Dritare e re + + + + New tab + Skedë e re + + + + Open file + Hap kartelë + + + + + Save + Ruaje + + + + Print + Shtype + + + + Switch theme + Këmbeni temë + + + + + Settings + Rregullime + + + + + Read-Only + Vetëm-Lexim + + + + You do not have permission to open %1 + S’keni leje të hapni %1 + + + + + Invalid file: %1 + Kartelë e pavlefshme: %1 + + + + + Do you want to save this file? + Doni të ruhet kjo kartelë? + + + + You do not have permission to save %1 + S’keni leje të ruani %1 + + + + Saved successfully + U ruajt me sukses + + + + + + Save File + Ruaje Kartelën + + + + Encoding + Kodim + + + + Read-Only mode is on + Mënyra “Vetëm Për Lexim” është e aktivizuar + + + + Current location remembered + Vendi i tanishëm u mbajt mend + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Përpunues + + + + Untitled %1 + %1 pa titull + + + + Cancel + Anuloje + + + + Discard + Hidhe Tej + + + \ No newline at end of file diff --git a/translations/deepin-editor_sr.ts b/translations/deepin-editor_sr.ts new file mode 100644 index 0000000000000000000000000000000000000000..52c6b30b114c29c60b125358715e421efb990ea1 --- /dev/null +++ b/translations/deepin-editor_sr.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Ред + + + + Column + Колона + + + + Characters %1 + Карактера %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + Ништа + + + + EditWrapper + + + + + + Save + Сачувај + + + + Do you want to save this file? + Желите ли да сачувате ову датотеку? + + + + + Cancel + Откажи + + + + Encoding changed. Do you want to save the file now? + Промењено кодирање. Желите ли да сачувате датотеку сад? + + + + Discard + Одбаци + + + + You do not have permission to save %1 + Немате дозволу да сачувате %1 + + + + File removed on the disk. Save it now? + Датотека је уклоњена са диска. Сачувајте је сад? + + + + File has changed on disk. Reload? + Датотека је промењена на диску. Поново учитати? + + + + + INSERT + УМЕТНИ + + + + OVERWRITE + ПРЕПИШИ + + + + R/O + С/Ч + + + + FindBar + + + Find + Тражи + + + + Previous + Претходно + + + + Next + Следеће + + + + JumpLineBar + + + Go to Line: + Иди на ред: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Уређивач Текста је моћан алат за приказ и уређивање текстуалних датотека. + + + + Text Editor + Уређивач текста + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Уређивач текста + + + + + + + + + Encoding + Кодирање + + + + Basic + Основно + + + + Font Style + Стил фонта + + + + Font + Фонт + + + + Font Size + Величина фонта + + + + Shortcuts + Пречице + + + + + Keymap + Мапа тастера + + + + + + Window + Прозор + + + + New tab + Нова картица + + + + New window + Нови прозор + + + + Save + Сачувај + + + + Save as + Сачувај као + + + + Next tab + Следећа картица + + + + Previous tab + Претходна картица + + + + Close tab + Затвори картицу + + + + Close other tabs + Затвори остале картице + + + + Restore tab + Обнови картицу + + + + Open file + Отвори датотеку + + + + Increment font size + Повећај величину фонта + + + + Decrement font size + Смањи величину фонта + + + + Reset font size + Врати величину фонта + + + + Help + Помоћ + + + + Toggle fullscreen + Цео екран + + + + Find + Тражи + + + + Replace + Замени + + + + Go to line + Иди на ред + + + + Save cursor position + Сачувај позицију показивача + + + + Reset cursor position + Врати позицију показивача + + + + Exit + Изађи + + + + Display shortcuts + Прикажи пречице + + + + Print + Штампај + + + + Editor + Уређивач + + + + Increase indent + Повећај увученост + + + + Decrease indent + Смањи увученост + + + + Forward character + Карактер унапред + + + + Backward character + Карактер уназад + + + + Forward word + Реч унапред + + + + Backward word + Реч уназад + + + + Next line + Следећи ред + + + + Previous line + Претходни ред + + + + New line + Нови ред + + + + New line above + Нови ред изнад + + + + New line below + Нови ред испод + + + + Duplicate line + Удвостручи ред + + + + Delete to end of line + Обриши до краја реда + + + + Delete current line + Обриши тренутни ред + + + + Swap line up + Замени са редом изнад + + + + Swap line down + Замени са редом испод + + + + Scroll up one line + Клизај један ред горе + + + + Scroll down one line + Клизај један ред доле + + + + Page up + Страница нагоре + + + + Page down + Страница надоле + + + + Move to end of line + Иди на крај реда + + + + Move to start of line + Иди на почетак реда + + + + Move to end of text + Иди на крај текста + + + + Move to start of text + Иди на почетак текста + + + + Move to line indentation + Помери до увучености реда + + + + Upper case + Велика слова + + + + Lower case + Мала слова + + + + Capitalize + Почетна велика + + + + Delete backward word + Брисање речи уназад + + + + Delete forward word + Брисање речи унапред + + + + Forward over a pair + Напред преко пара + + + + Backward over a pair + Назад преко пара + + + + Select all + Изабери све + + + + Copy + Копирај + + + + Cut + Исеци + + + + Paste + Убаци + + + + Transpose character + Ротирај карактере + + + + Mark + Истакни + + + + Unmark + Уклони истицање + + + + Copy line + Копирај ред + + + + Cut line + Исеци ред + + + + Merge lines + Сједини редове + + + + Read-Only mode + Режим Само-Читање + + + + Add comment + Додај коментар + + + + Remove comment + Уклони коментар + + + + Undo + Опозови + + + + Redo + Обнови + + + + Add/Remove bookmark + Додај/Уклони забелешку + + + + Move to previous bookmark + Иди на претходну забелешку + + + + Move to next bookmark + Иди на следећу забелешку + + + + Advanced + Напредно + + + + Window size + Величина прозора + + + + Tab width + Ширина табулатора + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Преламање редова + + + + Code folding flag + Назнака скупљеног кода + + + + Show line numbers + Прикажи бројеве редова + + + + Show bookmarks icon + Прикажи иконице забелешки + + + + Show whitespaces and tabs + Прикажи белине и табулаторе + + + + Highlight current line + Истакни тренутни ред + + + + Color mark + Истицање у боји + + + + Unicode + Unicode + + + + WesternEuropean + Западноевропски + + + + CentralEuropean + Централноевропски + + + + Baltic + Балтички + + + + Cyrillic + Ћирилични + + + + Arabic + Арапски + + + + Celtic + Келтски + + + + SouthEasternEuropean + Југоисточно-европски + + + + Greek + Грчки + + + + Hebrew + Хебрејски + + + + ChineseSimplified + Поједностављени кинески + + + + ChineseTraditional + Традиционални кински + + + + Japanese + Јапански + + + + Korean + Корејски + + + + Thai + Тајландски + + + + Turkish + Турски + + + + Vietnamese + Вијетнамски + + + + File not saved + Датотека није сачувана + + + + + + Line Endings + Крајеви редова + + + + ReplaceBar + + + Find + Тражи + + + + Replace With + Замени са + + + + Replace + Замени + + + + Skip + Прескочи + + + + Replace Rest + Замени остатак + + + + Replace All + Замени све + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Стандардно + + + + Customize + Прилагоди + + + + Normal + Нормална + + + + Maximum + Максимум + + + + Fullscreen + Цео екран + + + + This shortcut conflicts with system shortcut %1 + Ова пречица је у сукобу са системском пречицом %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Ова пречица је у сукобу са %1, кликните на Замени да пречица одмах ступи на снагу + + + + + The shortcut %1 is invalid, please set another one. + Пречица %1 је неважећа, поставите другу. + + + + Cancel + Откажи + + + + Replace + Замени + + + + OK + У реду + + + + StartManager + + + Untitled %1 + Ненасловњено %1 + + + + Tabbar + + + Close tab + Затвори картицу + + + + Close other tabs + Затвори остале картице + + + + More options + Више опција + + + + Close tabs to the left + Затвори леве картице + + + + Close tabs to the right + Затвори десне картице + + + + Close unmodified tabs + Затвори непромењене картице + + + + TextEdit + + + Undo + Опозови + + + + Redo + Обнови + + + + Cut + Исеци + + + + Copy + Копирај + + + + Paste + Убаци + + + + Delete + Обриши + + + + Select All + Изабери све + + + + + Find + Тражи + + + + + Replace + Замени + + + + Go to Line + Иди на ред + + + + Turn on Read-Only mode + Укључи режим Само-Читање + + + + Turn off Read-Only mode + Искључи режим Само-Читање + + + + Fullscreen + Цео екран + + + + Exit fullscreen + Напусти цео екран + + + + Display in file manager + Прикажи у управнику података + + + + + Add Comment + Додај коментар + + + + Text to Speech + Текст у говор + + + + Stop reading + Заустави читање + + + + Speech to Text + Говор у текст + + + + Translate + Преведи + + + + Column Mode + Режим колона + + + + Add bookmark + Додај забелешку + + + + Remove Bookmark + Уклони забелешку + + + + Previous bookmark + Претходна забелешка + + + + Next bookmark + Следећа забелешка + + + + Remove All Bookmarks + Уклони све забелешке + + + + Fold All + Скупи све + + + + Fold Current Level + Скупи тренутни ниво + + + + Unfold All + Рашири све + + + + Unfold Current Level + Рашири тренутни ниво + + + + Color Mark + Истицање у боји + + + + Clear All Marks + Уклони сва истицања + + + + Clear Last Mark + Уклони последње истицање + + + + Mark + Обележи + + + + Mark All + Обележи све + + + + Remove Comment + Уклони коментар + + + + Copy failed: not enough memory + + + + + Press ALT and click lines to edit in column mode + Притисните ALT и кликните на редове да уредите у режиму колона + + + + Change Case + Промени величину слова + + + + Upper Case + Велика слова + + + + Lower Case + Мала слова + + + + Capitalize + Почетна велика + + + + None + Ништа + + + + Selected line(s) copied + Изабрани редови копирани + + + + Current line copied + Тренутни ред копиран + + + + Selected line(s) clipped + Изабрани редови копирани + + + + Current line clipped + Тренутни ред копиран + + + + Paste failed: not enough memory + + + + + Read-Only mode is off + Режим Само-Читање је искључен + + + + + + Read-Only mode is on + Режим Само-Читање је укључен + + + + WarningNotices + + + Reload + Поново учитај + + + + Window + + + + Save as + Сачувај као + + + + New window + Нови прозор + + + + New tab + Нова картица + + + + Open file + Отвори датотеку + + + + + Save + Сачувај + + + + Print + Штампај + + + + Switch theme + Промени тему + + + + + Settings + Подешавања + + + + + Read-Only + Само-Чтање + + + + You do not have permission to open %1 + Немате дозволу да отворите %1 + + + + Invalid file: %1 + Неважећа датотека: %1 + + + + + Do you want to save this file? + Да ли желите да сачувате ову датотеку? + + + + You do not have permission to save %1 + Немате дозволу да сачувате %1 + + + + Saved successfully + Успешно сачувано + + + + + + Save File + Сачувај датотеку + + + + Encoding + Кодирање + + + + Read-Only mode is on + Режим Само-Читање је укључен + + + + Current location remembered + Тренутна локација запамћена + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Уређивач + + + + Untitled %1 + Ненасловњено %1 + + + + Cancel + Откажи + + + + Discard + Одбаци + + + \ No newline at end of file diff --git a/translations/deepin-editor_tr.ts b/translations/deepin-editor_tr.ts new file mode 100644 index 0000000000000000000000000000000000000000..7bd8f92f14cee4fb7527222cfe003cb296508d50 --- /dev/null +++ b/translations/deepin-editor_tr.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Satır + + + + Column + Sütun + + + + Characters %1 + %1 Karakter + + + + Loading: + + + + + DDropdownMenu + + + + + None + Yok + + + + EditWrapper + + + + + + Save + Kaydet + + + + Do you want to save this file? + Bu dosyayı kaydetmek ister misiniz? + + + + + Cancel + İptal + + + + Encoding changed. Do you want to save the file now? + Kodlama değişti. Dosyayı şimdi kaydetmek istiyor musunuz? + + + + Discard + Yoksay + + + + You do not have permission to save %1 + %1 dosyasını kaydetme izniniz yok + + + + File removed on the disk. Save it now? + Dosya diskten silinmiş. Şimdi kaydetmek ister misiniz? + + + + File has changed on disk. Reload? + Disk üzerindeki dosya değişmiş. Yeniden yüklensin mi? + + + + + INSERT + EKLE + + + + OVERWRITE + ÜZERİNE YAZ + + + + R/O + S/O + + + + FindBar + + + Find + Bul + + + + Previous + Önceki + + + + Next + Sonraki + + + + JumpLineBar + + + Go to Line: + Şu Satıra Git: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Metin Düzenleyici, metni görüntülemek ve düzenlemek için güçlü bir araçtır. + + + + Text Editor + Metin Düzenleyici + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + Metin Düzenleyici + + + + + + + + + Encoding + Kodlama + + + + Basic + Temel + + + + Font Style + Yazı Tipi Biçimi + + + + Font + Yazı Tipi + + + + Font Size + Yazı Tipi Boyutu + + + + Shortcuts + Kısayollar + + + + + Keymap + Tuş Eşleşmesi + + + + + + Window + Pencere + + + + New tab + Yeni sekme + + + + New window + Yeni pencere + + + + Save + Kaydet + + + + Save as + Farklı kaydet + + + + Next tab + Sonraki sekme + + + + Previous tab + Önceki sekme + + + + Close tab + Sekmeyi kapat + + + + Close other tabs + Diğer sekmeleri kapat + + + + Restore tab + Sekmeyi geri yükle + + + + Open file + Dosya aç + + + + Increment font size + Yazı boyutunu büyüt + + + + Decrement font size + Yazı boyutunu küçült + + + + Reset font size + Yazı tipi boyutunu sıfırla + + + + Help + Yardım + + + + Toggle fullscreen + Tam ekranı aç/kapat + + + + Find + Bul + + + + Replace + Değiştir + + + + Go to line + Şu satıra git + + + + Save cursor position + İmleç konumunu kaydet + + + + Reset cursor position + İmleç konumunu sıfırla + + + + Exit + Çıkış + + + + Display shortcuts + Kısayolları görüntüle + + + + Print + Yazdır + + + + Editor + Düzenleyici + + + + Increase indent + Girinti düzeyini arttır + + + + Decrease indent + Girinti düzeyini azalt + + + + Forward character + Sonraki karakter + + + + Backward character + Önceki karakter + + + + Forward word + Sonraki sözcük + + + + Backward word + Önceki sözcük + + + + Next line + Sonraki satır + + + + Previous line + Önceki satır + + + + New line + Yeni satır + + + + New line above + Üste yeni satır + + + + New line below + Alta yeni satır + + + + Duplicate line + Yinelenen satır + + + + Delete to end of line + Satır sonuna kadar sil + + + + Delete current line + Mevcut satırı sil + + + + Swap line up + Üstteki satır ile değiştir + + + + Swap line down + Alttaki satır ile değiştir + + + + Scroll up one line + Bir satır yukarı kaydır + + + + Scroll down one line + Bir satır aşağı kaydır + + + + Page up + Sayfa üstü + + + + Page down + Sayfa altı + + + + Move to end of line + Satır sonuna git + + + + Move to start of line + Satır başına git + + + + Move to end of text + Metnin sonuna git + + + + Move to start of text + Metnin başına git + + + + Move to line indentation + Satır girintisine git + + + + Upper case + Büyük harf + + + + Lower case + Küçük harf + + + + Capitalize + İlk harfleri büyüt + + + + Delete backward word + Önceki sözcüğü sil + + + + Delete forward word + Sonraki sözcüğü sil + + + + Forward over a pair + Sonraki çift + + + + Backward over a pair + Önceki çift + + + + Select all + Tümünü seç + + + + Copy + Kopyala + + + + Cut + Kes + + + + Paste + Yapıştır + + + + Transpose character + Karakteri dönüştür + + + + Mark + İşaretle + + + + Unmark + İşareti kaldır + + + + Copy line + Satırı kopyala + + + + Cut line + Satırı kes + + + + Merge lines + Satırları birleştir + + + + Read-Only mode + Salt okunur kip + + + + Add comment + Yorum ekle + + + + Remove comment + Yorumu kaldır + + + + Undo + Geri al + + + + Redo + Yinele + + + + Add/Remove bookmark + Yer imi Ekle/Kaldır + + + + Move to previous bookmark + Önceki yer imine git + + + + Move to next bookmark + Sonraki yer imine git + + + + Advanced + Gelişmiş + + + + Window size + Pencere boyutu + + + + Tab width + Sekme genişliği + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + Sözcük kaydır + + + + Code folding flag + Kod katlama bayrağı + + + + Show line numbers + Satır numaralarını göster + + + + Show bookmarks icon + Yer imi simgesini göster + + + + Show whitespaces and tabs + Boşluk ve sekmeleri göster + + + + Highlight current line + Mevcut satırı vurgula + + + + Color mark + Renk işareti + + + + Unicode + Unicode + + + + WesternEuropean + WesternEuropean + + + + CentralEuropean + CentralEuropean + + + + Baltic + Baltic + + + + Cyrillic + Cyrillic + + + + Arabic + Arabic + + + + Celtic + Celtic + + + + SouthEasternEuropean + SouthEasternEuropean + + + + Greek + Greek + + + + Hebrew + Hebrew + + + + ChineseSimplified + ChineseSimplified + + + + ChineseTraditional + ChineseTraditional + + + + Japanese + Japonca + + + + Korean + Korece + + + + Thai + Tayca + + + + Turkish + Türkçe + + + + Vietnamese + Vietnamca + + + + File not saved + Dosya kaydedilmedi + + + + + + Line Endings + Satır Sonları + + + + ReplaceBar + + + Find + Bul + + + + Replace With + Şununla Değiştir + + + + Replace + Değiştir + + + + Skip + Atla + + + + Replace Rest + Kalanları Değiştir + + + + Replace All + Tümünü Değiştir + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Standart + + + + Customize + Özelleştir + + + + Normal + Normal + + + + Maximum + En fazla + + + + Fullscreen + Tam ekran + + + + This shortcut conflicts with system shortcut %1 + Bu kısayol, %1 sistem kısayolu ile çakışıyor + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Bu kısayol %1 ile çakışıyor, bu kısayolu hemen etkin hale getirmek için Değiştire tıklayın + + + + + The shortcut %1 is invalid, please set another one. + %1 kısayolu geçersiz, lütfen başka bir tane ayarlayın. + + + + Cancel + İptal + + + + Replace + Değiştir + + + + OK + Tamam + + + + StartManager + + + Untitled %1 + Başlıksız %1 + + + + Tabbar + + + Close tab + Sekmeyi kapat + + + + Close other tabs + Diğer sekmeleri kapat + + + + More options + Daha fazla seçenek + + + + Close tabs to the left + Soldaki sekmeleri kapat + + + + Close tabs to the right + Sağdaki sekmeleri kapat + + + + Close unmodified tabs + Değiştirilmemiş sekmeleri kapat + + + + TextEdit + + + Undo + Geri al + + + + Redo + Yinele + + + + Cut + Kes + + + + Copy + Kopyala + + + + Paste + Yapıştır + + + + Delete + Sil + + + + Select All + Tümünü Seç + + + + + Find + Bul + + + + + Replace + Değiştir + + + + Go to Line + Şu Satıra Git + + + + Turn on Read-Only mode + Salt Okunur Kipi Aç + + + + Turn off Read-Only mode + Salt Okunur Kipi Kapat + + + + Fullscreen + Tam ekran + + + + Exit fullscreen + Tam ekrandan çık + + + + Display in file manager + Dosya yöneticisinde görüntüle + + + + + Add Comment + Yorum Ekle + + + + Text to Speech + Yazıdan Konuşmaya + + + + Stop reading + Okumayı durdur + + + + Speech to Text + Konuşmadan Yazıya + + + + Translate + Çeviri + + + + Column Mode + Sütun Kipi + + + + Add bookmark + Yer imlerine ekle + + + + Remove Bookmark + Yer İmini Kaldır + + + + Previous bookmark + Önceki yer imi + + + + Next bookmark + Sonraki yer imi + + + + Remove All Bookmarks + Tüm Yer İmlerini Kaldır + + + + Fold All + Tümünü Katla + + + + Fold Current Level + Mevcut Seviyeyi Katla + + + + Unfold All + Tümünü Katlama + + + + Unfold Current Level + Mevcut Seviyeyi Katlama + + + + Color Mark + Renk İşareti + + + + Clear All Marks + Tüm İşaretleri Temizle + + + + Clear Last Mark + Son İşareti Temizle + + + + Mark + İşaretle + + + + Mark All + Tümünü İşaretle + + + + Remove Comment + Yorumu Kaldır + + + + Copy failed: not enough memory + Kopyalama başarısız: yeterli bellek yok + + + + Press ALT and click lines to edit in column mode + Sütun kipinde düzenlemek için ALT tuşuna bas ve satırları tıkla + + + + Change Case + Büyük Küçük Harfi Değiştir + + + + Upper Case + Büyük Harf + + + + Lower Case + Küçük Harf + + + + Capitalize + İlk Harfleri Büyüt + + + + None + Yok + + + + Selected line(s) copied + Seçilen satır(lar) kopyalandı + + + + Current line copied + Mevcut satır kopyalandı + + + + Selected line(s) clipped + Seçilen satır(lar) kırpıldı + + + + Current line clipped + Mevcut satır kopyalandı + + + + Paste failed: not enough memory + Yapıştırılamadı: yeterli bellek yok + + + + Read-Only mode is off + Salt okunur kip kapalı + + + + + + Read-Only mode is on + Salt okunur kip açık + + + + WarningNotices + + + Reload + Yeniden yükle + + + + Window + + + + Save as + Farklı kaydet + + + + New window + Yeni pencere + + + + New tab + Yeni sekme + + + + Open file + Dosya aç + + + + + Save + Kaydet + + + + Print + Yazdır + + + + Switch theme + Temayı değiştir + + + + + Settings + Ayarlar + + + + + Read-Only + Salt Okunur + + + + You do not have permission to open %1 + %1 dosyasını açma izniniz yok + + + + Invalid file: %1 + Geçersiz dosya: %1 + + + + + Do you want to save this file? + Bu dosyayı kaydetmek ister misiniz? + + + + You do not have permission to save %1 + %1 dosyasını kaydetme izniniz yok + + + + Saved successfully + Başarıyla kaydedildi + + + + + + Save File + Dosyayı Kaydet + + + + Encoding + Kodlama + + + + Read-Only mode is on + Salt okunur kip açık + + + + Current location remembered + Mevcut konum hatırlandı + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Düzenleyici + + + + Untitled %1 + Başlıksız %1 + + + + Cancel + İptal + + + + Discard + Yoksay + + + \ No newline at end of file diff --git a/translations/deepin-editor_ug.ts b/translations/deepin-editor_ug.ts new file mode 100644 index 0000000000000000000000000000000000000000..e490c2617a1988eecc5532ba5c23aca646a3a447 --- /dev/null +++ b/translations/deepin-editor_ug.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + قۇر + + + + Column + قاتار + + + + Characters %1 + ھەرپ-بەلگە سانى %1 + + + + Loading: + + + + + DDropdownMenu + + + + + None + يوق + + + + EditWrapper + + + + + + Save + ساقلاش + + + + Do you want to save this file? + بۇ ھۆججەتنى ساقلامسىز؟ + + + + + Cancel + بىكار قىلىش + + + + Encoding changed. Do you want to save the file now? + ھۆججەت كودلاش ئۇسۇلى ئۆزگەرتىلدى، ئۇنى ئاۋۋال ساقلىماقچىمۇ؟ + + + + Discard + ساقلىمايمەن + + + + You do not have permission to save %1 + %1نى ساقلاش ھوقۇقىڭىز يوق + + + + File removed on the disk. Save it now? + دىسكىدىكى ئەسلى ھۆججەت ئۆچۈرۈلدى، قايتا ساقلىماقچىمۇ؟ + + + + File has changed on disk. Reload? + دىسكىدىكى ئەسلى ھۆججەت ئۆزگەرتىلدى، قايتا يۈكلىمەكچىمۇ؟ + + + + + INSERT + كىرگۈزۈش + + + + OVERWRITE + باستۇرۇش + + + + R/O + پەقەت ئوقۇش + + + + FindBar + + + Find + ئىزدەش + + + + Previous + ئالدىنقىسى + + + + Next + كېيىنكىسى + + + + JumpLineBar + + + Go to Line: + سەكرەش: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + تېكىست تەھرىرلىگۈچ تېكىست ھۆججەتلىرىنى كۆرۈش ۋە تەھرىرلەش قورالىدۇر. + + + + Text Editor + تېكىست تەھرىرلىگۈچ + + + + PathSettingWgt + + + Remember the last used path + + + + + Same path as the current file + + + + + Customize the default path + + + + + QObject + + + Text Editor + تېكىست تەھرىرلىگۈچ + + + + + + + + + Encoding + كودلاش + + + + Basic + ئاساسىي تەڭشەكلەر + + + + Font Style + خەت شەكلى ھالىتى + + + + Font + خەت شەكلى + + + + Font Size + خەت نومۇرى + + + + Shortcuts + تېزلەتمە + + + + + Keymap + تېزلەتمە كۆرۈنسۇن + + + + + + Window + كۆزنەك + + + + New tab + يېڭى خەتكۈچ + + + + New window + يېڭى كۆزنەك + + + + Save + ساقلاش + + + + Save as + باشقا ساقلاش + + + + Next tab + كېيىنكى خەتكۈچ + + + + Previous tab + ئالدىنقى خەتكۈچ + + + + Close tab + خەتكۈچنى تاقاش + + + + Close other tabs + باشقا خەتكۈچنى تاقاش + + + + Restore tab + خەتكۈچنى ئەسلگە كەلتۈرۈش + + + + Open file + ئېچىش + + + + Increment font size + خەت نومۇرىنى چوڭايتىش + + + + Decrement font size + خەت نومۇرىنى كىچىكلىتىش + + + + Reset font size + خەت نومۇرىنى ئەسلىگە قايتۇرۇش + + + + Help + ياردەم + + + + Toggle fullscreen + پۈتۈن ئېكرانغا ئالماشتۇرۇش + + + + Find + ئىزدەش + + + + Replace + ئالماشتۇرۇش + + + + Go to line + سەكرەش + + + + Save cursor position + نۇر بەلگىسىنىڭ ئورنىنى ساقلاش + + + + Reset cursor position + نۇر بەلگىسى ساقلانغان ئورۇنغا سەكرىسۇن + + + + Exit + چېكىنىش + + + + Display shortcuts + تېزلەتمە كۆرۈنسۇن + + + + Print + بېسىش + + + + Editor + تەھرىرلەش + + + + Increase indent + قۇر بېشىنى قىسقارتىش + + + + Decrease indent + قۇر بېسىنى كېڭەيتىش + + + + Forward character + ئوڭغا بىر ھەرپ-بەلگە سۈرۈلسۇن + + + + Backward character + سولغا بىر ھەرپ-بەلگە سۈرۈلسۇن + + + + Forward word + ئوڭغا بىر سۆز يۆتكەلسۇن + + + + Backward word + سولغا بىر سۆز يۆتكەلسۇن + + + + Next line + كېيىنكى قۇر + + + + Previous line + ئالدىنقى قۇر + + + + New line + قۇر ئالمىشىش + + + + New line above + ئۈستىگە بىر قۇر قوشۇش + + + + New line below + ئاستىغا بىر قۇر قوشۇش + + + + Duplicate line + ھازىرقى ئورۇنغا كۆچۈرۈش ۋە چاپلاش + + + + Delete to end of line + قۇر ئاخىرىغىچە ئۆچۈرۈش + + + + Delete current line + بۇ قۇرنى ئۆچۈرۈش + + + + Swap line up + ئۈستىگە بىر قۇر يۆتكەش + + + + Swap line down + ئاستىغا بىر قۇر يۆتكەش + + + + Scroll up one line + ئۈستىگە بىر قۇر سىيرىش + + + + Scroll down one line + ئاستىغا بىر قۇر سىيرىش + + + + Page up + ئۈستىگە بىر بەت سىيرىش + + + + Page down + ئاستىغا بىر بەت سىيرىش + + + + Move to end of line + قۇر ئاخىرىغا يۆتكەش + + + + Move to start of line + قۇر بېشىغا يۆتكەش + + + + Move to end of text + تېكىست ئاخىرىغا يۆتكەش + + + + Move to start of text + تېكىست بېشىغا يۆتكەش + + + + Move to line indentation + قۇر قىسقارغۇچە يۆتكەش + + + + Upper case + چوڭ يېزىلىشقا ئالماشتۇرۇش + + + + Lower case + كىچىك يېزىلىشقا ئالماشتۇرۇش + + + + Capitalize + 1-ھەرپ چوڭ يېزىلسۇن + + + + Delete backward word + سولغا بىر خەت ئۆچۈرسۇن + + + + Delete forward word + ئوڭغا بىر خەت ئۆچۈرسۇن + + + + Forward over a pair + ئوڭغا ماسلاشسۇن + + + + Backward over a pair + سولغا ماسلاشسۇن + + + + Select all + ھەممىسى + + + + Copy + كۆچۈرۈش + + + + Cut + كېسىش + + + + Paste + چاپلاش + + + + Transpose character + ھەرپ-بەلگە ئالماشتۇرۇش + + + + Mark + بەلگە قويۇش + + + + Unmark + بەلگىنى ئېلىۋېتىش + + + + Copy line + قۇرنى كۆچۈرۈش + + + + Cut line + قۇرنى كېسىۋېلىش + + + + Merge lines + قۇرنى قوشۇۋېتىش + + + + Read-Only mode + پەقەت ئوقۇيدىغان قىلىش + + + + Add comment + ئىزاھات قوشۇش + + + + Remove comment + ئىزاھاتنى بىكار قىلىش + + + + Undo + ئەمەلدىن قالدۇرۇش + + + + Redo + قايتا + + + + Add/Remove bookmark + خەتكۈچ قوشۇش/چىقىرىۋېتىش + + + + Move to previous bookmark + ئالدىنقى خەتكۈچ + + + + Move to next bookmark + كېيىنكى خەتكۈچ + + + + Advanced + ئالىي تەڭشەك + + + + Window size + كۆزنەك ھالىتى + + + + Tab width + Tab ھەرپ-بەلگىسىنىڭ كەڭلىكى + + + + Paste by pressing a middle mouse button + + + + + Startup + + + + + Reopen last closed tabs + + + + + Open/Save Settings + + + + + Word wrap + قۇر ئاپتوماتىك ئالماشسۇن + + + + Code folding flag + كود قاتلىۋەتكەن بەلگىلەرنى كۆرسىتىش + + + + Show line numbers + قۇر نومۇرى كۆرۈنسۇن + + + + Show bookmarks icon + خەتكۈچ سىنبەلگىسى كۆرۈنسۇن + + + + Show whitespaces and tabs + قۇرۇق ھەرپ/بەتكۈچلەر كۆرۈنسۇن + + + + Highlight current line + نۆۋەتتىكى قۇر ئىگىزلىكى يورۇقلۇقى + + + + Color mark + رەڭ بەلگىسى + + + + Unicode + يۇنىكود + + + + WesternEuropean + غەربىي ياۋروپا تىل سىستېمىسى + + + + CentralEuropean + ئوتتۇرا ياۋروپا تىل سىستېمىسى + + + + Baltic + بالتىق دىڭىزى تىللىرى + + + + Cyrillic + سىرىل يېزىقى + + + + Arabic + ئەرەب تىلى + + + + Celtic + كېلتىك تىلى + + + + SouthEasternEuropean + شەرقىي جەنۇبىي ياۋروپا تىل سىستېمىسى + + + + Greek + گرېك تىلى + + + + Hebrew + ئىبرانى تىلى + + + + ChineseSimplified + ئاددىي خەنزۇ يېزىقى + + + + ChineseTraditional + مۇرەككەپ خەنزۇ يېزىقى + + + + Japanese + ياپونچە + + + + Korean + كورىيەچە + + + + Thai + تەي + + + + Turkish + تۈرك تىلى + + + + Vietnamese + ۋېيتنامچە + + + + File not saved + ھۆججەت ساقلانمىغان + + + + + + Line Endings + قۇر تاشلاش بەلگىسى + + + + ReplaceBar + + + Find + ئىزدەش + + + + Replace With + غا ئالماشتۇرۇش + + + + Replace + ئالماشتۇرۇش + + + + Skip + ئاتلاش + + + + Replace Rest + قالغانلىرىنى ئالماشتۇرۇش + + + + Replace All + ھەممىنى ئالماشتۇرۇش + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + ئۆلچەملىك + + + + Customize + بەلگىلەش + + + + Normal + نورمال كۆزنەك + + + + Maximum + كىچىكلىتىش + + + + Fullscreen + پۈتۈن ئېكران + + + + This shortcut conflicts with system shortcut %1 + بۇ تېزلەتمە سىستېما تېزلەتمىسى %1 بىلەن توقۇنۇشىدۇ + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + بۇ تېزلەتمە %1 بىلەن توقۇنۇشىدۇ، ئالماشتۇرۇشنى بېسىپ بۇ تېزلەتمنى ئۈنۈملۈك قىلىڭ + + + + + The shortcut %1 is invalid, please set another one. + %1 ئۈنۈمسىز، قايتا بەلگىلەڭ + + + + Cancel + بىكار قىلىش + + + + Replace + ئالماشتۇرۇش + + + + OK + ھەئە + + + + StartManager + + + Untitled %1 + %1نىڭ نامىنى ئۆزگەتىش + + + + Tabbar + + + Close tab + خەتكۈچنى تاقاش + + + + Close other tabs + باشقا خەتكۈچنى تاقاش + + + + More options + تېخىمۇ كۆپ تاقاش ئۇسۇلى + + + + Close tabs to the left + سولدىكى بارلىق خەتكۈچنى تاقاش + + + + Close tabs to the right + ئوڭدىكى بارلىق خەتكۈچنى تاقاش + + + + Close unmodified tabs + ئۆزگەرتىلمىگەن بارلىق خەتكۈچنى تاقاش + + + + TextEdit + + + Undo + ئەمەلدىن قالدۇرۇش + + + + Redo + قايتا + + + + Cut + چاپلاش + + + + Copy + كۆچۈرۈش + + + + Paste + چاپلاش + + + + Delete + ئۆچۈرۈش + + + + Select All + ھەممىنى + + + + + Find + ئىزدەش + + + + + Replace + ئالماشتۇرۇش + + + + Go to Line + سەكرەش + + + + Turn on Read-Only mode + پەقەت ئوقۇيدىغان ھالەتنى ئېچىش + + + + Turn off Read-Only mode + پەقەت ئوقۇيدىغان ھالەتنى تاقاش + + + + Fullscreen + پۈتۈن ئېكران + + + + Exit fullscreen + پۈتۈن ئېكراندىن چېكىنىش + + + + Display in file manager + ھۆججەت باشقۇرغۇچتا كۆرسىتىش + + + + + Add Comment + ئىزاھات قوشۇش + + + + Text to Speech + تېكىستنى ئاۋازغا ئايلاندۇرۇش + + + + Stop reading + ئوقۇشنى توختىتىش + + + + Speech to Text + ئاۋازنى تېكىستكە ئايلاندۇرۇش + + + + Translate + تەرجىمان + + + + Column Mode + ئىستون تەھرىرلەش ھالىتى + + + + Add bookmark + خەتكۈچ قوشۇش + + + + Remove Bookmark + خەتكۈچ چىقىرىۋېتىش + + + + Previous bookmark + ئالدىنقى خەتكۈچ + + + + Next bookmark + كېيىنكى خەتكۈچ + + + + Remove All Bookmarks + بارلىق خەتكۈچنى چىقىرىۋېتىش + + + + Fold All + بارلىق قاتلامنى قاتلاش + + + + Fold Current Level + ھازىرقى قاتلامنى قاتلاش + + + + Unfold All + بارلىق قاتلامنى ئېچىش + + + + Unfold Current Level + ھازىرقى قاتلامنى ئېچىش + + + + Color Mark + رەڭ بەلگىسى + + + + Clear All Marks + بارلىق بەلگىلەرنى چىقىرىۋېتىش + + + + Clear Last Mark + ئالدىنقى بەلگىنى چىقىرىۋېتىش + + + + Mark + بەلگە قويۇش + + + + Mark All + ھەممىسىگە بەلگە قويۇش + + + + Remove Comment + ئىزاھاتنى بىكار قىلىش + + + + Copy failed: not enough memory + ئىچكى ساقلىغۇچ يېتىشمىدى، كۆچۈرەلمىدى + + + + Press ALT and click lines to edit in column mode + ئىستون تەھرىرلەش ھالىتىنى ئالماشتۇرۇش ئۈچۈن ALT بىلەن مائۇسنى ئىشلىتىڭ + + + + Change Case + چوڭ-كىچىك يېزىلىشىنى ئالماشتۇرۇش + + + + Upper Case + چوڭ يېزىلىش + + + + Lower Case + كىچىك يېزىلىش + + + + Capitalize + 1-ھەرپ چوڭ يېزىلسۇن + + + + None + يوق + + + + Selected line(s) copied + تاللانغان قۇر چاپلاش تاختىسىغا كۆچۈرۈلدى + + + + Current line copied + نۆۋەتتىكى قۇر چاپلاش تاختىسىغا كۆچۈرۈلدى + + + + Selected line(s) clipped + تاللانغان قۇر چاپلاش تاختىسىغا كېسىلدى + + + + Current line clipped + نۆۋەتتىكى قۇر چاپلاش تاختىسىغا كېسىلدى + + + + Paste failed: not enough memory + ئىچكى ساقلىغۇچ يېتىشمىدى، چاپلانمىدى + + + + Read-Only mode is off + پەقەت ئوقۇيدىغان ھالەت تاقالدى + + + + + + Read-Only mode is on + پەقەت ئوقۇيدىغان ھالەتنى ئېچىلدى + + + + WarningNotices + + + Reload + قايتا كىرگۈزۈڭ + + + + Window + + + + Save as + باشقا ساقلاش + + + + New window + يېڭى كۆزنەك + + + + New tab + يېڭى خەتكۈچ + + + + Open file + ئېچىش + + + + + Save + ساقلاش + + + + Print + بېسىش + + + + Switch theme + ئۇسلۇب ئالماشتۇرۇش + + + + + Settings + تەڭشەك + + + + + Read-Only + پەقەت ئوقۇيدىغان قىلىش + + + + You do not have permission to open %1 + %1نى ئېچىش ھوقۇقىڭىز يوق + + + + Invalid file: %1 + ئۈنۈمسىز ھۆججەت: %1 + + + + + Do you want to save this file? + بۇ ھۆججەتنى ساقلامسىز؟ + + + + You do not have permission to save %1 + %1نى ساقلاش ھوقۇقىڭىز يوق + + + + Saved successfully + ھۆججەت ساقلاندى + + + + + + Save File + ساقلاش + + + + Encoding + كودلاش + + + + Read-Only mode is on + پەقەت ئوقۇيدىغان ھالەتنى ئېچىلدى + + + + Current location remembered + نۆۋەتتىكى ئورۇن ئەستە ساقلاندى + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + تەھرىرلەش + + + + Untitled %1 + %1نىڭ نامىنى ئۆزگەتىش + + + + Cancel + بىكار قىلىش + + + + Discard + ساقلىمايمەن + + + \ No newline at end of file diff --git a/translations/deepin-editor_uk.ts b/translations/deepin-editor_uk.ts new file mode 100644 index 0000000000000000000000000000000000000000..55d8a7e468ebfcb53d2221d77588bbc277250892 --- /dev/null +++ b/translations/deepin-editor_uk.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + Рядок + + + + Column + Стовпчик + + + + Characters %1 + %1 символів + + + + Loading: + Завантаження: + + + + DDropdownMenu + + + + + None + Ніякий + + + + EditWrapper + + + + + + Save + Зберегти + + + + Do you want to save this file? + Хочете зберегти цей файл? + + + + + Cancel + Скасувати + + + + Encoding changed. Do you want to save the file now? + Кодування змінено. Хочете зберегти файл зараз? + + + + Discard + Відкинути + + + + You do not have permission to save %1 + У вас немає прав на збереження %1 + + + + File removed on the disk. Save it now? + Файл вилучено з диска. Зберегти його? + + + + File has changed on disk. Reload? + Файл на диску був змінений. Перезавантажити? + + + + + INSERT + ВСТАВЛЯТИ + + + + OVERWRITE + ПЕРЕЗАПИСУВАТИ + + + + R/O + ЛИШЕ ЧИТАННЯ + + + + FindBar + + + Find + Знайти + + + + Previous + Попереднє + + + + Next + Наступне + + + + JumpLineBar + + + Go to Line: + Перейти до рядка: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + Текстовий редактор є потужним інструментом для перегляду та редагування текстових файлів. + + + + Text Editor + Текстовий редактор + + + + PathSettingWgt + + + Remember the last used path + Запам'ятовувати останній використаний шлях + + + + Same path as the current file + Той самий шлях, що і для поточного файла + + + + Customize the default path + Налаштувати типовий шлях + + + + QObject + + + Text Editor + Текстовий редактор + + + + + + + + + Encoding + Кодування + + + + Basic + Базові + + + + Font Style + Стиль шрифту + + + + Font + Шрифт + + + + Font Size + Розмір шрифту + + + + Shortcuts + Сполучення клавіш + + + + + Keymap + Розкладка + + + + + + Window + Вікно + + + + New tab + Нова вкладка + + + + New window + Нове вікно + + + + Save + Зберегти + + + + Save as + Зберегти як + + + + Next tab + Наступна вкладка + + + + Previous tab + Попередня вкладка + + + + Close tab + Закрити вкладку + + + + Close other tabs + Закрити інші вкладки + + + + Restore tab + Відновити вкладку + + + + Open file + Відкрити файл + + + + Increment font size + Збільшити розмір шрифту + + + + Decrement font size + Зменшити розмір шрифту + + + + Reset font size + Відновити початковий розмір шрифту + + + + Help + Довідка + + + + Toggle fullscreen + Увімкнути/вимкнути повноекранний режим + + + + Find + Знайти + + + + Replace + Замінити + + + + Go to line + Перейти до рядка + + + + Save cursor position + Зберегти розташування курсора + + + + Reset cursor position + Скинути розташування курсора + + + + Exit + Вийти + + + + Display shortcuts + Показати сполучення клавіш + + + + Print + Друк + + + + Editor + Редактор + + + + Increase indent + Збільшити відступ + + + + Decrease indent + Зменшити відступ + + + + Forward character + Вперед на символ + + + + Backward character + Назад на символ + + + + Forward word + Вперед на слово + + + + Backward word + Назад на слово + + + + Next line + Наступний рядок + + + + Previous line + Попередній рядок + + + + New line + Новий рядок + + + + New line above + Новий рядок вище + + + + New line below + Новий рядок нижче + + + + Duplicate line + Дублювати рядок + + + + Delete to end of line + Видалити до кінця рядка + + + + Delete current line + Видалити поточний рядок + + + + Swap line up + Поміняти місцями з рядком вище + + + + Swap line down + Поміняти місцями з рядком нижче + + + + Scroll up one line + Прокрутити вище на рядок + + + + Scroll down one line + Прокрутити нижче на рядок + + + + Page up + На сторінку вгору + + + + Page down + На сторінку вниз + + + + Move to end of line + Перейти до кінця рядка + + + + Move to start of line + Перейти до початку рядка + + + + Move to end of text + Перейти до кінця тексту + + + + Move to start of text + Перейти до початку тексту + + + + Move to line indentation + Перейти до відступу рядка + + + + Upper case + Верхній регістр + + + + Lower case + Нижній регістр + + + + Capitalize + Великі перші літери + + + + Delete backward word + Вилучити слово назад + + + + Delete forward word + Вилучити слово вперед + + + + Forward over a pair + Вперед через пару + + + + Backward over a pair + Назад через пару + + + + Select all + Вибрати все + + + + Copy + Копіювати + + + + Cut + Вирізати + + + + Paste + Вставити + + + + Transpose character + Транспонувати символ + + + + Mark + Позначити + + + + Unmark + Зняти позначку + + + + Copy line + Копіювати рядок + + + + Cut line + Вирізати рядок + + + + Merge lines + Об'єднати рядки + + + + Read-Only mode + Режим лише для читання + + + + Add comment + Додати коментування + + + + Remove comment + Вилучити коментар + + + + Undo + Скасувати + + + + Redo + Повторити + + + + Add/Remove bookmark + Додати або вилучити закладку + + + + Move to previous bookmark + Перейти до попередньої закладки + + + + Move to next bookmark + Перейти до наступної закладки + + + + Advanced + Розширені + + + + Window size + Розмір вікна + + + + Tab width + Ширина табуляції + + + + Paste by pressing a middle mouse button + Вставляти клацанням середньої кнопки миші + + + + Startup + Запуск + + + + Reopen last closed tabs + Повторно відкрити останні закриті вкладки + + + + Open/Save Settings + Відкрити/Зберегти параметри + + + + Word wrap + Перенесення рядків + + + + Code folding flag + Прапорець згортання коду + + + + Show line numbers + Показувати номери рядків + + + + Show bookmarks icon + Показувати піктограму закладок + + + + Show whitespaces and tabs + Показувати пробіли і табуляції + + + + Highlight current line + Підсвічувати поточний рядок + + + + Color mark + Кольорова позначка + + + + Unicode + Юнікод + + + + WesternEuropean + Західноевропейське + + + + CentralEuropean + Центральноєвропейське + + + + Baltic + Балтійське + + + + Cyrillic + Кириличне + + + + Arabic + Арабська + + + + Celtic + Кельтське + + + + SouthEasternEuropean + Південно-східноєвропейське + + + + Greek + Грецька + + + + Hebrew + Іврит + + + + ChineseSimplified + Китайське спрощене + + + + ChineseTraditional + Китайське традиційне + + + + Japanese + Японська + + + + Korean + Корейська + + + + Thai + Тайська + + + + Turkish + Турецька + + + + Vietnamese + В'єтнамська + + + + File not saved + Файл не збережено + + + + + + Line Endings + Символ закінчення рядка + + + + ReplaceBar + + + Find + Знайти + + + + Replace With + Замінити на + + + + Replace + Замінити + + + + Skip + Пропустити + + + + Replace Rest + Замінити решту + + + + Replace All + Замінити все + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + Стандартна + + + + Customize + Налаштувати + + + + Normal + Звичайний + + + + Maximum + Максимум + + + + Fullscreen + На весь екран + + + + This shortcut conflicts with system shortcut %1 + Це клавіатурне скорочення конфліктує із загальносистемним скороченням %1 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + Це клавіатурне скорочення конфліктує з %1. Натисніть кнопку «Замінити», щоб це клавіатурне скорочення набуло чинності негайно. + + + + + The shortcut %1 is invalid, please set another one. + Скорочення %1 є некоректним. Будь ласка, встановіть інше. + + + + Cancel + Скасувати + + + + Replace + Замінити + + + + OK + Гаразд + + + + StartManager + + + Untitled %1 + Без назви %1 + + + + Tabbar + + + Close tab + Закрити вкладку + + + + Close other tabs + Закрити інші вкладки + + + + More options + Додаткові параметри + + + + Close tabs to the left + Закрити вкладки ліворуч + + + + Close tabs to the right + Закрити вкладки праворуч + + + + Close unmodified tabs + Закрити вкладки без змін + + + + TextEdit + + + Undo + Скасувати + + + + Redo + Повторити + + + + Cut + Вирізати + + + + Copy + Копіювати + + + + Paste + Вставити + + + + Delete + Видалити + + + + Select All + Вибрати все + + + + + Find + Знайти + + + + + Replace + Замінити + + + + Go to Line + Перейти до рядка + + + + Turn on Read-Only mode + Увімкнути режим лише для читання + + + + Turn off Read-Only mode + Вимкнути режим лише для читання + + + + Fullscreen + На весь екран + + + + Exit fullscreen + Вийти з повноекранного режиму + + + + Display in file manager + Показати у файловому менеджері + + + + + Add Comment + Додати коментування + + + + Text to Speech + Озвучення тексту + + + + Stop reading + Припинити читання + + + + Speech to Text + Перетворення звуку на текст + + + + Translate + Перекласти + + + + Column Mode + Режим стовпчиків + + + + Add bookmark + Додати закладку + + + + Remove Bookmark + Вилучити закладку + + + + Previous bookmark + Попередня закладка + + + + Next bookmark + Наступна закладка + + + + Remove All Bookmarks + Вилучити усі закладки + + + + Fold All + Згорнути усе + + + + Fold Current Level + Згорнути поточний рівень + + + + Unfold All + Розгорнути усе + + + + Unfold Current Level + Розгорнути поточний рівень + + + + Color Mark + Кольорова позначка + + + + Clear All Marks + Вилучити усі позначки + + + + Clear Last Mark + Вилучити останню позначку + + + + Mark + Позначити + + + + Mark All + Позначити усе + + + + Remove Comment + Вилучити коментування + + + + Copy failed: not enough memory + Не вдалося скопіювати: недостатньо пам'яті + + + + Press ALT and click lines to edit in column mode + Натисніть клавішу Alt і клацайте на рядках, щоб редагувати текст у режимі стовпчиків + + + + Change Case + Змінити регістр + + + + Upper Case + Верхній регістр + + + + Lower Case + Нижній регістр + + + + Capitalize + Починати з великої літери + + + + None + Ніякий + + + + Selected line(s) copied + Вибрані рядки(ок) скопійовано + + + + Current line copied + Поточний рядок скопійовано + + + + Selected line(s) clipped + Вибрані рядки(ок) вирізано + + + + Current line clipped + Поточний рядок вирізано + + + + Paste failed: not enough memory + Не вдалося вставити: недостатньо пам'яті + + + + Read-Only mode is off + Режим лише для читання вимкнено + + + + + + Read-Only mode is on + Режим лише для читання увімкнено + + + + WarningNotices + + + Reload + Перезавантажити + + + + Window + + + + Save as + Зберегти як + + + + New window + Нове вікно + + + + New tab + Нова вкладка + + + + Open file + Відкрити файл + + + + + Save + Зберегти + + + + Print + Друк + + + + Switch theme + Змінити тему + + + + + Settings + Налаштування + + + + + Read-Only + Лише читання + + + + You do not have permission to open %1 + У вас немає прав на відкриття %1 + + + + Invalid file: %1 + Некоректний файл: %1 + + + + + Do you want to save this file? + Хочете зберегти цей файл? + + + + You do not have permission to save %1 + У вас немає прав на збереження %1 + + + + Saved successfully + Успішно збережено + + + + + + Save File + Зберегти файл + + + + Encoding + Кодування + + + + Read-Only mode is on + Режим лише для читання увімкнено + + + + Current location remembered + Програма запам'ятала поточне місце + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + Редактор + + + + Untitled %1 + Без назви %1 + + + + Cancel + Скасувати + + + + Discard + Відкинути + + + \ No newline at end of file diff --git a/translations/deepin-editor_zh_CN.ts b/translations/deepin-editor_zh_CN.ts new file mode 100644 index 0000000000000000000000000000000000000000..5f292da1101c757f8cdc519725697ee7f2ce811e --- /dev/null +++ b/translations/deepin-editor_zh_CN.ts @@ -0,0 +1,1306 @@ + + + BottomBar + + + Row + + + + + Column + + + + + Characters %1 + 字数 %1 + + + + Loading: + 文件加载中: + + + + DDropdownMenu + + + + + None + + + + + EditWrapper + + + + + + Save + 保存 + + + + Do you want to save this file? + 您是否要保存此文件? + + + + + Cancel + 取消 + + + + Encoding changed. Do you want to save the file now? + 文件编码已更改,是否先进行保存? + + + + Discard + 不保存 + + + + You do not have permission to save %1 + 您没有权限保存%1 + + + + File removed on the disk. Save it now? + 磁盘中的原文件已被移除,是否另存? + + + + File has changed on disk. Reload? + 磁盘中的原文件已被修改,是否重新载入? + + + + + INSERT + 插入 + + + + OVERWRITE + 覆盖 + + + + R/O + 只读 + + + + The file cannot be read, which may be too large or has been damaged! + 无法读取该文件,文件可能过大或损坏 + + + + FindBar + + + Find + 查找 + + + + Previous + 上一个 + + + + Next + 下一个 + + + + JumpLineBar + + + Go to Line: + 跳到行: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + 文本编辑器是一款用来查看和编辑文本文件的工具。 + + + + Text Editor + 文本编辑器 + + + + PathSettingWgt + + + Remember the last used path + 记住最后的操作路径 + + + + Same path as the current file + 与当前文件保持一致 + + + + Customize the default path + 自定义操作路径 + + + + QObject + + + Text Editor + 文本编辑器 + + + + + + + + + Encoding + 编码 + + + + Basic + 基础设置 + + + + Font Style + 字体样式 + + + + Font + 字体 + + + + Font Size + 字号 + + + + Shortcuts + 快捷键 + + + + + Keymap + 快捷键映射 + + + + + + Window + 窗口 + + + + New tab + 新标签页 + + + + New window + 新窗口 + + + + Save + 保存 + + + + Save as + 另存为 + + + + Next tab + 下一个标签页 + + + + Previous tab + 上一个标签页 + + + + Close tab + 关闭标签页 + + + + Close other tabs + 关闭其他标签页 + + + + Restore tab + 恢复标签页 + + + + Open file + 打开文件 + + + + Increment font size + 放大字号 + + + + Decrement font size + 缩小字号 + + + + Reset font size + 还原字号 + + + + Help + 帮助 + + + + Toggle fullscreen + 切换全屏 + + + + Find + 查找 + + + + Find Next + 查找下一个 + + + + Find Previous + 查找上一个 + + + + Replace + 替换 + + + + Go to line + 跳到行 + + + + Save cursor position + 保存光标位置 + + + + Reset cursor position + 跳转到保存光标位置 + + + + Exit + 退出 + + + + Display shortcuts + 显示快捷键 + + + + Print + 打印 + + + + Editor + 编辑 + + + + Increase indent + 增加缩进 + + + + Decrease indent + 减少缩进 + + + + Forward character + 右移一个字符 + + + + Backward character + 左移一个字符 + + + + Forward word + 右移一个词 + + + + Backward word + 左移一个词 + + + + Next line + 下一行 + + + + Previous line + 上一行 + + + + New line + 换行 + + + + New line above + 向上插入一行 + + + + New line below + 向下插入一行 + + + + Duplicate line + 复制并粘贴当前行 + + + + Delete to end of line + 删除到行尾 + + + + Delete current line + 删除当前行 + + + + Swap line up + 上移一行 + + + + Swap line down + 下移一行 + + + + Scroll up one line + 向上滚动一行 + + + + Scroll down one line + 向下滚动一行 + + + + Page up + 向上滚动一页 + + + + Page down + 向下滚动一页 + + + + Move to end of line + 移动到行尾 + + + + Move to start of line + 移动到行头 + + + + Move to end of text + 移动到文本结尾 + + + + Move to start of text + 移动到文本开头 + + + + Move to line indentation + 移动到行缩进 + + + + Upper case + 转换为大写 + + + + Lower case + 转换为小写 + + + + Capitalize + 首字母大写 + + + + Delete backward word + 向左删除一个词 + + + + Delete forward word + 向右删除一个词 + + + + Forward over a pair + 向右匹配 + + + + Backward over a pair + 向左匹配 + + + + Select all + 全选 + + + + Copy + 复制 + + + + Cut + 剪切 + + + + Paste + 粘贴 + + + + Transpose character + 调换字符 + + + + Mark + 设置标记 + + + + Unmark + 取消标记 + + + + Copy line + 复制行 + + + + Cut line + 剪切行 + + + + Merge lines + 合并行 + + + + Read-Only mode + 切换到只读模式 + + + + Add comment + 添加注释 + + + + Remove comment + 取消注释 + + + + Undo + 撤销 + + + + Redo + 重做 + + + + Add/Remove bookmark + 添加/清除书签 + + + + Move to previous bookmark + 跳转到上一个书签 + + + + Move to next bookmark + 跳转到下一个书签 + + + + Advanced + 高级设置 + + + + Window size + 窗口状态 + + + + Tab width + Tab字符宽度 + + + + Paste by pressing a middle mouse button + 允许鼠标中键粘贴 + + + + Startup + 启动 + + + + Reopen last closed tabs + 保留关闭前的页签 + + + + Open/Save Settings + 打开/保存设置 + + + + Word wrap + 自动换行 + + + + Code folding flag + 显示代码折叠标志 + + + + Show line numbers + 显示行号 + + + + Show bookmarks icon + 显示书签图标 + + + + Show whitespaces and tabs + 显示空白字符/制表符 + + + + Highlight current line + 当前行高亮 + + + + Color mark + 颜色标记 + + + + Unicode + Unicode + + + + WesternEuropean + 西欧语系 + + + + CentralEuropean + 中欧语系 + + + + Baltic + 波罗的海语言 + + + + Cyrillic + 西里尔文 + + + + Arabic + 阿拉伯语 + + + + Celtic + 凯尔特语 + + + + SouthEasternEuropean + 东南欧语系 + + + + Greek + 希腊语 + + + + Hebrew + 希伯来语 + + + + ChineseSimplified + 简体中文 + + + + ChineseTraditional + 繁体中文 + + + + Japanese + 日语 + + + + Korean + 韩语 + + + + Thai + 泰语 + + + + Turkish + 土耳其语 + + + + Vietnamese + 越南语 + + + + File not saved + 文件未保存 + + + + + + Line Endings + 换行符 + + + + ReplaceBar + + + Find + 查找 + + + + Replace With + 替换为 + + + + Replace + 替换 + + + + Skip + 跳过 + + + + Replace Rest + 剩余替换 + + + + Replace All + 全部替换 + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + 标准 + + + + Customize + 自定义 + + + + Normal + 正常窗口 + + + + Maximum + 最大化 + + + + Fullscreen + 全屏 + + + + This shortcut conflicts with system shortcut %1 + 此快捷键与系统快捷键%1冲突 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + 此快捷键与%1冲突,点击替换使这个快捷键立即生效 + + + + + + The shortcut %1 is invalid, please set another one. + %1为无效快捷键,请重新设置 + + + + Cancel + 取消 + + + + Replace + 替换 + + + + OK + 确定 + + + + StartManager + + + Untitled %1 + 未命名文档%1 + + + + Tabbar + + + Close tab + 关闭标签页 + + + + Close other tabs + 关闭其他标签页 + + + + More options + 更多关闭方式 + + + + Close tabs to the left + 关闭左侧所有标签页 + + + + Close tabs to the right + 关闭右侧所有标签页 + + + + Close unmodified tabs + 关闭所有未修改标签页 + + + + TextEdit + + + Undo + 撤销 + + + + Redo + 重做 + + + + Cut + 剪切 + + + + Copy + 复制 + + + + Paste + 粘贴 + + + + Delete + 删除 + + + + Select All + 全选 + + + + + Find + 查找 + + + + + Replace + 替换 + + + + Go to Line + 跳到行 + + + + Turn on Read-Only mode + 开启只读模式 + + + + Turn off Read-Only mode + 关闭只读模式 + + + + Fullscreen + 全屏 + + + + Exit fullscreen + 退出全屏 + + + + Display in file manager + 在文件管理器中显示 + + + + + Add Comment + 添加注释 + + + + Text to Speech + 语音朗读 + + + + Stop reading + 停止朗读 + + + + Speech to Text + 语音听写 + + + + Translate + 文本翻译 + + + + Column Mode + 列编辑模式 + + + + Add bookmark + 添加书签 + + + + Remove Bookmark + 清除书签 + + + + Previous bookmark + 上一个书签 + + + + Next bookmark + 下一个书签 + + + + Remove All Bookmarks + 清除所有书签 + + + + Fold All + 折叠所有层次 + + + + Fold Current Level + 折叠当前层次 + + + + Unfold All + 展开所有层次 + + + + Unfold Current Level + 展开当前层次 + + + + Color Mark + 颜色标记 + + + + Clear All Marks + 清除所有标记 + + + + Clear Last Mark + 清除上次标记 + + + + Mark + 添加标记 + + + + Mark All + 标记所有 + + + + Remove Comment + 取消注释 + + + + Copy failed: not enough memory + 内存不足,复制失败 + + + + Press ALT and click lines to edit in column mode + 请使用ALT+鼠标点选切换列编辑模式 + + + + Change Case + 切换大小写 + + + + Upper Case + 大写 + + + + Lower Case + 小写 + + + + Capitalize + 首字母大写 + + + + None + + + + + Selected line(s) copied + 已复制选中行到剪贴板 + + + + Current line copied + 已复制当前行到剪贴板 + + + + Selected line(s) clipped + 已剪切选中行到剪贴板 + + + + Current line clipped + 已剪切当前行到剪贴板 + + + + Paste failed: not enough memory + 内存不足,粘贴失败 + + + + Read-Only mode is off + 只读模式已关闭 + + + + + + + + + Read-Only mode is on + 只读模式已开启 + + + + WarningNotices + + + Reload + 重新载入 + + + + Window + + + + Save as + 另存为 + + + + New window + 新窗口 + + + + New tab + 新标签页 + + + + Open file + 打开文件 + + + + + Save + 保存 + + + + Print + 打印 + + + + Switch theme + 切换主题 + + + + + Settings + 设置 + + + + + Read-Only + 只读 + + + + You do not have permission to open %1 + 您没有权限打开%1 + + + + + Invalid file: %1 + 无效文件:%1 + + + + + Do you want to save this file? + 您是否要保存此文件? + + + + You do not have permission to save %1 + 您没有权限保存%1 + + + + Saved successfully + 文件已保存 + + + + + + Save File + 保存 + + + + Encoding + 编码 + + + + Read-Only mode is on + 只读模式已开启 + + + + Current location remembered + 已记住当前位置 + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + 编辑 + + + + Untitled %1 + 未命名文档%1 + + + + Cancel + 取消 + + + + Discard + 不保存 + + + \ No newline at end of file diff --git a/translations/deepin-editor_zh_HK.ts b/translations/deepin-editor_zh_HK.ts new file mode 100644 index 0000000000000000000000000000000000000000..dee8f2545b1c23cee5f174d59688af0a5fbacc3b --- /dev/null +++ b/translations/deepin-editor_zh_HK.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + + + + + Column + + + + + Characters %1 + 字數 %1 + + + + Loading: + 文件加載中: + + + + DDropdownMenu + + + + + None + + + + + EditWrapper + + + + + + Save + 保存 + + + + Do you want to save this file? + 您是否要保存此文件? + + + + + Cancel + 取消 + + + + Encoding changed. Do you want to save the file now? + 文件編碼已更改,是否先進行保存? + + + + Discard + 不保存 + + + + You do not have permission to save %1 + 您沒有權限保存%1 + + + + File removed on the disk. Save it now? + 磁盤中的原文件已被移除,是否另存? + + + + File has changed on disk. Reload? + 磁盤中的原文件已被修改,是否重新載入? + + + + + INSERT + 插入 + + + + OVERWRITE + 覆蓋 + + + + R/O + 只讀 + + + + FindBar + + + Find + 查找 + + + + Previous + 上一個 + + + + Next + 下一個 + + + + JumpLineBar + + + Go to Line: + 跳到行: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + 文本編輯器是一款用來查看和編輯文本文件的工具。 + + + + Text Editor + 文本編輯器 + + + + PathSettingWgt + + + Remember the last used path + 記住最後的操作路徑 + + + + Same path as the current file + 與當前文件保持一致 + + + + Customize the default path + 自定義操作路徑 + + + + QObject + + + Text Editor + 文本編輯器 + + + + + + + + + Encoding + 編碼 + + + + Basic + 基礎設置 + + + + Font Style + 字體樣式 + + + + Font + 字體 + + + + Font Size + 字號 + + + + Shortcuts + 快捷鍵 + + + + + Keymap + 快捷鍵映射 + + + + + + Window + 窗口 + + + + New tab + 新標籤頁 + + + + New window + 新窗口 + + + + Save + 保存 + + + + Save as + 另存為 + + + + Next tab + 下一個標籤頁 + + + + Previous tab + 上一個標籤頁 + + + + Close tab + 關閉標籤頁 + + + + Close other tabs + 關閉其他標籤頁 + + + + Restore tab + 恢復標籤頁 + + + + Open file + 打開文件 + + + + Increment font size + 放大字號 + + + + Decrement font size + 縮小字號 + + + + Reset font size + 還原字號 + + + + Help + 幫助 + + + + Toggle fullscreen + 切換全螢幕 + + + + Find + 查找 + + + + Replace + 替換 + + + + Go to line + 跳到行 + + + + Save cursor position + 保存光標位置 + + + + Reset cursor position + 跳轉到保存光標位置 + + + + Exit + 退出 + + + + Display shortcuts + 顯示快捷鍵 + + + + Print + 打印 + + + + Editor + 編輯 + + + + Increase indent + 增加縮進 + + + + Decrease indent + 減少縮進 + + + + Forward character + 右移一個字符 + + + + Backward character + 左移一個字符 + + + + Forward word + 右移一個詞 + + + + Backward word + 左移一個詞 + + + + Next line + 下一行 + + + + Previous line + 上一行 + + + + New line + 換行 + + + + New line above + 向上插入一行 + + + + New line below + 向下插入一行 + + + + Duplicate line + 複製並黏貼當前行 + + + + Delete to end of line + 刪除到行尾 + + + + Delete current line + 刪除當前行 + + + + Swap line up + 上移一行 + + + + Swap line down + 下移一行 + + + + Scroll up one line + 向上滾動一行 + + + + Scroll down one line + 向下滾動一行 + + + + Page up + 向上滾動一頁 + + + + Page down + 向下滾動一頁 + + + + Move to end of line + 移動到行尾 + + + + Move to start of line + 移動到行頭 + + + + Move to end of text + 移動到文本結尾 + + + + Move to start of text + 移動到文本開頭 + + + + Move to line indentation + 移動到行縮進 + + + + Upper case + 轉換為大寫 + + + + Lower case + 轉換為小寫 + + + + Capitalize + 首字母大寫 + + + + Delete backward word + 向左刪除一個詞 + + + + Delete forward word + 向右刪除一個詞 + + + + Forward over a pair + 向右匹配 + + + + Backward over a pair + 向左匹配 + + + + Select all + 全選 + + + + Copy + 複製 + + + + Cut + 剪切 + + + + Paste + 黏貼 + + + + Transpose character + 調換字符 + + + + Mark + 設置標記 + + + + Unmark + 取消標記 + + + + Copy line + 複製行 + + + + Cut line + 剪切行 + + + + Merge lines + 合併行 + + + + Read-Only mode + 切換到只讀模式 + + + + Add comment + 添加注釋 + + + + Remove comment + 取消注釋 + + + + Undo + 撤銷 + + + + Redo + 重做 + + + + Add/Remove bookmark + 添加/清除書籤 + + + + Move to previous bookmark + 跳轉到上一個書籤 + + + + Move to next bookmark + 跳轉到下一個書籤 + + + + Advanced + 高級設定 + + + + Window size + 窗口狀態 + + + + Tab width + Tab字符寬度 + + + + Paste by pressing a middle mouse button + 允許鼠標中鍵黏貼 + + + + Startup + 啟動 + + + + Reopen last closed tabs + 保留關閉前的頁簽 + + + + Open/Save Settings + 打開/保存設置 + + + + Word wrap + 自動換行 + + + + Code folding flag + 顯示代碼摺疊標誌 + + + + Show line numbers + 顯示行號 + + + + Show bookmarks icon + 顯示書籤圖標 + + + + Show whitespaces and tabs + 顯示空白字符/製表符 + + + + Highlight current line + 當前行高亮 + + + + Color mark + 顏色標記 + + + + Unicode + Unicode + + + + WesternEuropean + 西歐語系 + + + + CentralEuropean + 中歐語系 + + + + Baltic + 波羅的海語言 + + + + Cyrillic + 西里爾文 + + + + Arabic + 阿拉伯語 + + + + Celtic + 凱爾特語 + + + + SouthEasternEuropean + 東南歐語系 + + + + Greek + 希臘語 + + + + Hebrew + 希伯來語 + + + + ChineseSimplified + 簡體中文 + + + + ChineseTraditional + 繁體中文 + + + + Japanese + 日語 + + + + Korean + 韓語 + + + + Thai + 泰語 + + + + Turkish + 土耳其語 + + + + Vietnamese + 越南語 + + + + File not saved + 文件未保存 + + + + + + Line Endings + 換行符 + + + + ReplaceBar + + + Find + 查找 + + + + Replace With + 替換為 + + + + Replace + 替換 + + + + Skip + 跳過 + + + + Replace Rest + 剩餘替換 + + + + Replace All + 全部替換 + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + 標準 + + + + Customize + 自定義 + + + + Normal + 正常窗口 + + + + Maximum + 最大化 + + + + Fullscreen + 全螢幕 + + + + This shortcut conflicts with system shortcut %1 + 此快捷鍵與系統快捷鍵%1衝突 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + 此快捷鍵與%1衝突,點擊替換使這個快捷鍵立即生效 + + + + + The shortcut %1 is invalid, please set another one. + %1為無效快捷鍵,請重新設置 + + + + Cancel + 取消 + + + + Replace + 替換 + + + + OK + 確定 + + + + StartManager + + + Untitled %1 + 未命名文檔%1 + + + + Tabbar + + + Close tab + 關閉標籤頁 + + + + Close other tabs + 關閉其他標籤頁 + + + + More options + 更多關閉方式 + + + + Close tabs to the left + 關閉左側所有標籤頁 + + + + Close tabs to the right + 關閉右側所有標籤頁 + + + + Close unmodified tabs + 關閉所有未修改標籤頁 + + + + TextEdit + + + Undo + 撤銷 + + + + Redo + 重做 + + + + Cut + 剪切 + + + + Copy + 複製 + + + + Paste + 黏貼 + + + + Delete + 刪除 + + + + Select All + 全選 + + + + + Find + 查找 + + + + + Replace + 替換 + + + + Go to Line + 跳到行 + + + + Turn on Read-Only mode + 開啟只讀模式 + + + + Turn off Read-Only mode + 關閉只讀模式 + + + + Fullscreen + 全螢幕 + + + + Exit fullscreen + 退出全螢幕 + + + + Display in file manager + 在文件管理器中顯示 + + + + + Add Comment + 添加注釋 + + + + Text to Speech + 語音朗讀 + + + + Stop reading + 停止朗讀 + + + + Speech to Text + 語音聽寫 + + + + Translate + 文本翻譯 + + + + Column Mode + 列編輯模式 + + + + Add bookmark + 添加書籤 + + + + Remove Bookmark + 清除書籤 + + + + Previous bookmark + 上一個書籤 + + + + Next bookmark + 下一個書籤 + + + + Remove All Bookmarks + 清除所有書籤 + + + + Fold All + 摺疊所有層次 + + + + Fold Current Level + 摺疊當前層次 + + + + Unfold All + 展開所有層次 + + + + Unfold Current Level + 展開當前層次 + + + + Color Mark + 顏色標記 + + + + Clear All Marks + 清除所有標記 + + + + Clear Last Mark + 清除上次標記 + + + + Mark + 添加標記 + + + + Mark All + 標記所有 + + + + Remove Comment + 取消注釋 + + + + Copy failed: not enough memory + 內存不足,複製失敗 + + + + Press ALT and click lines to edit in column mode + 請使用ALT+鼠標點選切換列編輯模式 + + + + Change Case + 切換大小寫 + + + + Upper Case + 大寫 + + + + Lower Case + 小寫 + + + + Capitalize + 首字母大寫 + + + + None + + + + + Selected line(s) copied + 已複製選中行到剪貼板 + + + + Current line copied + 已複製當前行到剪貼板 + + + + Selected line(s) clipped + 已剪切選中行到剪貼板 + + + + Current line clipped + 已剪切當前行到剪貼板 + + + + Paste failed: not enough memory + 內存不足,黏貼失敗 + + + + Read-Only mode is off + 只讀模式已關閉 + + + + + + Read-Only mode is on + 只讀模式已開啟 + + + + WarningNotices + + + Reload + 重新載入 + + + + Window + + + + Save as + 另存為 + + + + New window + 新窗口 + + + + New tab + 新標籤頁 + + + + Open file + 打開文件 + + + + + Save + 保存 + + + + Print + 打印 + + + + Switch theme + 切換主題 + + + + + Settings + 設置 + + + + + Read-Only + 只讀 + + + + You do not have permission to open %1 + 您沒有權限打開%1 + + + + Invalid file: %1 + 無效文件:%1 + + + + + Do you want to save this file? + 您是否要保存此文件? + + + + You do not have permission to save %1 + 您沒有權限保存%1 + + + + Saved successfully + 文件已保存 + + + + + + Save File + 保存 + + + + Encoding + 編碼 + + + + Read-Only mode is on + 只讀模式已開啟 + + + + Current location remembered + 已記住當前位置 + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + 編輯 + + + + Untitled %1 + 未命名文檔%1 + + + + Cancel + 取消 + + + + Discard + 不保存 + + + \ No newline at end of file diff --git a/translations/deepin-editor_zh_TW.ts b/translations/deepin-editor_zh_TW.ts new file mode 100644 index 0000000000000000000000000000000000000000..ea89e76d5e225c8120ab0a87a94caf9d18253a78 --- /dev/null +++ b/translations/deepin-editor_zh_TW.ts @@ -0,0 +1,1286 @@ + + + BottomBar + + + Row + + + + + Column + + + + + Characters %1 + 字數 %1 + + + + Loading: + 文件載入中: + + + + DDropdownMenu + + + + + None + + + + + EditWrapper + + + + + + Save + 儲存 + + + + Do you want to save this file? + 您是否要儲存此文件? + + + + + Cancel + 取消 + + + + Encoding changed. Do you want to save the file now? + 文件編碼已更改,是否先進行儲存? + + + + Discard + 不儲存 + + + + You do not have permission to save %1 + 您沒有權限儲存%1 + + + + File removed on the disk. Save it now? + 磁碟中的原文件已被移除,是否另存? + + + + File has changed on disk. Reload? + 磁碟上的檔案已被更改。是否重新載入? + + + + + INSERT + 插入 + + + + OVERWRITE + 覆蓋 + + + + R/O + 唯讀 + + + + FindBar + + + Find + 尋找 + + + + Previous + 上一個 + + + + Next + 下一個 + + + + JumpLineBar + + + Go to Line: + 跳到行: + + + + MainWindow + + + Text Editor is a powerful tool for viewing and editing text files. + 文字編輯器是一款用來查看和編輯文字文件的工具。 + + + + Text Editor + 文字編輯器 + + + + PathSettingWgt + + + Remember the last used path + 記住最後的操作路徑 + + + + Same path as the current file + 與目前文件保持一致 + + + + Customize the default path + 自訂操作路徑 + + + + QObject + + + Text Editor + 文字編輯器 + + + + + + + + + Encoding + 編碼 + + + + Basic + 基礎設定 + + + + Font Style + 字體樣式 + + + + Font + 字體 + + + + Font Size + 字號 + + + + Shortcuts + 快捷鍵 + + + + + Keymap + 快捷鍵映射 + + + + + + Window + 視窗 + + + + New tab + 新分頁 + + + + New window + 新視窗 + + + + Save + 儲存 + + + + Save as + 另存為 + + + + Next tab + 下一個分頁 + + + + Previous tab + 上一個分頁 + + + + Close tab + 關閉分頁 + + + + Close other tabs + 關閉其他分頁 + + + + Restore tab + 復原分頁 + + + + Open file + 打開文件 + + + + Increment font size + 放大字號 + + + + Decrement font size + 縮小字號 + + + + Reset font size + 還原字號 + + + + Help + 幫助 + + + + Toggle fullscreen + 切換全螢幕 + + + + Find + 尋找 + + + + Replace + 取代 + + + + Go to line + 跳到行 + + + + Save cursor position + 儲存游標位置 + + + + Reset cursor position + 跳轉到儲存游標位置 + + + + Exit + 退出 + + + + Display shortcuts + 顯示快捷鍵 + + + + Print + 列印 + + + + Editor + 編輯 + + + + Increase indent + 增加縮排 + + + + Decrease indent + 減少縮排 + + + + Forward character + 右移一個字元 + + + + Backward character + 左移一個字元 + + + + Forward word + 右移一個詞 + + + + Backward word + 左移一個詞 + + + + Next line + 下一行 + + + + Previous line + 上一行 + + + + New line + 換行 + + + + New line above + 向上插入一行 + + + + New line below + 向下插入一行 + + + + Duplicate line + 複製並貼上目前行 + + + + Delete to end of line + 刪除到行尾 + + + + Delete current line + 刪除目前行 + + + + Swap line up + 上移一行 + + + + Swap line down + 下移一行 + + + + Scroll up one line + 向上滾動一行 + + + + Scroll down one line + 向下滾動一行 + + + + Page up + 向上滾動一頁 + + + + Page down + 向下滾動一頁 + + + + Move to end of line + 移動到行尾 + + + + Move to start of line + 移動到行頭 + + + + Move to end of text + 移動到文字結尾 + + + + Move to start of text + 移動到文字開頭 + + + + Move to line indentation + 移動到行縮排 + + + + Upper case + 轉換為大寫 + + + + Lower case + 轉換為小寫 + + + + Capitalize + 首字母大寫 + + + + Delete backward word + 向左刪除一個詞 + + + + Delete forward word + 向右刪除一個詞 + + + + Forward over a pair + 向右匹配 + + + + Backward over a pair + 向左匹配 + + + + Select all + 全選 + + + + Copy + 複製 + + + + Cut + 剪下 + + + + Paste + 貼上 + + + + Transpose character + 調換字元 + + + + Mark + 設定標記 + + + + Unmark + 取消標記 + + + + Copy line + 複製行 + + + + Cut line + 剪下行 + + + + Merge lines + 合併行 + + + + Read-Only mode + 切換到唯讀模式 + + + + Add comment + 添加注釋 + + + + Remove comment + 取消注釋 + + + + Undo + 復原 + + + + Redo + 重做 + + + + Add/Remove bookmark + 添加/清除書籤 + + + + Move to previous bookmark + 跳轉到上一個書籤 + + + + Move to next bookmark + 跳轉到下一個書籤 + + + + Advanced + 進階設定 + + + + Window size + 視窗狀態 + + + + Tab width + Tab字元寬度 + + + + Paste by pressing a middle mouse button + 允許滑鼠中鍵貼上 + + + + Startup + 啟動 + + + + Reopen last closed tabs + 保留關閉前的頁簽 + + + + Open/Save Settings + 打開/儲存設定 + + + + Word wrap + 自動換行 + + + + Code folding flag + 顯示程式碼摺疊標誌 + + + + Show line numbers + 顯示行號 + + + + Show bookmarks icon + 顯示書籤圖示 + + + + Show whitespaces and tabs + 顯示空白字元/定位符號 + + + + Highlight current line + 目前行突顯 + + + + Color mark + 顏色標記 + + + + Unicode + Unicode + + + + WesternEuropean + 西歐語系 + + + + CentralEuropean + 中歐語系 + + + + Baltic + 波羅的海語言 + + + + Cyrillic + 西里爾文 + + + + Arabic + 阿拉伯語 + + + + Celtic + 凱爾特語 + + + + SouthEasternEuropean + 東南歐語系 + + + + Greek + 希臘語 + + + + Hebrew + 希伯來語 + + + + ChineseSimplified + 簡體中文 + + + + ChineseTraditional + 繁體中文 + + + + Japanese + 日語 + + + + Korean + 韓語 + + + + Thai + 泰語 + + + + Turkish + 土耳其語 + + + + Vietnamese + 越南語 + + + + File not saved + 文件未儲存 + + + + + + Line Endings + 換行符 + + + + ReplaceBar + + + Find + 尋找 + + + + Replace With + 取代為 + + + + Replace + 取代 + + + + Skip + 跳過 + + + + Replace Rest + 剩餘取代 + + + + Replace All + 全部取代 + + + + S: + + + + The first line of the short usage message. + + + + + Settings + + + Standard + 標準 + + + + Customize + 自訂 + + + + Normal + 正常視窗 + + + + Maximum + 最大化 + + + + Fullscreen + 全螢幕 + + + + This shortcut conflicts with system shortcut %1 + 此快捷鍵與系統快捷鍵%1衝突 + + + + This shortcut conflicts with %1, click on Replace to make this shortcut effective immediately + 此快捷鍵與%1衝突,點擊取代使這個快捷鍵立即生效 + + + + + The shortcut %1 is invalid, please set another one. + %1為無效快捷鍵,請重新設定 + + + + Cancel + 取消 + + + + Replace + 取代 + + + + OK + 確定 + + + + StartManager + + + Untitled %1 + 未命名文件%1 + + + + Tabbar + + + Close tab + 關閉分頁 + + + + Close other tabs + 關閉其他分頁 + + + + More options + 更多關閉方式 + + + + Close tabs to the left + 關閉左側所有分頁 + + + + Close tabs to the right + 關閉右側所有分頁 + + + + Close unmodified tabs + 關閉所有未修改分頁 + + + + TextEdit + + + Undo + 復原 + + + + Redo + 重做 + + + + Cut + 剪下 + + + + Copy + 複製 + + + + Paste + 貼上 + + + + Delete + 刪除 + + + + Select All + 全選 + + + + + Find + 尋找 + + + + + Replace + 取代 + + + + Go to Line + 跳到行 + + + + Turn on Read-Only mode + 開啟唯讀模式 + + + + Turn off Read-Only mode + 關閉唯讀模式 + + + + Fullscreen + 全螢幕 + + + + Exit fullscreen + 退出全螢幕 + + + + Display in file manager + 在檔案管理器中顯示 + + + + + Add Comment + 添加注釋 + + + + Text to Speech + 語音朗讀 + + + + Stop reading + 停止朗讀 + + + + Speech to Text + 語音聽寫 + + + + Translate + 文字翻譯 + + + + Column Mode + 列編輯模式 + + + + Add bookmark + 添加書籤 + + + + Remove Bookmark + 清除書籤 + + + + Previous bookmark + 上一個書籤 + + + + Next bookmark + 下一個書籤 + + + + Remove All Bookmarks + 清除所有書籤 + + + + Fold All + 摺疊所有層次 + + + + Fold Current Level + 摺疊目前層次 + + + + Unfold All + 展開所有層次 + + + + Unfold Current Level + 展開目前層次 + + + + Color Mark + 顏色標記 + + + + Clear All Marks + 清除所有標記 + + + + Clear Last Mark + 清除上次標記 + + + + Mark + 添加標記 + + + + Mark All + 標記所有 + + + + Remove Comment + 取消注釋 + + + + Copy failed: not enough memory + 記憶體不足,複製失敗 + + + + Press ALT and click lines to edit in column mode + 請使用ALT+滑鼠點選切換列編輯模式 + + + + Change Case + 切換大小寫 + + + + Upper Case + 大寫 + + + + Lower Case + 小寫 + + + + Capitalize + 首字母大寫 + + + + None + + + + + Selected line(s) copied + 已複製選中行到剪貼簿 + + + + Current line copied + 已複製目前行到剪貼簿 + + + + Selected line(s) clipped + 已剪下選中行到剪貼簿 + + + + Current line clipped + 已剪下目前行到剪貼簿 + + + + Paste failed: not enough memory + 記憶體不足,貼上失敗 + + + + Read-Only mode is off + 唯讀模式已關閉 + + + + + + Read-Only mode is on + 唯讀模式已開啟 + + + + WarningNotices + + + Reload + 重新載入 + + + + Window + + + + Save as + 另存為 + + + + New window + 新視窗 + + + + New tab + 新分頁 + + + + Open file + 打開文件 + + + + + Save + 儲存 + + + + Print + 列印 + + + + Switch theme + 切換主題 + + + + + Settings + 設定 + + + + + Read-Only + 唯讀 + + + + You do not have permission to open %1 + 您沒有權限打開%1 + + + + Invalid file: %1 + 無效文件:%1 + + + + + Do you want to save this file? + 您是否要儲存此文件? + + + + You do not have permission to save %1 + 您沒有權限儲存%1 + + + + Saved successfully + 文件已儲存 + + + + + + Save File + 儲存 + + + + Encoding + 編碼 + + + + Read-Only mode is on + 唯讀模式已開啟 + + + + Current location remembered + 已記住目前位置 + + + + Ctrl+'=' + Ctrl+'=' + + + + Ctrl+'-' + Ctrl+'-' + + + + Editor + 編輯 + + + + Untitled %1 + 未命名文件%1 + + + + Cancel + 取消 + + + + Discard + 不儲存 + + + \ No newline at end of file diff --git a/translations/desktop/desktop.ts b/translations/desktop/desktop.ts new file mode 100644 index 0000000000000000000000000000000000000000..f15ecc0c4503bf22ca205001854e2213a91c5461 --- /dev/null +++ b/translations/desktop/desktop.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin Text EditorText EditorText EditorSimple and easy to use text editorSimple and easy to use text editor \ No newline at end of file diff --git a/translations/desktop/desktop_ar.ts b/translations/desktop/desktop_ar.ts new file mode 100644 index 0000000000000000000000000000000000000000..509f08f527937c0be7c9acdefcd49ccc264906d0 --- /dev/null +++ b/translations/desktop/desktop_ar.ts @@ -0,0 +1 @@ +desktopDeepin Text Editorمحرر نصوص ديبينText Editorمحرر النصوصSimple and easy to use text editorمحرر النصوص بسيط وسهل الاستخدام \ No newline at end of file diff --git a/translations/desktop/desktop_az.ts b/translations/desktop/desktop_az.ts new file mode 100644 index 0000000000000000000000000000000000000000..14960ecadce1d8e117c61d0182b105a294e71283 --- /dev/null +++ b/translations/desktop/desktop_az.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin Mətn RedaktoruText EditorMətn RedaktoruSimple and easy to use text editorSadə və rahat mətn redaktoru \ No newline at end of file diff --git a/translations/desktop/desktop_bo.ts b/translations/desktop/desktop_bo.ts new file mode 100644 index 0000000000000000000000000000000000000000..36524383e916be1935cbcf9dd4950f9c7e52fe82 --- /dev/null +++ b/translations/desktop/desktop_bo.ts @@ -0,0 +1 @@ +desktopDeepin Text Editorགཏིང་ཟབ་ཡིག་ཆ་རྩོམ་སྒྲིག་ཆས།Text Editorཡིག་ཆ་རྩོམ་སྒྲུག་ཆས།Simple and easy to use text editorསྟབས་བདེ་ལ་སྤྱོད་བདེ་བའི་ཡིག་ཆ་རྩོམ་སྒྲིག་ཆས། \ No newline at end of file diff --git a/translations/desktop/desktop_br.ts b/translations/desktop/desktop_br.ts new file mode 100644 index 0000000000000000000000000000000000000000..42d923ec4eb7c5a558b5df4ba5f44d3d5abe2690 --- /dev/null +++ b/translations/desktop/desktop_br.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorAozer testennoù DeepinText EditorAozer testennoùSimple and easy to use text editorAn aozer testennoù simpl hag aes d'ober gantañ \ No newline at end of file diff --git a/translations/desktop/desktop_ca.ts b/translations/desktop/desktop_ca.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb4cd18dc83f02c303dc278fb823c2784b990ce8 --- /dev/null +++ b/translations/desktop/desktop_ca.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorEditor de text del DeepinText EditorEditor de textSimple and easy to use text editorEditor de text simple i fàcil d'usar \ No newline at end of file diff --git a/translations/desktop/desktop_cs.ts b/translations/desktop/desktop_cs.ts new file mode 100644 index 0000000000000000000000000000000000000000..7f412605b02d68c740d618023220e841f0788d80 --- /dev/null +++ b/translations/desktop/desktop_cs.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin textový editorText EditorTextový editorSimple and easy to use text editorJednoduchý a snadno se používající textový editor \ No newline at end of file diff --git a/translations/desktop/desktop_da.ts b/translations/desktop/desktop_da.ts new file mode 100644 index 0000000000000000000000000000000000000000..4d6c1a9ca704563aa2a2437e56cd482840888f89 --- /dev/null +++ b/translations/desktop/desktop_da.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin teksteditorText EditorTeksteditorSimple and easy to use text editorSimpel og letanvendelig teksteditor \ No newline at end of file diff --git a/translations/desktop/desktop_de.ts b/translations/desktop/desktop_de.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb2d88bc2510ebace8dd2c1bb5a3ca4d215bfc88 --- /dev/null +++ b/translations/desktop/desktop_de.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin TexteditorText EditorTexteditorSimple and easy to use text editorEinfacher, leicht zu bedienender Texteditor \ No newline at end of file diff --git a/translations/desktop/desktop_el.ts b/translations/desktop/desktop_el.ts new file mode 100644 index 0000000000000000000000000000000000000000..fc6f6f9c361a8c46d947a99d56d9f5c1f924903d --- /dev/null +++ b/translations/desktop/desktop_el.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin Επεξεργαστής ΚειμένουText EditorΕπεξεργαστής ΚειμένουSimple and easy to use text editorΑπλός κι εύχρηστος επεξεργαστής κειμένου \ No newline at end of file diff --git a/translations/desktop/desktop_es.ts b/translations/desktop/desktop_es.ts new file mode 100644 index 0000000000000000000000000000000000000000..d74e4e473f72eae7184b0ee1ac84ec3dc18a4c08 --- /dev/null +++ b/translations/desktop/desktop_es.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorEditor de textoText EditorEditor de textoSimple and easy to use text editorEditor de texto simple y fácil de usar \ No newline at end of file diff --git a/translations/desktop/desktop_et.ts b/translations/desktop/desktop_et.ts new file mode 100644 index 0000000000000000000000000000000000000000..9beda8aff1b4ccb29b93128b5b2866234ee57674 --- /dev/null +++ b/translations/desktop/desktop_et.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin tekstiredaktorText EditorTekstiredaktorSimple and easy to use text editorLihtne ja kergesti kasutatav tekstiredaktor \ No newline at end of file diff --git a/translations/desktop/desktop_fi.ts b/translations/desktop/desktop_fi.ts new file mode 100644 index 0000000000000000000000000000000000000000..1af9b5e8ea24dcaa954442b81416c7a5679c3604 --- /dev/null +++ b/translations/desktop/desktop_fi.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin tekstieditoriText EditorTekstieditoriSimple and easy to use text editorYksinkertainen ja helppokäyttöinen tekstieditori \ No newline at end of file diff --git a/translations/desktop/desktop_fr.ts b/translations/desktop/desktop_fr.ts new file mode 100644 index 0000000000000000000000000000000000000000..6ba205d067c6586c0f097455916ca940c20d356f --- /dev/null +++ b/translations/desktop/desktop_fr.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorÉditeur de texte DeepinText EditorÉditeur de texteSimple and easy to use text editorÉditeur de texte simple et facile à utiliser \ No newline at end of file diff --git a/translations/desktop/desktop_gl_ES.ts b/translations/desktop/desktop_gl_ES.ts new file mode 100644 index 0000000000000000000000000000000000000000..f5eaffd259ea398691cb7a84f83ea06632177a48 --- /dev/null +++ b/translations/desktop/desktop_gl_ES.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorEditor de texto DeepinText EditorEditor de textoSimple and easy to use text editorEditor de texto sinxelo e fácil de usar \ No newline at end of file diff --git a/translations/desktop/desktop_hi_IN.ts b/translations/desktop/desktop_hi_IN.ts new file mode 100644 index 0000000000000000000000000000000000000000..85edf0b202f6caf24c1863ac89529fda049bf417 --- /dev/null +++ b/translations/desktop/desktop_hi_IN.ts @@ -0,0 +1 @@ +desktopDeepin Text Editorदीपिन लेख संपादकText Editorलेख संपादकSimple and easy to use text editorसरल व उपयोग हेतु सुगम लेख संपादक \ No newline at end of file diff --git a/translations/desktop/desktop_hr.ts b/translations/desktop/desktop_hr.ts new file mode 100644 index 0000000000000000000000000000000000000000..d028fc968470fe1a9c96bb6f5a4520c09cd3bffe --- /dev/null +++ b/translations/desktop/desktop_hr.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin uređivač tekstaText EditorUređivač tekstaSimple and easy to use text editorJednostavan i lagan za korištenje uređivač teksta \ No newline at end of file diff --git a/translations/desktop/desktop_hu.ts b/translations/desktop/desktop_hu.ts new file mode 100644 index 0000000000000000000000000000000000000000..829da23822e32a1147dd698860e12386867a6907 --- /dev/null +++ b/translations/desktop/desktop_hu.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin® SzövegszerkesztőText EditorSzövegszerkesztőSimple and easy to use text editorLetisztult és könnyen használható szövegszerkesztő \ No newline at end of file diff --git a/translations/desktop/desktop_it.ts b/translations/desktop/desktop_it.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b5ff69bd85e35b85be012923ef3a244e8c39c19 --- /dev/null +++ b/translations/desktop/desktop_it.ts @@ -0,0 +1,2 @@ +desktopDeepin Text EditorEditor di Testo di DeepinText EditorEditor di TestoSimple and easy to use text editorEditor di testo semplice e facile da usare. +Localizzazione italiana a cura di Massimo A. Carofano. \ No newline at end of file diff --git a/translations/desktop/desktop_ko.ts b/translations/desktop/desktop_ko.ts new file mode 100644 index 0000000000000000000000000000000000000000..cbbb598df20ef76a9dbc062740eb6cad1262b1c1 --- /dev/null +++ b/translations/desktop/desktop_ko.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin 텍스트 편집기Text Editor텍스트 편집기Simple and easy to use text editor단순하고 사용하기 쉬운 텍스트 편집기 \ No newline at end of file diff --git a/translations/desktop/desktop_lt.ts b/translations/desktop/desktop_lt.ts new file mode 100644 index 0000000000000000000000000000000000000000..225fe7274804bc5cfad3809b3f3a880a7efd78db --- /dev/null +++ b/translations/desktop/desktop_lt.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin tekstų redaktoriusText EditorTekstų redaktoriusSimple and easy to use text editorPaprastas ir lengvas naudoti tekstų redaktorius \ No newline at end of file diff --git a/translations/desktop/desktop_ms.ts b/translations/desktop/desktop_ms.ts new file mode 100644 index 0000000000000000000000000000000000000000..c662d8ef9662be237ac192f455d5e650466096b9 --- /dev/null +++ b/translations/desktop/desktop_ms.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorPenyunting Teks DeepinText EditorPenyunting TeksSimple and easy to use text editorPenyunting teks yang ringkas dan mudah digunakan \ No newline at end of file diff --git a/translations/desktop/desktop_nl.ts b/translations/desktop/desktop_nl.ts new file mode 100644 index 0000000000000000000000000000000000000000..7467114e5d277a4cd79fe8342d98385e9f3ab839 --- /dev/null +++ b/translations/desktop/desktop_nl.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin TekstbewerkerText EditorTekstbewerkerSimple and easy to use text editorEenvoudig te gebruiken tekstbewerker \ No newline at end of file diff --git a/translations/desktop/desktop_pl.ts b/translations/desktop/desktop_pl.ts new file mode 100644 index 0000000000000000000000000000000000000000..7cb6caf66dea12001830067fe02bbfdd9f09fea0 --- /dev/null +++ b/translations/desktop/desktop_pl.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorEdytor Tekstu DeepinText EditorEdytor tekstuSimple and easy to use text editorProsty i łatwy w użyciu edytor tekstu \ No newline at end of file diff --git a/translations/desktop/desktop_pt.ts b/translations/desktop/desktop_pt.ts new file mode 100644 index 0000000000000000000000000000000000000000..18446141417efe5c2eb04daa4f3e2498eacd7ad7 --- /dev/null +++ b/translations/desktop/desktop_pt.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorEditor de texto DeepinText EditorEditor de textoSimple and easy to use text editorEditor de texto simples e fácil de usar \ No newline at end of file diff --git a/translations/desktop/desktop_pt_BR.ts b/translations/desktop/desktop_pt_BR.ts new file mode 100644 index 0000000000000000000000000000000000000000..0f656a6e3c410ca040a7746adb4f8cd6278daa62 --- /dev/null +++ b/translations/desktop/desktop_pt_BR.ts @@ -0,0 +1 @@ +desktopDeepin Text Editordeepin Editor de TextosText EditorEditor de TextosSimple and easy to use text editorUm editor de texto simples e fácil de usar \ No newline at end of file diff --git a/translations/desktop/desktop_ru.ts b/translations/desktop/desktop_ru.ts new file mode 100644 index 0000000000000000000000000000000000000000..1ab23f0f7e69dd7c8bb602718a989f21a821eeb1 --- /dev/null +++ b/translations/desktop/desktop_ru.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorТекстовый Редактор DeepinText EditorТекстовый редакторSimple and easy to use text editorПростой и удобный текстовый редактор \ No newline at end of file diff --git a/translations/desktop/desktop_sl.ts b/translations/desktop/desktop_sl.ts new file mode 100644 index 0000000000000000000000000000000000000000..62f40e7e749e8d65d0ab9e1138d29b106532e411 --- /dev/null +++ b/translations/desktop/desktop_sl.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin urejevalnik besedilText EditorUrejevalnik besedilSimple and easy to use text editorPreprost urejevalnik besedil \ No newline at end of file diff --git a/translations/desktop/desktop_sq.ts b/translations/desktop/desktop_sq.ts new file mode 100644 index 0000000000000000000000000000000000000000..0e3dd9a0fcaa3afb382a3cbacb038b07fbb8dac5 --- /dev/null +++ b/translations/desktop/desktop_sq.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorPërpunues Tekstesh DeepinText EditorPërpunues TeksteshSimple and easy to use text editorPërpunues tekstesh i thjeshtë dhe i kollajtë për t’u përdorur \ No newline at end of file diff --git a/translations/desktop/desktop_sr.ts b/translations/desktop/desktop_sr.ts new file mode 100644 index 0000000000000000000000000000000000000000..93638c5e2f010e7cccb2cd0bdf403652d838ef21 --- /dev/null +++ b/translations/desktop/desktop_sr.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorДипин Уређивач ТекстаText EditorУређивач ТекстаSimple and easy to use text editorУењђивач текста који је једноставан за употребу \ No newline at end of file diff --git a/translations/desktop/desktop_tr.ts b/translations/desktop/desktop_tr.ts new file mode 100644 index 0000000000000000000000000000000000000000..fa87995a10625205f6f8241a7a910eaeefe9a0e1 --- /dev/null +++ b/translations/desktop/desktop_tr.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin Metin DüzenleyiciText EditorMetin DüzenleyiciSimple and easy to use text editorBasit ve kullanımı kolay metin düzenleyici \ No newline at end of file diff --git a/translations/desktop/desktop_ug.ts b/translations/desktop/desktop_ug.ts new file mode 100644 index 0000000000000000000000000000000000000000..e271d6f628fc5830d5d4a0bf14ac26130908cc40 --- /dev/null +++ b/translations/desktop/desktop_ug.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin تېكىست تەھرىرلىگۈچText Editorتېكىست تەھرىرلىگۈچSimple and easy to use text editorئاددىي، قوللىنىشچان تېكىست تەھرىرلىگۈچ \ No newline at end of file diff --git a/translations/desktop/desktop_uk.ts b/translations/desktop/desktop_uk.ts new file mode 100644 index 0000000000000000000000000000000000000000..58c1e707858cb6a81e96ad289adc7f02af6bd49a --- /dev/null +++ b/translations/desktop/desktop_uk.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorТекстовий редактор DeepinText EditorТекстовий редакторSimple and easy to use text editorПростий і доступний текстовий редактор \ No newline at end of file diff --git a/translations/desktop/desktop_zh_CN.ts b/translations/desktop/desktop_zh_CN.ts new file mode 100644 index 0000000000000000000000000000000000000000..5fbbbdcfe9c28b7cbc92217be5e5a2a17f398621 --- /dev/null +++ b/translations/desktop/desktop_zh_CN.ts @@ -0,0 +1 @@ +desktopDeepin Text Editor深度文本编辑器Text Editor文本编辑器Simple and easy to use text editor简单好用的文本编辑器 \ No newline at end of file diff --git a/translations/desktop/desktop_zh_HK.ts b/translations/desktop/desktop_zh_HK.ts new file mode 100644 index 0000000000000000000000000000000000000000..3d6461a78331fb5c070abc157fd80789778da7b4 --- /dev/null +++ b/translations/desktop/desktop_zh_HK.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin 文本編輯器Text Editor文本編輯器Simple and easy to use text editor簡單好用的文本編輯器 \ No newline at end of file diff --git a/translations/desktop/desktop_zh_TW.ts b/translations/desktop/desktop_zh_TW.ts new file mode 100644 index 0000000000000000000000000000000000000000..261870872ff08b2105db72cf6bc48ff51fb084b6 --- /dev/null +++ b/translations/desktop/desktop_zh_TW.ts @@ -0,0 +1 @@ +desktopDeepin Text EditorDeepin 文字編輯器Text Editor文字編輯器Simple and easy to use text editor簡單好用的文字編輯器 \ No newline at end of file