Merge lp:~dpm/ubuntu-terminal-app/merge-plugin into lp:ubuntu-terminal-app

Proposed by David Planella
Status: Merged
Approved by: Nicholas Skaggs
Approved revision: 75
Merged at revision: 57
Proposed branch: lp:~dpm/ubuntu-terminal-app/merge-plugin
Merge into: lp:ubuntu-terminal-app
Diff against target: 25271 lines (+24506/-71)
106 files modified
.bzrignore (+0/-6)
CMakeLists.txt (+33/-18)
README (+0/-1)
README.md (+152/-0)
apparmor.json (+3/-2)
click/CMakeLists.txt (+0/-8)
debian/changelog (+6/-2)
debian/control (+29/-8)
debian/qtdeclarative5-konsole-qml-plugin.install (+1/-0)
manifest.json (+6/-6)
plugins.json (+0/-6)
src/CMakeLists.txt (+2/-0)
src/app/CMakeLists.txt (+24/-0)
src/app/main.cpp (+120/-0)
src/plugin/CMakeLists.txt (+7/-0)
src/plugin/konsole/BlockArray.cpp (+377/-0)
src/plugin/konsole/BlockArray.h (+126/-0)
src/plugin/konsole/CMakeLists.txt (+93/-0)
src/plugin/konsole/Character.h (+221/-0)
src/plugin/konsole/CharacterColor.h (+294/-0)
src/plugin/konsole/ColorScheme.cpp (+774/-0)
src/plugin/konsole/ColorScheme.h (+342/-0)
src/plugin/konsole/ColorTables.h (+55/-0)
src/plugin/konsole/DefaultTranslatorText.h (+2/-0)
src/plugin/konsole/Emulation.cpp (+458/-0)
src/plugin/konsole/Emulation.h (+467/-0)
src/plugin/konsole/ExtendedDefaultTranslator.h (+74/-0)
src/plugin/konsole/Filter.cpp (+542/-0)
src/plugin/konsole/Filter.h (+380/-0)
src/plugin/konsole/History.cpp (+986/-0)
src/plugin/konsole/History.h (+490/-0)
src/plugin/konsole/KeyboardTranslator.cpp (+892/-0)
src/plugin/konsole/KeyboardTranslator.h (+584/-0)
src/plugin/konsole/LineFont.h (+21/-0)
src/plugin/konsole/LineFont.src (+786/-0)
src/plugin/konsole/Pty.cpp (+310/-0)
src/plugin/konsole/Pty.h (+206/-0)
src/plugin/konsole/Screen.cpp (+1360/-0)
src/plugin/konsole/Screen.h (+672/-0)
src/plugin/konsole/ScreenWindow.cpp (+292/-0)
src/plugin/konsole/ScreenWindow.h (+257/-0)
src/plugin/konsole/Session.cpp (+1064/-0)
src/plugin/konsole/Session.h (+626/-0)
src/plugin/konsole/ShellCommand.cpp (+167/-0)
src/plugin/konsole/ShellCommand.h (+90/-0)
src/plugin/konsole/TerminalCharacterDecoder.cpp (+251/-0)
src/plugin/konsole/TerminalCharacterDecoder.h (+148/-0)
src/plugin/konsole/TerminalDisplay.cpp (+2170/-0)
src/plugin/konsole/TerminalDisplay.h (+715/-0)
src/plugin/konsole/Vt102Emulation.cpp (+1221/-0)
src/plugin/konsole/Vt102Emulation.h (+188/-0)
src/plugin/konsole/assets/color-schemes/BlackOnLightYellow.schema (+42/-0)
src/plugin/konsole/assets/color-schemes/BlackOnRandomLight.colorscheme (+104/-0)
src/plugin/konsole/assets/color-schemes/BlackOnWhite.schema (+42/-0)
src/plugin/konsole/assets/color-schemes/DarkPastels.colorscheme (+103/-0)
src/plugin/konsole/assets/color-schemes/GreenOnBlack.colorscheme (+104/-0)
src/plugin/konsole/assets/color-schemes/Linux.colorscheme (+100/-0)
src/plugin/konsole/assets/color-schemes/WhiteOnBlack.schema (+42/-0)
src/plugin/konsole/assets/color-schemes/historic/BlackOnLightColor.schema (+42/-0)
src/plugin/konsole/assets/color-schemes/historic/DarkPicture.schema (+44/-0)
src/plugin/konsole/assets/color-schemes/historic/Example.Schema (+47/-0)
src/plugin/konsole/assets/color-schemes/historic/GreenOnBlack.schema (+42/-0)
src/plugin/konsole/assets/color-schemes/historic/GreenTint.schema (+49/-0)
src/plugin/konsole/assets/color-schemes/historic/GreenTint_MC.schema (+49/-0)
src/plugin/konsole/assets/color-schemes/historic/LightPicture.schema (+44/-0)
src/plugin/konsole/assets/color-schemes/historic/Linux.schema (+47/-0)
src/plugin/konsole/assets/color-schemes/historic/README.Schema (+132/-0)
src/plugin/konsole/assets/color-schemes/historic/README.default.Schema (+44/-0)
src/plugin/konsole/assets/color-schemes/historic/Transparent.schema (+49/-0)
src/plugin/konsole/assets/color-schemes/historic/Transparent_MC.schema (+51/-0)
src/plugin/konsole/assets/color-schemes/historic/Transparent_darkbg.schema (+42/-0)
src/plugin/konsole/assets/color-schemes/historic/Transparent_lightbg.schema (+51/-0)
src/plugin/konsole/assets/color-schemes/historic/XTerm.schema (+46/-0)
src/plugin/konsole/assets/color-schemes/historic/syscolor.schema (+44/-0)
src/plugin/konsole/assets/color-schemes/historic/vim.schema (+40/-0)
src/plugin/konsole/assets/kb-layouts/README (+72/-0)
src/plugin/konsole/assets/kb-layouts/default.keytab (+169/-0)
src/plugin/konsole/assets/kb-layouts/historic/vt100.keytab (+133/-0)
src/plugin/konsole/assets/kb-layouts/historic/x11r5.keytab (+71/-0)
src/plugin/konsole/assets/kb-layouts/linux.keytab (+164/-0)
src/plugin/konsole/assets/kb-layouts/macbook.keytab (+175/-0)
src/plugin/konsole/assets/kb-layouts/solaris.keytab (+108/-0)
src/plugin/konsole/assets/kb-layouts/vt420pc.keytab (+168/-0)
src/plugin/konsole/default.keytab (+128/-0)
src/plugin/konsole/konsole_wcwidth.cpp (+224/-0)
src/plugin/konsole/konsole_wcwidth.h (+24/-0)
src/plugin/konsole/kprocess.cpp (+412/-0)
src/plugin/konsole/kprocess.h (+372/-0)
src/plugin/konsole/kpty.cpp (+701/-0)
src/plugin/konsole/kpty.h (+191/-0)
src/plugin/konsole/kpty_p.h (+50/-0)
src/plugin/konsole/kptydevice.cpp (+422/-0)
src/plugin/konsole/kptydevice.h (+360/-0)
src/plugin/konsole/kptyprocess.cpp (+129/-0)
src/plugin/konsole/kptyprocess.h (+178/-0)
src/plugin/konsole/ksession.cpp (+242/-0)
src/plugin/konsole/ksession.h (+132/-0)
src/plugin/konsole/plugin.cpp (+63/-0)
src/plugin/konsole/plugin.h (+46/-0)
src/plugin/konsole/plugins.qmltypes (+169/-0)
src/plugin/konsole/qmldir (+3/-0)
src/plugin/konsole/tools.cpp (+80/-0)
src/plugin/konsole/tools.h (+10/-0)
tests/autopilot/CMakeLists.txt (+1/-1)
tests/autopilot/ubuntu_terminal_app/tests/__init__.py (+25/-10)
ubuntu-terminal-app.in (+0/-3)
To merge this branch: bzr merge lp:~dpm/ubuntu-terminal-app/merge-plugin
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Nicholas Skaggs Pending
Review via email: mp+217380@code.launchpad.net

Commit message

Merge the terminal app's plugin into the app's repository

Description of the change

This branch merges the terminal app's plugin into the app's repository, enabling shipping the plugin into the same .click package. Separate .deb packages for the app and the plugin are still generated.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :

FAILED: Continuous integration, rev:67
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~dpm/ubuntu-terminal-app/merge-plugin/+merge/217380/+edit-commit-message

http://91.189.93.70:8080/job/ubuntu-terminal-app-ci/49/
Executed test runs:
    SUCCESS: http://91.189.93.70:8080/job/generic-mediumtests-trusty/2254
    SUCCESS: http://91.189.93.70:8080/job/ubuntu-terminal-app-raring-amd64-ci/49
    SUCCESS: http://91.189.93.70:8080/job/ubuntu-terminal-app-saucy-amd64-ci/49
    SUCCESS: http://91.189.93.70:8080/job/ubuntu-terminal-app-trusty-amd64-ci/37

Click here to trigger a rebuild:
http://91.189.93.70:8080/job/ubuntu-terminal-app-ci/49/rebuild

review: Needs Fixing (continuous-integration)
68. By David Planella

Added rule to copy the plugin to the build directory

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 🦄 (popey) wrote :

Tried building this in qtcreator, it built a click package, but that fails the click-reviewers-tools..

ERROR: Could not find 'com.ubuntu.terminal.desktop.in'

69. By David Planella

Fixed wrong desktop file in the manifest

Revision history for this message
David Planella (dpm) wrote :

Sorry, that was a typo in the manifest file. Fixed now.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 🦄 (popey) wrote :

Trying to test this but qtc is conspiring against me: bug 1314960

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

In order to get this to run, you need the python3-lxml lib added to /home/phablet/autopilot -- and you need the armhf version as it's a compiled module ;-) I would recommend adding this info to the readme.

I was able to successfully build and run this on my device.

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

I would also change the dependency to python3-lxml from python-lxml.

70. By David Planella

Updated python-lxml dependency to Python 3, added note about manual set up for running tests on device

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

could not import package ubuntu_terminal_app: No module named 'ubuntu_terminal_app'
Loading tests from:

Did not find any tests

We had this same issue with shorts; py3 meant jenkins couldn't find the tests. If you change back to python-lxml I assume it will work.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

On 6 May 2014 18:09, Nicholas Skaggs <email address hidden> wrote:
> could not import package ubuntu_terminal_app: No module named 'ubuntu_terminal_app'
> Loading tests from:
>
> Did not find any tests
>
> We had this same issue with shorts; py3 meant jenkins couldn't find the tests. If you change back to python-lxml I assume it will work.

Both Python2 & Python3 comes with an xml module in the standard
library is that not sufficient?

--
Regards,

Dimitri.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

Dimitri, yes in this case I think we simply drop the lxml dependency.

In regards to what I was saying about jenkins missing tests, I finally figured out why jenkins wasn't finding the tests. It requires the core app to depend on python3, and for the cmakelists file for autopilot tests to copy the module to the python3 path, instead of python2 :-)

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

On 6 May 2014 19:39, Nicholas Skaggs <email address hidden> wrote:
> See https://code.launchpad.net/~nskaggs/ubuntu-terminal-app/working-py3-jenkins/+merge/218488 for the fix
> --
> https://code.launchpad.net/~dpm/ubuntu-terminal-app/merge-plugin/+merge/217380
> Your team Ubuntu Terminal Developers is subscribed to branch lp:ubuntu-terminal-app.

Or see... https://code.launchpad.net/~xnox/ubuntu-terminal-app/merge-plugin+lxml+py3
which is mid-air colition, slightly older than your branch.

--
Regards,

Dimitri.

Revision history for this message
David Planella (dpm) wrote :

As far as I can tell, the standard module is not a drop-in replacement for lxml, so just replacing the import won't work.

In any case, as discussed on IRC, I'll split this MP to separate the change that introduced the lxml dependency.

71. By David Planella

Reverted the feature of autodetecting Qt Creator's build dir. Will submit it in a separate MP

72. By David Planella

Updated README too

73. By David Planella

Merged nskagg's Jenkins Python 3 fixes

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
74. By David Planella

Merge Python 3 print() fix from balloons

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

Specify python3-autopilot so jenkins runs with it.

=== modified file 'debian/control'
--- debian/control 2014-05-06 19:04:04 +0000
+++ debian/control 2014-05-06 21:41:01 +0000
@@ -45,6 +45,7 @@
 Depends: ${misc:Depends},
          libautopilot-qt,
          libqt5test5,
+ python3-autopilot,
          ubuntu-terminal-app (>= ${source:Version}),
          ubuntu-ui-toolkit-autopilot,
 Description: Autopilot tests for Terminal Application

75. By David Planella

Add Python 3 dependency to make Jenkins happy

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2014-05-06 21:50:22 +0000
@@ -0,0 +1,16 @@
1Makefile
2src/*.so
3*user
4
5.moc/
6.obj/
7
8debian/files
9debian/qtdeclarative5-konsole-qml-plugin/
10debian/*.debhelper.log
11debian/*.substvars
12.excludes
13obj-x86_64-linux-gnu
14debian/tmp
15debian/ubuntu-terminal-app
16debian/ubuntu-terminal-app-autopilot
017
=== removed file '.bzrignore'
--- .bzrignore 2013-04-23 20:42:10 +0000
+++ .bzrignore 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
1*.qmlproject.user
2
3debian/files
4debian/ubuntu-terminal-app/
5debian/*.debhelper.log
6debian/*.substvars
70
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-04-15 18:00:53 +0000
+++ CMakeLists.txt 2014-05-06 21:50:22 +0000
@@ -1,6 +1,9 @@
1project(com.ubuntu.terminal)1project(com.ubuntu.terminal C CXX)
2cmake_minimum_required(VERSION 2.8.9)2cmake_minimum_required(VERSION 2.8.9)
33
4set(CMAKE_AUTOMOC ON)
5set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra -fPIC")
6
4# Standard install paths7# Standard install paths
5include(GNUInstallDirs)8include(GNUInstallDirs)
69
@@ -8,49 +11,61 @@
8option(CLICK_MODE "Installs to a contained location" off)11option(CLICK_MODE "Installs to a contained location" off)
912
10set(APP_NAME terminal)13set(APP_NAME terminal)
11set(DESKTOP_FILE "${PROJECT_NAME}_${APP_NAME}.desktop")14set(DESKTOP_FILE "${PROJECT_NAME}.desktop")
12set(URLS_FILE "${PROJECT_NAME}_${APP_NAME}.url-dispatcher")15set(URLS_FILE "${PROJECT_NAME}.url-dispatcher")
13set(APP_HARDCODE ubuntu-terminal-app)16set(APP_HARDCODE ubuntu-terminal-app)
14set(MAIN_QML ubuntu-terminal-app.qml)17set(MAIN_QML ubuntu-terminal-app.qml)
15set(ICON_FILE terminal64.png)18set(ICON_FILE terminal64.png)
16set(AUTOPILOT_DIR ubuntu_terminal_app)19set(AUTOPILOT_DIR ubuntu_terminal_app)
20set(EXEC "${APP_NAME}")
1721
18if(CLICK_MODE)22if(CLICK_MODE)
19 if(NOT DEFINED BZR_SOURCE)23 if(NOT DEFINED BZR_SOURCE)
20 set(BZR_SOURCE "lp:${APP_HARDCODE}")24 set(BZR_SOURCE "lp:${APP_HARDCODE}")
21 message("-- Setting BZR_SOURCE to ${BZR_SOURCE}")25 message("-- Setting BZR_SOURCE to ${BZR_SOURCE}")
22 endif(NOT DEFINED BZR_SOURCE)26 endif(NOT DEFINED BZR_SOURCE)
27 # Find out the architecture for package building
28 # to determine the plugin's installation path
29 execute_process(
30 COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
31 OUTPUT_VARIABLE ARCH_TRIPLET
32 OUTPUT_STRIP_TRAILING_WHITESPACE
33 )
23 set(CMAKE_INSTALL_PREFIX /)34 set(CMAKE_INSTALL_PREFIX /)
24 set(CMAKE_INSTALL_BINDIR /)35 set(CMAKE_INSTALL_BINDIR /)
25 set(DATA_DIR /)36 set(DATA_DIR /)
26 set(EXEC "qmlscene ${MAIN_QML}")
27 set(DESKTOP_DIR ${DATA_DIR})37 set(DESKTOP_DIR ${DATA_DIR})
28 set(URLS_DIR ${DATA_DIR})38 set(URLS_DIR ${DATA_DIR})
29 set(ICON ${ICON_FILE})39 set(ICON ${ICON_FILE})
40 set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}")
41 set(BIN_DIR /lib/${ARCH_TRIPLET}/bin)
42 if(NOT BZR_REVNO)
43 set(BZR_REVNO "latest")
44 endif(NOT BZR_REVNO)
45 configure_file(manifest.json ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
46 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json apparmor.json DESTINATION ${CMAKE_INSTALL_PREFIX})
30else(CLICK_MODE)47else(CLICK_MODE)
31 set(DATA_DIR ${CMAKE_INSTALL_DATADIR}/${APP_HARDCODE})48 execute_process(
32 set(EXEC ${APP_HARDCODE})49 COMMAND qmake -query QT_INSTALL_QML
33 set(ICON ${CMAKE_INSTALL_PREFIX}/${DATA_DIR}/${ICON_FILE})50 OUTPUT_VARIABLE QT_IMPORTS_DIR
34 configure_file(${APP_HARDCODE}.in51 OUTPUT_STRIP_TRAILING_WHITESPACE
35 ${CMAKE_CURRENT_BINARY_DIR}/${APP_HARDCODE})52 )
36 install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${APP_HARDCODE}53 set(DATA_DIR ${CMAKE_INSTALL_DATADIR}/${APP_NAME})
37 DESTINATION ${CMAKE_INSTALL_BINDIR})54 set(ICON ${CMAKE_INSTALL_PREFIX}/${DATA_DIR}/${ICON_FILE})
38 set(DESKTOP_DIR ${CMAKE_INSTALL_DATADIR}/applications)55 set(DESKTOP_DIR ${CMAKE_INSTALL_DATADIR}/applications)
39 set(URLS_DIR ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)56 set(URLS_DIR ${CMAKE_INSTALL_DATADIR}/url-dispatcher/urls)
40endif(CLICK_MODE)57endif(CLICK_MODE)
4158
42file(GLOB_RECURSE I18N_SRC_FILES59file(GLOB_RECURSE I18N_SRC_FILES
43 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}60 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
44 rc/**.qml desktop/**.desktop.in)61 src/app/**.qml *.desktop.in)
45list(SORT I18N_SRC_FILES)62list(SORT I18N_SRC_FILES)
4663
47
48file(GLOB SRC_FILES64file(GLOB SRC_FILES
49 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}65 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
50 *.qml *.js *.png *.js)66 *.qml *.js *.png *.js)
51install(DIRECTORY config extraPanel DESTINATION ${DATA_DIR})67install(FILES ${SRC_FILES}
52install(FILES Terminal.qml Configs.qml settings.png avatar@8.png68 DESTINATION ${DATA_DIR})
53 ${MAIN_QML} ${ICON_FILE} DESTINATION ${DATA_DIR})
5469
55configure_file(${DESKTOP_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE})70configure_file(${DESKTOP_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE})
56install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE}71install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE}
@@ -61,6 +76,6 @@
61# Tests76# Tests
62enable_testing()77enable_testing()
6378
64add_subdirectory(click)
65add_subdirectory(po)79add_subdirectory(po)
66add_subdirectory(tests)80add_subdirectory(tests)
81add_subdirectory(src)
6782
=== removed file 'README'
--- README 2013-02-12 16:18:48 +0000
+++ README 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
1this is an example README file.
20
=== added file 'README.md'
--- README.md 1970-01-01 00:00:00 +0000
+++ README.md 2014-05-06 21:50:22 +0000
@@ -0,0 +1,152 @@
1# Ubuntu Terminal
2
3A terminal app for desktop and mobile devices. It provides access to terminal
4sessions and is based on KDE's Konsole plugin.
5
6The current plugin consists of:
7- KTerminal: offers access to terminal session from qml
8- KSessions: offers access to pty(s) from C++ layer
9
10## Building the app
11
12### For the desktop
13
14Install the following build dependencies:
15
16(none required at the moment)
17
18Then open the CMakeLists.txt file in Qt Creator, and ensure that the kit
19selected on the left sidebar (just above the green "Run" button) is "Desktop"
20
21### For a device
22
23If you don't have one already, you'll need to create an armhf chroot to
24cross-compile the app. Here's how:
25
261. In Qt Creator, open the CMakeLists.txt file
272. Go to Tools > Options > Ubuntu > Click
282. Click on Create Click Target
293. Follow the prompts to generate the chroot. You will be asked for your sudo
30 password
314. Once created, you'll need to add the build dependencies for the app:
32 - At this time, none are required, but the steps are shown for the sake of
33 completion
34 - Click on the Maintain button on your chroot
35 - On the terminal prompt that is started, type
36 apt-get install $DEPENDENCY_NAME:armhf'
37 - Close the terminal when the installation finishes
385. Now you can either do a clean checkout and wait to be prompted by Qt Creator
39 to add the armhf kit, or alternatively:
406. Go to the Projects tab > Add kit and then select the UbuntuSDK armhf kit
41
42Additionally, you'll have to tell Qt Creator that you are doing a build for a
43device to ultimately create a click package for installation:
44
451. In Qt Creator, go to the Projects tab on the sidebar
462. Click on the "Build" subtab of the "UbuntuSDK for armhf..." tab
473. Then go to the "CMake arguments" text field and add "-DCLICK_MODE=on"
48 without the quotes
49
50Before starting the build make sure to select the "UbuntuSDK" kit on Qt
51Creator's left sidebar (just above the green "Run" button).
52
53### Doing the build
54
55Ensure you've selected the kit you want for your build and press the build
56button on Qt Creator's left sidebar (or alternatively Ctrl+B).
57
58## Running the app
59
60### On the desktop
61
62No additional steps are required before running the app on the desktop.
63
64### On a device
65
66Due to Qt Creator's bug #1312094 in launchpad.net, there needs to be a manual
67workaround done before the app can run on the device:
68
691. Modify the desktop.in file: change the Exec line to read:
70 Exec=lib/arm-linux-gnueabihf/bin/@EXEC@
71
72Remember to revert this temporary change if you are building a click package or
73if you're making other changes to be committed to the code!
74
75### Starting the app
76
77Ensure you've selected the kit you want for your build and press the run
78button on Qt Creator's left sidebar (or alternatively Ctrl+R).
79
80If the app hasn't been built yet, or if there are pending changes that require
81a build, the app will automatically be built first before running.
82
83If you're starting the app on a device, the build will be copied over and the
84code will run unconfined.
85
86## Building a click package
87
88There are two alternative ways of building a click package.
89
90### Using Qt Creator
91
921. Ensure you've selected the UbuntuSDK for armhf kit on Qt Creator's sidebar
932. Click on Publish on the sidebar
943. Click on "Create package"
954. If all goes well, you'll find the final click package in the build directory
96
97Notes:
98- You can see the output of the click build if you click on Edit on the sidebar
99 and then "Application Output" at the bottom. This is useful to identify any
100 failures during the build
101- Run `sudo apt-get install click-reviewers-tools` to enable click package
102 validation in Qt Creator. You might need to restart Qt Creator after you've
103 installed them for it to detect them
104
105### Using click-buddy
106
1071. Install phablet-tools: `sudo apt-get install phablet-tools`
1082. Run click-buddy in your source tree:
109 click-buddy --dir . --arch armhf --framework ubuntu-sdk-14.04
1103. Once finished, click-buddy will tell you the location of your source package
111
112## Installing a click package
113
114First of all, ensure you've got a working Ubuntu device attached over USB to
115your host computer
116
117### Manually
118
119Run the following commands to manually install the click package (replace 0.1
120with the version of your package):
121
122 adb push /home/phablet com.ubuntu.terminal_0.1_armhf.click
123 adb shell
124 sudo -H -u phablet pkcon install-local /home/phablet/com.ubuntu.terminal_0.1_armhf.click
125
126### Using click-buddy
127
128You can add the --provision argument to the previous command to install the
129click package on the device.
130
131### Starting the app
132
1331. Either kill unity8 with `pkill unity8` or restart the system for the Apps
134 (click) scope to pick up your newly installed click package
1352. Search for Reminders in the Apps scope and tap on its icon to start it
1363. You'll find the runtime logs at ~/.cache/upstart/application-click/
137
138## Uninstalling a click package
139
140Run the following commands, replacing the version of the click package you want
141to uninstall:
142
143 adb shell
144 sudo -iu phablet
145 sudo click unregister com.ubuntu.terminal 0.1
146
147## Run the autopilot tests
148
149Once the app has been built, you can go to the build directory and run:
150
151 cd tests/autopilot
152 autopilot run ubuntu_terminal_app
0153
=== renamed file 'click/apparmor.json' => 'apparmor.json'
--- click/apparmor.json 2014-03-14 18:33:50 +0000
+++ apparmor.json 2014-05-06 21:50:22 +0000
@@ -1,4 +1,5 @@
1{1{
2 "policy_version": 1.1, 2 "policy_groups": [],
3 "policy_version": 1.1,
3 "template": "unconfined"4 "template": "unconfined"
4}5}
5\ No newline at end of file6\ No newline at end of file
67
=== removed directory 'click'
=== removed file 'click/CMakeLists.txt'
--- click/CMakeLists.txt 2014-01-31 21:52:08 +0000
+++ click/CMakeLists.txt 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
1if(CLICK_MODE)
2 if(NOT BZR_REVNO)
3 set(BZR_REVNO "latest")
4 endif(NOT BZR_REVNO)
5 configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
6 install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json apparmor.json
7 DESTINATION ${CMAKE_INSTALL_PREFIX})
8endif(CLICK_MODE)
90
=== renamed file 'com.ubuntu.terminal_terminal.desktop.in' => 'com.ubuntu.terminal.desktop.in'
=== renamed file 'com.ubuntu.terminal_terminal.url-dispatcher' => 'com.ubuntu.terminal.url-dispatcher'
=== modified file 'debian/changelog'
--- debian/changelog 2014-03-10 10:19:53 +0000
+++ debian/changelog 2014-05-06 21:50:22 +0000
@@ -1,8 +1,12 @@
1ubuntu-terminal-app (0.5ubuntu1) UNRELEASED; urgency=medium1ubuntu-terminal-app (0.5ubuntu2) trusty; urgency=medium
22
3 [ Alan Pope ]
3 * Add -qt5 command line option (LP: #1288885) 4 * Add -qt5 command line option (LP: #1288885)
45
5 -- Alan Pope <popey@ubuntu.com> Mon, 10 Mar 2014 10:19:27 +00006 [ David Planella ]
7 * Merge konsole plugin into the app's repo.
8
9 -- David Planella <david.planella@ubuntu.com> Sun, 27 Apr 2014 12:08:04 +0200
610
7ubuntu-terminal-app (0.5) raring; urgency=low11ubuntu-terminal-app (0.5) raring; urgency=low
812
913
=== modified file 'debian/control'
--- debian/control 2014-03-07 21:06:44 +0000
+++ debian/control 2014-05-06 21:50:22 +0000
@@ -3,29 +3,50 @@
3Maintainer: Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>3Maintainer: Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>
4Build-Depends: cmake,4Build-Depends: cmake,
5 debhelper (>= 9),5 debhelper (>= 9),
6 python,6 python3-all,
7Standards-Version: 3.9.47 gettext,
8 qtbase5-dev,
9 qtdeclarative5-dev,
10 qt5-default,
11Standards-Version: 3.9.5
8Section: misc12Section: misc
9Homepage: https://launchpad.net/ubuntu-terminal-app13Homepage: https://launchpad.net/ubuntu-terminal-app
10Vcs-Bzr: https://code.launchpad.net/~ubuntu-terminal-dev/ubuntu-terminal-app/trunk14Vcs-Bzr: https://code.launchpad.net/~ubuntu-terminal-dev/ubuntu-terminal-app/trunk
1115
12Package: ubuntu-terminal-app16Package: ubuntu-terminal-app
13Section: misc17Section: misc
14Architecture: all18Architecture: any
15Depends: qmlscene,19Depends: ${misc:Depends},
20 ${shlibs:Depends},
16 qtdeclarative5-konsole-qml-plugin (>= 0.1.1),21 qtdeclarative5-konsole-qml-plugin (>= 0.1.1),
17 qtdeclarative5-localstorage-plugin,22 qtdeclarative5-localstorage-plugin,
18 qtdeclarative5-qtquick2-plugin,23 qtdeclarative5-qtquick2-plugin,
19 qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,24 qtdeclarative5-ubuntu-ui-toolkit-plugin,
20 ${misc:Depends},
21Description: Terminal application25Description: Terminal application
22 Core Terminal application26 Core Terminal application
2327
28Package: qtdeclarative5-konsole-qml-plugin
29Architecture: any
30Multi-Arch: same
31Depends: ${misc:Depends},
32 ${shlibs:Depends},
33 ${misc:Pre-Depends},
34Description: KDE Konsole QML plugin - qml terminal plugin
35 Konsole is a terminal emulator from KDE. This is a ported
36 version for the Ubuntu Terminal app and does not require KDE.
37 .
38 This package contains the Konsole terminal emulator plugin
39 for Qt Qml, which offers access to terminal by KTerminal and
40 KSession elements. KTerminal is used for displaying information
41 given by KSession.
42
24Package: ubuntu-terminal-app-autopilot43Package: ubuntu-terminal-app-autopilot
25Architecture: all44Architecture: all
26Depends: libautopilot-qt,45Depends: ${misc:Depends},
46 libautopilot-qt,
27 libqt5test5,47 libqt5test5,
28 ubuntu-terminal-app (= ${source:Version}),48 python3-autopilot,
49 ubuntu-terminal-app (>= ${source:Version}),
29 ubuntu-ui-toolkit-autopilot,50 ubuntu-ui-toolkit-autopilot,
30Description: Autopilot tests for Terminal Application51Description: Autopilot tests for Terminal Application
31 This package contains the autopilot tests for the Terminal52 This package contains the autopilot tests for the Terminal
3253
=== added file 'debian/qtdeclarative5-konsole-qml-plugin.install'
--- debian/qtdeclarative5-konsole-qml-plugin.install 1970-01-01 00:00:00 +0000
+++ debian/qtdeclarative5-konsole-qml-plugin.install 2014-05-06 21:50:22 +0000
@@ -0,0 +1,1 @@
1usr/lib/*/qt5/qml/org/kde/konsole/
02
=== renamed file 'click/manifest.json.in' => 'manifest.json'
--- click/manifest.json.in 2014-04-11 22:59:46 +0000
+++ manifest.json 2014-05-06 21:50:22 +0000
@@ -3,15 +3,15 @@
3 "framework": "ubuntu-sdk-14.04-dev1",3 "framework": "ubuntu-sdk-14.04-dev1",
4 "architecture": "armhf",4 "architecture": "armhf",
5 "hooks": {5 "hooks": {
6 "@APP_NAME@": {6 "terminal": {
7 "apparmor": "apparmor.json",7 "apparmor": "apparmor.json",
8 "desktop": "@DESKTOP_FILE@",8 "desktop": "com.ubuntu.terminal.desktop",
9 "urls": "@URLS_FILE@"9 "urls": "com.ubuntu.terminal.url-dispatcher"
10 }10 }
11 },11 },
12 "icon": "@ICON@",12 "icon": "terminal64.png",
13 "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>",13 "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>",
14 "name": "@PROJECT_NAME@",14 "name": "com.ubuntu.terminal",
15 "title": "Terminal",15 "title": "Terminal",
16 "version": "0.5.@BZR_REVNO@",16 "version": "0.5.@BZR_REVNO@",
17 "x-source": {17 "x-source": {
@@ -21,4 +21,4 @@
21 "x-test": {21 "x-test": {
22 "autopilot": "@AUTOPILOT_DIR@"22 "autopilot": "@AUTOPILOT_DIR@"
23 }23 }
24}24}
25\ No newline at end of file25\ No newline at end of file
2626
=== removed file 'plugins.json'
--- plugins.json 2013-10-11 14:30:09 +0000
+++ plugins.json 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
1[
2{
3 "package": "qtdeclarative5-konsole-qml-plugin",
4 "ppa": "ppa:ubuntu-touch-coreapps-drivers/daily"
5}
6]
70
=== added directory 'src'
=== added file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/CMakeLists.txt 2014-05-06 21:50:22 +0000
@@ -0,0 +1,2 @@
1add_subdirectory(plugin)
2add_subdirectory(app)
03
=== added directory 'src/app'
=== added file 'src/app/CMakeLists.txt'
--- src/app/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/app/CMakeLists.txt 2014-05-06 21:50:22 +0000
@@ -0,0 +1,24 @@
1file(GLOB_RECURSE QML_SRCS *.qml *.js)
2
3set(terminal_SRCS
4 main.cpp
5 ${QML_SRCS}
6)
7
8add_executable(terminal ${terminal_SRCS})
9
10qt5_use_modules(terminal Gui Qml Quick)
11
12if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
13add_custom_target(terminal-qmlfiles ALL
14 COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/qml ${CMAKE_CURRENT_BINARY_DIR}
15 DEPENDS ${QMLFILES}
16)
17endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
18
19install(DIRECTORY qml DESTINATION ${DATA_DIR})
20if(CLICK_MODE)
21 install(TARGETS terminal DESTINATION ${BIN_DIR})
22else()
23 install(TARGETS terminal RUNTIME DESTINATION bin)
24endif()
025
=== added file 'src/app/main.cpp'
--- src/app/main.cpp 1970-01-01 00:00:00 +0000
+++ src/app/main.cpp 2014-05-06 21:50:22 +0000
@@ -0,0 +1,120 @@
1/*
2 * Copyright: 2013 - 2014 Canonical, Ltd
3 *
4 * This file is part of ubuntu-terminal-app
5 *
6 * ubuntu-terminal-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ubuntu-terminal-app is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
20 * Riccardo Padovani <rpadovani@ubuntu.com>
21 * David Planella <david.planella@ubuntu.com>
22 */
23
24#include <QtGui/QGuiApplication>
25#include <QtQuick/QQuickView>
26#include <QtQml/QtQml>
27#include <QLibrary>
28#include <QDir>
29
30#include <QDebug>
31
32int main(int argc, char *argv[])
33{
34 QGuiApplication a(argc, argv);
35 QQuickView view;
36 view.setResizeMode(QQuickView::SizeRootObjectToView);
37
38 // Set up import paths
39 QStringList importPathList = view.engine()->importPathList();
40 // Prepend the location of the plugin in the build dir,
41 // so that Qt Creator finds it there, thus overriding the one installed
42 // in the sistem if there is one
43 importPathList.prepend(QCoreApplication::applicationDirPath() + "/../plugin/");
44
45 QStringList args = a.arguments();
46 if (args.contains("-h") || args.contains("--help")) {
47 qDebug() << "usage: " + args.at(0) + " [-p|--phone] [-t|--tablet] [-h|--help] [-I <path>]";
48 qDebug() << " -p|--phone If running on Desktop, start in a phone sized window.";
49 qDebug() << " -t|--tablet If running on Desktop, start in a tablet sized window.";
50 qDebug() << " -h|--help Print this help.";
51 qDebug() << " -I <path> Give a path for an additional QML import directory. May be used multiple times.";
52 qDebug() << " -q <qmlfile> Give an alternative location for the main qml file.";
53 return 0;
54 }
55
56 QString qmlfile;
57 for (int i = 0; i < args.count(); i++) {
58 if (args.at(i) == "-I" && args.count() > i + 1) {
59 QString addedPath = args.at(i+1);
60 if (addedPath.startsWith('.')) {
61 addedPath = addedPath.right(addedPath.length() - 1);
62 addedPath.prepend(QDir::currentPath());
63 }
64 importPathList.append(addedPath);
65 } else if (args.at(i) == "-q" && args.count() > i + 1) {
66 qmlfile = args.at(i+1);
67 }
68 }
69
70 if (args.contains(QLatin1String("-testability")) || getenv("QT_LOAD_TESTABILITY")) {
71 QLibrary testLib(QLatin1String("qttestability"));
72 if (testLib.load()) {
73 typedef void (*TasInitialize)(void);
74 TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
75 if (initFunction) {
76 initFunction();
77 } else {
78 qCritical("Library qttestability resolve failed!");
79 }
80 } else {
81 qCritical("Library qttestability load failed!");
82 }
83 }
84
85 view.engine()->rootContext()->setContextProperty("tablet", QVariant(false));
86 view.engine()->rootContext()->setContextProperty("phone", QVariant(false));
87 if (args.contains("-t") || args.contains("--tablet")) {
88 qDebug() << "running in tablet mode";
89 view.engine()->rootContext()->setContextProperty("tablet", QVariant(true));
90 } else if (args.contains("-p") || args.contains("--phone")){
91 qDebug() << "running in phone mode";
92 view.engine()->rootContext()->setContextProperty("phone", QVariant(true));
93 } else if (qgetenv("QT_QPA_PLATFORM") != "ubuntumirclient") {
94 // Default to tablet size on X11
95 view.engine()->rootContext()->setContextProperty("tablet", QVariant(true));
96 }
97
98 view.engine()->setImportPathList(importPathList);
99
100 // load the qml file
101 if (qmlfile.isEmpty()) {
102 QStringList paths = QStandardPaths::standardLocations(QStandardPaths::DataLocation);
103 paths.prepend(QDir::currentPath());
104 paths.prepend(QCoreApplication::applicationDirPath());
105
106 foreach (const QString &path, paths) {
107 QFileInfo fi(path + "/qml/ubuntu-terminal-app.qml");
108 qDebug() << "Trying to load QML from:" << path + "/qml/ubuntu-terminal-app.qml";
109 if (fi.exists()) {
110 qmlfile = path + "/qml/ubuntu-terminal-app.qml";
111 break;
112 }
113 }
114 }
115 qDebug() << "using main qml file from:" << qmlfile;
116 view.setSource(QUrl::fromLocalFile(qmlfile));
117 view.show();
118
119 return a.exec();
120}
0121
=== added directory 'src/app/qml'
=== renamed file 'Configs.qml' => 'src/app/qml/Configs.qml'
=== renamed file 'Terminal.qml' => 'src/app/qml/Terminal.qml'
=== renamed file 'avatar@8.png' => 'src/app/qml/avatar@8.png'
=== renamed directory 'config' => 'src/app/qml/config'
=== renamed directory 'extraPanel' => 'src/app/qml/extraPanel'
=== renamed file 'settings.png' => 'src/app/qml/settings.png'
=== renamed file 'terminal.qmlproject' => 'src/app/qml/terminal.qmlproject'
=== renamed file 'ubuntu-terminal-app.qml' => 'src/app/qml/ubuntu-terminal-app.qml'
=== added directory 'src/plugin'
=== added file 'src/plugin/CMakeLists.txt'
--- src/plugin/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/plugin/CMakeLists.txt 2014-05-06 21:50:22 +0000
@@ -0,0 +1,7 @@
1include(FindPkgConfig)
2find_package(Qt5Core)
3find_package(Qt5Qml)
4find_package(Qt5Quick)
5find_package(Qt5Widgets)
6
7add_subdirectory(konsole)
08
=== added directory 'src/plugin/konsole'
=== added file 'src/plugin/konsole/BlockArray.cpp'
--- src/plugin/konsole/BlockArray.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/BlockArray.cpp 2014-05-06 21:50:22 +0000
@@ -0,0 +1,377 @@
1/*
2 This file is part of Konsole, an X terminal.
3 Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
4
5 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21
22*/
23
24// Own
25#include "BlockArray.h"
26
27#include <QtCore>
28
29// System
30#include <assert.h>
31#include <sys/mman.h>
32#include <sys/param.h>
33#include <unistd.h>
34#include <stdio.h>
35
36
37static int blocksize = 0;
38
39BlockArray::BlockArray()
40 : size(0),
41 current(size_t(-1)),
42 index(size_t(-1)),
43 lastmap(0),
44 lastmap_index(size_t(-1)),
45 lastblock(0), ion(-1),
46 length(0)
47{
48 // lastmap_index = index = current = size_t(-1);
49 if (blocksize == 0) {
50 blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize();
51 }
52
53}
54
55BlockArray::~BlockArray()
56{
57 setHistorySize(0);
58 assert(!lastblock);
59}
60
61size_t BlockArray::append(Block * block)
62{
63 if (!size) {
64 return size_t(-1);
65 }
66
67 ++current;
68 if (current >= size) {
69 current = 0;
70 }
71
72 int rc;
73 rc = lseek(ion, current * blocksize, SEEK_SET);
74 if (rc < 0) {
75 perror("HistoryBuffer::add.seek");
76 setHistorySize(0);
77 return size_t(-1);
78 }
79 rc = write(ion, block, blocksize);
80 if (rc < 0) {
81 perror("HistoryBuffer::add.write");
82 setHistorySize(0);
83 return size_t(-1);
84 }
85
86 length++;
87 if (length > size) {
88 length = size;
89 }
90
91 ++index;
92
93 delete block;
94 return current;
95}
96
97size_t BlockArray::newBlock()
98{
99 if (!size) {
100 return size_t(-1);
101 }
102 append(lastblock);
103
104 lastblock = new Block();
105 return index + 1;
106}
107
108Block * BlockArray::lastBlock() const
109{
110 return lastblock;
111}
112
113bool BlockArray::has(size_t i) const
114{
115 if (i == index + 1) {
116 return true;
117 }
118
119 if (i > index) {
120 return false;
121 }
122 if (index - i >= length) {
123 return false;
124 }
125 return true;
126}
127
128const Block * BlockArray::at(size_t i)
129{
130 if (i == index + 1) {
131 return lastblock;
132 }
133
134 if (i == lastmap_index) {
135 return lastmap;
136 }
137
138 if (i > index) {
139 qDebug() << "BlockArray::at() i > index\n";
140 return 0;
141 }
142
143// if (index - i >= length) {
144// kDebug(1211) << "BlockArray::at() index - i >= length\n";
145// return 0;
146// }
147
148 size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ;
149
150 assert(j < size);
151 unmap();
152
153 Block * block = (Block *)mmap(0, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
154
155 if (block == (Block *)-1) {
156 perror("mmap");
157 return 0;
158 }
159
160 lastmap = block;
161 lastmap_index = i;
162
163 return block;
164}
165
166void BlockArray::unmap()
167{
168 if (lastmap) {
169 int res = munmap((char *)lastmap, blocksize);
170 if (res < 0) {
171 perror("munmap");
172 }
173 }
174 lastmap = 0;
175 lastmap_index = size_t(-1);
176}
177
178bool BlockArray::setSize(size_t newsize)
179{
180 return setHistorySize(newsize * 1024 / blocksize);
181}
182
183bool BlockArray::setHistorySize(size_t newsize)
184{
185// kDebug(1211) << "setHistorySize " << size << " " << newsize;
186
187 if (size == newsize) {
188 return false;
189 }
190
191 unmap();
192
193 if (!newsize) {
194 delete lastblock;
195 lastblock = 0;
196 if (ion >= 0) {
197 close(ion);
198 }
199 ion = -1;
200 current = size_t(-1);
201 return true;
202 }
203
204 if (!size) {
205 FILE * tmp = tmpfile();
206 if (!tmp) {
207 perror("konsole: cannot open temp file.\n");
208 } else {
209 ion = dup(fileno(tmp));
210 if (ion<0) {
211 perror("konsole: cannot dup temp file.\n");
212 fclose(tmp);
213 }
214 }
215 if (ion < 0) {
216 return false;
217 }
218
219 assert(!lastblock);
220
221 lastblock = new Block();
222 size = newsize;
223 return false;
224 }
225
226 if (newsize > size) {
227 increaseBuffer();
228 size = newsize;
229 return false;
230 } else {
231 decreaseBuffer(newsize);
232 ftruncate(ion, length*blocksize);
233 size = newsize;
234
235 return true;
236 }
237}
238
239void moveBlock(FILE * fion, int cursor, int newpos, char * buffer2)
240{
241 int res = fseek(fion, cursor * blocksize, SEEK_SET);
242 if (res) {
243 perror("fseek");
244 }
245 res = fread(buffer2, blocksize, 1, fion);
246 if (res != 1) {
247 perror("fread");
248 }
249
250 res = fseek(fion, newpos * blocksize, SEEK_SET);
251 if (res) {
252 perror("fseek");
253 }
254 res = fwrite(buffer2, blocksize, 1, fion);
255 if (res != 1) {
256 perror("fwrite");
257 }
258 // printf("moving block %d to %d\n", cursor, newpos);
259}
260
261void BlockArray::decreaseBuffer(size_t newsize)
262{
263 if (index < newsize) { // still fits in whole
264 return;
265 }
266
267 int offset = (current - (newsize - 1) + size) % size;
268
269 if (!offset) {
270 return;
271 }
272
273 // The Block constructor could do somthing in future...
274 char * buffer1 = new char[blocksize];
275
276 FILE * fion = fdopen(dup(ion), "w+b");
277 if (!fion) {
278 delete [] buffer1;
279 perror("fdopen/dup");
280 return;
281 }
282
283 int firstblock;
284 if (current <= newsize) {
285 firstblock = current + 1;
286 } else {
287 firstblock = 0;
288 }
289
290 size_t oldpos;
291 for (size_t i = 0, cursor=firstblock; i < newsize; i++) {
292 oldpos = (size + cursor + offset) % size;
293 moveBlock(fion, oldpos, cursor, buffer1);
294 if (oldpos < newsize) {
295 cursor = oldpos;
296 } else {
297 cursor++;
298 }
299 }
300
301 current = newsize - 1;
302 length = newsize;
303
304 delete [] buffer1;
305
306 fclose(fion);
307
308}
309
310void BlockArray::increaseBuffer()
311{
312 if (index < size) { // not even wrapped once
313 return;
314 }
315
316 int offset = (current + size + 1) % size;
317 if (!offset) { // no moving needed
318 return;
319 }
320
321 // The Block constructor could do somthing in future...
322 char * buffer1 = new char[blocksize];
323 char * buffer2 = new char[blocksize];
324
325 int runs = 1;
326 int bpr = size; // blocks per run
327
328 if (size % offset == 0) {
329 bpr = size / offset;
330 runs = offset;
331 }
332
333 FILE * fion = fdopen(dup(ion), "w+b");
334 if (!fion) {
335 perror("fdopen/dup");
336 delete [] buffer1;
337 delete [] buffer2;
338 return;
339 }
340
341 int res;
342 for (int i = 0; i < runs; i++) {
343 // free one block in chain
344 int firstblock = (offset + i) % size;
345 res = fseek(fion, firstblock * blocksize, SEEK_SET);
346 if (res) {
347 perror("fseek");
348 }
349 res = fread(buffer1, blocksize, 1, fion);
350 if (res != 1) {
351 perror("fread");
352 }
353 int newpos = 0;
354 for (int j = 1, cursor=firstblock; j < bpr; j++) {
355 cursor = (cursor + offset) % size;
356 newpos = (cursor - offset + size) % size;
357 moveBlock(fion, cursor, newpos, buffer2);
358 }
359 res = fseek(fion, i * blocksize, SEEK_SET);
360 if (res) {
361 perror("fseek");
362 }
363 res = fwrite(buffer1, blocksize, 1, fion);
364 if (res != 1) {
365 perror("fwrite");
366 }
367 }
368 current = size - 1;
369 length = size;
370
371 delete [] buffer1;
372 delete [] buffer2;
373
374 fclose(fion);
375
376}
377
0378
=== added file 'src/plugin/konsole/BlockArray.h'
--- src/plugin/konsole/BlockArray.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/BlockArray.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,126 @@
1/*
2 This file is part of Konsole, an X terminal.
3 Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
4
5 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21*/
22
23#ifndef BLOCKARRAY_H
24#define BLOCKARRAY_H
25
26#include <unistd.h>
27
28//#error Do not use in KDE 2.1
29
30#define BlockSize (1 << 12)
31#define ENTRIES ((BlockSize - sizeof(size_t) ) / sizeof(unsigned char))
32
33struct Block {
34 Block() {
35 size = 0;
36 }
37 unsigned char data[ENTRIES];
38 size_t size;
39};
40
41// ///////////////////////////////////////////////////////
42
43class BlockArray {
44public:
45 /**
46 * Creates a history file for holding
47 * maximal size blocks. If more blocks
48 * are requested, then it drops earlier
49 * added ones.
50 */
51 BlockArray();
52
53 /// destructor
54 ~BlockArray();
55
56 /**
57 * adds the Block at the end of history.
58 * This may drop other blocks.
59 *
60 * The ownership on the block is transfered.
61 * An unique index number is returned for accessing
62 * it later (if not yet dropped then)
63 *
64 * Note, that the block may be dropped completely
65 * if history is turned off.
66 */
67 size_t append(Block * block);
68
69 /**
70 * gets the block at the index. Function may return
71 * 0 if the block isn't available any more.
72 *
73 * The returned block is strictly readonly as only
74 * maped in memory - and will be invalid on the next
75 * operation on this class.
76 */
77 const Block * at(size_t index);
78
79 /**
80 * reorders blocks as needed. If newsize is null,
81 * the history is emptied completely. The indices
82 * returned on append won't change their semantic,
83 * but they may not be valid after this call.
84 */
85 bool setHistorySize(size_t newsize);
86
87 size_t newBlock();
88
89 Block * lastBlock() const;
90
91 /**
92 * Convenient function to set the size in KBytes
93 * instead of blocks
94 */
95 bool setSize(size_t newsize);
96
97 size_t len() const {
98 return length;
99 }
100
101 bool has(size_t index) const;
102
103 size_t getCurrent() const {
104 return current;
105 }
106
107private:
108 void unmap();
109 void increaseBuffer();
110 void decreaseBuffer(size_t newsize);
111
112 size_t size;
113 // current always shows to the last inserted block
114 size_t current;
115 size_t index;
116
117 Block * lastmap;
118 size_t lastmap_index;
119 Block * lastblock;
120
121 int ion;
122 size_t length;
123
124};
125
126#endif
0127
=== added file 'src/plugin/konsole/CMakeLists.txt'
--- src/plugin/konsole/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/CMakeLists.txt 2014-05-06 21:50:22 +0000
@@ -0,0 +1,93 @@
1include_directories(
2 ${CMAKE_CURRENT_SOURCE_DIR}
3)
4
5set(PLUGIN_DIR org/kde/konsole)
6add_definitions(-DHAVE_POSIX_OPENPT -DHAVE_SYS_TIME_H -DHAVE_UPDWTMPX)
7add_definitions(-DQ_WS_UBUNTU)
8
9set(konsole_SRCS
10 BlockArray.cpp
11 BlockArray.h
12 CharacterColor.h
13 Character.h
14 ColorScheme.cpp
15 ColorScheme.h
16 ColorTables.h
17 DefaultTranslatorText.h
18 Emulation.cpp
19 Emulation.h
20 ExtendedDefaultTranslator.h
21 Filter.cpp
22 Filter.h
23 History.cpp
24 History.h
25 KeyboardTranslator.cpp
26 KeyboardTranslator.h
27 konsole_wcwidth.cpp
28 konsole_wcwidth.h
29 kprocess.cpp
30 kprocess.h
31 kpty.cpp
32 kptydevice.cpp
33 kptydevice.h
34 kpty.h
35 kpty_p.h
36 kptyprocess.cpp
37 kptyprocess.h
38 ksession.cpp
39 ksession.h
40 LineFont.h
41 plugin.cpp
42 plugin.h
43 Pty.cpp
44 Pty.h
45 Screen.cpp
46 Screen.h
47 ScreenWindow.cpp
48 ScreenWindow.h
49 Session.cpp
50 Session.h
51 ShellCommand.cpp
52 ShellCommand.h
53 TerminalCharacterDecoder.cpp
54 TerminalCharacterDecoder.h
55 TerminalDisplay.cpp
56 TerminalDisplay.h
57 tools.cpp
58 tools.h
59 Vt102Emulation.cpp
60 Vt102Emulation.h
61)
62
63add_library(kdekonsole MODULE
64 ${konsole_SRCS}
65)
66
67qt5_use_modules(kdekonsole Gui Qml Quick Widgets)
68
69# Copy the plugin, the qmldir file and other assets to the build dir for running in QtCreator
70if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
71 add_custom_target(konsole-qmldir ALL
72 COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
73 DEPENDS ${QMLFILES}
74 )
75 add_custom_target(konsole-layouts-schemes ALL
76 COMMAND cp -a ${CMAKE_CURRENT_SOURCE_DIR}/assets/color-schemes ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
77 COMMAND cp -a ${CMAKE_CURRENT_SOURCE_DIR}/assets/kb-layouts ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
78 DEPENDS ${QMLFILES}
79 )
80 add_custom_command(TARGET kdekonsole POST_BUILD
81 COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
82 COMMENT "Creating plugin directory layout in the build dir"
83 COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:kdekonsole> ${CMAKE_CURRENT_BINARY_DIR}/../${PLUGIN_DIR}
84 COMMENT "Copying to output directory"
85 )
86endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
87
88
89install(TARGETS kdekonsole DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
90install(FILES qmldir DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
91install(DIRECTORY assets/color-schemes DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
92install(DIRECTORY assets/kb-layouts DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN_DIR})
93
094
=== added file 'src/plugin/konsole/Character.h'
--- src/plugin/konsole/Character.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/Character.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,221 @@
1/*
2 This file is part of Konsole, KDE's terminal.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5 Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21*/
22
23#ifndef CHARACTER_H
24#define CHARACTER_H
25
26// Qt
27#include <QtCore/QHash>
28
29// Local
30#include "CharacterColor.h"
31
32typedef unsigned char LineProperty;
33
34static const int LINE_DEFAULT = 0;
35static const int LINE_WRAPPED = (1 << 0);
36static const int LINE_DOUBLEWIDTH = (1 << 1);
37static const int LINE_DOUBLEHEIGHT = (1 << 2);
38
39#define DEFAULT_RENDITION 0
40#define RE_BOLD (1 << 0)
41#define RE_BLINK (1 << 1)
42#define RE_UNDERLINE (1 << 2)
43#define RE_REVERSE (1 << 3) // Screen only
44#define RE_INTENSIVE (1 << 3) // Widget only
45#define RE_CURSOR (1 << 4)
46#define RE_EXTENDED_CHAR (1 << 5)
47
48/**
49 * A single character in the terminal which consists of a unicode character
50 * value, foreground and background colors and a set of rendition attributes
51 * which specify how it should be drawn.
52 */
53class Character
54{
55public:
56 /**
57 * Constructs a new character.
58 *
59 * @param _c The unicode character value of this character.
60 * @param _f The foreground color used to draw the character.
61 * @param _b The color used to draw the character's background.
62 * @param _r A set of rendition flags which specify how this character is to be drawn.
63 */
64 inline Character(quint16 _c = ' ',
65 CharacterColor _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
66 CharacterColor _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
67 quint8 _r = DEFAULT_RENDITION)
68 : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}
69
70 union
71 {
72 /** The unicode character value for this character. */
73 quint16 character;
74 /**
75 * Experimental addition which allows a single Character instance to contain more than
76 * one unicode character.
77 *
78 * charSequence is a hash code which can be used to look up the unicode
79 * character sequence in the ExtendedCharTable used to create the sequence.
80 */
81 quint16 charSequence;
82 };
83
84 /** A combination of RENDITION flags which specify options for drawing the character. */
85 quint8 rendition;
86
87 /** The foreground color used to draw this character. */
88 CharacterColor foregroundColor;
89 /** The color used to draw this character's background. */
90 CharacterColor backgroundColor;
91
92 /**
93 * Returns true if this character has a transparent background when
94 * it is drawn with the specified @p palette.
95 */
96 bool isTransparent(const ColorEntry* palette) const;
97 /**
98 * Returns true if this character should always be drawn in bold when
99 * it is drawn with the specified @p palette, independent of whether
100 * or not the character has the RE_BOLD rendition flag.
101 */
102 ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
103
104 /**
105 * returns true if the format (color, rendition flag) of the compared characters is equal
106 */
107 bool equalsFormat(const Character &other) const;
108
109 /**
110 * Compares two characters and returns true if they have the same unicode character value,
111 * rendition and colors.
112 */
113 friend bool operator == (const Character& a, const Character& b);
114 /**
115 * Compares two characters and returns true if they have different unicode character values,
116 * renditions or colors.
117 */
118 friend bool operator != (const Character& a, const Character& b);
119};
120
121inline bool operator == (const Character& a, const Character& b)
122{
123 return a.character == b.character &&
124 a.rendition == b.rendition &&
125 a.foregroundColor == b.foregroundColor &&
126 a.backgroundColor == b.backgroundColor;
127}
128
129inline bool operator != (const Character& a, const Character& b)
130{
131 return a.character != b.character ||
132 a.rendition != b.rendition ||
133 a.foregroundColor != b.foregroundColor ||
134 a.backgroundColor != b.backgroundColor;
135}
136
137inline bool Character::isTransparent(const ColorEntry* base) const
138{
139 return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
140 base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
141 || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
142 base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
143}
144
145inline bool Character::equalsFormat(const Character& other) const
146{
147 return
148 backgroundColor==other.backgroundColor &&
149 foregroundColor==other.foregroundColor &&
150 rendition==other.rendition;
151}
152
153inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
154{
155 if (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT)
156 return base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
157 else if (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM)
158 return base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
159 else
160 return ColorEntry::UseCurrentFormat;
161}
162
163extern unsigned short vt100_graphics[32];
164
165
166/**
167 * A table which stores sequences of unicode characters, referenced
168 * by hash keys. The hash key itself is the same size as a unicode
169 * character ( ushort ) so that it can occupy the same space in
170 * a structure.
171 */
172class ExtendedCharTable
173{
174public:
175 /** Constructs a new character table. */
176 ExtendedCharTable();
177 ~ExtendedCharTable();
178
179 /**
180 * Adds a sequences of unicode characters to the table and returns
181 * a hash code which can be used later to look up the sequence
182 * using lookupExtendedChar()
183 *
184 * If the same sequence already exists in the table, the hash
185 * of the existing sequence will be returned.
186 *
187 * @param unicodePoints An array of unicode character points
188 * @param length Length of @p unicodePoints
189 */
190 ushort createExtendedChar(ushort* unicodePoints , ushort length);
191 /**
192 * Looks up and returns a pointer to a sequence of unicode characters
193 * which was added to the table using createExtendedChar().
194 *
195 * @param hash The hash key returned by createExtendedChar()
196 * @param length This variable is set to the length of the
197 * character sequence.
198 *
199 * @return A unicode character sequence of size @p length.
200 */
201 ushort* lookupExtendedChar(ushort hash , ushort& length) const;
202
203 /** The global ExtendedCharTable instance. */
204 static ExtendedCharTable instance;
205private:
206 // calculates the hash key of a sequence of unicode points of size 'length'
207 ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
208 // tests whether the entry in the table specified by 'hash' matches the
209 // character sequence 'unicodePoints' of size 'length'
210 bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
211 // internal, maps hash keys to character sequence buffers. The first ushort
212 // in each value is the length of the buffer, followed by the ushorts in the buffer
213 // themselves.
214 QHash<ushort,ushort*> extendedCharTable;
215};
216
217
218Q_DECLARE_TYPEINFO(Character, Q_MOVABLE_TYPE);
219
220#endif // CHARACTER_H
221
0222
=== added file 'src/plugin/konsole/CharacterColor.h'
--- src/plugin/konsole/CharacterColor.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/CharacterColor.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,294 @@
1/*
2 This file is part of Konsole, KDE's terminal.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5 Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21*/
22
23#ifndef CHARACTERCOLOR_H
24#define CHARACTERCOLOR_H
25
26// Qt
27#include <QtGui/QColor>
28
29//#include <kdemacros.h>
30#define KDE_NO_EXPORT
31
32/**
33 * An entry in a terminal display's color palette.
34 *
35 * A color palette is an array of 16 ColorEntry instances which map
36 * system color indexes (from 0 to 15) into actual colors.
37 *
38 * Each entry can be set as bold, in which case any text
39 * drawn using the color should be drawn in bold.
40 *
41 * Each entry can also be transparent, in which case the terminal
42 * display should avoid drawing the background for any characters
43 * using the entry as a background.
44 */
45class ColorEntry
46{
47public:
48 /** Specifies the weight to use when drawing text with this color. */
49 enum FontWeight
50 {
51 /** Always draw text in this color with a bold weight. */
52 Bold,
53 /** Always draw text in this color with a normal weight. */
54 Normal,
55 /**
56 * Use the current font weight set by the terminal application.
57 * This is the default behavior.
58 */
59 UseCurrentFormat
60 };
61
62 /**
63 * Constructs a new color palette entry.
64 *
65 * @param c The color value for this entry.
66 * @param tr Specifies that the color should be transparent when used as a background color.
67 * @param weight Specifies the font weight to use when drawing text with this color.
68 */
69 ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat)
70 : color(c), transparent(tr), fontWeight(weight) {}
71
72 /**
73 * Constructs a new color palette entry with an undefined color, and
74 * with the transparent and bold flags set to false.
75 */
76 ColorEntry() : transparent(false), fontWeight(UseCurrentFormat) {}
77
78 /**
79 * Sets the color, transparency and boldness of this color to those of @p rhs.
80 */
81 void operator=(const ColorEntry& rhs)
82 {
83 color = rhs.color;
84 transparent = rhs.transparent;
85 fontWeight = rhs.fontWeight;
86 }
87
88 /** The color value of this entry for display. */
89 QColor color;
90
91 /**
92 * If true character backgrounds using this color should be transparent.
93 * This is not applicable when the color is used to render text.
94 */
95 bool transparent;
96 /**
97 * Specifies the font weight to use when drawing text with this color.
98 * This is not applicable when the color is used to draw a character's background.
99 */
100 FontWeight fontWeight;
101};
102
103
104// Attributed Character Representations ///////////////////////////////
105
106// Colors
107
108#define BASE_COLORS (2+8)
109#define INTENSITIES 2
110#define TABLE_COLORS (INTENSITIES*BASE_COLORS)
111
112#define DEFAULT_FORE_COLOR 0
113#define DEFAULT_BACK_COLOR 1
114
115//a standard set of colors using black text on a white background.
116//defined in TerminalDisplay.cpp
117
118extern const ColorEntry base_color_table[TABLE_COLORS] KDE_NO_EXPORT;
119
120/* CharacterColor is a union of the various color spaces.
121
122 Assignment is as follows:
123
124 Type - Space - Values
125
126 0 - Undefined - u: 0, v:0 w:0
127 1 - Default - u: 0..1 v:intense w:0
128 2 - System - u: 0..7 v:intense w:0
129 3 - Index(256) - u: 16..255 v:0 w:0
130 4 - RGB - u: 0..255 v:0..256 w:0..256
131
132 Default colour space has two separate colours, namely
133 default foreground and default background colour.
134*/
135
136#define COLOR_SPACE_UNDEFINED 0
137#define COLOR_SPACE_DEFAULT 1
138#define COLOR_SPACE_SYSTEM 2
139#define COLOR_SPACE_256 3
140#define COLOR_SPACE_RGB 4
141
142/**
143 * Describes the color of a single character in the terminal.
144 */
145class CharacterColor
146{
147 friend class Character;
148
149public:
150 /** Constructs a new CharacterColor whoose color and color space are undefined. */
151 CharacterColor()
152 : _colorSpace(COLOR_SPACE_UNDEFINED),
153 _u(0),
154 _v(0),
155 _w(0)
156 {}
157
158 /**
159 * Constructs a new CharacterColor using the specified @p colorSpace and with
160 * color value @p co
161 *
162 * The meaning of @p co depends on the @p colorSpace used.
163 *
164 * TODO : Document how @p co relates to @p colorSpace
165 *
166 * TODO : Add documentation about available color spaces.
167 */
168 CharacterColor(quint8 colorSpace, int co)
169 : _colorSpace(colorSpace),
170 _u(0),
171 _v(0),
172 _w(0)
173 {
174 switch (colorSpace)
175 {
176 case COLOR_SPACE_DEFAULT:
177 _u = co & 1;
178 break;
179 case COLOR_SPACE_SYSTEM:
180 _u = co & 7;
181 _v = (co >> 3) & 1;
182 break;
183 case COLOR_SPACE_256:
184 _u = co & 255;
185 break;
186 case COLOR_SPACE_RGB:
187 _u = co >> 16;
188 _v = co >> 8;
189 _w = co;
190 break;
191 default:
192 _colorSpace = COLOR_SPACE_UNDEFINED;
193 }
194 }
195
196 /**
197 * Returns true if this character color entry is valid.
198 */
199 bool isValid()
200 {
201 return _colorSpace != COLOR_SPACE_UNDEFINED;
202 }
203
204 /**
205 * Toggles the value of this color between a normal system color and the corresponding intensive
206 * system color.
207 *
208 * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM
209 * color spaces.
210 */
211 void toggleIntensive();
212
213 /**
214 * Returns the color within the specified color @p palette
215 *
216 * The @p palette is only used if this color is one of the 16 system colors, otherwise
217 * it is ignored.
218 */
219 QColor color(const ColorEntry* palette) const;
220
221 /**
222 * Compares two colors and returns true if they represent the same color value and
223 * use the same color space.
224 */
225 friend bool operator == (const CharacterColor& a, const CharacterColor& b);
226 /**
227 * Compares two colors and returns true if they represent different color values
228 * or use different color spaces.
229 */
230 friend bool operator != (const CharacterColor& a, const CharacterColor& b);
231
232private:
233 quint8 _colorSpace;
234
235 // bytes storing the character color
236 quint8 _u;
237 quint8 _v;
238 quint8 _w;
239};
240
241inline bool operator == (const CharacterColor& a, const CharacterColor& b)
242{
243 return a._colorSpace == b._colorSpace &&
244 a._u == b._u &&
245 a._v == b._v &&
246 a._w == b._w;
247}
248inline bool operator != (const CharacterColor& a, const CharacterColor& b)
249{
250 return !operator==(a,b);
251}
252
253inline const QColor color256(quint8 u, const ColorEntry* base)
254{
255 // 0.. 16: system colors
256 if (u < 8) return base[u+2 ].color; u -= 8;
257 if (u < 8) return base[u+2+BASE_COLORS].color; u -= 8;
258
259 // 16..231: 6x6x6 rgb color cube
260 if (u < 216) return QColor(((u/36)%6) ? (40*((u/36)%6)+55) : 0,
261 ((u/ 6)%6) ? (40*((u/ 6)%6)+55) : 0,
262 ((u/ 1)%6) ? (40*((u/ 1)%6)+55) : 0); u -= 216;
263
264 // 232..255: gray, leaving out black and white
265 int gray = u*10+8; return QColor(gray,gray,gray);
266}
267
268inline QColor CharacterColor::color(const ColorEntry* base) const
269{
270 switch (_colorSpace)
271 {
272 case COLOR_SPACE_DEFAULT: return base[_u+0+(_v?BASE_COLORS:0)].color;
273 case COLOR_SPACE_SYSTEM: return base[_u+2+(_v?BASE_COLORS:0)].color;
274 case COLOR_SPACE_256: return color256(_u,base);
275 case COLOR_SPACE_RGB: return QColor(_u,_v,_w);
276 case COLOR_SPACE_UNDEFINED: return QColor();
277 }
278
279 Q_ASSERT(false); // invalid color space
280
281 return QColor();
282}
283
284inline void CharacterColor::toggleIntensive()
285{
286 if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT)
287 {
288 _v = !_v;
289 }
290}
291
292
293#endif // CHARACTERCOLOR_H
294
0295
=== added file 'src/plugin/konsole/ColorScheme.cpp'
--- src/plugin/konsole/ColorScheme.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/ColorScheme.cpp 2014-05-06 21:50:22 +0000
@@ -0,0 +1,774 @@
1/*
2 This source file is part of Konsole, a terminal emulator.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20*/
21
22// Own
23#include "ColorScheme.h"
24#include "tools.h"
25
26// Qt
27#include <QtGui/QBrush>
28#include <QtCore/QFile>
29#include <QtCore/QFileInfo>
30#include <QtDebug>
31#include <QSettings>
32#include <QDir>
33
34
35// KDE
36//#include <KColorScheme>
37//#include <KConfig>
38//#include <KLocale>
39//#include <KDebug>
40//#include <KConfigGroup>
41//#include <KStandardDirs>
42
43
44const ColorEntry ColorScheme::defaultTable[TABLE_COLORS] =
45 // The following are almost IBM standard color codes, with some slight
46 // gamma correction for the dim colors to compensate for bright X screens.
47 // It contains the 8 ansiterm/xterm colors in 2 intensities.
48{
49 ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
50QColor(0xFF,0xFF,0xFF), 1), // Dfore, Dback
51 ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
52QColor(0xB2,0x18,0x18), 0), // Black, Red
53 ColorEntry( QColor(0x18,0xB2,0x18), 0), ColorEntry(
54QColor(0xB2,0x68,0x18), 0), // Green, Yellow
55 ColorEntry( QColor(0x18,0x18,0xB2), 0), ColorEntry(
56QColor(0xB2,0x18,0xB2), 0), // Blue, Magenta
57 ColorEntry( QColor(0x18,0xB2,0xB2), 0), ColorEntry(
58QColor(0xB2,0xB2,0xB2), 0), // Cyan, White
59 // intensive
60 ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
61QColor(0xFF,0xFF,0xFF), 1),
62 ColorEntry( QColor(0x68,0x68,0x68), 0), ColorEntry(
63QColor(0xFF,0x54,0x54), 0),
64 ColorEntry( QColor(0x54,0xFF,0x54), 0), ColorEntry(
65QColor(0xFF,0xFF,0x54), 0),
66 ColorEntry( QColor(0x54,0x54,0xFF), 0), ColorEntry(
67QColor(0xFF,0x54,0xFF), 0),
68 ColorEntry( QColor(0x54,0xFF,0xFF), 0), ColorEntry(
69QColor(0xFF,0xFF,0xFF), 0)
70};
71
72const char* const ColorScheme::colorNames[TABLE_COLORS] =
73{
74 "Foreground",
75 "Background",
76 "Color0",
77 "Color1",
78 "Color2",
79 "Color3",
80 "Color4",
81 "Color5",
82 "Color6",
83 "Color7",
84 "ForegroundIntense",
85 "BackgroundIntense",
86 "Color0Intense",
87 "Color1Intense",
88 "Color2Intense",
89 "Color3Intense",
90 "Color4Intense",
91 "Color5Intense",
92 "Color6Intense",
93 "Color7Intense"
94};
95// dummy silently comment out the tr_NOOP
96#define tr_NOOP
97const char* const ColorScheme::translatedColorNames[TABLE_COLORS] =
98{
99 tr_NOOP("Foreground"),
100 tr_NOOP("Background"),
101 tr_NOOP("Color 1"),
102 tr_NOOP("Color 2"),
103 tr_NOOP("Color 3"),
104 tr_NOOP("Color 4"),
105 tr_NOOP("Color 5"),
106 tr_NOOP("Color 6"),
107 tr_NOOP("Color 7"),
108 tr_NOOP("Color 8"),
109 tr_NOOP("Foreground (Intense)"),
110 tr_NOOP("Background (Intense)"),
111 tr_NOOP("Color 1 (Intense)"),
112 tr_NOOP("Color 2 (Intense)"),
113 tr_NOOP("Color 3 (Intense)"),
114 tr_NOOP("Color 4 (Intense)"),
115 tr_NOOP("Color 5 (Intense)"),
116 tr_NOOP("Color 6 (Intense)"),
117 tr_NOOP("Color 7 (Intense)"),
118 tr_NOOP("Color 8 (Intense)")
119};
120
121ColorScheme::ColorScheme()
122{
123 _table = 0;
124 _randomTable = 0;
125 _opacity = 1.0;
126}
127ColorScheme::ColorScheme(const ColorScheme& other)
128 : _opacity(other._opacity)
129 ,_table(0)
130 ,_randomTable(0)
131{
132 setName(other.name());
133 setDescription(other.description());
134
135 if ( other._table != 0 )
136 {
137 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
138 setColorTableEntry(i,other._table[i]);
139 }
140
141 if ( other._randomTable != 0 )
142 {
143 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
144 {
145 const RandomizationRange& range = other._randomTable[i];
146 setRandomizationRange(i,range.hue,range.saturation,range.value);
147 }
148 }
149}
150ColorScheme::~ColorScheme()
151{
152 delete[] _table;
153 delete[] _randomTable;
154}
155
156void ColorScheme::setDescription(const QString& description) { _description = description; }
157QString ColorScheme::description() const { return _description; }
158
159void ColorScheme::setName(const QString& name) { _name = name; }
160QString ColorScheme::name() const { return _name; }
161
162void ColorScheme::setColorTableEntry(int index , const ColorEntry& entry)
163{
164 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
165
166 if ( !_table )
167 {
168 _table = new ColorEntry[TABLE_COLORS];
169
170 for (int i=0;i<TABLE_COLORS;i++)
171 _table[i] = defaultTable[i];
172 }
173
174 _table[index] = entry;
175}
176ColorEntry ColorScheme::colorEntry(int index , uint randomSeed) const
177{
178 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
179
180 if ( randomSeed != 0 )
181 qsrand(randomSeed);
182
183 ColorEntry entry = colorTable()[index];
184
185 if ( randomSeed != 0 &&
186 _randomTable != 0 &&
187 !_randomTable[index].isNull() )
188 {
189 const RandomizationRange& range = _randomTable[index];
190
191
192 int hueDifference = range.hue ? (qrand() % range.hue) - range.hue/2 : 0;
193 int saturationDifference = range.saturation ? (qrand() % range.saturation) - range.saturation/2 : 0;
194 int valueDifference = range.value ? (qrand() % range.value) - range.value/2 : 0;
195
196 QColor& color = entry.color;
197
198 int newHue = qAbs( (color.hue() + hueDifference) % MAX_HUE );
199 int newValue = qMin( qAbs(color.value() + valueDifference) , 255 );
200 int newSaturation = qMin( qAbs(color.saturation() + saturationDifference) , 255 );
201
202 color.setHsv(newHue,newSaturation,newValue);
203 }
204
205 return entry;
206}
207void ColorScheme::getColorTable(ColorEntry* table , uint randomSeed) const
208{
209 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
210 table[i] = colorEntry(i,randomSeed);
211}
212bool ColorScheme::randomizedBackgroundColor() const
213{
214 return _randomTable == 0 ? false : !_randomTable[1].isNull();
215}
216void ColorScheme::setRandomizedBackgroundColor(bool randomize)
217{
218 // the hue of the background colour is allowed to be randomly
219 // adjusted as much as possible.
220 //
221 // the value and saturation are left alone to maintain read-ability
222 if ( randomize )
223 {
224 setRandomizationRange( 1 /* background color index */ , MAX_HUE , 255 , 0 );
225 }
226 else
227 {
228 if ( _randomTable )
229 setRandomizationRange( 1 /* background color index */ , 0 , 0 , 0 );
230 }
231}
232
233void ColorScheme::setRandomizationRange( int index , quint16 hue , quint8 saturation ,
234 quint8 value )
235{
236 Q_ASSERT( hue <= MAX_HUE );
237 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
238
239 if ( _randomTable == 0 )
240 _randomTable = new RandomizationRange[TABLE_COLORS];
241
242 _randomTable[index].hue = hue;
243 _randomTable[index].value = value;
244 _randomTable[index].saturation = saturation;
245}
246
247const ColorEntry* ColorScheme::colorTable() const
248{
249 if ( _table )
250 return _table;
251 else
252 return defaultTable;
253}
254QColor ColorScheme::foregroundColor() const
255{
256 return colorTable()[0].color;
257}
258QColor ColorScheme::backgroundColor() const
259{
260 return colorTable()[1].color;
261}
262bool ColorScheme::hasDarkBackground() const
263{
264 // value can range from 0 - 255, with larger values indicating higher brightness.
265 // so 127 is in the middle, anything less is deemed 'dark'
266 return backgroundColor().value() < 127;
267}
268void ColorScheme::setOpacity(qreal opacity) { _opacity = opacity; }
269qreal ColorScheme::opacity() const { return _opacity; }
270
271void ColorScheme::read(const QString & fileName)
272{
273 QSettings s(fileName, QSettings::IniFormat);
274 s.beginGroup("General");
275
276 _description = s.value("Description", QObject::tr("Un-named Color Scheme")).toString();
277 _opacity = s.value("Opacity",qreal(1.0)).toDouble();
278 s.endGroup();
279
280 for (int i=0 ; i < TABLE_COLORS ; i++)
281 {
282 readColorEntry(&s, i);
283 }
284}
285#if 0
286// implemented upstream - user apps
287void ColorScheme::read(KConfig& config)
288{
289 KConfigGroup configGroup = config.group("General");
290
291 QString description = configGroup.readEntry("Description", QObject::tr("Un-named Color Scheme"));
292
293 _description = tr(description.toUtf8());
294 _opacity = configGroup.readEntry("Opacity",qreal(1.0));
295
296 for (int i=0 ; i < TABLE_COLORS ; i++)
297 {
298 readColorEntry(config,i);
299 }
300}
301void ColorScheme::write(KConfig& config) const
302{
303 KConfigGroup configGroup = config.group("General");
304
305 configGroup.writeEntry("Description",_description);
306 configGroup.writeEntry("Opacity",_opacity);
307
308 for (int i=0 ; i < TABLE_COLORS ; i++)
309 {
310 RandomizationRange random = _randomTable != 0 ? _randomTable[i] : RandomizationRange();
311 writeColorEntry(config,colorNameForIndex(i),colorTable()[i],random);
312 }
313}
314#endif
315
316QString ColorScheme::colorNameForIndex(int index)
317{
318 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
319
320 return QString(colorNames[index]);
321}
322QString ColorScheme::translatedColorNameForIndex(int index)
323{
324 Q_ASSERT( index >= 0 && index < TABLE_COLORS );
325
326 return translatedColorNames[index];
327}
328
329void ColorScheme::readColorEntry(QSettings * s , int index)
330{
331 s->beginGroup(colorNameForIndex(index));
332
333 ColorEntry entry;
334
335 QStringList rgbList = s->value("Color", QStringList()).toStringList();
336 if (rgbList.count() != 3)
337 {
338 Q_ASSERT(0);
339 }
340 int r, g, b;
341 r = rgbList[0].toInt();
342 g = rgbList[1].toInt();
343 b = rgbList[2].toInt();
344 entry.color = QColor(r, g, b);
345
346 entry.transparent = s->value("Transparent",false).toBool();
347
348 // Deprecated key from KDE 4.0 which set 'Bold' to true to force
349 // a color to be bold or false to use the current format
350 //
351 // TODO - Add a new tri-state key which allows for bold, normal or
352 // current format
353 if (s->contains("Bold"))
354 entry.fontWeight = s->value("Bold",false).toBool() ? ColorEntry::Bold :
355 ColorEntry::UseCurrentFormat;
356
357 quint16 hue = s->value("MaxRandomHue",0).toInt();
358 quint8 value = s->value("MaxRandomValue",0).toInt();
359 quint8 saturation = s->value("MaxRandomSaturation",0).toInt();
360
361 setColorTableEntry( index , entry );
362
363 if ( hue != 0 || value != 0 || saturation != 0 )
364 setRandomizationRange( index , hue , saturation , value );
365
366 s->endGroup();
367}
368#if 0
369// implemented upstream - user apps
370void ColorScheme::writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry , const RandomizationRange& random) const
371{
372 KConfigGroup configGroup(&config,colorName);
373
374 configGroup.writeEntry("Color",entry.color);
375 configGroup.writeEntry("Transparency",(bool)entry.transparent);
376 if (entry.fontWeight != ColorEntry::UseCurrentFormat)
377 {
378 configGroup.writeEntry("Bold",entry.fontWeight == ColorEntry::Bold);
379 }
380
381 // record randomization if this color has randomization or
382 // if one of the keys already exists
383 if ( !random.isNull() || configGroup.hasKey("MaxRandomHue") )
384 {
385 configGroup.writeEntry("MaxRandomHue",(int)random.hue);
386 configGroup.writeEntry("MaxRandomValue",(int)random.value);
387 configGroup.writeEntry("MaxRandomSaturation",(int)random.saturation);
388 }
389}
390#endif
391
392//
393// Work In Progress - A color scheme for use on KDE setups for users
394// with visual disabilities which means that they may have trouble
395// reading text with the supplied color schemes.
396//
397// This color scheme uses only the 'safe' colors defined by the
398// KColorScheme class.
399//
400// A complication this introduces is that each color provided by
401// KColorScheme is defined as a 'background' or 'foreground' color.
402// Only foreground colors are allowed to be used to render text and
403// only background colors are allowed to be used for backgrounds.
404//
405// The ColorEntry and TerminalDisplay classes do not currently
406// support this restriction.
407//
408// Requirements:
409// - A color scheme which uses only colors from the KColorScheme class
410// - Ability to restrict which colors the TerminalDisplay widget
411// uses as foreground and background color
412// - Make use of KGlobalSettings::allowDefaultBackgroundImages() as
413// a hint to determine whether this accessible color scheme should
414// be used by default.
415//
416//
417// -- Robert Knight <robertknight@gmail.com> 21/07/2007
418//
419AccessibleColorScheme::AccessibleColorScheme()
420 : ColorScheme()
421{
422#if 0
423// It's not finished in konsole and it breaks Qt4 compilation as well
424 // basic attributes
425 setName("accessible");
426 setDescription(QObject::tr("Accessible Color Scheme"));
427
428 // setup colors
429 const int ColorRoleCount = 8;
430
431 const KColorScheme colorScheme(QPalette::Active);
432
433 QBrush colors[ColorRoleCount] =
434 {
435 colorScheme.foreground( colorScheme.NormalText ),
436 colorScheme.background( colorScheme.NormalBackground ),
437
438 colorScheme.foreground( colorScheme.InactiveText ),
439 colorScheme.foreground( colorScheme.ActiveText ),
440 colorScheme.foreground( colorScheme.LinkText ),
441 colorScheme.foreground( colorScheme.VisitedText ),
442 colorScheme.foreground( colorScheme.NegativeText ),
443 colorScheme.foreground( colorScheme.NeutralText )
444 };
445
446 for ( int i = 0 ; i < TABLE_COLORS ; i++ )
447 {
448 ColorEntry entry;
449 entry.color = colors[ i % ColorRoleCount ].color();
450
451 setColorTableEntry( i , entry );
452 }
453#endif
454}
455
456KDE3ColorSchemeReader::KDE3ColorSchemeReader( QIODevice* device ) :
457 _device(device)
458{
459}
460ColorScheme* KDE3ColorSchemeReader::read()
461{
462 Q_ASSERT( _device->openMode() == QIODevice::ReadOnly ||
463 _device->openMode() == QIODevice::ReadWrite );
464
465 ColorScheme* scheme = new ColorScheme();
466
467 QRegExp comment("#.*$");
468 while ( !_device->atEnd() )
469 {
470 QString line(_device->readLine());
471 line.remove(comment);
472 line = line.simplified();
473
474 if ( line.isEmpty() )
475 continue;
476
477 if ( line.startsWith(QLatin1String("color")) )
478 {
479 if (!readColorLine(line,scheme))
480 qDebug() << "Failed to read KDE 3 color scheme line" << line;
481 }
482 else if ( line.startsWith(QLatin1String("title")) )
483 {
484 if (!readTitleLine(line,scheme))
485 qDebug() << "Failed to read KDE 3 color scheme title line" << line;
486 }
487 else
488 {
489 qDebug() << "KDE 3 color scheme contains an unsupported feature, '" <<
490 line << "'";
491 }
492 }
493
494 return scheme;
495}
496bool KDE3ColorSchemeReader::readColorLine(const QString& line,ColorScheme* scheme)
497{
498 QStringList list = line.split(QChar(' '));
499
500 if (list.count() != 7)
501 return false;
502 if (list.first() != "color")
503 return false;
504
505 int index = list[1].toInt();
506 int red = list[2].toInt();
507 int green = list[3].toInt();
508 int blue = list[4].toInt();
509 int transparent = list[5].toInt();
510 int bold = list[6].toInt();
511
512 const int MAX_COLOR_VALUE = 255;
513
514 if( (index < 0 || index >= TABLE_COLORS )
515 || (red < 0 || red > MAX_COLOR_VALUE )
516 || (blue < 0 || blue > MAX_COLOR_VALUE )
517 || (green < 0 || green > MAX_COLOR_VALUE )
518 || (transparent != 0 && transparent != 1 )
519 || (bold != 0 && bold != 1) )
520 return false;
521
522 ColorEntry entry;
523 entry.color = QColor(red,green,blue);
524 entry.transparent = ( transparent != 0 );
525 entry.fontWeight = ( bold != 0 ) ? ColorEntry::Bold : ColorEntry::UseCurrentFormat;
526
527 scheme->setColorTableEntry(index,entry);
528 return true;
529}
530bool KDE3ColorSchemeReader::readTitleLine(const QString& line,ColorScheme* scheme)
531{
532 if( !line.startsWith(QLatin1String("title")) )
533 return false;
534
535 int spacePos = line.indexOf(' ');
536 if( spacePos == -1 )
537 return false;
538
539 QString description = line.mid(spacePos+1);
540
541 scheme->setDescription(description.toUtf8());
542 return true;
543}
544ColorSchemeManager::ColorSchemeManager()
545 : _haveLoadedAll(false)
546{
547}
548ColorSchemeManager::~ColorSchemeManager()
549{
550 QHashIterator<QString,const ColorScheme*> iter(_colorSchemes);
551 while (iter.hasNext())
552 {
553 iter.next();
554 delete iter.value();
555 }
556}
557void ColorSchemeManager::loadAllColorSchemes()
558{
559 qDebug() << "loadAllColorSchemes";
560 int success = 0;
561 int failed = 0;
562
563 QList<QString> nativeColorSchemes = listColorSchemes();
564
565 QListIterator<QString> nativeIter(nativeColorSchemes);
566 while ( nativeIter.hasNext() )
567 {
568 if ( loadColorScheme( nativeIter.next() ) )
569 success++;
570 else
571 failed++;
572 }
573
574 QList<QString> kde3ColorSchemes = listKDE3ColorSchemes();
575 QListIterator<QString> kde3Iter(kde3ColorSchemes);
576 while ( kde3Iter.hasNext() )
577 {
578 if ( loadKDE3ColorScheme( kde3Iter.next() ) )
579 success++;
580 else
581 failed++;
582 }
583
584 if ( failed > 0 )
585 qDebug() << "failed to load " << failed << " color schemes.";
586
587 _haveLoadedAll = true;
588}
589QList<const ColorScheme*> ColorSchemeManager::allColorSchemes()
590{
591 if ( !_haveLoadedAll )
592 {
593 loadAllColorSchemes();
594 }
595
596 return _colorSchemes.values();
597}
598bool ColorSchemeManager::loadKDE3ColorScheme(const QString& filePath)
599{
600 QFile file(filePath);
601 if (!filePath.endsWith(QLatin1String(".schema")) || !file.open(QIODevice::ReadOnly))
602 return false;
603
604 KDE3ColorSchemeReader reader(&file);
605 ColorScheme* scheme = reader.read();
606 scheme->setName(QFileInfo(file).baseName());
607 file.close();
608
609 if (scheme->name().isEmpty())
610 {
611 qDebug() << "color scheme name is not valid.";
612 delete scheme;
613 return false;
614 }
615
616 QFileInfo info(filePath);
617
618 if ( !_colorSchemes.contains(info.baseName()) )
619 _colorSchemes.insert(scheme->name(),scheme);
620 else
621 {
622 qDebug() << "color scheme with name" << scheme->name() << "has already been" <<
623 "found, ignoring.";
624 delete scheme;
625 }
626
627 return true;
628}
629#if 0
630void ColorSchemeManager::addColorScheme(ColorScheme* scheme)
631{
632 _colorSchemes.insert(scheme->name(),scheme);
633
634 // save changes to disk
635 QString path = KGlobal::dirs()->saveLocation("data","konsole/") + scheme->name() + ".colorscheme";
636 KConfig config(path , KConfig::NoGlobals);
637
638 scheme->write(config);
639}
640#endif
641bool ColorSchemeManager::loadColorScheme(const QString& filePath)
642{
643 if ( !filePath.endsWith(QLatin1String(".colorscheme")) || !QFile::exists(filePath) )
644 return false;
645
646 QFileInfo info(filePath);
647
648 ColorScheme* scheme = new ColorScheme();
649 scheme->setName(info.baseName());
650 scheme->read(filePath);
651
652 if (scheme->name().isEmpty())
653 {
654 qDebug() << "Color scheme in" << filePath << "does not have a valid name and was not loaded.";
655 delete scheme;
656 return false;
657 }
658
659 if ( !_colorSchemes.contains(info.baseName()) )
660 {
661 _colorSchemes.insert(scheme->name(),scheme);
662 }
663 else
664 {
665 qDebug() << "color scheme with name" << scheme->name() << "has already been" <<
666 "found, ignoring.";
667
668 delete scheme;
669 }
670
671 return true;
672}
673QList<QString> ColorSchemeManager::listKDE3ColorSchemes()
674{
675 QString dname(get_color_schemes_dir());
676 QDir dir(dname);
677 QStringList filters;
678 filters << "*.schema";
679 dir.setNameFilters(filters);
680 QStringList list = dir.entryList(filters);
681 QStringList ret;
682 foreach(QString i, list)
683 ret << dname + "/" + i;
684 return ret;
685 //return KGlobal::dirs()->findAllResources("data",
686 // "konsole/*.schema",
687 // KStandardDirs::NoDuplicates);
688 //
689}
690QList<QString> ColorSchemeManager::listColorSchemes()
691{
692 QString dname(get_color_schemes_dir());
693 QDir dir(dname);
694 QStringList filters;
695 filters << "*.colorscheme";
696 dir.setNameFilters(filters);
697 QStringList list = dir.entryList(filters);
698 QStringList ret;
699 foreach(QString i, list)
700 ret << dname + "/" + i;
701 return ret;
702// return KGlobal::dirs()->findAllResources("data",
703// "konsole/*.colorscheme",
704// KStandardDirs::NoDuplicates);
705}
706const ColorScheme ColorSchemeManager::_defaultColorScheme;
707const ColorScheme* ColorSchemeManager::defaultColorScheme() const
708{
709 return &_defaultColorScheme;
710}
711bool ColorSchemeManager::deleteColorScheme(const QString& name)
712{
713 Q_ASSERT( _colorSchemes.contains(name) );
714
715 // lookup the path and delete
716 QString path = findColorSchemePath(name);
717 if ( QFile::remove(path) )
718 {
719 _colorSchemes.remove(name);
720 return true;
721 }
722 else
723 {
724 qDebug() << "Failed to remove color scheme -" << path;
725 return false;
726 }
727}
728QString ColorSchemeManager::findColorSchemePath(const QString& name) const
729{
730// QString path = KStandardDirs::locate("data","konsole/"+name+".colorscheme");
731 QString path(get_color_schemes_dir() + "/"+ name + ".colorscheme");
732 if ( !path.isEmpty() )
733 return path;
734
735 //path = KStandardDirs::locate("data","konsole/"+name+".schema");
736 path = get_color_schemes_dir() + "/"+ name + ".schema";
737
738 return path;
739}
740const ColorScheme* ColorSchemeManager::findColorScheme(const QString& name)
741{
742 if ( name.isEmpty() )
743 return defaultColorScheme();
744
745 if ( _colorSchemes.contains(name) )
746 return _colorSchemes[name];
747 else
748 {
749 // look for this color scheme
750 QString path = findColorSchemePath(name);
751 if ( !path.isEmpty() && loadColorScheme(path) )
752 {
753 return findColorScheme(name);
754 }
755 else
756 {
757 if (!path.isEmpty() && loadKDE3ColorScheme(path))
758 return findColorScheme(name);
759 }
760
761 qDebug() << "Could not find color scheme - " << name;
762
763 return 0;
764 }
765}
766
767ColorSchemeManager* ColorSchemeManager::theColorSchemeManager = 0;
768//K_GLOBAL_STATIC( ColorSchemeManager , theColorSchemeManager )
769ColorSchemeManager* ColorSchemeManager::instance()
770{
771 if (! theColorSchemeManager)
772 theColorSchemeManager = new ColorSchemeManager();
773 return theColorSchemeManager;
774}
0775
=== added file 'src/plugin/konsole/ColorScheme.h'
--- src/plugin/konsole/ColorScheme.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/ColorScheme.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,342 @@
1/*
2 This source file is part of Konsole, a terminal emulator.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20*/
21
22#ifndef COLORSCHEME_H
23#define COLORSCHEME_H
24
25// Qt
26#include <QtCore/QHash>
27#include <QtCore/QList>
28#include <QtCore/QMetaType>
29#include <QtCore/QIODevice>
30#include <QtCore/QSet>
31#include <QSettings>
32
33// Konsole
34#include "CharacterColor.h"
35
36class QIODevice;
37//class KConfig;
38
39
40/**
41 * Represents a color scheme for a terminal display.
42 *
43 * The color scheme includes the palette of colors used to draw the text and character backgrounds
44 * in the display and the opacity level of the display background.
45 */
46class ColorScheme
47{
48public:
49 /**
50 * Constructs a new color scheme which is initialised to the default color set
51 * for Konsole.
52 */
53 ColorScheme();
54 ColorScheme(const ColorScheme& other);
55 ~ColorScheme();
56
57 /** Sets the descriptive name of the color scheme. */
58 void setDescription(const QString& description);
59 /** Returns the descriptive name of the color scheme. */
60 QString description() const;
61
62 /** Sets the name of the color scheme */
63 void setName(const QString& name);
64 /** Returns the name of the color scheme */
65 QString name() const;
66
67#if 0
68// Implemented upstream - in user apps
69 /** Reads the color scheme from the specified configuration source */
70 void read(KConfig& config);
71 /** Writes the color scheme to the specified configuration source */
72 void write(KConfig& config) const;
73#endif
74 void read(const QString & filename);
75
76 /** Sets a single entry within the color palette. */
77 void setColorTableEntry(int index , const ColorEntry& entry);
78
79 /**
80 * Copies the color entries which form the palette for this color scheme
81 * into @p table. @p table should be an array with TABLE_COLORS entries.
82 *
83 * @param table Array into which the color entries for this color scheme
84 * are copied.
85 * @param randomSeed Color schemes may allow certain colors in their
86 * palette to be randomized. The seed is used to pick the random color.
87 */
88 void getColorTable(ColorEntry* table, uint randomSeed = 0) const;
89
90 /**
91 * Retrieves a single color entry from the table.
92 *
93 * See getColorTable()
94 */
95 ColorEntry colorEntry(int index , uint randomSeed = 0) const;
96
97 /**
98 * Convenience method. Returns the
99 * foreground color for this scheme,
100 * this is the primary color used to draw the
101 * text in this scheme.
102 */
103 QColor foregroundColor() const;
104 /**
105 * Convenience method. Returns the background color for
106 * this scheme, this is the primary color used to
107 * draw the terminal background in this scheme.
108 */
109 QColor backgroundColor() const;
110
111 /**
112 * Returns true if this color scheme has a dark background.
113 * The background color is said to be dark if it has a value of less than 127
114 * in the HSV color space.
115 */
116 bool hasDarkBackground() const;
117
118 /**
119 * Sets the opacity level of the display background. @p opacity ranges
120 * between 0 (completely transparent background) and 1 (completely
121 * opaque background).
122 *
123 * Defaults to 1.
124 *
125 * TODO: More documentation
126 */
127 void setOpacity(qreal opacity);
128 /**
129 * Returns the opacity level for this color scheme, see setOpacity()
130 * TODO: More documentation
131 */
132 qreal opacity() const;
133
134 /**
135 * Enables randomization of the background color. This will cause
136 * the palette returned by getColorTable() and colorEntry() to
137 * be adjusted depending on the value of the random seed argument
138 * to them.
139 */
140 void setRandomizedBackgroundColor(bool randomize);
141
142 /** Returns true if the background color is randomized. */
143 bool randomizedBackgroundColor() const;
144
145 static QString colorNameForIndex(int index);
146 static QString translatedColorNameForIndex(int index);
147
148private:
149 // specifies how much a particular color can be randomized by
150 class RandomizationRange
151 {
152 public:
153 RandomizationRange() : hue(0) , saturation(0) , value(0) {}
154
155 bool isNull() const
156 {
157 return ( hue == 0 && saturation == 0 && value == 0 );
158 }
159
160 quint16 hue;
161 quint8 saturation;
162 quint8 value;
163 };
164
165 // returns the active color table. if none has been set specifically,
166 // this is the default color table.
167 const ColorEntry* colorTable() const;
168
169#if 0
170// implemented upstream - user apps
171 // reads a single colour entry from a KConfig source
172 // and sets the palette entry at 'index' to the entry read.
173 void readColorEntry(KConfig& config , int index);
174 // writes a single colour entry to a KConfig source
175 void writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry,const RandomizationRange& range) const;
176#endif
177 void readColorEntry(QSettings *s, int index);
178
179 // sets the amount of randomization allowed for a particular color
180 // in the palette. creates the randomization table if
181 // it does not already exist
182 void setRandomizationRange( int index , quint16 hue , quint8 saturation , quint8 value );
183
184 QString _description;
185 QString _name;
186 qreal _opacity;
187 ColorEntry* _table; // pointer to custom color table or 0 if the default
188 // color scheme is being used
189
190
191 static const quint16 MAX_HUE = 340;
192
193 RandomizationRange* _randomTable; // pointer to randomization table or 0
194 // if no colors in the color scheme support
195 // randomization
196
197 static const char* const colorNames[TABLE_COLORS];
198 static const char* const translatedColorNames[TABLE_COLORS];
199
200 static const ColorEntry defaultTable[]; // table of default color entries
201};
202
203/**
204 * A color scheme which uses colors from the standard KDE color palette.
205 *
206 * This is designed primarily for the benefit of users who are using specially
207 * designed colors.
208 *
209 * TODO Implement and make it the default on systems with specialized KDE
210 * color schemes.
211 */
212class AccessibleColorScheme : public ColorScheme
213{
214public:
215 AccessibleColorScheme();
216};
217
218/**
219 * Reads a color scheme stored in the .schema format used in the KDE 3 incarnation
220 * of Konsole
221 *
222 * Only the basic essentials ( title and color palette entries ) are currently
223 * supported. Additional options such as background image and background
224 * blend colors are ignored.
225 */
226class KDE3ColorSchemeReader
227{
228public:
229 /**
230 * Constructs a new reader which reads from the specified device.
231 * The device should be open in read-only mode.
232 */
233 KDE3ColorSchemeReader( QIODevice* device );
234
235 /**
236 * Reads and parses the contents of the .schema file from the input
237 * device and returns the ColorScheme defined within it.
238 *
239 * Returns a null pointer if an error occurs whilst parsing
240 * the contents of the file.
241 */
242 ColorScheme* read();
243
244private:
245 // reads a line from the file specifying a colour palette entry
246 // format is: color [index] [red] [green] [blue] [transparent] [bold]
247 bool readColorLine(const QString& line , ColorScheme* scheme);
248 bool readTitleLine(const QString& line , ColorScheme* scheme);
249
250 QIODevice* _device;
251};
252
253/**
254 * Manages the color schemes available for use by terminal displays.
255 * See ColorScheme
256 */
257class ColorSchemeManager
258{
259public:
260
261 /**
262 * Constructs a new ColorSchemeManager and loads the list
263 * of available color schemes.
264 *
265 * The color schemes themselves are not loaded until they are first
266 * requested via a call to findColorScheme()
267 */
268 ColorSchemeManager();
269 /**
270 * Destroys the ColorSchemeManager and saves any modified color schemes to disk.
271 */
272 ~ColorSchemeManager();
273
274 /**
275 * Returns the default color scheme for Konsole
276 */
277 const ColorScheme* defaultColorScheme() const;
278
279 /**
280 * Returns the color scheme with the given name or 0 if no
281 * scheme with that name exists. If @p name is empty, the
282 * default color scheme is returned.
283 *
284 * The first time that a color scheme with a particular name is
285 * requested, the configuration information is loaded from disk.
286 */
287 const ColorScheme* findColorScheme(const QString& name);
288
289#if 0
290 /**
291 * Adds a new color scheme to the manager. If @p scheme has the same name as
292 * an existing color scheme, it replaces the existing scheme.
293 *
294 * TODO - Ensure the old color scheme gets deleted
295 */
296 void addColorScheme(ColorScheme* scheme);
297#endif
298 /**
299 * Deletes a color scheme. Returns true on successful deletion or false otherwise.
300 */
301 bool deleteColorScheme(const QString& name);
302
303 /**
304 * Returns a list of the all the available color schemes.
305 * This may be slow when first called because all of the color
306 * scheme resources on disk must be located, read and parsed.
307 *
308 * Subsequent calls will be inexpensive.
309 */
310 QList<const ColorScheme*> allColorSchemes();
311
312 /** Returns the global color scheme manager instance. */
313 static ColorSchemeManager* instance();
314
315private:
316 // loads a color scheme from a KDE 4+ .colorscheme file
317 bool loadColorScheme(const QString& path);
318 // loads a color scheme from a KDE 3 .schema file
319 bool loadKDE3ColorScheme(const QString& path);
320 // returns a list of paths of color schemes in the KDE 4+ .colorscheme file format
321 QList<QString> listColorSchemes();
322 // returns a list of paths of color schemes in the .schema file format
323 // used in KDE 3
324 QList<QString> listKDE3ColorSchemes();
325 // loads all of the color schemes
326 void loadAllColorSchemes();
327 // finds the path of a color scheme
328 QString findColorSchemePath(const QString& name) const;
329
330 QHash<QString,const ColorScheme*> _colorSchemes;
331 QSet<ColorScheme*> _modifiedSchemes;
332
333 bool _haveLoadedAll;
334
335 static const ColorScheme _defaultColorScheme;
336
337 static ColorSchemeManager * theColorSchemeManager;
338};
339
340Q_DECLARE_METATYPE(const ColorScheme*)
341
342#endif //COLORSCHEME_H
0343
=== added file 'src/plugin/konsole/ColorTables.h'
--- src/plugin/konsole/ColorTables.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/ColorTables.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,55 @@
1#ifndef _COLOR_TABLE_H
2#define _COLOR_TABLE_H
3
4#include "CharacterColor.h"
5
6//using namespace Konsole;
7#if 0
8static const ColorEntry whiteonblack_color_table[TABLE_COLORS] = {
9 // normal
10 ColorEntry(QColor(0xFF,0xFF,0xFF), false ), ColorEntry( QColor(0x00,0x00,0x00), true ), // Dfore, Dback
11 ColorEntry(QColor(0x00,0x00,0x00), false ), ColorEntry( QColor(0xB2,0x18,0x18), false ), // Black, Red
12 ColorEntry(QColor(0x18,0xB2,0x18), false ), ColorEntry( QColor(0xB2,0x68,0x18), false ), // Green, Yellow
13 ColorEntry(QColor(0x18,0x18,0xB2), false ), ColorEntry( QColor(0xB2,0x18,0xB2), false ), // Blue, Magenta
14 ColorEntry(QColor(0x18,0xB2,0xB2), false ), ColorEntry( QColor(0xB2,0xB2,0xB2), false ), // Cyan, White
15 // intensiv
16 ColorEntry(QColor(0x00,0x00,0x00), false ), ColorEntry( QColor(0xFF,0xFF,0xFF), true ),
17 ColorEntry(QColor(0x68,0x68,0x68), false ), ColorEntry( QColor(0xFF,0x54,0x54), false ),
18 ColorEntry(QColor(0x54,0xFF,0x54), false ), ColorEntry( QColor(0xFF,0xFF,0x54), false ),
19 ColorEntry(QColor(0x54,0x54,0xFF), false ), ColorEntry( QColor(0xFF,0x54,0xFF), false ),
20 ColorEntry(QColor(0x54,0xFF,0xFF), false ), ColorEntry( QColor(0xFF,0xFF,0xFF), false )
21};
22
23static const ColorEntry greenonblack_color_table[TABLE_COLORS] = {
24 ColorEntry(QColor( 24, 240, 24), false), ColorEntry(QColor( 0, 0, 0), true),
25 ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 178, 24, 24), false),
26 ColorEntry(QColor( 24, 178, 24), false), ColorEntry(QColor( 178, 104, 24), false),
27 ColorEntry(QColor( 24, 24, 178), false), ColorEntry(QColor( 178, 24, 178), false),
28 ColorEntry(QColor( 24, 178, 178), false), ColorEntry(QColor( 178, 178, 178), false),
29 // intensive colors
30 ColorEntry(QColor( 24, 240, 24), false ), ColorEntry(QColor( 0, 0, 0), true ),
31 ColorEntry(QColor( 104, 104, 104), false ), ColorEntry(QColor( 255, 84, 84), false ),
32 ColorEntry(QColor( 84, 255, 84), false ), ColorEntry(QColor( 255, 255, 84), false ),
33 ColorEntry(QColor( 84, 84, 255), false ), ColorEntry(QColor( 255, 84, 255), false ),
34 ColorEntry(QColor( 84, 255, 255), false ), ColorEntry(QColor( 255, 255, 255), false )
35};
36
37static const ColorEntry blackonlightyellow_color_table[TABLE_COLORS] = {
38 ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 255, 255, 221), true),
39 ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 178, 24, 24), false),
40 ColorEntry(QColor( 24, 178, 24), false), ColorEntry(QColor( 178, 104, 24), false),
41 ColorEntry(QColor( 24, 24, 178), false), ColorEntry(QColor( 178, 24, 178), false),
42 ColorEntry(QColor( 24, 178, 178), false), ColorEntry(QColor( 178, 178, 178), false),
43 ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 255, 255, 221), true),
44 ColorEntry(QColor(104, 104, 104), false), ColorEntry(QColor( 255, 84, 84), false),
45 ColorEntry(QColor( 84, 255, 84), false), ColorEntry(QColor( 255, 255, 84), false),
46 ColorEntry(QColor( 84, 84, 255), false), ColorEntry(QColor( 255, 84, 255), false),
47 ColorEntry(QColor( 84, 255, 255), false), ColorEntry(QColor( 255, 255, 255), false)
48};
49
50
51#endif
52
53
54#endif
55
056
=== added file 'src/plugin/konsole/DefaultTranslatorText.h'
--- src/plugin/konsole/DefaultTranslatorText.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/DefaultTranslatorText.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,2 @@
1"keyboard \"Fallback Key Translator\"\n"
2"key Tab : \"\\t\" \0"
03
=== added file 'src/plugin/konsole/Emulation.cpp'
--- src/plugin/konsole/Emulation.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/Emulation.cpp 2014-05-06 21:50:22 +0000
@@ -0,0 +1,458 @@
1/*
2 Copyright 2007-2008 Robert Knight <robertknight@gmail.com>
3 Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
4 Copyright 1996 by Matthias Ettrich <ettrich@kde.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20*/
21
22// Own
23#include "Emulation.h"
24
25// System
26#include <assert.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <unistd.h>
30
31// Qt
32#include <QGuiApplication>
33#include <QtGui/QClipboard>
34#include <QtCore/QHash>
35#include <QtGui/QKeyEvent>
36#include <QtCore/QRegExp>
37#include <QtCore/QTextStream>
38#include <QtCore/QThread>
39
40#include <QtCore/QTime>
41
42// KDE
43//#include <kdebug.h>
44
45// Konsole
46#include "KeyboardTranslator.h"
47#include "Screen.h"
48#include "TerminalCharacterDecoder.h"
49#include "ScreenWindow.h"
50
51Emulation::Emulation() :
52 _currentScreen(0),
53 _codec(0),
54 _decoder(0),
55 _keyTranslator(0),
56 _usesMouse(false)
57{
58 // create screens with a default size
59 _screen[0] = new Screen(40,80);
60 _screen[1] = new Screen(40,80);
61 _currentScreen = _screen[0];
62
63 QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk()) );
64 QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk()) );
65
66 // listen for mouse status changes
67 connect( this , SIGNAL(programUsesMouseChanged(bool)) ,
68 SLOT(usesMouseChanged(bool)) );
69}
70
71bool Emulation::programUsesMouse() const
72{
73 return _usesMouse;
74}
75
76void Emulation::usesMouseChanged(bool usesMouse)
77{
78 _usesMouse = usesMouse;
79}
80
81ScreenWindow* Emulation::createWindow()
82{
83 ScreenWindow* window = new ScreenWindow();
84 window->setScreen(_currentScreen);
85 _windows << window;
86
87 connect(window , SIGNAL(selectionChanged()),
88 this , SLOT(bufferedUpdate()));
89
90 connect(this , SIGNAL(outputChanged()),
91 window , SLOT(notifyOutputChanged()) );
92 return window;
93}
94
95Emulation::~Emulation()
96{
97 QListIterator<ScreenWindow*> windowIter(_windows);
98
99 while (windowIter.hasNext())
100 {
101 delete windowIter.next();
102 }
103
104 delete _screen[0];
105 delete _screen[1];
106 delete _decoder;
107}
108
109void Emulation::setScreen(int n)
110{
111 Screen *old = _currentScreen;
112 _currentScreen = _screen[n & 1];
113 if (_currentScreen != old)
114 {
115 // tell all windows onto this emulation to switch to the newly active screen
116 foreach(ScreenWindow* window,_windows)
117 window->setScreen(_currentScreen);
118 }
119}
120
121void Emulation::clearHistory()
122{
123 _screen[0]->setScroll( _screen[0]->getScroll() , false );
124}
125void Emulation::setHistory(const HistoryType& t)
126{
127 _screen[0]->setScroll(t);
128
129 showBulk();
130}
131
132const HistoryType& Emulation::history() const
133{
134 return _screen[0]->getScroll();
135}
136
137void Emulation::setCodec(const QTextCodec * qtc)
138{
139 if (qtc)
140 _codec = qtc;
141 else
142 setCodec(LocaleCodec);
143
144 delete _decoder;
145 _decoder = _codec->makeDecoder();
146
147 emit useUtf8Request(utf8());
148}
149
150void Emulation::setCodec(EmulationCodec codec)
151{
152 if ( codec == Utf8Codec )
153 setCodec( QTextCodec::codecForName("utf8") );
154 else if ( codec == LocaleCodec )
155 setCodec( QTextCodec::codecForLocale() );
156}
157
158void Emulation::setKeyBindings(const QString& name)
159{
160 _keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name);
161 if (!_keyTranslator)
162 {
163 _keyTranslator = KeyboardTranslatorManager::instance()->defaultTranslator();
164 }
165}
166
167QString Emulation::keyBindings() const
168{
169 return _keyTranslator->name();
170}
171
172void Emulation::receiveChar(int c)
173// process application unicode input to terminal
174// this is a trivial scanner
175{
176 c &= 0xff;
177 switch (c)
178 {
179 case '\b' : _currentScreen->backspace(); break;
180 case '\t' : _currentScreen->tab(); break;
181 case '\n' : _currentScreen->newLine(); break;
182 case '\r' : _currentScreen->toStartOfLine(); break;
183 case 0x07 : emit stateSet(NOTIFYBELL);
184 break;
185 default : _currentScreen->displayCharacter(c); break;
186 };
187}
188
189void Emulation::sendKeyEvent( QKeyEvent* ev )
190{
191 emit stateSet(NOTIFYNORMAL);
192
193 if (!ev->text().isEmpty())
194 { // A block of text
195 // Note that the text is proper unicode.
196 // We should do a conversion here
197 emit sendData(ev->text().toUtf8(),ev->text().length());
198 }
199}
200
201void Emulation::sendString(const char*,int)
202{
203 // default implementation does nothing
204}
205
206void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int /*eventType*/)
207{
208 // default implementation does nothing
209}
210
211/*
212 We are doing code conversion from locale to unicode first.
213TODO: Character composition from the old code. See #96536
214*/
215
216void Emulation::receiveData(const char* text, int length)
217{
218 emit stateSet(NOTIFYACTIVITY);
219
220 bufferedUpdate();
221
222 QString unicodeText = _decoder->toUnicode(text,length);
223
224 //send characters to terminal emulator
225 for (int i=0;i<unicodeText.length();i++)
226 receiveChar(unicodeText[i].unicode());
227
228 //look for z-modem indicator
229 //-- someone who understands more about z-modems that I do may be able to move
230 //this check into the above for loop?
231 for (int i=0;i<length;i++)
232 {
233 if (text[i] == '\030')
234 {
235 if ((length-i-1 > 3) && (strncmp(text+i+1, "B00", 3) == 0))
236 emit zmodemDetected();
237 }
238 }
239}
240
241//OLDER VERSION
242//This version of onRcvBlock was commented out because
243// a) It decoded incoming characters one-by-one, which is slow in the current version of Qt (4.2 tech preview)
244// b) It messed up decoding of non-ASCII characters, with the result that (for example) chinese characters
245// were not printed properly.
246//
247//There is something about stopping the _decoder if "we get a control code halfway a multi-byte sequence" (see below)
248//which hasn't been ported into the newer function (above). Hopefully someone who understands this better
249//can find an alternative way of handling the check.
250
251
252/*void Emulation::onRcvBlock(const char *s, int len)
253{
254 emit notifySessionState(NOTIFYACTIVITY);
255
256 bufferedUpdate();
257 for (int i = 0; i < len; i++)
258 {
259
260 QString result = _decoder->toUnicode(&s[i],1);
261 int reslen = result.length();
262
263 // If we get a control code halfway a multi-byte sequence
264 // we flush the _decoder and continue with the control code.
265 if ((s[i] < 32) && (s[i] > 0))
266 {
267 // Flush _decoder
268 while(!result.length())
269 result = _decoder->toUnicode(&s[i],1);
270 reslen = 1;
271 result.resize(reslen);
272 result[0] = QChar(s[i]);
273 }
274
275 for (int j = 0; j < reslen; j++)
276 {
277 if (result[j].characterategory() == QChar::Mark_NonSpacing)
278 _currentScreen->compose(result.mid(j,1));
279 else
280 onRcvChar(result[j].unicode());
281 }
282 if (s[i] == '\030')
283 {
284 if ((len-i-1 > 3) && (strncmp(s+i+1, "B00", 3) == 0))
285 emit zmodemDetected();
286 }
287 }
288}*/
289
290void Emulation::writeToStream( TerminalCharacterDecoder* _decoder ,
291 int startLine ,
292 int endLine)
293{
294 _currentScreen->writeLinesToStream(_decoder,startLine,endLine);
295}
296
297int Emulation::lineCount() const
298{
299 // sum number of lines currently on _screen plus number of lines in history
300 return _currentScreen->getLines() + _currentScreen->getHistLines();
301}
302
303#define BULK_TIMEOUT1 10
304#define BULK_TIMEOUT2 40
305
306void Emulation::showBulk()
307{
308 _bulkTimer1.stop();
309 _bulkTimer2.stop();
310
311 emit outputChanged();
312
313 _currentScreen->resetScrolledLines();
314 _currentScreen->resetDroppedLines();
315}
316
317void Emulation::bufferedUpdate()
318{
319 _bulkTimer1.setSingleShot(true);
320 _bulkTimer1.start(BULK_TIMEOUT1);
321 if (!_bulkTimer2.isActive())
322 {
323 _bulkTimer2.setSingleShot(true);
324 _bulkTimer2.start(BULK_TIMEOUT2);
325 }
326}
327
328char Emulation::eraseChar() const
329{
330 return '\b';
331}
332
333void Emulation::setImageSize(int lines, int columns)
334{
335 if ((lines < 1) || (columns < 1))
336 return;
337
338 QSize screenSize[2] = { QSize(_screen[0]->getColumns(),
339 _screen[0]->getLines()),
340 QSize(_screen[1]->getColumns(),
341 _screen[1]->getLines()) };
342 QSize newSize(columns,lines);
343
344 if (newSize == screenSize[0] && newSize == screenSize[1])
345 return;
346
347 _screen[0]->resizeImage(lines,columns);
348 _screen[1]->resizeImage(lines,columns);
349
350 emit imageSizeChanged(lines,columns);
351
352 bufferedUpdate();
353}
354
355QSize Emulation::imageSize() const
356{
357 return QSize(_currentScreen->getColumns(), _currentScreen->getLines());
358}
359
360ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const
361{
362 ushort hash = 0;
363 for ( ushort i = 0 ; i < length ; i++ )
364 {
365 hash = 31*hash + unicodePoints[i];
366 }
367 return hash;
368}
369bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const
370{
371 ushort* entry = extendedCharTable[hash];
372
373 // compare given length with stored sequence length ( given as the first ushort in the
374 // stored buffer )
375 if ( entry == 0 || entry[0] != length )
376 return false;
377 // if the lengths match, each character must be checked. the stored buffer starts at
378 // entry[1]
379 for ( int i = 0 ; i < length ; i++ )
380 {
381 if ( entry[i+1] != unicodePoints[i] )
382 return false;
383 }
384 return true;
385}
386ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length)
387{
388 // look for this sequence of points in the table
389 ushort hash = extendedCharHash(unicodePoints,length);
390
391 // check existing entry for match
392 while ( extendedCharTable.contains(hash) )
393 {
394 if ( extendedCharMatch(hash,unicodePoints,length) )
395 {
396 // this sequence already has an entry in the table,
397 // return its hash
398 return hash;
399 }
400 else
401 {
402 // if hash is already used by another, different sequence of unicode character
403 // points then try next hash
404 hash++;
405 }
406 }
407
408
409 // add the new sequence to the table and
410 // return that index
411 ushort* buffer = new ushort[length+1];
412 buffer[0] = length;
413 for ( int i = 0 ; i < length ; i++ )
414 buffer[i+1] = unicodePoints[i];
415
416 extendedCharTable.insert(hash,buffer);
417
418 return hash;
419}
420
421ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const
422{
423 // lookup index in table and if found, set the length
424 // argument and return a pointer to the character sequence
425
426 ushort* buffer = extendedCharTable[hash];
427 if ( buffer )
428 {
429 length = buffer[0];
430 return buffer+1;
431 }
432 else
433 {
434 length = 0;
435 return 0;
436 }
437}
438
439ExtendedCharTable::ExtendedCharTable()
440{
441}
442ExtendedCharTable::~ExtendedCharTable()
443{
444 // free all allocated character buffers
445 QHashIterator<ushort,ushort*> iter(extendedCharTable);
446 while ( iter.hasNext() )
447 {
448 iter.next();
449 delete[] iter.value();
450 }
451}
452
453// global instance
454ExtendedCharTable ExtendedCharTable::instance;
455
456
457//#include "Emulation.moc"
458
0459
=== added file 'src/plugin/konsole/Emulation.h'
--- src/plugin/konsole/Emulation.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/Emulation.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,467 @@
1/*
2 This file is part of Konsole, an X terminal.
3
4 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
5 Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21*/
22
23#ifndef EMULATION_H
24#define EMULATION_H
25
26// System
27#include <stdio.h>
28
29// Qt
30#include <QtGui/QKeyEvent>
31//#include <QPointer>
32#include <QtCore/QTextCodec>
33#include <QtCore/QTextStream>
34#include <QtCore/QTimer>
35
36// Konsole
37//#include "konsole_export.h"
38#define KONSOLEPRIVATE_EXPORT
39
40class KeyboardTranslator;
41class HistoryType;
42class Screen;
43class ScreenWindow;
44class TerminalCharacterDecoder;
45
46/**
47 * This enum describes the available states which
48 * the terminal emulation may be set to.
49 *
50 * These are the values used by Emulation::stateChanged()
51 */
52enum
53{
54 /** The emulation is currently receiving user input. */
55 NOTIFYNORMAL=0,
56 /**
57 * The terminal program has triggered a bell event
58 * to get the user's attention.
59 */
60 NOTIFYBELL=1,
61 /**
62 * The emulation is currently receiving data from its
63 * terminal input.
64 */
65 NOTIFYACTIVITY=2,
66
67 // unused here?
68 NOTIFYSILENCE=3
69};
70
71/**
72 * Base class for terminal emulation back-ends.
73 *
74 * The back-end is responsible for decoding an incoming character stream and
75 * producing an output image of characters.
76 *
77 * When input from the terminal is received, the receiveData() slot should be called with
78 * the data which has arrived. The emulation will process the data and update the
79 * screen image accordingly. The codec used to decode the incoming character stream
80 * into the unicode characters used internally can be specified using setCodec()
81 *
82 * The size of the screen image can be specified by calling setImageSize() with the
83 * desired number of lines and columns. When new lines are added, old content
84 * is moved into a history store, which can be set by calling setHistory().
85 *
86 * The screen image can be accessed by creating a ScreenWindow onto this emulation
87 * by calling createWindow(). Screen windows provide access to a section of the
88 * output. Each screen window covers the same number of lines and columns as the
89 * image size returned by imageSize(). The screen window can be moved up and down
90 * and provides transparent access to both the current on-screen image and the
91 * previous output. The screen windows emit an outputChanged signal
92 * when the section of the image they are looking at changes.
93 * Graphical views can then render the contents of a screen window, listening for notifications
94 * of output changes from the screen window which they are associated with and updating
95 * accordingly.
96 *
97 * The emulation also is also responsible for converting input from the connected views such
98 * as keypresses and mouse activity into a character string which can be sent
99 * to the terminal program. Key presses can be processed by calling the sendKeyEvent() slot,
100 * while mouse events can be processed using the sendMouseEvent() slot. When the character
101 * stream has been produced, the emulation will emit a sendData() signal with a pointer
102 * to the character buffer. This data should be fed to the standard input of the terminal
103 * process. The translation of key presses into an output character stream is performed
104 * using a lookup in a set of key bindings which map key sequences to output
105 * character sequences. The name of the key bindings set used can be specified using
106 * setKeyBindings()
107 *
108 * The emulation maintains certain state information which changes depending on the
109 * input received. The emulation can be reset back to its starting state by calling
110 * reset().
111 *
112 * The emulation also maintains an activity state, which specifies whether
113 * terminal is currently active ( when data is received ), normal
114 * ( when the terminal is idle or receiving user input ) or trying
115 * to alert the user ( also known as a "Bell" event ). The stateSet() signal
116 * is emitted whenever the activity state is set. This can be used to determine
117 * how long the emulation has been active/idle for and also respond to
118 * a 'bell' event in different ways.
119 */
120class KONSOLEPRIVATE_EXPORT Emulation : public QObject
121{
122Q_OBJECT
123
124public:
125
126 /** Constructs a new terminal emulation */
127 Emulation();
128 ~Emulation();
129
130 /**
131 * Creates a new window onto the output from this emulation. The contents
132 * of the window are then rendered by views which are set to use this window using the
133 * TerminalDisplay::setScreenWindow() method.
134 */
135 ScreenWindow* createWindow();
136
137 /** Returns the size of the screen image which the emulation produces */
138 QSize imageSize() const;
139
140 /**
141 * Returns the total number of lines, including those stored in the history.
142 */
143 int lineCount() const;
144
145 /**
146 * Sets the history store used by this emulation. When new lines
147 * are added to the output, older lines at the top of the screen are transferred to a history
148 * store.
149 *
150 * The number of lines which are kept and the storage location depend on the
151 * type of store.
152 */
153 void setHistory(const HistoryType&);
154 /** Returns the history store used by this emulation. See setHistory() */
155 const HistoryType& history() const;
156 /** Clears the history scroll. */
157 void clearHistory();
158
159 /**
160 * Copies the output history from @p startLine to @p endLine
161 * into @p stream, using @p decoder to convert the terminal
162 * characters into text.
163 *
164 * @param decoder A decoder which converts lines of terminal characters with
165 * appearance attributes into output text. PlainTextDecoder is the most commonly
166 * used decoder.
167 * @param startLine Index of first line to copy
168 * @param endLine Index of last line to copy
169 */
170 virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine);
171
172 /** Returns the codec used to decode incoming characters. See setCodec() */
173 const QTextCodec* codec() const { return _codec; }
174 /** Sets the codec used to decode incoming characters. */
175 void setCodec(const QTextCodec*);
176
177 /**
178 * Convenience method.
179 * Returns true if the current codec used to decode incoming
180 * characters is UTF-8
181 */
182 bool utf8() const
183 { Q_ASSERT(_codec); return _codec->mibEnum() == 106; }
184
185
186 /** TODO Document me */
187 virtual char eraseChar() const;
188
189 /**
190 * Sets the key bindings used to key events
191 * ( received through sendKeyEvent() ) into character
192 * streams to send to the terminal.
193 */
194 void setKeyBindings(const QString& name);
195 /**
196 * Returns the name of the emulation's current key bindings.
197 * See setKeyBindings()
198 */
199 QString keyBindings() const;
200
201 /**
202 * Copies the current image into the history and clears the screen.
203 */
204 virtual void clearEntireScreen() =0;
205
206 /** Resets the state of the terminal. */
207 virtual void reset() =0;
208
209 /**
210 * Returns true if the active terminal program wants
211 * mouse input events.
212 *
213 * The programUsesMouseChanged() signal is emitted when this
214 * changes.
215 */
216 bool programUsesMouse() const;
217
218public slots:
219
220 /** Change the size of the emulation's image */
221 virtual void setImageSize(int lines, int columns);
222
223 /**
224 * Interprets a sequence of characters and sends the result to the terminal.
225 * This is equivalent to calling sendKeyEvent() for each character in @p text in succession.
226 */
227 virtual void sendText(const QString& text) = 0;
228
229 /**
230 * Interprets a key press event and emits the sendData() signal with
231 * the resulting character stream.
232 */
233 virtual void sendKeyEvent(QKeyEvent*);
234
235 /**
236 * Converts information about a mouse event into an xterm-compatible escape
237 * sequence and emits the character sequence via sendData()
238 */
239 virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
240
241 /**
242 * Sends a string of characters to the foreground terminal process.
243 *
244 * @param string The characters to send.
245 * @param length Length of @p string or if set to a negative value, @p string will
246 * be treated as a null-terminated string and its length will be determined automatically.
247 */
248 virtual void sendString(const char* string, int length = -1) = 0;
249
250 /**
251 * Processes an incoming stream of characters. receiveData() decodes the incoming
252 * character buffer using the current codec(), and then calls receiveChar() for
253 * each unicode character in the resulting buffer.
254 *
255 * receiveData() also starts a timer which causes the outputChanged() signal
256 * to be emitted when it expires. The timer allows multiple updates in quick
257 * succession to be buffered into a single outputChanged() signal emission.
258 *
259 * @param buffer A string of characters received from the terminal program.
260 * @param len The length of @p buffer
261 */
262 void receiveData(const char* buffer,int len);
263
264signals:
265
266 /**
267 * Emitted when a buffer of data is ready to send to the
268 * standard input of the terminal.
269 *
270 * @param data The buffer of data ready to be sent
271 * @param len The length of @p data in bytes
272 */
273 void sendData(const char* data,int len);
274
275 /**
276 * Requests that sending of input to the emulation
277 * from the terminal process be suspended or resumed.
278 *
279 * @param suspend If true, requests that sending of
280 * input from the terminal process' stdout be
281 * suspended. Otherwise requests that sending of
282 * input be resumed.
283 */
284 void lockPtyRequest(bool suspend);
285
286 /**
287 * Requests that the pty used by the terminal process
288 * be set to UTF 8 mode.
289 *
290 * TODO: More documentation
291 */
292 void useUtf8Request(bool);
293
294 /**
295 * Emitted when the activity state of the emulation is set.
296 *
297 * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY
298 * or NOTIFYBELL
299 */
300 void stateSet(int state);
301
302 /** TODO Document me */
303 void zmodemDetected();
304
305
306 /**
307 * Requests that the color of the text used
308 * to represent the tabs associated with this
309 * emulation be changed. This is a Konsole-specific
310 * extension from pre-KDE 4 times.
311 *
312 * TODO: Document how the parameter works.
313 */
314 void changeTabTextColorRequest(int color);
315
316 /**
317 * This is emitted when the program running in the shell indicates whether or
318 * not it is interested in mouse events.
319 *
320 * @param usesMouse This will be true if the program wants to be informed about
321 * mouse events or false otherwise.
322 */
323 void programUsesMouseChanged(bool usesMouse);
324
325 /**
326 * Emitted when the contents of the screen image change.
327 * The emulation buffers the updates from successive image changes,
328 * and only emits outputChanged() at sensible intervals when
329 * there is a lot of terminal activity.
330 *
331 * Normally there is no need for objects other than the screen windows
332 * created with createWindow() to listen for this signal.
333 *
334 * ScreenWindow objects created using createWindow() will emit their
335 * own outputChanged() signal in response to this signal.
336 */
337 void outputChanged();
338
339 /**
340 * Emitted when the program running in the terminal wishes to update the
341 * session's title. This also allows terminal programs to customize other
342 * aspects of the terminal emulation display.
343 *
344 * This signal is emitted when the escape sequence "\033]ARG;VALUE\007"
345 * is received in the input string, where ARG is a number specifying what
346 * should change and VALUE is a string specifying the new value.
347 *
348 * TODO: The name of this method is not very accurate since this method
349 * is used to perform a whole range of tasks besides just setting
350 * the user-title of the session.
351 *
352 * @param title Specifies what to change.
353 * <ul>
354 * <li>0 - Set window icon text and session title to @p newTitle</li>
355 * <li>1 - Set window icon text to @p newTitle</li>
356 * <li>2 - Set session title to @p newTitle</li>
357 * <li>11 - Set the session's default background color to @p newTitle,
358 * where @p newTitle can be an HTML-style string ("#RRGGBB") or a named
359 * color (eg 'red', 'blue').
360 * See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more
361 * details.
362 * </li>
363 * <li>31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)</li>
364 * <li>32 - Sets the icon associated with the session. @p newTitle is the name
365 * of the icon to use, which can be the name of any icon in the current KDE icon
366 * theme (eg: 'konsole', 'kate', 'folder_home')</li>
367 * </ul>
368 * @param newTitle Specifies the new title
369 */
370
371 void titleChanged(int title,const QString& newTitle);
372
373 /**
374 * Emitted when the program running in the terminal changes the
375 * screen size.
376 */
377 void imageSizeChanged(int lineCount , int columnCount);
378
379 /**
380 * Emitted when the terminal program requests to change various properties
381 * of the terminal display.
382 *
383 * A profile change command occurs when a special escape sequence, followed
384 * by a string containing a series of name and value pairs is received.
385 * This string can be parsed using a ProfileCommandParser instance.
386 *
387 * @param text A string expected to contain a series of key and value pairs in
388 * the form: name=value;name2=value2 ...
389 */
390 void profileChangeCommandReceived(const QString& text);
391
392 /**
393 * Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed.
394 * @param suspendKeyPressed True if Ctrl+S was pressed to suspend output or Ctrl+Q to
395 * resume output.
396 */
397 void flowControlKeyPressed(bool suspendKeyPressed);
398
399protected:
400 virtual void setMode(int mode) = 0;
401 virtual void resetMode(int mode) = 0;
402
403 /**
404 * Processes an incoming character. See receiveData()
405 * @p ch A unicode character code.
406 */
407 virtual void receiveChar(int ch);
408
409 /**
410 * Sets the active screen. The terminal has two screens, primary and alternate.
411 * The primary screen is used by default. When certain interactive programs such
412 * as Vim are run, they trigger a switch to the alternate screen.
413 *
414 * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen
415 */
416 void setScreen(int index);
417
418 enum EmulationCodec
419 {
420 LocaleCodec = 0,
421 Utf8Codec = 1
422 };
423 void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8
424
425
426 QList<ScreenWindow*> _windows;
427
428 Screen* _currentScreen; // pointer to the screen which is currently active,
429 // this is one of the elements in the screen[] array
430
431 Screen* _screen[2]; // 0 = primary screen ( used by most programs, including the shell
432 // scrollbars are enabled in this mode )
433 // 1 = alternate ( used by vi , emacs etc.
434 // scrollbars are not enabled in this mode )
435
436
437 //decodes an incoming C-style character stream into a unicode QString using
438 //the current text codec. (this allows for rendering of non-ASCII characters in text files etc.)
439 const QTextCodec* _codec;
440 QTextDecoder* _decoder;
441 const KeyboardTranslator* _keyTranslator; // the keyboard layout
442
443protected slots:
444 /**
445 * Schedules an update of attached views.
446 * Repeated calls to bufferedUpdate() in close succession will result in only a single update,
447 * much like the Qt buffered update of widgets.
448 */
449 void bufferedUpdate();
450
451private slots:
452
453 // triggered by timer, causes the emulation to send an updated screen image to each
454 // view
455 void showBulk();
456
457 void usesMouseChanged(bool usesMouse);
458
459private:
460 bool _usesMouse;
461 QTimer _bulkTimer1;
462 QTimer _bulkTimer2;
463
464};
465
466
467#endif // ifndef EMULATION_H
0468
=== added file 'src/plugin/konsole/ExtendedDefaultTranslator.h'
--- src/plugin/konsole/ExtendedDefaultTranslator.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/ExtendedDefaultTranslator.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,74 @@
1"keyboard \"Default (XFree 4)\""
2"key Escape : \"\\E\""
3"key Tab -Shift : \"\\t\"\n"
4"key Tab +Shift+Ansi : \"\\E[Z\"\n"
5"key Tab +Shift-Ansi : \"\\t\"\n"
6"key Backtab +Ansi : \"\\E[Z\"\n"
7"key Backtab -Ansi : \"\\t\"\n"
8"key Return-Shift-NewLine : \"\\r\"\n"
9"key Return-Shift+NewLine : \"\\r\\n\"\n"
10"key Return+Shift : \"\\EOM\"\n"
11"key Backspace : \"\\x7f\"\n"
12"key Up -Shift-Ansi : \"\\EA\"\n"
13"key Down -Shift-Ansi : \"\\EB\"\n"
14"key Right-Shift-Ansi : \"\\EC\"\n"
15"key Left -Shift-Ansi : \"\\ED\"\n"
16"key Up -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOA\"\n"
17"key Down -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOB\"\n"
18"key Right -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOC\"\n"
19"key Left -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOD\"\n"
20"key Up -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[A\"\n"
21"key Down -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[B\"\n"
22"key Right -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[C\"\n"
23"key Left -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[D\"\n"
24"key Up -Shift+AnyMod+Ansi : \"\\E[1;*A\"\n"
25"key Down -Shift+AnyMod+Ansi : \"\\E[1;*B\"\n"
26"key Right -Shift+AnyMod+Ansi : \"\\E[1;*C\"\n"
27"key Left -Shift+AnyMod+Ansi : \"\\E[1;*D\"\n"
28"key Enter+NewLine : \"\\r\\n\"\n"
29"key Enter-NewLine : \"\\r\"\n"
30"key Home -AnyMod -AppCuKeys : \"\\E[H\" \n"
31"key End -AnyMod -AppCuKeys : \"\\E[F\" \n"
32"key Home -AnyMod +AppCuKeys : \"\\EOH\" \n"
33"key End -AnyMod +AppCuKeys : \"\\EOF\" \n"
34"key Home +AnyMod : \"\\E[1;*H\"\n"
35"key End +AnyMod : \"\\E[1;*F\"\n"
36"key Insert -AnyMod : \"\\E[2~\"\n"
37"key Delete -AnyMod : \"\\E[3~\"\n"
38"key Insert +AnyMod : \"\\E[2;*~\"\n"
39"key Delete +AnyMod : \"\\E[3;*~\"\n"
40"key Prior -Shift-AnyMod : \"\\E[5~\"\n"
41"key Next -Shift-AnyMod : \"\\E[6~\"\n"
42"key Prior -Shift+AnyMod : \"\\E[5;*~\"\n"
43"key Next -Shift+AnyMod : \"\\E[6;*~\"\n"
44"key F1 -AnyMod : \"\\EOP\"\n"
45"key F2 -AnyMod : \"\\EOQ\"\n"
46"key F3 -AnyMod : \"\\EOR\"\n"
47"key F4 -AnyMod : \"\\EOS\"\n"
48"key F5 -AnyMod : \"\\E[15~\"\n"
49"key F6 -AnyMod : \"\\E[17~\"\n"
50"key F7 -AnyMod : \"\\E[18~\"\n"
51"key F8 -AnyMod : \"\\E[19~\"\n"
52"key F9 -AnyMod : \"\\E[20~\"\n"
53"key F10 -AnyMod : \"\\E[21~\"\n"
54"key F11 -AnyMod : \"\\E[23~\"\n"
55"key F12 -AnyMod : \"\\E[24~\"\n"
56"key F1 +AnyMod : \"\\EO*P\"\n"
57"key F2 +AnyMod : \"\\EO*Q\"\n"
58"key F3 +AnyMod : \"\\EO*R\"\n"
59"key F4 +AnyMod : \"\\EO*S\"\n"
60"key F5 +AnyMod : \"\\E[15;*~\"\n"
61"key F6 +AnyMod : \"\\E[17;*~\"\n"
62"key F7 +AnyMod : \"\\E[18;*~\"\n"
63"key F8 +AnyMod : \"\\E[19;*~\"\n"
64"key F9 +AnyMod : \"\\E[20;*~\"\n"
65"key F10 +AnyMod : \"\\E[21;*~\"\n"
66"key F11 +AnyMod : \"\\E[23;*~\"\n"
67"key F12 +AnyMod : \"\\E[24;*~\"\n"
68"key Space +Control : \"\\x00\"\n"
69"key Up +Shift-AppScreen : scrollLineUp\n"
70"key Prior +Shift-AppScreen : scrollPageUp\n"
71"key Down +Shift-AppScreen : scrollLineDown\n"
72"key Next +Shift-AppScreen : scrollPageDown\n"
73"key ScrollLock : scrollLock\n"
74"\0"
075
=== added file 'src/plugin/konsole/Filter.cpp'
--- src/plugin/konsole/Filter.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/Filter.cpp 2014-05-06 21:50:22 +0000
@@ -0,0 +1,542 @@
1/*
2 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
18*/
19
20// Own
21#include "Filter.h"
22
23// System
24#include <iostream>
25
26// Qt
27#include <QtWidgets/QAction>
28#include <QtWidgets/QApplication>
29#include <QtGui/QClipboard>
30#include <QtCore/QString>
31#include <QtCore/QTextStream>
32#include <QtCore/QSharedData>
33#include <QtCore/QFile>
34#include <QDesktopServices>
35#include <QUrl>
36
37// KDE
38//#include <KLocale>
39//#include <KRun>
40
41// Konsole
42#include "TerminalCharacterDecoder.h"
43#include "konsole_wcwidth.h"
44
45
46FilterChain::~FilterChain()
47{
48 QMutableListIterator<Filter*> iter(*this);
49
50 while ( iter.hasNext() )
51 {
52 Filter* filter = iter.next();
53 iter.remove();
54 delete filter;
55 }
56}
57
58void FilterChain::addFilter(Filter* filter)
59{
60 append(filter);
61}
62void FilterChain::removeFilter(Filter* filter)
63{
64 removeAll(filter);
65}
66bool FilterChain::containsFilter(Filter* filter)
67{
68 return contains(filter);
69}
70void FilterChain::reset()
71{
72 QListIterator<Filter*> iter(*this);
73 while (iter.hasNext())
74 iter.next()->reset();
75}
76void FilterChain::setBuffer(const QString* buffer , const QList<int>* linePositions)
77{
78 QListIterator<Filter*> iter(*this);
79 while (iter.hasNext())
80 iter.next()->setBuffer(buffer,linePositions);
81}
82void FilterChain::process()
83{
84 QListIterator<Filter*> iter(*this);
85 while (iter.hasNext())
86 iter.next()->process();
87}
88void FilterChain::clear()
89{
90 QList<Filter*>::clear();
91}
92Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const
93{
94 QListIterator<Filter*> iter(*this);
95 while (iter.hasNext())
96 {
97 Filter* filter = iter.next();
98 Filter::HotSpot* spot = filter->hotSpotAt(line,column);
99 if ( spot != 0 )
100 {
101 return spot;
102 }
103 }
104
105 return 0;
106}
107
108QList<Filter::HotSpot*> FilterChain::hotSpots() const
109{
110 QList<Filter::HotSpot*> list;
111 QListIterator<Filter*> iter(*this);
112 while (iter.hasNext())
113 {
114 Filter* filter = iter.next();
115 list << filter->hotSpots();
116 }
117 return list;
118}
119//QList<Filter::HotSpot*> FilterChain::hotSpotsAtLine(int line) const;
120
121TerminalImageFilterChain::TerminalImageFilterChain()
122: _buffer(0)
123, _linePositions(0)
124{
125}
126
127TerminalImageFilterChain::~TerminalImageFilterChain()
128{
129 delete _buffer;
130 delete _linePositions;
131}
132
133void TerminalImageFilterChain::setImage(const Character* const image , int lines , int columns, const QVector<LineProperty>& lineProperties)
134{
135 if (empty())
136 return;
137
138 // reset all filters and hotspots
139 reset();
140
141 PlainTextDecoder decoder;
142 decoder.setTrailingWhitespace(false);
143
144 // setup new shared buffers for the filters to process on
145 QString* newBuffer = new QString();
146 QList<int>* newLinePositions = new QList<int>();
147 setBuffer( newBuffer , newLinePositions );
148
149 // free the old buffers
150 delete _buffer;
151 delete _linePositions;
152
153 _buffer = newBuffer;
154 _linePositions = newLinePositions;
155
156 QTextStream lineStream(_buffer);
157 decoder.begin(&lineStream);
158
159 for (int i=0 ; i < lines ; i++)
160 {
161 _linePositions->append(_buffer->length());
162 decoder.decodeLine(image + i*columns,columns,LINE_DEFAULT);
163
164 // pretend that each line ends with a newline character.
165 // this prevents a link that occurs at the end of one line
166 // being treated as part of a link that occurs at the start of the next line
167 //
168 // the downside is that links which are spread over more than one line are not
169 // highlighted.
170 //
171 // TODO - Use the "line wrapped" attribute associated with lines in a
172 // terminal image to avoid adding this imaginary character for wrapped
173 // lines
174 if ( !(lineProperties.value(i,LINE_DEFAULT) & LINE_WRAPPED) )
175 lineStream << QChar('\n');
176 }
177 decoder.end();
178}
179
180Filter::Filter() :
181_linePositions(0),
182_buffer(0)
183{
184}
185
186Filter::~Filter()
187{
188 QListIterator<HotSpot*> iter(_hotspotList);
189 while (iter.hasNext())
190 {
191 delete iter.next();
192 }
193}
194void Filter::reset()
195{
196 _hotspots.clear();
197 _hotspotList.clear();
198}
199
200void Filter::setBuffer(const QString* buffer , const QList<int>* linePositions)
201{
202 _buffer = buffer;
203 _linePositions = linePositions;
204}
205
206void Filter::getLineColumn(int position , int& startLine , int& startColumn)
207{
208 Q_ASSERT( _linePositions );
209 Q_ASSERT( _buffer );
210
211
212 for (int i = 0 ; i < _linePositions->count() ; i++)
213 {
214 int nextLine = 0;
215
216 if ( i == _linePositions->count()-1 )
217 nextLine = _buffer->length() + 1;
218 else
219 nextLine = _linePositions->value(i+1);
220
221 if ( _linePositions->value(i) <= position && position < nextLine )
222 {
223 startLine = i;
224 startColumn = string_width(buffer()->mid(_linePositions->value(i),position - _linePositions->value(i)));
225 return;
226 }
227 }
228}
229
230
231/*void Filter::addLine(const QString& text)
232{
233 _linePositions << _buffer.length();
234 _buffer.append(text);
235}*/
236
237const QString* Filter::buffer()
238{
239 return _buffer;
240}
241Filter::HotSpot::~HotSpot()
242{
243}
244void Filter::addHotSpot(HotSpot* spot)
245{
246 _hotspotList << spot;
247
248 for (int line = spot->startLine() ; line <= spot->endLine() ; line++)
249 {
250 _hotspots.insert(line,spot);
251 }
252}
253QList<Filter::HotSpot*> Filter::hotSpots() const
254{
255 return _hotspotList;
256}
257QList<Filter::HotSpot*> Filter::hotSpotsAtLine(int line) const
258{
259 return _hotspots.values(line);
260}
261
262Filter::HotSpot* Filter::hotSpotAt(int line , int column) const
263{
264 QListIterator<HotSpot*> spotIter(_hotspots.values(line));
265
266 while (spotIter.hasNext())
267 {
268 HotSpot* spot = spotIter.next();
269
270 if ( spot->startLine() == line && spot->startColumn() > column )
271 continue;
272 if ( spot->endLine() == line && spot->endColumn() < column )
273 continue;
274
275 return spot;
276 }
277
278 return 0;
279}
280
281Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int endColumn)
282 : _startLine(startLine)
283 , _startColumn(startColumn)
284 , _endLine(endLine)
285 , _endColumn(endColumn)
286 , _type(NotSpecified)
287{
288}
289QString Filter::HotSpot::tooltip() const
290{
291 return QString();
292}
293QList<QAction*> Filter::HotSpot::actions()
294{
295 return QList<QAction*>();
296}
297int Filter::HotSpot::startLine() const
298{
299 return _startLine;
300}
301int Filter::HotSpot::endLine() const
302{
303 return _endLine;
304}
305int Filter::HotSpot::startColumn() const
306{
307 return _startColumn;
308}
309int Filter::HotSpot::endColumn() const
310{
311 return _endColumn;
312}
313Filter::HotSpot::Type Filter::HotSpot::type() const
314{
315 return _type;
316}
317void Filter::HotSpot::setType(Type type)
318{
319 _type = type;
320}
321
322RegExpFilter::RegExpFilter()
323{
324}
325
326RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
327 : Filter::HotSpot(startLine,startColumn,endLine,endColumn)
328{
329 setType(Marker);
330}
331
332void RegExpFilter::HotSpot::activate(QObject*)
333{
334}
335
336void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts)
337{
338 _capturedTexts = texts;
339}
340QStringList RegExpFilter::HotSpot::capturedTexts() const
341{
342 return _capturedTexts;
343}
344
345void RegExpFilter::setRegExp(const QRegExp& regExp)
346{
347 _searchText = regExp;
348}
349QRegExp RegExpFilter::regExp() const
350{
351 return _searchText;
352}
353/*void RegExpFilter::reset(int)
354{
355 _buffer = QString();
356}*/
357void RegExpFilter::process()
358{
359 int pos = 0;
360 const QString* text = buffer();
361
362 Q_ASSERT( text );
363
364 // ignore any regular expressions which match an empty string.
365 // otherwise the while loop below will run indefinitely
366 static const QString emptyString("");
367 if ( _searchText.exactMatch(emptyString) )
368 return;
369
370 while(pos >= 0)
371 {
372 pos = _searchText.indexIn(*text,pos);
373
374 if ( pos >= 0 )
375 {
376 int startLine = 0;
377 int endLine = 0;
378 int startColumn = 0;
379 int endColumn = 0;
380
381 getLineColumn(pos,startLine,startColumn);
382 getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn);
383
384 RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn,
385 endLine,endColumn);
386 spot->setCapturedTexts(_searchText.capturedTexts());
387
388 addHotSpot( spot );
389 pos += _searchText.matchedLength();
390
391 // if matchedLength == 0, the program will get stuck in an infinite loop
392 if ( _searchText.matchedLength() == 0 )
393 pos = -1;
394 }
395 }
396}
397
398RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn,
399 int endLine,int endColumn)
400{
401 return new RegExpFilter::HotSpot(startLine,startColumn,
402 endLine,endColumn);
403}
404RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine,
405 int endColumn)
406{
407 return new UrlFilter::HotSpot(startLine,startColumn,
408 endLine,endColumn);
409}
410UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
411: RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn)
412, _urlObject(new FilterObject(this))
413{
414 setType(Link);
415}
416QString UrlFilter::HotSpot::tooltip() const
417{
418 QString url = capturedTexts().first();
419
420 const UrlType kind = urlType();
421
422 if ( kind == StandardUrl )
423 return QString();
424 else if ( kind == Email )
425 return QString();
426 else
427 return QString();
428}
429UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
430{
431 QString url = capturedTexts().first();
432
433 if ( FullUrlRegExp.exactMatch(url) )
434 return StandardUrl;
435 else if ( EmailAddressRegExp.exactMatch(url) )
436 return Email;
437 else
438 return Unknown;
439}
440
441void UrlFilter::HotSpot::activate(QObject* object)
442{
443 QString url = capturedTexts().first();
444
445 const UrlType kind = urlType();
446
447 const QString& actionName = object ? object->objectName() : QString();
448
449 if ( actionName == "copy-action" )
450 {
451 QApplication::clipboard()->setText(url);
452 return;
453 }
454
455 if ( !object || actionName == "open-action" )
456 {
457 if ( kind == StandardUrl )
458 {
459 // if the URL path does not include the protocol ( eg. "www.kde.org" ) then
460 // prepend http:// ( eg. "www.kde.org" --> "http://www.kde.org" )
461 if (!url.contains("://"))
462 {
463 url.prepend("http://");
464 }
465 }
466 else if ( kind == Email )
467 {
468 url.prepend("mailto:");
469 }
470
471 QDesktopServices::openUrl(QUrl(url));
472 //new KRun(url,QApplication::activeWindow());
473 }
474}
475
476// Note: Altering these regular expressions can have a major effect on the performance of the filters
477// used for finding URLs in the text, especially if they are very general and could match very long
478// pieces of text.
479// Please be careful when altering them.
480
481//regexp matches:
482// full url:
483// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot
484const QRegExp UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]");
485// email address:
486// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
487const QRegExp UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b");
488
489// matches full url or email address
490const QRegExp UrlFilter::CompleteUrlRegExp('('+FullUrlRegExp.pattern()+'|'+
491 EmailAddressRegExp.pattern()+')');
492
493UrlFilter::UrlFilter()
494{
495 setRegExp( CompleteUrlRegExp );
496}
497UrlFilter::HotSpot::~HotSpot()
498{
499 delete _urlObject;
500}
501void FilterObject::activated()
502{
503 _filter->activate(sender());
504}
505QList<QAction*> UrlFilter::HotSpot::actions()
506{
507 QList<QAction*> list;
508
509 const UrlType kind = urlType();
510
511 QAction* openAction = new QAction(_urlObject);
512 QAction* copyAction = new QAction(_urlObject);;
513
514 Q_ASSERT( kind == StandardUrl || kind == Email );
515
516 if ( kind == StandardUrl )
517 {
518 openAction->setText(QObject::tr("Open Link"));
519 copyAction->setText(QObject::tr("Copy Link Address"));
520 }
521 else if ( kind == Email )
522 {
523 openAction->setText(QObject::tr("Send Email To..."));
524 copyAction->setText(QObject::tr("Copy Email Address"));
525 }
526
527 // object names are set here so that the hotspot performs the
528 // correct action when activated() is called with the triggered
529 // action passed as a parameter.
530 openAction->setObjectName( QLatin1String("open-action" ));
531 copyAction->setObjectName( QLatin1String("copy-action" ));
532
533 QObject::connect( openAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
534 QObject::connect( copyAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
535
536 list << openAction;
537 list << copyAction;
538
539 return list;
540}
541
542//#include "Filter.moc"
0543
=== added file 'src/plugin/konsole/Filter.h'
--- src/plugin/konsole/Filter.h 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/Filter.h 2014-05-06 21:50:22 +0000
@@ -0,0 +1,380 @@
1/*
2 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
18*/
19
20#ifndef FILTER_H
21#define FILTER_H
22
23// Qt
24#include <QtWidgets/QAction>
25#include <QtCore/QList>
26#include <QtCore/QObject>
27#include <QtCore/QStringList>
28#include <QtCore/QHash>
29#include <QtCore/QRegExp>
30
31// Local
32#include "Character.h"
33
34
35/**
36 * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
37 * and marks the areas which match the filter's patterns as 'hotspots'.
38 *
39 * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
40 * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
41 * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
42 * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
43 *
44 * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
45 * Hotspots may have more than one action, in which case the list of actions can be obtained using the
46 * actions() method.
47 *
48 * Different subclasses of filter will return different types of hotspot.
49 * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
50 * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
51 * and add them to the filter's list of hotspots using addHotSpot()
52 */
53class Filter
54{
55public:
56 /**
57 * Represents an area of text which matched the pattern a particular filter has been looking for.
58 *
59 * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
60 * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
61 * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
62 * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
63 *
64 * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
65 * Hotspots may have more than one action, in which case the list of actions can be obtained using the
66 * actions() method. These actions may then be displayed in a popup menu or toolbar for example.
67 */
68 class HotSpot
69 {
70 public:
71 /**
72 * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
73 * in a block of text.
74 */
75 HotSpot(int startLine , int startColumn , int endLine , int endColumn);
76 virtual ~HotSpot();
77
78 enum Type
79 {
80 // the type of the hotspot is not specified
81 NotSpecified,
82 // this hotspot represents a clickable link
83 Link,
84 // this hotspot represents a marker
85 Marker
86 };
87
88 /** Returns the line when the hotspot area starts */
89 int startLine() const;
90 /** Returns the line where the hotspot area ends */
91 int endLine() const;
92 /** Returns the column on startLine() where the hotspot area starts */
93 int startColumn() const;
94 /** Returns the column on endLine() where the hotspot area ends */
95 int endColumn() const;
96 /**
97 * Returns the type of the hotspot. This is usually used as a hint for views on how to represent
98 * the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them
99 */
100 Type type() const;
101 /**
102 * Causes the an action associated with a hotspot to be triggered.
103 *
104 * @param object The object which caused the hotspot to be triggered. This is
105 * typically null ( in which case the default action should be performed ) or
106 * one of the objects from the actions() list. In which case the associated
107 * action should be performed.
108 */
109 virtual void activate(QObject* object = 0) = 0;
110 /**
111 * Returns a list of actions associated with the hotspot which can be used in a
112 * menu or toolbar
113 */
114 virtual QList<QAction*> actions();
115
116 /**
117 * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
118 * an empty string if there is no tooltip associated with this hotspot.
119 *
120 * The default implementation returns an empty string.
121 */
122 virtual QString tooltip() const;
123
124 protected:
125 /** Sets the type of a hotspot. This should only be set once */
126 void setType(Type type);
127
128 private:
129 int _startLine;
130 int _startColumn;
131 int _endLine;
132 int _endColumn;
133 Type _type;
134
135 };
136
137 /** Constructs a new filter. */
138 Filter();
139 virtual ~Filter();
140
141 /** Causes the filter to process the block of text currently in its internal buffer */
142 virtual void process() = 0;
143
144 /**
145 * Empties the filters internal buffer and resets the line count back to 0.
146 * All hotspots are deleted.
147 */
148 void reset();
149
150 /** Adds a new line of text to the filter and increments the line count */
151 //void addLine(const QString& string);
152
153 /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
154 HotSpot* hotSpotAt(int line , int column) const;
155
156 /** Returns the list of hotspots identified by the filter */
157 QList<HotSpot*> hotSpots() const;
158
159 /** Returns the list of hotspots identified by the filter which occur on a given line */
160 QList<HotSpot*> hotSpotsAtLine(int line) const;
161
162 /**
163 * TODO: Document me
164 */
165 void setBuffer(const QString* buffer , const QList<int>* linePositions);
166
167protected:
168 /** Adds a new hotspot to the list */
169 void addHotSpot(HotSpot*);
170 /** Returns the internal buffer */
171 const QString* buffer();
172 /** Converts a character position within buffer() to a line and column */
173 void getLineColumn(int position , int& startLine , int& startColumn);
174
175private:
176 QMultiHash<int,HotSpot*> _hotspots;
177 QList<HotSpot*> _hotspotList;
178
179 const QList<int>* _linePositions;
180 const QString* _buffer;
181};
182
183/**
184 * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot
185 * instance for them.
186 *
187 * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
188 * are found.
189 */
190class RegExpFilter : public Filter
191{
192public:
193 /**
194 * Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the text
195 * matched by the filter's regular expression.
196 */
197 class HotSpot : public Filter::HotSpot
198 {
199 public:
200 HotSpot(int startLine, int startColumn, int endLine , int endColumn);
201 virtual void activate(QObject* object = 0);
202
203 /** Sets the captured texts associated with this hotspot */
204 void setCapturedTexts(const QStringList& texts);
205 /** Returns the texts found by the filter when matching the filter's regular expression */
206 QStringList capturedTexts() const;
207 private:
208 QStringList _capturedTexts;
209 };
210
211 /** Constructs a new regular expression filter */
212 RegExpFilter();
213
214 /**
215 * Sets the regular expression which the filter searches for in blocks of text.
216 *
217 * Regular expressions which match the empty string are treated as not matching
218 * anything.
219 */
220 void setRegExp(const QRegExp& text);
221 /** Returns the regular expression which the filter searches for in blocks of text */
222 QRegExp regExp() const;
223
224 /**
225 * Reimplemented to search the filter's text buffer for text matching regExp()
226 *
227 * If regexp matches the empty string, then process() will return immediately
228 * without finding results.
229 */
230 virtual void process();
231
232protected:
233 /**
234 * Called when a match for the regular expression is encountered. Subclasses should reimplement this
235 * to return custom hotspot types
236 */
237 virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
238 int endLine,int endColumn);
239
240private:
241 QRegExp _searchText;
242};
243
244class FilterObject;
245
246/** A filter which matches URLs in blocks of text */
247class UrlFilter : public RegExpFilter
248{
249public:
250 /**
251 * Hotspot type created by UrlFilter instances. The activate() method opens a web browser
252 * at the given URL when called.
253 */
254 class HotSpot : public RegExpFilter::HotSpot
255 {
256 public:
257 HotSpot(int startLine,int startColumn,int endLine,int endColumn);
258 virtual ~HotSpot();
259
260 virtual QList<QAction*> actions();
261
262 /**
263 * Open a web browser at the current URL. The url itself can be determined using
264 * the capturedTexts() method.
265 */
266 virtual void activate(QObject* object = 0);
267
268 virtual QString tooltip() const;
269 private:
270 enum UrlType
271 {
272 StandardUrl,
273 Email,
274 Unknown
275 };
276 UrlType urlType() const;
277
278 FilterObject* _urlObject;
279 };
280
281 UrlFilter();
282
283protected:
284 virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
285
286private:
287
288 static const QRegExp FullUrlRegExp;
289 static const QRegExp EmailAddressRegExp;
290
291 // combined OR of FullUrlRegExp and EmailAddressRegExp
292 static const QRegExp CompleteUrlRegExp;
293};
294
295class FilterObject : public QObject
296{
297Q_OBJECT
298public:
299 FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
300private slots:
301 void activated();
302private:
303 Filter::HotSpot* _filter;
304};
305
306/**
307 * A chain which allows a group of filters to be processed as one.
308 * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
309 *
310 * Use addFilter() to add a new filter to the chain.
311 * When new text to be filtered arrives, use addLine() to add each additional
312 * line of text which needs to be processed and then after adding the last line, use
313 * process() to cause each filter in the chain to process the text.
314 *
315 * After processing a block of text, the reset() method can be used to set the filter chain's
316 * internal cursor back to the first line.
317 *
318 * The hotSpotAt() method will return the first hotspot which covers a given position.
319 *
320 * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
321 * a given line respectively.
322 */
323class FilterChain : protected QList<Filter*>
324{
325public:
326 virtual ~FilterChain();
327
328 /** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */
329 void addFilter(Filter* filter);
330 /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */
331 void removeFilter(Filter* filter);
332 /** Returns true if the chain contains @p filter */
333 bool containsFilter(Filter* filter);
334 /** Removes all filters from the chain */
335 void clear();
336
337 /** Resets each filter in the chain */
338 void reset();
339 /**
340 * Processes each filter in the chain
341 */
342 void process();
343
344 /** Sets the buffer for each filter in the chain to process. */
345 void setBuffer(const QString* buffer , const QList<int>* linePositions);
346
347 /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
348 Filter::HotSpot* hotSpotAt(int line , int column) const;
349 /** Returns a list of all the hotspots in all the chain's filters */
350 QList<Filter::HotSpot*> hotSpots() const;
351 /** Returns a list of all hotspots at the given line in all the chain's filters */
352 QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
353
354};
355
356/** A filter chain which processes character images from terminal displays */
357class TerminalImageFilterChain : public FilterChain
358{
359public:
360 TerminalImageFilterChain();
361 virtual ~TerminalImageFilterChain();
362
363 /**
364 * Set the current terminal image to @p image.
365 *
366 * @param image The terminal image
367 * @param lines The number of lines in the terminal image
368 * @param columns The number of columns in the terminal image
369 * @param lineProperties The line properties to set for image
370 */
371 void setImage(const Character* const image , int lines , int columns,
372 const QVector<LineProperty>& lineProperties);
373
374private:
375 QString* _buffer;
376 QList<int>* _linePositions;
377};
378
379
380#endif //FILTER_H
0381
=== added file 'src/plugin/konsole/History.cpp'
--- src/plugin/konsole/History.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/konsole/History.cpp 2014-05-06 21:50:22 +0000
@@ -0,0 +1,986 @@
1/*
2 This file is part of Konsole, an X terminal.
3 Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 02110-1301 USA.
19*/
20
21// Own
22#include "History.h"
23
24// System
25#include <iostream>
26#include <stdlib.h>
27#include <assert.h>
28#include <stdio.h>
29#include <sys/types.h>
30#include <sys/mman.h>
31#include <unistd.h>
32#include <errno.h>
33
34#include <QtDebug>
35
36// KDE
37//#include <kde_file.h>
38//#include <kdebug.h>
39
40// Reasonable line size
41#define LINE_SIZE 1024
42#define KDE_lseek lseek
43
44
45/*
46 An arbitrary long scroll.
47
48 One can modify the scroll only by adding either cells
49 or newlines, but access it randomly.
50
51 The model is that of an arbitrary wide typewriter scroll
52 in that the scroll is a serie of lines and each line is
53 a serie of cells with no overwriting permitted.
54
55 The implementation provides arbitrary length and numbers
56 of cells and line/column indexed read access to the scroll
57 at constant costs.
58
59KDE4: Can we use QTemporaryFile here, instead of KTempFile?
60
61FIXME: some complain about the history buffer comsuming the
62 memory of their machines. This problem is critical
63 since the history does not behave gracefully in cases
64 where the memory is used up completely.
65
66 I put in a workaround that should handle it problem
67 now gracefully. I'm not satisfied with the solution.
68
69FIXME: Terminating the history is not properly indicated
70 in the menu. We should throw a signal.
71
72FIXME: There is noticeable decrease in speed, also. Perhaps,
73 there whole feature needs to be revisited therefore.
74 Disadvantage of a more elaborated, say block-oriented
75 scheme with wrap around would be it's complexity.
76*/
77
78//FIXME: tempory replacement for tmpfile
79// this is here one for debugging purpose.
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches