commit
c44b7c83a0
@ -0,0 +1,15 @@
|
|||||||
|
Originally forked from Konsole by <e_k@users.sourceforge.net>
|
||||||
|
|
||||||
|
Revived by Petr Vanek <petr@yarpen.cz>
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
|
||||||
|
Adam Treat <atreat@rim.com>
|
||||||
|
Chris Mueller <ruunsmail@googlemail.com>
|
||||||
|
Christian Surlykke <christian@surlykke.dk>
|
||||||
|
Daniel O'Neill <doneill@cammy.riverroadcable.com>
|
||||||
|
Francisco Ballina <zballinita@gmail.com>
|
||||||
|
Georg Rudoy <0xd34df00d@gmail.com>
|
||||||
|
Jerome Leclanche <jerome@leclan.ch>
|
||||||
|
Petr Vanek <petr@yarpen.cz>
|
||||||
|
@kulti <kultihell@gmail.com>
|
@ -0,0 +1,239 @@
|
|||||||
|
cmake_minimum_required( VERSION 2.8 )
|
||||||
|
|
||||||
|
project(qtermwidget)
|
||||||
|
|
||||||
|
option(BUILD_DESIGNER_PLUGIN "Build Qt4 designer plugin" ON)
|
||||||
|
option(USE_QT5 "Build using Qt5. Default OFF." OFF)
|
||||||
|
option(BUILD_TEST "Build test application. Default OFF." OFF)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
# just change version for releases
|
||||||
|
set(QTERMWIDGET_VERSION_MAJOR "0")
|
||||||
|
set(QTERMWIDGET_VERSION_MINOR "6")
|
||||||
|
set(QTERMWIDGET_VERSION_PATCH "0")
|
||||||
|
|
||||||
|
set(QTERMWIDGET_VERSION "${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH}")
|
||||||
|
|
||||||
|
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
"${CMAKE_SOURCE_DIR}/lib"
|
||||||
|
"${CMAKE_BINARY_DIR}/lib"
|
||||||
|
"${CMAKE_BINARY_DIR}"
|
||||||
|
)
|
||||||
|
add_definitions(-Wall)
|
||||||
|
|
||||||
|
|
||||||
|
if(USE_QT5)
|
||||||
|
set(QTERMWIDGET_LIBRARY_NAME qtermwidget5)
|
||||||
|
include(qtermwidget5_use)
|
||||||
|
else()
|
||||||
|
include(qtermwidget4_use)
|
||||||
|
set(QTERMWIDGET_LIBRARY_NAME qtermwidget4)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
# main library
|
||||||
|
|
||||||
|
set(SRCS
|
||||||
|
lib/BlockArray.cpp
|
||||||
|
lib/ColorScheme.cpp
|
||||||
|
lib/Emulation.cpp
|
||||||
|
lib/Filter.cpp
|
||||||
|
lib/History.cpp
|
||||||
|
lib/HistorySearch.cpp
|
||||||
|
lib/KeyboardTranslator.cpp
|
||||||
|
lib/konsole_wcwidth.cpp
|
||||||
|
lib/kprocess.cpp
|
||||||
|
lib/kpty.cpp
|
||||||
|
lib/kptydevice.cpp
|
||||||
|
lib/kptyprocess.cpp
|
||||||
|
lib/Pty.cpp
|
||||||
|
lib/qtermwidget.cpp
|
||||||
|
lib/Screen.cpp
|
||||||
|
lib/ScreenWindow.cpp
|
||||||
|
lib/SearchBar.cpp
|
||||||
|
lib/Session.cpp
|
||||||
|
lib/ShellCommand.cpp
|
||||||
|
lib/TerminalCharacterDecoder.cpp
|
||||||
|
lib/TerminalDisplay.cpp
|
||||||
|
lib/tools.cpp
|
||||||
|
lib/Vt102Emulation.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Only the Headers that need to be moc'd go here
|
||||||
|
set(HDRS
|
||||||
|
lib/Emulation.h
|
||||||
|
lib/Filter.h
|
||||||
|
lib/HistorySearch.h
|
||||||
|
lib/kprocess.h
|
||||||
|
lib/kptydevice.h
|
||||||
|
lib/kptyprocess.h
|
||||||
|
lib/Pty.h
|
||||||
|
lib/qtermwidget.h
|
||||||
|
lib/ScreenWindow.h
|
||||||
|
lib/SearchBar.h
|
||||||
|
lib/Session.h
|
||||||
|
lib/TerminalDisplay.h
|
||||||
|
lib/Vt102Emulation.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(UI
|
||||||
|
lib/SearchBar.ui
|
||||||
|
)
|
||||||
|
|
||||||
|
# for distribution
|
||||||
|
set(HDRS_DISTRIB
|
||||||
|
lib/qtermwidget.h
|
||||||
|
lib/Filter.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# dirs
|
||||||
|
set(KB_LAYOUT_DIR "${CMAKE_INSTALL_DATADIR}/${QTERMWIDGET_LIBRARY_NAME}/kb-layouts/")
|
||||||
|
message(STATUS "Keyboard layouts will be installed in: ${KB_LAYOUT_DIR}")
|
||||||
|
add_definitions(-DKB_LAYOUT_DIR="${CMAKE_INSTALL_PREFIX}/${KB_LAYOUT_DIR}")
|
||||||
|
|
||||||
|
set(COLORSCHEMES_DIR "${CMAKE_INSTALL_DATADIR}/${QTERMWIDGET_LIBRARY_NAME}/color-schemes/")
|
||||||
|
message(STATUS "Color schemes will be installed in: ${COLORSCHEMES_DIR}" )
|
||||||
|
add_definitions(-DCOLORSCHEMES_DIR="${CMAKE_INSTALL_PREFIX}/${COLORSCHEMES_DIR}")
|
||||||
|
|
||||||
|
set(QTERMWIDGET_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/${QTERMWIDGET_LIBRARY_NAME}")
|
||||||
|
|
||||||
|
#| Defines
|
||||||
|
add_definitions(-DHAVE_POSIX_OPENPT -DHAVE_SYS_TIME_H)
|
||||||
|
if(APPLE)
|
||||||
|
add_definitions(-DHAVE_UTMPX -D_UTMPX_COMPAT)
|
||||||
|
endif()
|
||||||
|
CHECK_FUNCTION_EXISTS(updwtmpx HAVE_UPDWTMPX)
|
||||||
|
if(HAVE_UPDWTMPX)
|
||||||
|
add_definitions(-DHAVE_UPDWTMPX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(USE_QT5)
|
||||||
|
qt5_wrap_cpp(MOCS ${HDRS})
|
||||||
|
qt5_wrap_ui(UI_SRCS ${UI})
|
||||||
|
set(PKG_CONFIG_REQ "Qt5Core, Qt5Xml, Qt5Widgets")
|
||||||
|
else()
|
||||||
|
qt4_wrap_cpp(MOCS ${HDRS})
|
||||||
|
qt4_wrap_ui(UI_SRCS ${UI})
|
||||||
|
set(PKG_CONFIG_REQ "QtCore, QtXml")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
add_library(${QTERMWIDGET_LIBRARY_NAME} SHARED ${SRCS} ${MOCS} ${UI_SRCS})
|
||||||
|
target_link_libraries(${QTERMWIDGET_LIBRARY_NAME} ${QTERMWIDGET_QT_LIBRARIES})
|
||||||
|
set_target_properties( ${QTERMWIDGET_LIBRARY_NAME} PROPERTIES
|
||||||
|
SOVERSION ${QTERMWIDGET_VERSION_MAJOR}
|
||||||
|
VERSION ${QTERMWIDGET_VERSION}
|
||||||
|
)
|
||||||
|
if(APPLE)
|
||||||
|
set (CMAKE_SKIP_RPATH 1)
|
||||||
|
# this is a must to load the lib correctly
|
||||||
|
set_target_properties( ${QTERMWIDGET_LIBRARY_NAME} PROPERTIES INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS ${QTERMWIDGET_LIBRARY_NAME} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
install(FILES ${HDRS_DISTRIB} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QTERMWIDGET_LIBRARY_NAME}")
|
||||||
|
# keyboard layouts
|
||||||
|
install(DIRECTORY lib/kb-layouts/ DESTINATION "${KB_LAYOUT_DIR}" FILES_MATCHING PATTERN "*.keytab" )
|
||||||
|
# color schemes
|
||||||
|
install(DIRECTORY lib/color-schemes/ DESTINATION "${COLORSCHEMES_DIR}" FILES_MATCHING PATTERN "*.*schem*")
|
||||||
|
|
||||||
|
include(create_pkgconfig_file)
|
||||||
|
create_pkgconfig_file(${QTERMWIDGET_LIBRARY_NAME}
|
||||||
|
"QTermWidget library for Qt ${QTERMWIDGET_VERSION_MAJOR}.x"
|
||||||
|
${PKG_CONFIG_REQ}
|
||||||
|
${QTERMWIDGET_LIBRARY_NAME}
|
||||||
|
${QTERMWIDGET_VERSION}
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_SOURCE_DIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}-config.cmake.in"
|
||||||
|
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake"
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_BINARY_DIR}/${QTERMWIDGET_LIBRARY_NAME}-config.cmake"
|
||||||
|
"${CMAKE_SOURCE_DIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}_use.cmake"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${QTERMWIDGET_LIBRARY_NAME}"
|
||||||
|
)
|
||||||
|
# end of main library
|
||||||
|
|
||||||
|
|
||||||
|
# designer plugin
|
||||||
|
if (BUILD_DESIGNER_PLUGIN)
|
||||||
|
if(USE_QT5)
|
||||||
|
message(FATAL_ERROR "Building Qt designer plugin is not supported for Qt5 yet. Use -DBUILD_DESIGNER_PLUGIN=0")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Building Qt designer plugin")
|
||||||
|
|
||||||
|
include_directories(designer "${QT_QTDESIGNER_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
set(DESIGNER_SRC lib/designer/qtermwidgetplugin.cpp)
|
||||||
|
qt4_wrap_cpp(DESIGNER_MOC lib/designer/qtermwidgetplugin.h)
|
||||||
|
qt4_add_resources(DESIGNER_QRC lib/designer/qtermwidgetplugin.qrc)
|
||||||
|
|
||||||
|
link_directories(${CMAKE_BINARY_DIR})
|
||||||
|
add_library(qtermwidget4plugin SHARED
|
||||||
|
${DESIGNER_MOC}
|
||||||
|
${DESIGNER_QRC}
|
||||||
|
${DESIGNER_SRC}
|
||||||
|
)
|
||||||
|
add_dependencies(qtermwidget4plugin qtermwidget4)
|
||||||
|
|
||||||
|
target_link_libraries(qtermwidget4plugin
|
||||||
|
${QT_QTCORE_LIBRARY}
|
||||||
|
${QT_QTDESIGNER_LIBRARY}
|
||||||
|
${QT_QTDESIGNERCOMPONENTS_LIBRARY}
|
||||||
|
${QTERMWIDGET_LIBRARY_NAME}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
# this is a must to load the lib correctly
|
||||||
|
set_target_properties(qtermwidget4plugin PROPERTIES
|
||||||
|
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/qt4/plugins/designer"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS qtermwidget4plugin DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/qt4/plugins/designer")
|
||||||
|
|
||||||
|
endif (BUILD_DESIGNER_PLUGIN)
|
||||||
|
# end of designer plugin
|
||||||
|
|
||||||
|
|
||||||
|
# test application
|
||||||
|
if(BUILD_TEST)
|
||||||
|
set(TEST_SRC src/main.cpp)
|
||||||
|
add_executable(test ${TEST_SRC})
|
||||||
|
add_dependencies(test ${QTERMWIDGET_LIBRARY_NAME})
|
||||||
|
link_directories(${CMAKE_BINARY_DIR})
|
||||||
|
target_link_libraries(test ${QTERMWIDGET_QT_LIBRARIES} ${QTERMWIDGET_LIBRARY_NAME} util)
|
||||||
|
endif (BUILD_TEST)
|
||||||
|
# end of test application
|
||||||
|
|
||||||
|
|
||||||
|
CONFIGURE_FILE(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||||
|
IMMEDIATE @ONLY
|
||||||
|
)
|
||||||
|
ADD_CUSTOM_TARGET(uninstall
|
||||||
|
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# make dist custom target
|
||||||
|
SET(CPACK_PACKAGE_NAME "qtermwidget")
|
||||||
|
# TODO/FIXME: versioning from player subdir... I don't know why it's separated...
|
||||||
|
SET(CPACK_PACKAGE_VERSION ${QTERMWIDGET_VERSION_MAJOR}.${QTERMWIDGET_VERSION_MINOR}.${QTERMWIDGET_VERSION_PATCH})
|
||||||
|
SET(CPACK_SOURCE_GENERATOR "TGZ;TBZ2")
|
||||||
|
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||||
|
SET(CPACK_IGNORE_FILES "/\\\\.git/;\\\\.swp$;\\\\.#;/#;\\\\.tar.gz$;/CMakeFiles/;CMakeCache.txt;\\\\.qm$;/build/;\\\\.diff$;.DS_Store'")
|
||||||
|
SET(CPACK_SOURCE_IGNORE_FILES ${CPACK_IGNORE_FILES})
|
||||||
|
INCLUDE(CPack)
|
||||||
|
# simulate autotools' "make dist"
|
||||||
|
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
@ -0,0 +1,27 @@
|
|||||||
|
0.6.0 (2014-10-21)
|
||||||
|
* Full Qt4 + Qt5 support
|
||||||
|
* Fixed Ctrl+Arrows in Linux emulation
|
||||||
|
* Fixed Drag & Drop support
|
||||||
|
|
||||||
|
|
||||||
|
## Old changelog
|
||||||
|
|
||||||
|
31.07.2008
|
||||||
|
Interface class from c-style conversions rewritten with pimpl support.
|
||||||
|
|
||||||
|
|
||||||
|
16.07.2008
|
||||||
|
Added optional scrollbar
|
||||||
|
|
||||||
|
|
||||||
|
06.06.2008
|
||||||
|
Some artefacts were removed, some added...
|
||||||
|
Also added support for color schemes, and 3 color schemes provided (classical - white on black, green on black, black on light yellow). Is it enough or not?
|
||||||
|
|
||||||
|
|
||||||
|
26.05.2008
|
||||||
|
Added file release as an archive with source code. But preferrable way is still getting code from CVS, cause file release can be outdated.
|
||||||
|
|
||||||
|
|
||||||
|
11.05.2008
|
||||||
|
Initial CVS import - first version comes with number 0.0.1
|
@ -0,0 +1,23 @@
|
|||||||
|
Requirements:
|
||||||
|
|
||||||
|
Qt4 or Qt5
|
||||||
|
cmake
|
||||||
|
|
||||||
|
Supported (tested) platforms:
|
||||||
|
|
||||||
|
Linux
|
||||||
|
*BSD
|
||||||
|
Mac OS X
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
|
A shadow build (out of source) is strongly recommended
|
||||||
|
http://www.cmake.org/Wiki/CMake_FAQ#Out-of-source_build_trees
|
||||||
|
|
||||||
|
1) mkdir -p build && cd build
|
||||||
|
2a) cmake path/to/source -DUSE_QT5=true # Qt 5
|
||||||
|
2b) cmake path/to/source # Qt 4 only
|
||||||
|
3) make
|
||||||
|
4) optional: make install
|
||||||
|
|
||||||
|
Read cmake docs to fine tune the build process (CMAKE_INSTALL_PREFIX, etc...)
|
@ -0,0 +1,10 @@
|
|||||||
|
QTermWidget is an opensource project originally based on KDE4 Konsole application,
|
||||||
|
but it took its own direction later.
|
||||||
|
The main goal of this project is to provide unicode-enabled, embeddable
|
||||||
|
Qt widget for using as a built-in console (or terminal emulation widget).
|
||||||
|
|
||||||
|
|
||||||
|
Current maintainer: Petr Vanek <petr@yarpen.cz>
|
||||||
|
License: GPLv2+
|
||||||
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
|
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||||
|
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
|
|
||||||
|
# this works on Linux, but not on mac.
|
||||||
|
#FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||||
|
#STRING(REGEX REPLACE "\n" ";" files "${files}")
|
||||||
|
#FOREACH(file ${files})
|
||||||
|
# MESSAGE(STATUS "Uninstalling \"${file}\"")
|
||||||
|
# IF(NOT EXISTS "${file}")
|
||||||
|
# MESSAGE(FATAL_ERROR "File \"${file}\" does not exists.")
|
||||||
|
# ENDIF(NOT EXISTS "${file}")
|
||||||
|
# EXEC_PROGRAM("@CMAKE_COMMAND@" ARGS "-E remove \"${file}\""
|
||||||
|
# OUTPUT_VARIABLE rm_out
|
||||||
|
# RETURN_VARIABLE rm_retval)
|
||||||
|
# IF("${rm_retval}" GREATER 0)
|
||||||
|
# MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"")
|
||||||
|
# ENDIF("${rm_retval}" GREATER 0)
|
||||||
|
#ENDFOREACH(file)
|
||||||
|
|
||||||
|
EXEC_PROGRAM("xargs rm < @CMAKE_BINARY_DIR@/install_manifest.txt"
|
||||||
|
OUTPUT_VARIABLE rm_out
|
||||||
|
RETURN_VARIABLE rm_ret)
|
@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# Write a pkg-config pc file for given "name" with "decription"
|
||||||
|
# Arguments:
|
||||||
|
# name: a library name (withoud "lib" prefix and "so" suffixes
|
||||||
|
# desc: a desription string
|
||||||
|
# requires: required libraries
|
||||||
|
# include_rel_dir: include directory, relative to includedir
|
||||||
|
# version: package version
|
||||||
|
#
|
||||||
|
macro (create_pkgconfig_file name desc requires include_rel_dir version)
|
||||||
|
set(_pkgfname "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc")
|
||||||
|
message(STATUS "${name}: writing pkgconfig file ${_pkgfname}")
|
||||||
|
|
||||||
|
file(WRITE "${_pkgfname}"
|
||||||
|
"prefix=${CMAKE_INSTALL_PREFIX}\n"
|
||||||
|
"libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}\n"
|
||||||
|
"includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}\n"
|
||||||
|
"\n"
|
||||||
|
"Name: ${name}\n"
|
||||||
|
"Description: ${desc}\n"
|
||||||
|
"Version: ${version}\n"
|
||||||
|
"Requires: ${requires}\n"
|
||||||
|
"Libs: -L\${libdir} -l${name}\n"
|
||||||
|
"Cflags: -I\${includedir} -I\${includedir}/${include_rel_dir}\n"
|
||||||
|
"\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${_pkgfname} DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
|
endmacro()
|
@ -0,0 +1,47 @@
|
|||||||
|
# - Find the QTermWidget include and library dirs and define a some macros
|
||||||
|
#
|
||||||
|
# The module defines the following variables
|
||||||
|
# QTERMWIDGET_FOUND - Set to TRUE if all of the above has been found
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_INCLUDE_DIR - The QTermWidget include directory
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_INCLUDE_DIRS - The QTermWidget include directory
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_LIBRARIES - The libraries needed to use QTermWidget
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_USE_FILE - The variable QTERMWIDGET_USE_FILE is set which is the path
|
||||||
|
# to a CMake file that can be included to compile qtermwidget
|
||||||
|
# applications and libraries. It sets up the compilation
|
||||||
|
# environment for include directories and populates a
|
||||||
|
# QTERMWIDGET_LIBRARIES variable.
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_QT_LIBRARIES - The Qt libraries needed by QTermWidget
|
||||||
|
#
|
||||||
|
# Typical usage:
|
||||||
|
# option(USE_QT5 "Build using Qt5. Default off" OFF)
|
||||||
|
# if (USE_QT5)
|
||||||
|
# find_package(QTERMWIDGET4)
|
||||||
|
# else()
|
||||||
|
# find_package(QTERMWIDGET5)
|
||||||
|
# endif()
|
||||||
|
#
|
||||||
|
# include(${QTERMWIDGET_USE_FILE})
|
||||||
|
# add_executable(foo main.cpp)
|
||||||
|
# target_link_libraries(foo ${QTERMWIDGET_QT_LIBRARIES} ${QTERMWIDGET_LIBRARIES})
|
||||||
|
|
||||||
|
set(QTERMWIDGET_INCLUDE_DIR @QTERMWIDGET_INCLUDE_DIR@)
|
||||||
|
set(QTERMWIDGET_LIBRARY @QTERMWIDGET_LIBRARY_NAME@)
|
||||||
|
|
||||||
|
set(QTERMWIDGET_LIBRARIES ${QTERMWIDGET_LIBRARY})
|
||||||
|
set(QTERMWIDGET_INCLUDE_DIRS "${QTERMWIDGET_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
set(QTERMWIDGET_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/qtermwidget4_use.cmake")
|
||||||
|
set(QTERMWIDGET_FOUND 1)
|
||||||
|
|
||||||
|
set(QTERMWIDGET_VERSION_MAJOR @QTERMWIDGET_VERSION_MAJOR@)
|
||||||
|
set(QTERMWIDGET_VERSION_MINOR @QTERMWIDGET_VERSION_MINOR@)
|
||||||
|
set(QTERMWIDGET_VERSION_PATCH @QTERMWIDGET_VERSION_PATCH@)
|
||||||
|
set(QTERMWIDGET_VERSION @QTERMWIDGET_VERSION@)
|
||||||
|
|
||||||
|
mark_as_advanced(QTERMWIDGET_LIBRARY QTERMWIDGET_INCLUDE_DIR)
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
find_package(Qt4 REQUIRED QUIET)
|
||||||
|
include(${QT_USE_FILE})
|
||||||
|
|
||||||
|
set(QTERMWIDGET_QT_LIBRARIES ${QT_LIBRARIES})
|
||||||
|
|
||||||
|
include_directories(${QTERMWIDGET_INCLUDE_DIRS})
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
# - Find the QTermWidget include and library dirs and define a some macros
|
||||||
|
#
|
||||||
|
# The module defines the following variables
|
||||||
|
# QTERMWIDGET_FOUND - Set to TRUE if all of the above has been found
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_INCLUDE_DIR - The QTermWidget include directory
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_INCLUDE_DIRS - The QTermWidget include directory
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_LIBRARIES - The libraries needed to use QTermWidget
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_USE_FILE - The variable QTERMWIDGET_USE_FILE is set which is the path
|
||||||
|
# to a CMake file that can be included to compile qtermwidget
|
||||||
|
# applications and libraries. It sets up the compilation
|
||||||
|
# environment for include directories and populates a
|
||||||
|
# QTERMWIDGET_LIBRARIES variable.
|
||||||
|
#
|
||||||
|
# QTERMWIDGET_QT_LIBRARIES - The Qt libraries needed by QTermWidget
|
||||||
|
#
|
||||||
|
# Typical usage:
|
||||||
|
# option(USE_QT5 "Build using Qt5. Default off" OFF)
|
||||||
|
# if (USE_QT5)
|
||||||
|
# find_package(QTERMWIDGET4)
|
||||||
|
# else()
|
||||||
|
# find_package(QTERMWIDGET5)
|
||||||
|
# endif()
|
||||||
|
#
|
||||||
|
# include(${QTERMWIDGET_USE_FILE})
|
||||||
|
# add_executable(foo main.cpp)
|
||||||
|
# target_link_libraries(foo ${QTERMWIDGET_QT_LIBRARIES} ${QTERMWIDGET_LIBRARIES})
|
||||||
|
|
||||||
|
set(QTERMWIDGET_INCLUDE_DIR @QTERMWIDGET_INCLUDE_DIR@)
|
||||||
|
set(QTERMWIDGET_LIBRARY @QTERMWIDGET_LIBRARY_NAME@)
|
||||||
|
|
||||||
|
set(QTERMWIDGET_LIBRARIES ${QTERMWIDGET_LIBRARY})
|
||||||
|
set(QTERMWIDGET_INCLUDE_DIRS "${QTERMWIDGET_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
set(QTERMWIDGET_USE_FILE "${CMAKE_CURRENT_LIST_DIR}/qtermwidget5_use.cmake")
|
||||||
|
set(QTERMWIDGET_FOUND 1)
|
||||||
|
|
||||||
|
set(QTERMWIDGET_VERSION_MAJOR @QTERMWIDGET_VERSION_MAJOR@)
|
||||||
|
set(QTERMWIDGET_VERSION_MINOR @QTERMWIDGET_VERSION_MINOR@)
|
||||||
|
set(QTERMWIDGET_VERSION_PATCH @QTERMWIDGET_VERSION_PATCH@)
|
||||||
|
set(QTERMWIDGET_VERSION @QTERMWIDGET_VERSION@)
|
||||||
|
|
||||||
|
mark_as_advanced(QTERMWIDGET_LIBRARY QTERMWIDGET_INCLUDE_DIR)
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
find_package(Qt5Widgets REQUIRED)
|
||||||
|
|
||||||
|
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||||
|
add_definitions(${Qt5Core_DEFINITIONS})
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||||
|
set(QTERMWIDGET_QT_LIBRARIES ${Qt5Widgets_LIBRARIES})
|
||||||
|
|
||||||
|
include_directories(${QTERMWIDGET_INCLUDE_DIRS})
|
||||||
|
|
@ -0,0 +1,379 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "BlockArray.h"
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
static int blocksize = 0;
|
||||||
|
|
||||||
|
BlockArray::BlockArray()
|
||||||
|
: size(0),
|
||||||
|
current(size_t(-1)),
|
||||||
|
index(size_t(-1)),
|
||||||
|
lastmap(0),
|
||||||
|
lastmap_index(size_t(-1)),
|
||||||
|
lastblock(0), ion(-1),
|
||||||
|
length(0)
|
||||||
|
{
|
||||||
|
// lastmap_index = index = current = size_t(-1);
|
||||||
|
if (blocksize == 0) {
|
||||||
|
blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockArray::~BlockArray()
|
||||||
|
{
|
||||||
|
setHistorySize(0);
|
||||||
|
assert(!lastblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BlockArray::append(Block * block)
|
||||||
|
{
|
||||||
|
if (!size) {
|
||||||
|
return size_t(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
++current;
|
||||||
|
if (current >= size) {
|
||||||
|
current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rc;
|
||||||
|
rc = lseek(ion, current * blocksize, SEEK_SET);
|
||||||
|
if (rc < 0) {
|
||||||
|
perror("HistoryBuffer::add.seek");
|
||||||
|
setHistorySize(0);
|
||||||
|
return size_t(-1);
|
||||||
|
}
|
||||||
|
rc = write(ion, block, blocksize);
|
||||||
|
if (rc < 0) {
|
||||||
|
perror("HistoryBuffer::add.write");
|
||||||
|
setHistorySize(0);
|
||||||
|
return size_t(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
length++;
|
||||||
|
if (length > size) {
|
||||||
|
length = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
|
|
||||||
|
delete block;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BlockArray::newBlock()
|
||||||
|
{
|
||||||
|
if (!size) {
|
||||||
|
return size_t(-1);
|
||||||
|
}
|
||||||
|
append(lastblock);
|
||||||
|
|
||||||
|
lastblock = new Block();
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Block * BlockArray::lastBlock() const
|
||||||
|
{
|
||||||
|
return lastblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlockArray::has(size_t i) const
|
||||||
|
{
|
||||||
|
if (i == index + 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (index - i >= length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Block * BlockArray::at(size_t i)
|
||||||
|
{
|
||||||
|
if (i == index + 1) {
|
||||||
|
return lastblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == lastmap_index) {
|
||||||
|
return lastmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > index) {
|
||||||
|
qDebug() << "BlockArray::at() i > index\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (index - i >= length) {
|
||||||
|
// kDebug(1211) << "BlockArray::at() index - i >= length\n";
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ;
|
||||||
|
|
||||||
|
assert(j < size);
|
||||||
|
unmap();
|
||||||
|
|
||||||
|
Block * block = (Block *)mmap(0, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
|
||||||
|
|
||||||
|
if (block == (Block *)-1) {
|
||||||
|
perror("mmap");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastmap = block;
|
||||||
|
lastmap_index = i;
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockArray::unmap()
|
||||||
|
{
|
||||||
|
if (lastmap) {
|
||||||
|
int res = munmap((char *)lastmap, blocksize);
|
||||||
|
if (res < 0) {
|
||||||
|
perror("munmap");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastmap = 0;
|
||||||
|
lastmap_index = size_t(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlockArray::setSize(size_t newsize)
|
||||||
|
{
|
||||||
|
return setHistorySize(newsize * 1024 / blocksize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlockArray::setHistorySize(size_t newsize)
|
||||||
|
{
|
||||||
|
// kDebug(1211) << "setHistorySize " << size << " " << newsize;
|
||||||
|
|
||||||
|
if (size == newsize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unmap();
|
||||||
|
|
||||||
|
if (!newsize) {
|
||||||
|
delete lastblock;
|
||||||
|
lastblock = 0;
|
||||||
|
if (ion >= 0) {
|
||||||
|
close(ion);
|
||||||
|
}
|
||||||
|
ion = -1;
|
||||||
|
current = size_t(-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!size) {
|
||||||
|
FILE * tmp = tmpfile();
|
||||||
|
if (!tmp) {
|
||||||
|
perror("konsole: cannot open temp file.\n");
|
||||||
|
} else {
|
||||||
|
ion = dup(fileno(tmp));
|
||||||
|
if (ion<0) {
|
||||||
|
perror("konsole: cannot dup temp file.\n");
|
||||||
|
fclose(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ion < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!lastblock);
|
||||||
|
|
||||||
|
lastblock = new Block();
|
||||||
|
size = newsize;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newsize > size) {
|
||||||
|
increaseBuffer();
|
||||||
|
size = newsize;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
decreaseBuffer(newsize);
|
||||||
|
ftruncate(ion, length*blocksize);
|
||||||
|
size = newsize;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void moveBlock(FILE * fion, int cursor, int newpos, char * buffer2)
|
||||||
|
{
|
||||||
|
int res = fseek(fion, cursor * blocksize, SEEK_SET);
|
||||||
|
if (res) {
|
||||||
|
perror("fseek");
|
||||||
|
}
|
||||||
|
res = fread(buffer2, blocksize, 1, fion);
|
||||||
|
if (res != 1) {
|
||||||
|
perror("fread");
|
||||||
|
}
|
||||||
|
|
||||||
|
res = fseek(fion, newpos * blocksize, SEEK_SET);
|
||||||
|
if (res) {
|
||||||
|
perror("fseek");
|
||||||
|
}
|
||||||
|
res = fwrite(buffer2, blocksize, 1, fion);
|
||||||
|
if (res != 1) {
|
||||||
|
perror("fwrite");
|
||||||
|
}
|
||||||
|
// printf("moving block %d to %d\n", cursor, newpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockArray::decreaseBuffer(size_t newsize)
|
||||||
|
{
|
||||||
|
if (index < newsize) { // still fits in whole
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = (current - (newsize - 1) + size) % size;
|
||||||
|
|
||||||
|
if (!offset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Block constructor could do somthing in future...
|
||||||
|
char * buffer1 = new char[blocksize];
|
||||||
|
|
||||||
|
FILE * fion = fdopen(dup(ion), "w+b");
|
||||||
|
if (!fion) {
|
||||||
|
delete [] buffer1;
|
||||||
|
perror("fdopen/dup");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstblock;
|
||||||
|
if (current <= newsize) {
|
||||||
|
firstblock = current + 1;
|
||||||
|
} else {
|
||||||
|
firstblock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t oldpos;
|
||||||
|
for (size_t i = 0, cursor=firstblock; i < newsize; i++) {
|
||||||
|
oldpos = (size + cursor + offset) % size;
|
||||||
|
moveBlock(fion, oldpos, cursor, buffer1);
|
||||||
|
if (oldpos < newsize) {
|
||||||
|
cursor = oldpos;
|
||||||
|
} else {
|
||||||
|
cursor++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current = newsize - 1;
|
||||||
|
length = newsize;
|
||||||
|
|
||||||
|
delete [] buffer1;
|
||||||
|
|
||||||
|
fclose(fion);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockArray::increaseBuffer()
|
||||||
|
{
|
||||||
|
if (index < size) { // not even wrapped once
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = (current + size + 1) % size;
|
||||||
|
if (!offset) { // no moving needed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Block constructor could do somthing in future...
|
||||||
|
char * buffer1 = new char[blocksize];
|
||||||
|
char * buffer2 = new char[blocksize];
|
||||||
|
|
||||||
|
int runs = 1;
|
||||||
|
int bpr = size; // blocks per run
|
||||||
|
|
||||||
|
if (size % offset == 0) {
|
||||||
|
bpr = size / offset;
|
||||||
|
runs = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE * fion = fdopen(dup(ion), "w+b");
|
||||||
|
if (!fion) {
|
||||||
|
perror("fdopen/dup");
|
||||||
|
delete [] buffer1;
|
||||||
|
delete [] buffer2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res;
|
||||||
|
for (int i = 0; i < runs; i++) {
|
||||||
|
// free one block in chain
|
||||||
|
int firstblock = (offset + i) % size;
|
||||||
|
res = fseek(fion, firstblock * blocksize, SEEK_SET);
|
||||||
|
if (res) {
|
||||||
|
perror("fseek");
|
||||||
|
}
|
||||||
|
res = fread(buffer1, blocksize, 1, fion);
|
||||||
|
if (res != 1) {
|
||||||
|
perror("fread");
|
||||||
|
}
|
||||||
|
int newpos = 0;
|
||||||
|
for (int j = 1, cursor=firstblock; j < bpr; j++) {
|
||||||
|
cursor = (cursor + offset) % size;
|
||||||
|
newpos = (cursor - offset + size) % size;
|
||||||
|
moveBlock(fion, cursor, newpos, buffer2);
|
||||||
|
}
|
||||||
|
res = fseek(fion, i * blocksize, SEEK_SET);
|
||||||
|
if (res) {
|
||||||
|
perror("fseek");
|
||||||
|
}
|
||||||
|
res = fwrite(buffer1, blocksize, 1, fion);
|
||||||
|
if (res != 1) {
|
||||||
|
perror("fwrite");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = size - 1;
|
||||||
|
length = size;
|
||||||
|
|
||||||
|
delete [] buffer1;
|
||||||
|
delete [] buffer2;
|
||||||
|
|
||||||
|
fclose(fion);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLOCKARRAY_H
|
||||||
|
#define BLOCKARRAY_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//#error Do not use in KDE 2.1
|
||||||
|
|
||||||
|
#define BlockSize (1 << 12)
|
||||||
|
#define ENTRIES ((BlockSize - sizeof(size_t) ) / sizeof(unsigned char))
|
||||||
|
|
||||||
|
namespace Konsole {
|
||||||
|
|
||||||
|
struct Block {
|
||||||
|
Block() {
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
unsigned char data[ENTRIES];
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ///////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class BlockArray {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a history file for holding
|
||||||
|
* maximal size blocks. If more blocks
|
||||||
|
* are requested, then it drops earlier
|
||||||
|
* added ones.
|
||||||
|
*/
|
||||||
|
BlockArray();
|
||||||
|
|
||||||
|
/// destructor
|
||||||
|
~BlockArray();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* adds the Block at the end of history.
|
||||||
|
* This may drop other blocks.
|
||||||
|
*
|
||||||
|
* The ownership on the block is transfered.
|
||||||
|
* An unique index number is returned for accessing
|
||||||
|
* it later (if not yet dropped then)
|
||||||
|
*
|
||||||
|
* Note, that the block may be dropped completely
|
||||||
|
* if history is turned off.
|
||||||
|
*/
|
||||||
|
size_t append(Block * block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the block at the index. Function may return
|
||||||
|
* 0 if the block isn't available any more.
|
||||||
|
*
|
||||||
|
* The returned block is strictly readonly as only
|
||||||
|
* maped in memory - and will be invalid on the next
|
||||||
|
* operation on this class.
|
||||||
|
*/
|
||||||
|
const Block * at(size_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reorders blocks as needed. If newsize is null,
|
||||||
|
* the history is emptied completely. The indices
|
||||||
|
* returned on append won't change their semantic,
|
||||||
|
* but they may not be valid after this call.
|
||||||
|
*/
|
||||||
|
bool setHistorySize(size_t newsize);
|
||||||
|
|
||||||
|
size_t newBlock();
|
||||||
|
|
||||||
|
Block * lastBlock() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenient function to set the size in KBytes
|
||||||
|
* instead of blocks
|
||||||
|
*/
|
||||||
|
bool setSize(size_t newsize);
|
||||||
|
|
||||||
|
size_t len() const {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(size_t index) const;
|
||||||
|
|
||||||
|
size_t getCurrent() const {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void unmap();
|
||||||
|
void increaseBuffer();
|
||||||
|
void decreaseBuffer(size_t newsize);
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
// current always shows to the last inserted block
|
||||||
|
size_t current;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
Block * lastmap;
|
||||||
|
size_t lastmap_index;
|
||||||
|
Block * lastblock;
|
||||||
|
|
||||||
|
int ion;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, KDE's terminal.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHARACTER_H
|
||||||
|
#define CHARACTER_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
// Local
|
||||||
|
#include "CharacterColor.h"
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef unsigned char LineProperty;
|
||||||
|
|
||||||
|
static const int LINE_DEFAULT = 0;
|
||||||
|
static const int LINE_WRAPPED = (1 << 0);
|
||||||
|
static const int LINE_DOUBLEWIDTH = (1 << 1);
|
||||||
|
static const int LINE_DOUBLEHEIGHT = (1 << 2);
|
||||||
|
|
||||||
|
#define DEFAULT_RENDITION 0
|
||||||
|
#define RE_BOLD (1 << 0)
|
||||||
|
#define RE_BLINK (1 << 1)
|
||||||
|
#define RE_UNDERLINE (1 << 2)
|
||||||
|
#define RE_REVERSE (1 << 3) // Screen only
|
||||||
|
#define RE_INTENSIVE (1 << 3) // Widget only
|
||||||
|
#define RE_CURSOR (1 << 4)
|
||||||
|
#define RE_EXTENDED_CHAR (1 << 5)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single character in the terminal which consists of a unicode character
|
||||||
|
* value, foreground and background colors and a set of rendition attributes
|
||||||
|
* which specify how it should be drawn.
|
||||||
|
*/
|
||||||
|
class Character
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new character.
|
||||||
|
*
|
||||||
|
* @param _c The unicode character value of this character.
|
||||||
|
* @param _f The foreground color used to draw the character.
|
||||||
|
* @param _b The color used to draw the character's background.
|
||||||
|
* @param _r A set of rendition flags which specify how this character is to be drawn.
|
||||||
|
*/
|
||||||
|
inline Character(quint16 _c = ' ',
|
||||||
|
CharacterColor _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR),
|
||||||
|
CharacterColor _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR),
|
||||||
|
quint8 _r = DEFAULT_RENDITION)
|
||||||
|
: character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {}
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
/** The unicode character value for this character. */
|
||||||
|
quint16 character;
|
||||||
|
/**
|
||||||
|
* Experimental addition which allows a single Character instance to contain more than
|
||||||
|
* one unicode character.
|
||||||
|
*
|
||||||
|
* charSequence is a hash code which can be used to look up the unicode
|
||||||
|
* character sequence in the ExtendedCharTable used to create the sequence.
|
||||||
|
*/
|
||||||
|
quint16 charSequence;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A combination of RENDITION flags which specify options for drawing the character. */
|
||||||
|
quint8 rendition;
|
||||||
|
|
||||||
|
/** The foreground color used to draw this character. */
|
||||||
|
CharacterColor foregroundColor;
|
||||||
|
/** The color used to draw this character's background. */
|
||||||
|
CharacterColor backgroundColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this character has a transparent background when
|
||||||
|
* it is drawn with the specified @p palette.
|
||||||
|
*/
|
||||||
|
bool isTransparent(const ColorEntry* palette) const;
|
||||||
|
/**
|
||||||
|
* Returns true if this character should always be drawn in bold when
|
||||||
|
* it is drawn with the specified @p palette, independent of whether
|
||||||
|
* or not the character has the RE_BOLD rendition flag.
|
||||||
|
*/
|
||||||
|
ColorEntry::FontWeight fontWeight(const ColorEntry* base) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns true if the format (color, rendition flag) of the compared characters is equal
|
||||||
|
*/
|
||||||
|
bool equalsFormat(const Character &other) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two characters and returns true if they have the same unicode character value,
|
||||||
|
* rendition and colors.
|
||||||
|
*/
|
||||||
|
friend bool operator == (const Character& a, const Character& b);
|
||||||
|
/**
|
||||||
|
* Compares two characters and returns true if they have different unicode character values,
|
||||||
|
* renditions or colors.
|
||||||
|
*/
|
||||||
|
friend bool operator != (const Character& a, const Character& b);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator == (const Character& a, const Character& b)
|
||||||
|
{
|
||||||
|
return a.character == b.character &&
|
||||||
|
a.rendition == b.rendition &&
|
||||||
|
a.foregroundColor == b.foregroundColor &&
|
||||||
|
a.backgroundColor == b.backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator != (const Character& a, const Character& b)
|
||||||
|
{
|
||||||
|
return a.character != b.character ||
|
||||||
|
a.rendition != b.rendition ||
|
||||||
|
a.foregroundColor != b.foregroundColor ||
|
||||||
|
a.backgroundColor != b.backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Character::isTransparent(const ColorEntry* base) const
|
||||||
|
{
|
||||||
|
return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) &&
|
||||||
|
base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent)
|
||||||
|
|| ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) &&
|
||||||
|
base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Character::equalsFormat(const Character& other) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
backgroundColor==other.backgroundColor &&
|
||||||
|
foregroundColor==other.foregroundColor &&
|
||||||
|
rendition==other.rendition;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColorEntry::FontWeight Character::fontWeight(const ColorEntry* base) const
|
||||||
|
{
|
||||||
|
if (backgroundColor._colorSpace == COLOR_SPACE_DEFAULT)
|
||||||
|
return base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
|
||||||
|
else if (backgroundColor._colorSpace == COLOR_SPACE_SYSTEM)
|
||||||
|
return base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].fontWeight;
|
||||||
|
else
|
||||||
|
return ColorEntry::UseCurrentFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern unsigned short vt100_graphics[32];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A table which stores sequences of unicode characters, referenced
|
||||||
|
* by hash keys. The hash key itself is the same size as a unicode
|
||||||
|
* character ( ushort ) so that it can occupy the same space in
|
||||||
|
* a structure.
|
||||||
|
*/
|
||||||
|
class ExtendedCharTable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Constructs a new character table. */
|
||||||
|
ExtendedCharTable();
|
||||||
|
~ExtendedCharTable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a sequences of unicode characters to the table and returns
|
||||||
|
* a hash code which can be used later to look up the sequence
|
||||||
|
* using lookupExtendedChar()
|
||||||
|
*
|
||||||
|
* If the same sequence already exists in the table, the hash
|
||||||
|
* of the existing sequence will be returned.
|
||||||
|
*
|
||||||
|
* @param unicodePoints An array of unicode character points
|
||||||
|
* @param length Length of @p unicodePoints
|
||||||
|
*/
|
||||||
|
ushort createExtendedChar(ushort* unicodePoints , ushort length);
|
||||||
|
/**
|
||||||
|
* Looks up and returns a pointer to a sequence of unicode characters
|
||||||
|
* which was added to the table using createExtendedChar().
|
||||||
|
*
|
||||||
|
* @param hash The hash key returned by createExtendedChar()
|
||||||
|
* @param length This variable is set to the length of the
|
||||||
|
* character sequence.
|
||||||
|
*
|
||||||
|
* @return A unicode character sequence of size @p length.
|
||||||
|
*/
|
||||||
|
ushort* lookupExtendedChar(ushort hash , ushort& length) const;
|
||||||
|
|
||||||
|
/** The global ExtendedCharTable instance. */
|
||||||
|
static ExtendedCharTable instance;
|
||||||
|
private:
|
||||||
|
// calculates the hash key of a sequence of unicode points of size 'length'
|
||||||
|
ushort extendedCharHash(ushort* unicodePoints , ushort length) const;
|
||||||
|
// tests whether the entry in the table specified by 'hash' matches the
|
||||||
|
// character sequence 'unicodePoints' of size 'length'
|
||||||
|
bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const;
|
||||||
|
// internal, maps hash keys to character sequence buffers. The first ushort
|
||||||
|
// in each value is the length of the buffer, followed by the ushorts in the buffer
|
||||||
|
// themselves.
|
||||||
|
QHash<ushort,ushort*> extendedCharTable;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
Q_DECLARE_TYPEINFO(Konsole::Character, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
|
#endif // CHARACTER_H
|
||||||
|
|
@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, KDE's terminal.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHARACTERCOLOR_H
|
||||||
|
#define CHARACTERCOLOR_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
//#include <kdemacros.h>
|
||||||
|
#define KDE_NO_EXPORT
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entry in a terminal display's color palette.
|
||||||
|
*
|
||||||
|
* A color palette is an array of 16 ColorEntry instances which map
|
||||||
|
* system color indexes (from 0 to 15) into actual colors.
|
||||||
|
*
|
||||||
|
* Each entry can be set as bold, in which case any text
|
||||||
|
* drawn using the color should be drawn in bold.
|
||||||
|
*
|
||||||
|
* Each entry can also be transparent, in which case the terminal
|
||||||
|
* display should avoid drawing the background for any characters
|
||||||
|
* using the entry as a background.
|
||||||
|
*/
|
||||||
|
class ColorEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Specifies the weight to use when drawing text with this color. */
|
||||||
|
enum FontWeight
|
||||||
|
{
|
||||||
|
/** Always draw text in this color with a bold weight. */
|
||||||
|
Bold,
|
||||||
|
/** Always draw text in this color with a normal weight. */
|
||||||
|
Normal,
|
||||||
|
/**
|
||||||
|
* Use the current font weight set by the terminal application.
|
||||||
|
* This is the default behavior.
|
||||||
|
*/
|
||||||
|
UseCurrentFormat
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new color palette entry.
|
||||||
|
*
|
||||||
|
* @param c The color value for this entry.
|
||||||
|
* @param tr Specifies that the color should be transparent when used as a background color.
|
||||||
|
* @param weight Specifies the font weight to use when drawing text with this color.
|
||||||
|
*/
|
||||||
|
ColorEntry(QColor c, bool tr, FontWeight weight = UseCurrentFormat)
|
||||||
|
: color(c), transparent(tr), fontWeight(weight) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new color palette entry with an undefined color, and
|
||||||
|
* with the transparent and bold flags set to false.
|
||||||
|
*/
|
||||||
|
ColorEntry() : transparent(false), fontWeight(UseCurrentFormat) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the color, transparency and boldness of this color to those of @p rhs.
|
||||||
|
*/
|
||||||
|
void operator=(const ColorEntry& rhs)
|
||||||
|
{
|
||||||
|
color = rhs.color;
|
||||||
|
transparent = rhs.transparent;
|
||||||
|
fontWeight = rhs.fontWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The color value of this entry for display. */
|
||||||
|
QColor color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true character backgrounds using this color should be transparent.
|
||||||
|
* This is not applicable when the color is used to render text.
|
||||||
|
*/
|
||||||
|
bool transparent;
|
||||||
|
/**
|
||||||
|
* Specifies the font weight to use when drawing text with this color.
|
||||||
|
* This is not applicable when the color is used to draw a character's background.
|
||||||
|
*/
|
||||||
|
FontWeight fontWeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Attributed Character Representations ///////////////////////////////
|
||||||
|
|
||||||
|
// Colors
|
||||||
|
|
||||||
|
#define BASE_COLORS (2+8)
|
||||||
|
#define INTENSITIES 2
|
||||||
|
#define TABLE_COLORS (INTENSITIES*BASE_COLORS)
|
||||||
|
|
||||||
|
#define DEFAULT_FORE_COLOR 0
|
||||||
|
#define DEFAULT_BACK_COLOR 1
|
||||||
|
|
||||||
|
//a standard set of colors using black text on a white background.
|
||||||
|
//defined in TerminalDisplay.cpp
|
||||||
|
|
||||||
|
extern const ColorEntry base_color_table[TABLE_COLORS] KDE_NO_EXPORT;
|
||||||
|
|
||||||
|
/* CharacterColor is a union of the various color spaces.
|
||||||
|
|
||||||
|
Assignment is as follows:
|
||||||
|
|
||||||
|
Type - Space - Values
|
||||||
|
|
||||||
|
0 - Undefined - u: 0, v:0 w:0
|
||||||
|
1 - Default - u: 0..1 v:intense w:0
|
||||||
|
2 - System - u: 0..7 v:intense w:0
|
||||||
|
3 - Index(256) - u: 16..255 v:0 w:0
|
||||||
|
4 - RGB - u: 0..255 v:0..256 w:0..256
|
||||||
|
|
||||||
|
Default colour space has two separate colours, namely
|
||||||
|
default foreground and default background colour.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define COLOR_SPACE_UNDEFINED 0
|
||||||
|
#define COLOR_SPACE_DEFAULT 1
|
||||||
|
#define COLOR_SPACE_SYSTEM 2
|
||||||
|
#define COLOR_SPACE_256 3
|
||||||
|
#define COLOR_SPACE_RGB 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the color of a single character in the terminal.
|
||||||
|
*/
|
||||||
|
class CharacterColor
|
||||||
|
{
|
||||||
|
friend class Character;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructs a new CharacterColor whoose color and color space are undefined. */
|
||||||
|
CharacterColor()
|
||||||
|
: _colorSpace(COLOR_SPACE_UNDEFINED),
|
||||||
|
_u(0),
|
||||||
|
_v(0),
|
||||||
|
_w(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new CharacterColor using the specified @p colorSpace and with
|
||||||
|
* color value @p co
|
||||||
|
*
|
||||||
|
* The meaning of @p co depends on the @p colorSpace used.
|
||||||
|
*
|
||||||
|
* TODO : Document how @p co relates to @p colorSpace
|
||||||
|
*
|
||||||
|
* TODO : Add documentation about available color spaces.
|
||||||
|
*/
|
||||||
|
CharacterColor(quint8 colorSpace, int co)
|
||||||
|
: _colorSpace(colorSpace),
|
||||||
|
_u(0),
|
||||||
|
_v(0),
|
||||||
|
_w(0)
|
||||||
|
{
|
||||||
|
switch (colorSpace)
|
||||||
|
{
|
||||||
|
case COLOR_SPACE_DEFAULT:
|
||||||
|
_u = co & 1;
|
||||||
|
break;
|
||||||
|
case COLOR_SPACE_SYSTEM:
|
||||||
|
_u = co & 7;
|
||||||
|
_v = (co >> 3) & 1;
|
||||||
|
break;
|
||||||
|
case COLOR_SPACE_256:
|
||||||
|
_u = co & 255;
|
||||||
|
break;
|
||||||
|
case COLOR_SPACE_RGB:
|
||||||
|
_u = co >> 16;
|
||||||
|
_v = co >> 8;
|
||||||
|
_w = co;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_colorSpace = COLOR_SPACE_UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this character color entry is valid.
|
||||||
|
*/
|
||||||
|
bool isValid()
|
||||||
|
{
|
||||||
|
return _colorSpace != COLOR_SPACE_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the value of this color between a normal system color and the corresponding intensive
|
||||||
|
* system color.
|
||||||
|
*
|
||||||
|
* This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM
|
||||||
|
* color spaces.
|
||||||
|
*/
|
||||||
|
void toggleIntensive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the color within the specified color @p palette
|
||||||
|
*
|
||||||
|
* The @p palette is only used if this color is one of the 16 system colors, otherwise
|
||||||
|
* it is ignored.
|
||||||
|
*/
|
||||||
|
QColor color(const ColorEntry* palette) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two colors and returns true if they represent the same color value and
|
||||||
|
* use the same color space.
|
||||||
|
*/
|
||||||
|
friend bool operator == (const CharacterColor& a, const CharacterColor& b);
|
||||||
|
/**
|
||||||
|
* Compares two colors and returns true if they represent different color values
|
||||||
|
* or use different color spaces.
|
||||||
|
*/
|
||||||
|
friend bool operator != (const CharacterColor& a, const CharacterColor& b);
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint8 _colorSpace;
|
||||||
|
|
||||||
|
// bytes storing the character color
|
||||||
|
quint8 _u;
|
||||||
|
quint8 _v;
|
||||||
|
quint8 _w;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator == (const CharacterColor& a, const CharacterColor& b)
|
||||||
|
{
|
||||||
|
return a._colorSpace == b._colorSpace &&
|
||||||
|
a._u == b._u &&
|
||||||
|
a._v == b._v &&
|
||||||
|
a._w == b._w;
|
||||||
|
}
|
||||||
|
inline bool operator != (const CharacterColor& a, const CharacterColor& b)
|
||||||
|
{
|
||||||
|
return !operator==(a,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const QColor color256(quint8 u, const ColorEntry* base)
|
||||||
|
{
|
||||||
|
// 0.. 16: system colors
|
||||||
|
if (u < 8) return base[u+2 ].color; u -= 8;
|
||||||
|
if (u < 8) return base[u+2+BASE_COLORS].color; u -= 8;
|
||||||
|
|
||||||
|
// 16..231: 6x6x6 rgb color cube
|
||||||
|
if (u < 216) return QColor(((u/36)%6) ? (40*((u/36)%6)+55) : 0,
|
||||||
|
((u/ 6)%6) ? (40*((u/ 6)%6)+55) : 0,
|
||||||
|
((u/ 1)%6) ? (40*((u/ 1)%6)+55) : 0); u -= 216;
|
||||||
|
|
||||||
|
// 232..255: gray, leaving out black and white
|
||||||
|
int gray = u*10+8; return QColor(gray,gray,gray);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QColor CharacterColor::color(const ColorEntry* base) const
|
||||||
|
{
|
||||||
|
switch (_colorSpace)
|
||||||
|
{
|
||||||
|
case COLOR_SPACE_DEFAULT: return base[_u+0+(_v?BASE_COLORS:0)].color;
|
||||||
|
case COLOR_SPACE_SYSTEM: return base[_u+2+(_v?BASE_COLORS:0)].color;
|
||||||
|
case COLOR_SPACE_256: return color256(_u,base);
|
||||||
|
case COLOR_SPACE_RGB: return QColor(_u,_v,_w);
|
||||||
|
case COLOR_SPACE_UNDEFINED: return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(false); // invalid color space
|
||||||
|
|
||||||
|
return QColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CharacterColor::toggleIntensive()
|
||||||
|
{
|
||||||
|
if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT)
|
||||||
|
{
|
||||||
|
_v = !_v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CHARACTERCOLOR_H
|
||||||
|
|
@ -0,0 +1,788 @@
|
|||||||
|
/*
|
||||||
|
This source file is part of Konsole, a terminal emulator.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "ColorScheme.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QBrush>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <KColorScheme>
|
||||||
|
//#include <KConfig>
|
||||||
|
//#include <KLocale>
|
||||||
|
//#include <KDebug>
|
||||||
|
//#include <KConfigGroup>
|
||||||
|
//#include <KStandardDirs>
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
const ColorEntry ColorScheme::defaultTable[TABLE_COLORS] =
|
||||||
|
// The following are almost IBM standard color codes, with some slight
|
||||||
|
// gamma correction for the dim colors to compensate for bright X screens.
|
||||||
|
// It contains the 8 ansiterm/xterm colors in 2 intensities.
|
||||||
|
{
|
||||||
|
ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
|
||||||
|
QColor(0xFF,0xFF,0xFF), 1), // Dfore, Dback
|
||||||
|
ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
|
||||||
|
QColor(0xB2,0x18,0x18), 0), // Black, Red
|
||||||
|
ColorEntry( QColor(0x18,0xB2,0x18), 0), ColorEntry(
|
||||||
|
QColor(0xB2,0x68,0x18), 0), // Green, Yellow
|
||||||
|
ColorEntry( QColor(0x18,0x18,0xB2), 0), ColorEntry(
|
||||||
|
QColor(0xB2,0x18,0xB2), 0), // Blue, Magenta
|
||||||
|
ColorEntry( QColor(0x18,0xB2,0xB2), 0), ColorEntry(
|
||||||
|
QColor(0xB2,0xB2,0xB2), 0), // Cyan, White
|
||||||
|
// intensive
|
||||||
|
ColorEntry( QColor(0x00,0x00,0x00), 0), ColorEntry(
|
||||||
|
QColor(0xFF,0xFF,0xFF), 1),
|
||||||
|
ColorEntry( QColor(0x68,0x68,0x68), 0), ColorEntry(
|
||||||
|
QColor(0xFF,0x54,0x54), 0),
|
||||||
|
ColorEntry( QColor(0x54,0xFF,0x54), 0), ColorEntry(
|
||||||
|
QColor(0xFF,0xFF,0x54), 0),
|
||||||
|
ColorEntry( QColor(0x54,0x54,0xFF), 0), ColorEntry(
|
||||||
|
QColor(0xFF,0x54,0xFF), 0),
|
||||||
|
ColorEntry( QColor(0x54,0xFF,0xFF), 0), ColorEntry(
|
||||||
|
QColor(0xFF,0xFF,0xFF), 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* const ColorScheme::colorNames[TABLE_COLORS] =
|
||||||
|
{
|
||||||
|
"Foreground",
|
||||||
|
"Background",
|
||||||
|
"Color0",
|
||||||
|
"Color1",
|
||||||
|
"Color2",
|
||||||
|
"Color3",
|
||||||
|
"Color4",
|
||||||
|
"Color5",
|
||||||
|
"Color6",
|
||||||
|
"Color7",
|
||||||
|
"ForegroundIntense",
|
||||||
|
"BackgroundIntense",
|
||||||
|
"Color0Intense",
|
||||||
|
"Color1Intense",
|
||||||
|
"Color2Intense",
|
||||||
|
"Color3Intense",
|
||||||
|
"Color4Intense",
|
||||||
|
"Color5Intense",
|
||||||
|
"Color6Intense",
|
||||||
|
"Color7Intense"
|
||||||
|
};
|
||||||
|
// dummy silently comment out the tr_NOOP
|
||||||
|
#define tr_NOOP
|
||||||
|
const char* const ColorScheme::translatedColorNames[TABLE_COLORS] =
|
||||||
|
{
|
||||||
|
tr_NOOP("Foreground"),
|
||||||
|
tr_NOOP("Background"),
|
||||||
|
tr_NOOP("Color 1"),
|
||||||
|
tr_NOOP("Color 2"),
|
||||||
|
tr_NOOP("Color 3"),
|
||||||
|
tr_NOOP("Color 4"),
|
||||||
|
tr_NOOP("Color 5"),
|
||||||
|
tr_NOOP("Color 6"),
|
||||||
|
tr_NOOP("Color 7"),
|
||||||
|
tr_NOOP("Color 8"),
|
||||||
|
tr_NOOP("Foreground (Intense)"),
|
||||||
|
tr_NOOP("Background (Intense)"),
|
||||||
|
tr_NOOP("Color 1 (Intense)"),
|
||||||
|
tr_NOOP("Color 2 (Intense)"),
|
||||||
|
tr_NOOP("Color 3 (Intense)"),
|
||||||
|
tr_NOOP("Color 4 (Intense)"),
|
||||||
|
tr_NOOP("Color 5 (Intense)"),
|
||||||
|
tr_NOOP("Color 6 (Intense)"),
|
||||||
|
tr_NOOP("Color 7 (Intense)"),
|
||||||
|
tr_NOOP("Color 8 (Intense)")
|
||||||
|
};
|
||||||
|
|
||||||
|
ColorScheme::ColorScheme()
|
||||||
|
{
|
||||||
|
_table = 0;
|
||||||
|
_randomTable = 0;
|
||||||
|
_opacity = 1.0;
|
||||||
|
}
|
||||||
|
ColorScheme::ColorScheme(const ColorScheme& other)
|
||||||
|
: _opacity(other._opacity)
|
||||||
|
,_table(0)
|
||||||
|
,_randomTable(0)
|
||||||
|
{
|
||||||
|
setName(other.name());
|
||||||
|
setDescription(other.description());
|
||||||
|
|
||||||
|
if ( other._table != 0 )
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < TABLE_COLORS ; i++ )
|
||||||
|
setColorTableEntry(i,other._table[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( other._randomTable != 0 )
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < TABLE_COLORS ; i++ )
|
||||||
|
{
|
||||||
|
const RandomizationRange& range = other._randomTable[i];
|
||||||
|
setRandomizationRange(i,range.hue,range.saturation,range.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColorScheme::~ColorScheme()
|
||||||
|
{
|
||||||
|
delete[] _table;
|
||||||
|
delete[] _randomTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorScheme::setDescription(const QString& description) { _description = description; }
|
||||||
|
QString ColorScheme::description() const { return _description; }
|
||||||
|
|
||||||
|
void ColorScheme::setName(const QString& name) { _name = name; }
|
||||||
|
QString ColorScheme::name() const { return _name; }
|
||||||
|
|
||||||
|
void ColorScheme::setColorTableEntry(int index , const ColorEntry& entry)
|
||||||
|
{
|
||||||
|
Q_ASSERT( index >= 0 && index < TABLE_COLORS );
|
||||||
|
|
||||||
|
if ( !_table )
|
||||||
|
{
|
||||||
|
_table = new ColorEntry[TABLE_COLORS];
|
||||||
|
|
||||||
|
for (int i=0;i<TABLE_COLORS;i++)
|
||||||
|
_table[i] = defaultTable[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
_table[index] = entry;
|
||||||
|
}
|
||||||
|
ColorEntry ColorScheme::colorEntry(int index , uint randomSeed) const
|
||||||
|
{
|
||||||
|
Q_ASSERT( index >= 0 && index < TABLE_COLORS );
|
||||||
|
|
||||||
|
if ( randomSeed != 0 )
|
||||||
|
qsrand(randomSeed);
|
||||||
|
|
||||||
|
ColorEntry entry = colorTable()[index];
|
||||||
|
|
||||||
|
if ( randomSeed != 0 &&
|
||||||
|
_randomTable != 0 &&
|
||||||
|
!_randomTable[index].isNull() )
|
||||||
|
{
|
||||||
|
const RandomizationRange& range = _randomTable[index];
|
||||||
|
|
||||||
|
|
||||||
|
int hueDifference = range.hue ? (qrand() % range.hue) - range.hue/2 : 0;
|
||||||
|
int saturationDifference = range.saturation ? (qrand() % range.saturation) - range.saturation/2 : 0;
|
||||||
|
int valueDifference = range.value ? (qrand() % range.value) - range.value/2 : 0;
|
||||||
|
|
||||||
|
QColor& color = entry.color;
|
||||||
|
|
||||||
|
int newHue = qAbs( (color.hue() + hueDifference) % MAX_HUE );
|
||||||
|
int newValue = qMin( qAbs(color.value() + valueDifference) , 255 );
|
||||||
|
int newSaturation = qMin( qAbs(color.saturation() + saturationDifference) , 255 );
|
||||||
|
|
||||||
|
color.setHsv(newHue,newSaturation,newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
void ColorScheme::getColorTable(ColorEntry* table , uint randomSeed) const
|
||||||
|
{
|
||||||
|
for ( int i = 0 ; i < TABLE_COLORS ; i++ )
|
||||||
|
table[i] = colorEntry(i,randomSeed);
|
||||||
|
}
|
||||||
|
bool ColorScheme::randomizedBackgroundColor() const
|
||||||
|
{
|
||||||
|
return _randomTable == 0 ? false : !_randomTable[1].isNull();
|
||||||
|
}
|
||||||
|
void ColorScheme::setRandomizedBackgroundColor(bool randomize)
|
||||||
|
{
|
||||||
|
// the hue of the background colour is allowed to be randomly
|
||||||
|
// adjusted as much as possible.
|
||||||
|
//
|
||||||
|
// the value and saturation are left alone to maintain read-ability
|
||||||
|
if ( randomize )
|
||||||
|
{
|
||||||
|
setRandomizationRange( 1 /* background color index */ , MAX_HUE , 255 , 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( _randomTable )
|
||||||
|
setRandomizationRange( 1 /* background color index */ , 0 , 0 , 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorScheme::setRandomizationRange( int index , quint16 hue , quint8 saturation ,
|
||||||
|
quint8 value )
|
||||||
|
{
|
||||||
|
Q_ASSERT( hue <= MAX_HUE );
|
||||||
|
Q_ASSERT( index >= 0 && index < TABLE_COLORS );
|
||||||
|
|
||||||
|
if ( _randomTable == 0 )
|
||||||
|
_randomTable = new RandomizationRange[TABLE_COLORS];
|
||||||
|
|
||||||
|
_randomTable[index].hue = hue;
|
||||||
|
_randomTable[index].value = value;
|
||||||
|
_randomTable[index].saturation = saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ColorEntry* ColorScheme::colorTable() const
|
||||||
|
{
|
||||||
|
if ( _table )
|
||||||
|
return _table;
|
||||||
|
else
|
||||||
|
return defaultTable;
|
||||||
|
}
|
||||||
|
QColor ColorScheme::foregroundColor() const
|
||||||
|
{
|
||||||
|
return colorTable()[0].color;
|
||||||
|
}
|
||||||
|
QColor ColorScheme::backgroundColor() const
|
||||||
|
{
|
||||||
|
return colorTable()[1].color;
|
||||||
|
}
|
||||||
|
bool ColorScheme::hasDarkBackground() const
|
||||||
|
{
|
||||||
|
// value can range from 0 - 255, with larger values indicating higher brightness.
|
||||||
|
// so 127 is in the middle, anything less is deemed 'dark'
|
||||||
|
return backgroundColor().value() < 127;
|
||||||
|
}
|
||||||
|
void ColorScheme::setOpacity(qreal opacity) { _opacity = opacity; }
|
||||||
|
qreal ColorScheme::opacity() const { return _opacity; }
|
||||||
|
|
||||||
|
void ColorScheme::read(const QString & fileName)
|
||||||
|
{
|
||||||
|
QSettings s(fileName, QSettings::IniFormat);
|
||||||
|
s.beginGroup("General");
|
||||||
|
|
||||||
|
_description = s.value("Description", QObject::tr("Un-named Color Scheme")).toString();
|
||||||
|
_opacity = s.value("Opacity",qreal(1.0)).toDouble();
|
||||||
|
s.endGroup();
|
||||||
|
|
||||||
|
for (int i=0 ; i < TABLE_COLORS ; i++)
|
||||||
|
{
|
||||||
|
readColorEntry(&s, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
// implemented upstream - user apps
|
||||||
|
void ColorScheme::read(KConfig& config)
|
||||||
|
{
|
||||||
|
KConfigGroup configGroup = config.group("General");
|
||||||
|
|
||||||
|
QString description = configGroup.readEntry("Description", QObject::tr("Un-named Color Scheme"));
|
||||||
|
|
||||||
|
_description = tr(description.toUtf8());
|
||||||
|
_opacity = configGroup.readEntry("Opacity",qreal(1.0));
|
||||||
|
|
||||||
|
for (int i=0 ; i < TABLE_COLORS ; i++)
|
||||||
|
{
|
||||||
|
readColorEntry(config,i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ColorScheme::write(KConfig& config) const
|
||||||
|
{
|
||||||
|
KConfigGroup configGroup = config.group("General");
|
||||||
|
|
||||||
|
configGroup.writeEntry("Description",_description);
|
||||||
|
configGroup.writeEntry("Opacity",_opacity);
|
||||||
|
|
||||||
|
for (int i=0 ; i < TABLE_COLORS ; i++)
|
||||||
|
{
|
||||||
|
RandomizationRange random = _randomTable != 0 ? _randomTable[i] : RandomizationRange();
|
||||||
|
writeColorEntry(config,colorNameForIndex(i),colorTable()[i],random);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QString ColorScheme::colorNameForIndex(int index)
|
||||||
|
{
|
||||||
|
Q_ASSERT( index >= 0 && index < TABLE_COLORS );
|
||||||
|
|
||||||
|
return QString(colorNames[index]);
|
||||||
|
}
|
||||||
|
QString ColorScheme::translatedColorNameForIndex(int index)
|
||||||
|
{
|
||||||
|
Q_ASSERT( index >= 0 && index < TABLE_COLORS );
|
||||||
|
|
||||||
|
return translatedColorNames[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ColorScheme::readColorEntry(QSettings * s , int index)
|
||||||
|
{
|
||||||
|
s->beginGroup(colorNameForIndex(index));
|
||||||
|
|
||||||
|
ColorEntry entry;
|
||||||
|
|
||||||
|
QStringList rgbList = s->value("Color", QStringList()).toStringList();
|
||||||
|
if (rgbList.count() != 3)
|
||||||
|
{
|
||||||
|
Q_ASSERT(0);
|
||||||
|
}
|
||||||
|
int r, g, b;
|
||||||
|
r = rgbList[0].toInt();
|
||||||
|
g = rgbList[1].toInt();
|
||||||
|
b = rgbList[2].toInt();
|
||||||
|
entry.color = QColor(r, g, b);
|
||||||
|
|
||||||
|
entry.transparent = s->value("Transparent",false).toBool();
|
||||||
|
|
||||||
|
// Deprecated key from KDE 4.0 which set 'Bold' to true to force
|
||||||
|
// a color to be bold or false to use the current format
|
||||||
|
//
|
||||||
|
// TODO - Add a new tri-state key which allows for bold, normal or
|
||||||
|
// current format
|
||||||
|
if (s->contains("Bold"))
|
||||||
|
entry.fontWeight = s->value("Bold",false).toBool() ? ColorEntry::Bold :
|
||||||
|
ColorEntry::UseCurrentFormat;
|
||||||
|
|
||||||
|
quint16 hue = s->value("MaxRandomHue",0).toInt();
|
||||||
|
quint8 value = s->value("MaxRandomValue",0).toInt();
|
||||||
|
quint8 saturation = s->value("MaxRandomSaturation",0).toInt();
|
||||||
|
|
||||||
|
setColorTableEntry( index , entry );
|
||||||
|
|
||||||
|
if ( hue != 0 || value != 0 || saturation != 0 )
|
||||||
|
setRandomizationRange( index , hue , saturation , value );
|
||||||
|
|
||||||
|
s->endGroup();
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
// implemented upstream - user apps
|
||||||
|
void ColorScheme::writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry , const RandomizationRange& random) const
|
||||||
|
{
|
||||||
|
KConfigGroup configGroup(&config,colorName);
|
||||||
|
|
||||||
|
configGroup.writeEntry("Color",entry.color);
|
||||||
|
configGroup.writeEntry("Transparency",(bool)entry.transparent);
|
||||||
|
if (entry.fontWeight != ColorEntry::UseCurrentFormat)
|
||||||
|
{
|
||||||
|
configGroup.writeEntry("Bold",entry.fontWeight == ColorEntry::Bold);
|
||||||
|
}
|
||||||
|
|
||||||
|
// record randomization if this color has randomization or
|
||||||
|
// if one of the keys already exists
|
||||||
|
if ( !random.isNull() || configGroup.hasKey("MaxRandomHue") )
|
||||||
|
{
|
||||||
|
configGroup.writeEntry("MaxRandomHue",(int)random.hue);
|
||||||
|
configGroup.writeEntry("MaxRandomValue",(int)random.value);
|
||||||
|
configGroup.writeEntry("MaxRandomSaturation",(int)random.saturation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Work In Progress - A color scheme for use on KDE setups for users
|
||||||
|
// with visual disabilities which means that they may have trouble
|
||||||
|
// reading text with the supplied color schemes.
|
||||||
|
//
|
||||||
|
// This color scheme uses only the 'safe' colors defined by the
|
||||||
|
// KColorScheme class.
|
||||||
|
//
|
||||||
|
// A complication this introduces is that each color provided by
|
||||||
|
// KColorScheme is defined as a 'background' or 'foreground' color.
|
||||||
|
// Only foreground colors are allowed to be used to render text and
|
||||||
|
// only background colors are allowed to be used for backgrounds.
|
||||||
|
//
|
||||||
|
// The ColorEntry and TerminalDisplay classes do not currently
|
||||||
|
// support this restriction.
|
||||||
|
//
|
||||||
|
// Requirements:
|
||||||
|
// - A color scheme which uses only colors from the KColorScheme class
|
||||||
|
// - Ability to restrict which colors the TerminalDisplay widget
|
||||||
|
// uses as foreground and background color
|
||||||
|
// - Make use of KGlobalSettings::allowDefaultBackgroundImages() as
|
||||||
|
// a hint to determine whether this accessible color scheme should
|
||||||
|
// be used by default.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- Robert Knight <robertknight@gmail.com> 21/07/2007
|
||||||
|
//
|
||||||
|
AccessibleColorScheme::AccessibleColorScheme()
|
||||||
|
: ColorScheme()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
// It's not finished in konsole and it breaks Qt4 compilation as well
|
||||||
|
// basic attributes
|
||||||
|
setName("accessible");
|
||||||
|
setDescription(QObject::tr("Accessible Color Scheme"));
|
||||||
|
|
||||||
|
// setup colors
|
||||||
|
const int ColorRoleCount = 8;
|
||||||
|
|
||||||
|
const KColorScheme colorScheme(QPalette::Active);
|
||||||
|
|
||||||
|
QBrush colors[ColorRoleCount] =
|
||||||
|
{
|
||||||
|
colorScheme.foreground( colorScheme.NormalText ),
|
||||||
|
colorScheme.background( colorScheme.NormalBackground ),
|
||||||
|
|
||||||
|
colorScheme.foreground( colorScheme.InactiveText ),
|
||||||
|
colorScheme.foreground( colorScheme.ActiveText ),
|
||||||
|
colorScheme.foreground( colorScheme.LinkText ),
|
||||||
|
colorScheme.foreground( colorScheme.VisitedText ),
|
||||||
|
colorScheme.foreground( colorScheme.NegativeText ),
|
||||||
|
colorScheme.foreground( colorScheme.NeutralText )
|
||||||
|
};
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < TABLE_COLORS ; i++ )
|
||||||
|
{
|
||||||
|
ColorEntry entry;
|
||||||
|
entry.color = colors[ i % ColorRoleCount ].color();
|
||||||
|
|
||||||
|
setColorTableEntry( i , entry );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
KDE3ColorSchemeReader::KDE3ColorSchemeReader( QIODevice* device ) :
|
||||||
|
_device(device)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ColorScheme* KDE3ColorSchemeReader::read()
|
||||||
|
{
|
||||||
|
Q_ASSERT( _device->openMode() == QIODevice::ReadOnly ||
|
||||||
|
_device->openMode() == QIODevice::ReadWrite );
|
||||||
|
|
||||||
|
ColorScheme* scheme = new ColorScheme();
|
||||||
|
|
||||||
|
QRegExp comment("#.*$");
|
||||||
|
while ( !_device->atEnd() )
|
||||||
|
{
|
||||||
|
QString line(_device->readLine());
|
||||||
|
line.remove(comment);
|
||||||
|
line = line.simplified();
|
||||||
|
|
||||||
|
if ( line.isEmpty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( line.startsWith(QLatin1String("color")) )
|
||||||
|
{
|
||||||
|
if (!readColorLine(line,scheme))
|
||||||
|
qDebug() << "Failed to read KDE 3 color scheme line" << line;
|
||||||
|
}
|
||||||
|
else if ( line.startsWith(QLatin1String("title")) )
|
||||||
|
{
|
||||||
|
if (!readTitleLine(line,scheme))
|
||||||
|
qDebug() << "Failed to read KDE 3 color scheme title line" << line;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "KDE 3 color scheme contains an unsupported feature, '" <<
|
||||||
|
line << "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return scheme;
|
||||||
|
}
|
||||||
|
bool KDE3ColorSchemeReader::readColorLine(const QString& line,ColorScheme* scheme)
|
||||||
|
{
|
||||||
|
QStringList list = line.split(QChar(' '));
|
||||||
|
|
||||||
|
if (list.count() != 7)
|
||||||
|
return false;
|
||||||
|
if (list.first() != "color")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int index = list[1].toInt();
|
||||||
|
int red = list[2].toInt();
|
||||||
|
int green = list[3].toInt();
|
||||||
|
int blue = list[4].toInt();
|
||||||
|
int transparent = list[5].toInt();
|
||||||
|
int bold = list[6].toInt();
|
||||||
|
|
||||||
|
const int MAX_COLOR_VALUE = 255;
|
||||||
|
|
||||||
|
if( (index < 0 || index >= TABLE_COLORS )
|
||||||
|
|| (red < 0 || red > MAX_COLOR_VALUE )
|
||||||
|
|| (blue < 0 || blue > MAX_COLOR_VALUE )
|
||||||
|
|| (green < 0 || green > MAX_COLOR_VALUE )
|
||||||
|
|| (transparent != 0 && transparent != 1 )
|
||||||
|
|| (bold != 0 && bold != 1) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ColorEntry entry;
|
||||||
|
entry.color = QColor(red,green,blue);
|
||||||
|
entry.transparent = ( transparent != 0 );
|
||||||
|
entry.fontWeight = ( bold != 0 ) ? ColorEntry::Bold : ColorEntry::UseCurrentFormat;
|
||||||
|
|
||||||
|
scheme->setColorTableEntry(index,entry);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool KDE3ColorSchemeReader::readTitleLine(const QString& line,ColorScheme* scheme)
|
||||||
|
{
|
||||||
|
if( !line.startsWith(QLatin1String("title")) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int spacePos = line.indexOf(' ');
|
||||||
|
if( spacePos == -1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QString description = line.mid(spacePos+1);
|
||||||
|
|
||||||
|
scheme->setDescription(description.toUtf8());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ColorSchemeManager::ColorSchemeManager()
|
||||||
|
: _haveLoadedAll(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ColorSchemeManager::~ColorSchemeManager()
|
||||||
|
{
|
||||||
|
QHashIterator<QString,const ColorScheme*> iter(_colorSchemes);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
iter.next();
|
||||||
|
delete iter.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ColorSchemeManager::loadAllColorSchemes()
|
||||||
|
{
|
||||||
|
qDebug() << "loadAllColorSchemes";
|
||||||
|
int success = 0;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
QList<QString> nativeColorSchemes = listColorSchemes();
|
||||||
|
|
||||||
|
QListIterator<QString> nativeIter(nativeColorSchemes);
|
||||||
|
while ( nativeIter.hasNext() )
|
||||||
|
{
|
||||||
|
if ( loadColorScheme( nativeIter.next() ) )
|
||||||
|
success++;
|
||||||
|
else
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> kde3ColorSchemes = listKDE3ColorSchemes();
|
||||||
|
QListIterator<QString> kde3Iter(kde3ColorSchemes);
|
||||||
|
while ( kde3Iter.hasNext() )
|
||||||
|
{
|
||||||
|
if ( loadKDE3ColorScheme( kde3Iter.next() ) )
|
||||||
|
success++;
|
||||||
|
else
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( failed > 0 )
|
||||||
|
qDebug() << "failed to load " << failed << " color schemes.";
|
||||||
|
|
||||||
|
_haveLoadedAll = true;
|
||||||
|
}
|
||||||
|
QList<const ColorScheme*> ColorSchemeManager::allColorSchemes()
|
||||||
|
{
|
||||||
|
if ( !_haveLoadedAll )
|
||||||
|
{
|
||||||
|
loadAllColorSchemes();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _colorSchemes.values();
|
||||||
|
}
|
||||||
|
bool ColorSchemeManager::loadKDE3ColorScheme(const QString& filePath)
|
||||||
|
{
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!filePath.endsWith(QLatin1String(".schema")) || !file.open(QIODevice::ReadOnly))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
KDE3ColorSchemeReader reader(&file);
|
||||||
|
ColorScheme* scheme = reader.read();
|
||||||
|
scheme->setName(QFileInfo(file).baseName());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
if (scheme->name().isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "color scheme name is not valid.";
|
||||||
|
delete scheme;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo info(filePath);
|
||||||
|
|
||||||
|
if ( !_colorSchemes.contains(info.baseName()) )
|
||||||
|
_colorSchemes.insert(scheme->name(),scheme);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "color scheme with name" << scheme->name() << "has already been" <<
|
||||||
|
"found, ignoring.";
|
||||||
|
delete scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
void ColorSchemeManager::addColorScheme(ColorScheme* scheme)
|
||||||
|
{
|
||||||
|
_colorSchemes.insert(scheme->name(),scheme);
|
||||||
|
|
||||||
|
// save changes to disk
|
||||||
|
QString path = KGlobal::dirs()->saveLocation("data","konsole/") + scheme->name() + ".colorscheme";
|
||||||
|
KConfig config(path , KConfig::NoGlobals);
|
||||||
|
|
||||||
|
scheme->write(config);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ColorSchemeManager::loadCustomColorScheme(const QString& path)
|
||||||
|
{
|
||||||
|
if (path.endsWith(QLatin1String(".colorscheme")))
|
||||||
|
return loadColorScheme(path);
|
||||||
|
else if (path.endsWith(QLatin1String(".schema")))
|
||||||
|
return loadKDE3ColorScheme(path);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ColorSchemeManager::loadColorScheme(const QString& filePath)
|
||||||
|
{
|
||||||
|
if ( !filePath.endsWith(QLatin1String(".colorscheme")) || !QFile::exists(filePath) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QFileInfo info(filePath);
|
||||||
|
|
||||||
|
const QString& schemeName = info.baseName();
|
||||||
|
|
||||||
|
ColorScheme* scheme = new ColorScheme();
|
||||||
|
scheme->setName(schemeName);
|
||||||
|
scheme->read(filePath);
|
||||||
|
|
||||||
|
if (scheme->name().isEmpty())
|
||||||
|
{
|
||||||
|
qDebug() << "Color scheme in" << filePath << "does not have a valid name and was not loaded.";
|
||||||
|
delete scheme;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !_colorSchemes.contains(schemeName) )
|
||||||
|
{
|
||||||
|
_colorSchemes.insert(schemeName,scheme);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "color scheme with name" << schemeName << "has already been" <<
|
||||||
|
"found, ignoring.";
|
||||||
|
|
||||||
|
delete scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
QList<QString> ColorSchemeManager::listKDE3ColorSchemes()
|
||||||
|
{
|
||||||
|
QString dname(get_color_schemes_dir());
|
||||||
|
QDir dir(dname);
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.schema";
|
||||||
|
dir.setNameFilters(filters);
|
||||||
|
QStringList list = dir.entryList(filters);
|
||||||
|
QStringList ret;
|
||||||
|
foreach(QString i, list)
|
||||||
|
ret << dname + "/" + i;
|
||||||
|
return ret;
|
||||||
|
//return KGlobal::dirs()->findAllResources("data",
|
||||||
|
// "konsole/*.schema",
|
||||||
|
// KStandardDirs::NoDuplicates);
|
||||||
|
//
|
||||||
|
}
|
||||||
|
QList<QString> ColorSchemeManager::listColorSchemes()
|
||||||
|
{
|
||||||
|
QString dname(get_color_schemes_dir());
|
||||||
|
QDir dir(dname);
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.colorscheme";
|
||||||
|
dir.setNameFilters(filters);
|
||||||
|
QStringList list = dir.entryList(filters);
|
||||||
|
QStringList ret;
|
||||||
|
foreach(QString i, list)
|
||||||
|
ret << dname + "/" + i;
|
||||||
|
return ret;
|
||||||
|
// return KGlobal::dirs()->findAllResources("data",
|
||||||
|
// "konsole/*.colorscheme",
|
||||||
|
// KStandardDirs::NoDuplicates);
|
||||||
|
}
|
||||||
|
const ColorScheme ColorSchemeManager::_defaultColorScheme;
|
||||||
|
const ColorScheme* ColorSchemeManager::defaultColorScheme() const
|
||||||
|
{
|
||||||
|
return &_defaultColorScheme;
|
||||||
|
}
|
||||||
|
bool ColorSchemeManager::deleteColorScheme(const QString& name)
|
||||||
|
{
|
||||||
|
Q_ASSERT( _colorSchemes.contains(name) );
|
||||||
|
|
||||||
|
// lookup the path and delete
|
||||||
|
QString path = findColorSchemePath(name);
|
||||||
|
if ( QFile::remove(path) )
|
||||||
|
{
|
||||||
|
_colorSchemes.remove(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Failed to remove color scheme -" << path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString ColorSchemeManager::findColorSchemePath(const QString& name) const
|
||||||
|
{
|
||||||
|
// QString path = KStandardDirs::locate("data","konsole/"+name+".colorscheme");
|
||||||
|
QString path(get_color_schemes_dir() + "/"+ name + ".colorscheme");
|
||||||
|
if ( !path.isEmpty() )
|
||||||
|
return path;
|
||||||
|
|
||||||
|
//path = KStandardDirs::locate("data","konsole/"+name+".schema");
|
||||||
|
path = get_color_schemes_dir() + "/"+ name + ".schema";
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
const ColorScheme* ColorSchemeManager::findColorScheme(const QString& name)
|
||||||
|
{
|
||||||
|
if ( name.isEmpty() )
|
||||||
|
return defaultColorScheme();
|
||||||
|
|
||||||
|
if ( _colorSchemes.contains(name) )
|
||||||
|
return _colorSchemes[name];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// look for this color scheme
|
||||||
|
QString path = findColorSchemePath(name);
|
||||||
|
if ( !path.isEmpty() && loadColorScheme(path) )
|
||||||
|
{
|
||||||
|
return findColorScheme(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!path.isEmpty() && loadKDE3ColorScheme(path))
|
||||||
|
return findColorScheme(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Could not find color scheme - " << name;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorSchemeManager* ColorSchemeManager::theColorSchemeManager = 0;
|
||||||
|
//K_GLOBAL_STATIC( ColorSchemeManager , theColorSchemeManager )
|
||||||
|
ColorSchemeManager* ColorSchemeManager::instance()
|
||||||
|
{
|
||||||
|
if (! theColorSchemeManager)
|
||||||
|
theColorSchemeManager = new ColorSchemeManager();
|
||||||
|
return theColorSchemeManager;
|
||||||
|
}
|
@ -0,0 +1,359 @@
|
|||||||
|
/*
|
||||||
|
This source file is part of Konsole, a terminal emulator.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COLORSCHEME_H
|
||||||
|
#define COLORSCHEME_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QHash>
|
||||||
|
#include <QList>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "CharacterColor.h"
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
//class KConfig;
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a color scheme for a terminal display.
|
||||||
|
*
|
||||||
|
* The color scheme includes the palette of colors used to draw the text and character backgrounds
|
||||||
|
* in the display and the opacity level of the display background.
|
||||||
|
*/
|
||||||
|
class ColorScheme
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new color scheme which is initialised to the default color set
|
||||||
|
* for Konsole.
|
||||||
|
*/
|
||||||
|
ColorScheme();
|
||||||
|
ColorScheme(const ColorScheme& other);
|
||||||
|
~ColorScheme();
|
||||||
|
|
||||||
|
/** Sets the descriptive name of the color scheme. */
|
||||||
|
void setDescription(const QString& description);
|
||||||
|
/** Returns the descriptive name of the color scheme. */
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
/** Sets the name of the color scheme */
|
||||||
|
void setName(const QString& name);
|
||||||
|
/** Returns the name of the color scheme */
|
||||||
|
QString name() const;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Implemented upstream - in user apps
|
||||||
|
/** Reads the color scheme from the specified configuration source */
|
||||||
|
void read(KConfig& config);
|
||||||
|
/** Writes the color scheme to the specified configuration source */
|
||||||
|
void write(KConfig& config) const;
|
||||||
|
#endif
|
||||||
|
void read(const QString & filename);
|
||||||
|
|
||||||
|
/** Sets a single entry within the color palette. */
|
||||||
|
void setColorTableEntry(int index , const ColorEntry& entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the color entries which form the palette for this color scheme
|
||||||
|
* into @p table. @p table should be an array with TABLE_COLORS entries.
|
||||||
|
*
|
||||||
|
* @param table Array into which the color entries for this color scheme
|
||||||
|
* are copied.
|
||||||
|
* @param randomSeed Color schemes may allow certain colors in their
|
||||||
|
* palette to be randomized. The seed is used to pick the random color.
|
||||||
|
*/
|
||||||
|
void getColorTable(ColorEntry* table, uint randomSeed = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a single color entry from the table.
|
||||||
|
*
|
||||||
|
* See getColorTable()
|
||||||
|
*/
|
||||||
|
ColorEntry colorEntry(int index , uint randomSeed = 0) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method. Returns the
|
||||||
|
* foreground color for this scheme,
|
||||||
|
* this is the primary color used to draw the
|
||||||
|
* text in this scheme.
|
||||||
|
*/
|
||||||
|
QColor foregroundColor() const;
|
||||||
|
/**
|
||||||
|
* Convenience method. Returns the background color for
|
||||||
|
* this scheme, this is the primary color used to
|
||||||
|
* draw the terminal background in this scheme.
|
||||||
|
*/
|
||||||
|
QColor backgroundColor() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this color scheme has a dark background.
|
||||||
|
* The background color is said to be dark if it has a value of less than 127
|
||||||
|
* in the HSV color space.
|
||||||
|
*/
|
||||||
|
bool hasDarkBackground() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the opacity level of the display background. @p opacity ranges
|
||||||
|
* between 0 (completely transparent background) and 1 (completely
|
||||||
|
* opaque background).
|
||||||
|
*
|
||||||
|
* Defaults to 1.
|
||||||
|
*
|
||||||
|
* TODO: More documentation
|
||||||
|
*/
|
||||||
|
void setOpacity(qreal opacity);
|
||||||
|
/**
|
||||||
|
* Returns the opacity level for this color scheme, see setOpacity()
|
||||||
|
* TODO: More documentation
|
||||||
|
*/
|
||||||
|
qreal opacity() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables randomization of the background color. This will cause
|
||||||
|
* the palette returned by getColorTable() and colorEntry() to
|
||||||
|
* be adjusted depending on the value of the random seed argument
|
||||||
|
* to them.
|
||||||
|
*/
|
||||||
|
void setRandomizedBackgroundColor(bool randomize);
|
||||||
|
|
||||||
|
/** Returns true if the background color is randomized. */
|
||||||
|
bool randomizedBackgroundColor() const;
|
||||||
|
|
||||||
|
static QString colorNameForIndex(int index);
|
||||||
|
static QString translatedColorNameForIndex(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// specifies how much a particular color can be randomized by
|
||||||
|
class RandomizationRange
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RandomizationRange() : hue(0) , saturation(0) , value(0) {}
|
||||||
|
|
||||||
|
bool isNull() const
|
||||||
|
{
|
||||||
|
return ( hue == 0 && saturation == 0 && value == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 hue;
|
||||||
|
quint8 saturation;
|
||||||
|
quint8 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// returns the active color table. if none has been set specifically,
|
||||||
|
// this is the default color table.
|
||||||
|
const ColorEntry* colorTable() const;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// implemented upstream - user apps
|
||||||
|
// reads a single colour entry from a KConfig source
|
||||||
|
// and sets the palette entry at 'index' to the entry read.
|
||||||
|
void readColorEntry(KConfig& config , int index);
|
||||||
|
// writes a single colour entry to a KConfig source
|
||||||
|
void writeColorEntry(KConfig& config , const QString& colorName, const ColorEntry& entry,const RandomizationRange& range) const;
|
||||||
|
#endif
|
||||||
|
void readColorEntry(QSettings *s, int index);
|
||||||
|
|
||||||
|
// sets the amount of randomization allowed for a particular color
|
||||||
|
// in the palette. creates the randomization table if
|
||||||
|
// it does not already exist
|
||||||
|
void setRandomizationRange( int index , quint16 hue , quint8 saturation , quint8 value );
|
||||||
|
|
||||||
|
QString _description;
|
||||||
|
QString _name;
|
||||||
|
qreal _opacity;
|
||||||
|
ColorEntry* _table; // pointer to custom color table or 0 if the default
|
||||||
|
// color scheme is being used
|
||||||
|
|
||||||
|
|
||||||
|
static const quint16 MAX_HUE = 340;
|
||||||
|
|
||||||
|
RandomizationRange* _randomTable; // pointer to randomization table or 0
|
||||||
|
// if no colors in the color scheme support
|
||||||
|
// randomization
|
||||||
|
|
||||||
|
static const char* const colorNames[TABLE_COLORS];
|
||||||
|
static const char* const translatedColorNames[TABLE_COLORS];
|
||||||
|
|
||||||
|
static const ColorEntry defaultTable[]; // table of default color entries
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A color scheme which uses colors from the standard KDE color palette.
|
||||||
|
*
|
||||||
|
* This is designed primarily for the benefit of users who are using specially
|
||||||
|
* designed colors.
|
||||||
|
*
|
||||||
|
* TODO Implement and make it the default on systems with specialized KDE
|
||||||
|
* color schemes.
|
||||||
|
*/
|
||||||
|
class AccessibleColorScheme : public ColorScheme
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AccessibleColorScheme();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a color scheme stored in the .schema format used in the KDE 3 incarnation
|
||||||
|
* of Konsole
|
||||||
|
*
|
||||||
|
* Only the basic essentials ( title and color palette entries ) are currently
|
||||||
|
* supported. Additional options such as background image and background
|
||||||
|
* blend colors are ignored.
|
||||||
|
*/
|
||||||
|
class KDE3ColorSchemeReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new reader which reads from the specified device.
|
||||||
|
* The device should be open in read-only mode.
|
||||||
|
*/
|
||||||
|
KDE3ColorSchemeReader( QIODevice* device );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and parses the contents of the .schema file from the input
|
||||||
|
* device and returns the ColorScheme defined within it.
|
||||||
|
*
|
||||||
|
* Returns a null pointer if an error occurs whilst parsing
|
||||||
|
* the contents of the file.
|
||||||
|
*/
|
||||||
|
ColorScheme* read();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// reads a line from the file specifying a colour palette entry
|
||||||
|
// format is: color [index] [red] [green] [blue] [transparent] [bold]
|
||||||
|
bool readColorLine(const QString& line , ColorScheme* scheme);
|
||||||
|
bool readTitleLine(const QString& line , ColorScheme* scheme);
|
||||||
|
|
||||||
|
QIODevice* _device;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the color schemes available for use by terminal displays.
|
||||||
|
* See ColorScheme
|
||||||
|
*/
|
||||||
|
class ColorSchemeManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ColorSchemeManager and loads the list
|
||||||
|
* of available color schemes.
|
||||||
|
*
|
||||||
|
* The color schemes themselves are not loaded until they are first
|
||||||
|
* requested via a call to findColorScheme()
|
||||||
|
*/
|
||||||
|
ColorSchemeManager();
|
||||||
|
/**
|
||||||
|
* Destroys the ColorSchemeManager and saves any modified color schemes to disk.
|
||||||
|
*/
|
||||||
|
~ColorSchemeManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default color scheme for Konsole
|
||||||
|
*/
|
||||||
|
const ColorScheme* defaultColorScheme() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the color scheme with the given name or 0 if no
|
||||||
|
* scheme with that name exists. If @p name is empty, the
|
||||||
|
* default color scheme is returned.
|
||||||
|
*
|
||||||
|
* The first time that a color scheme with a particular name is
|
||||||
|
* requested, the configuration information is loaded from disk.
|
||||||
|
*/
|
||||||
|
const ColorScheme* findColorScheme(const QString& name);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/**
|
||||||
|
* Adds a new color scheme to the manager. If @p scheme has the same name as
|
||||||
|
* an existing color scheme, it replaces the existing scheme.
|
||||||
|
*
|
||||||
|
* TODO - Ensure the old color scheme gets deleted
|
||||||
|
*/
|
||||||
|
void addColorScheme(ColorScheme* scheme);
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Deletes a color scheme. Returns true on successful deletion or false otherwise.
|
||||||
|
*/
|
||||||
|
bool deleteColorScheme(const QString& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of the all the available color schemes.
|
||||||
|
* This may be slow when first called because all of the color
|
||||||
|
* scheme resources on disk must be located, read and parsed.
|
||||||
|
*
|
||||||
|
* Subsequent calls will be inexpensive.
|
||||||
|
*/
|
||||||
|
QList<const ColorScheme*> allColorSchemes();
|
||||||
|
|
||||||
|
/** Returns the global color scheme manager instance. */
|
||||||
|
static ColorSchemeManager* instance();
|
||||||
|
|
||||||
|
/** @brief Loads a custom color scheme under given \em path.
|
||||||
|
*
|
||||||
|
* The \em path may refer to either KDE 4 .colorscheme or KDE 3
|
||||||
|
* .schema file
|
||||||
|
*
|
||||||
|
* The loaded color scheme is available under the name equal to
|
||||||
|
* the base name of the \em path via the allColorSchemes() and
|
||||||
|
* findColorScheme() methods after this call if loaded successfully.
|
||||||
|
*
|
||||||
|
* @param[in] path The path to KDE 4 .colorscheme or KDE 3 .schema.
|
||||||
|
* @return Whether the color scheme is loaded successfully.
|
||||||
|
*/
|
||||||
|
bool loadCustomColorScheme(const QString& path);
|
||||||
|
private:
|
||||||
|
// loads a color scheme from a KDE 4+ .colorscheme file
|
||||||
|
bool loadColorScheme(const QString& path);
|
||||||
|
// loads a color scheme from a KDE 3 .schema file
|
||||||
|
bool loadKDE3ColorScheme(const QString& path);
|
||||||
|
// returns a list of paths of color schemes in the KDE 4+ .colorscheme file format
|
||||||
|
QList<QString> listColorSchemes();
|
||||||
|
// returns a list of paths of color schemes in the .schema file format
|
||||||
|
// used in KDE 3
|
||||||
|
QList<QString> listKDE3ColorSchemes();
|
||||||
|
// loads all of the color schemes
|
||||||
|
void loadAllColorSchemes();
|
||||||
|
// finds the path of a color scheme
|
||||||
|
QString findColorSchemePath(const QString& name) const;
|
||||||
|
|
||||||
|
QHash<QString,const ColorScheme*> _colorSchemes;
|
||||||
|
QSet<ColorScheme*> _modifiedSchemes;
|
||||||
|
|
||||||
|
bool _haveLoadedAll;
|
||||||
|
|
||||||
|
static const ColorScheme _defaultColorScheme;
|
||||||
|
|
||||||
|
static ColorSchemeManager * theColorSchemeManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(const Konsole::ColorScheme*)
|
||||||
|
|
||||||
|
#endif //COLORSCHEME_H
|
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef _COLOR_TABLE_H
|
||||||
|
#define _COLOR_TABLE_H
|
||||||
|
|
||||||
|
#include "CharacterColor.h"
|
||||||
|
|
||||||
|
//using namespace Konsole;
|
||||||
|
#if 0
|
||||||
|
static const ColorEntry whiteonblack_color_table[TABLE_COLORS] = {
|
||||||
|
// normal
|
||||||
|
ColorEntry(QColor(0xFF,0xFF,0xFF), false ), ColorEntry( QColor(0x00,0x00,0x00), true ), // Dfore, Dback
|
||||||
|
ColorEntry(QColor(0x00,0x00,0x00), false ), ColorEntry( QColor(0xB2,0x18,0x18), false ), // Black, Red
|
||||||
|
ColorEntry(QColor(0x18,0xB2,0x18), false ), ColorEntry( QColor(0xB2,0x68,0x18), false ), // Green, Yellow
|
||||||
|
ColorEntry(QColor(0x18,0x18,0xB2), false ), ColorEntry( QColor(0xB2,0x18,0xB2), false ), // Blue, Magenta
|
||||||
|
ColorEntry(QColor(0x18,0xB2,0xB2), false ), ColorEntry( QColor(0xB2,0xB2,0xB2), false ), // Cyan, White
|
||||||
|
// intensiv
|
||||||
|
ColorEntry(QColor(0x00,0x00,0x00), false ), ColorEntry( QColor(0xFF,0xFF,0xFF), true ),
|
||||||
|
ColorEntry(QColor(0x68,0x68,0x68), false ), ColorEntry( QColor(0xFF,0x54,0x54), false ),
|
||||||
|
ColorEntry(QColor(0x54,0xFF,0x54), false ), ColorEntry( QColor(0xFF,0xFF,0x54), false ),
|
||||||
|
ColorEntry(QColor(0x54,0x54,0xFF), false ), ColorEntry( QColor(0xFF,0x54,0xFF), false ),
|
||||||
|
ColorEntry(QColor(0x54,0xFF,0xFF), false ), ColorEntry( QColor(0xFF,0xFF,0xFF), false )
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ColorEntry greenonblack_color_table[TABLE_COLORS] = {
|
||||||
|
ColorEntry(QColor( 24, 240, 24), false), ColorEntry(QColor( 0, 0, 0), true),
|
||||||
|
ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 178, 24, 24), false),
|
||||||
|
ColorEntry(QColor( 24, 178, 24), false), ColorEntry(QColor( 178, 104, 24), false),
|
||||||
|
ColorEntry(QColor( 24, 24, 178), false), ColorEntry(QColor( 178, 24, 178), false),
|
||||||
|
ColorEntry(QColor( 24, 178, 178), false), ColorEntry(QColor( 178, 178, 178), false),
|
||||||
|
// intensive colors
|
||||||
|
ColorEntry(QColor( 24, 240, 24), false ), ColorEntry(QColor( 0, 0, 0), true ),
|
||||||
|
ColorEntry(QColor( 104, 104, 104), false ), ColorEntry(QColor( 255, 84, 84), false ),
|
||||||
|
ColorEntry(QColor( 84, 255, 84), false ), ColorEntry(QColor( 255, 255, 84), false ),
|
||||||
|
ColorEntry(QColor( 84, 84, 255), false ), ColorEntry(QColor( 255, 84, 255), false ),
|
||||||
|
ColorEntry(QColor( 84, 255, 255), false ), ColorEntry(QColor( 255, 255, 255), false )
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ColorEntry blackonlightyellow_color_table[TABLE_COLORS] = {
|
||||||
|
ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 255, 255, 221), true),
|
||||||
|
ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 178, 24, 24), false),
|
||||||
|
ColorEntry(QColor( 24, 178, 24), false), ColorEntry(QColor( 178, 104, 24), false),
|
||||||
|
ColorEntry(QColor( 24, 24, 178), false), ColorEntry(QColor( 178, 24, 178), false),
|
||||||
|
ColorEntry(QColor( 24, 178, 178), false), ColorEntry(QColor( 178, 178, 178), false),
|
||||||
|
ColorEntry(QColor( 0, 0, 0), false), ColorEntry(QColor( 255, 255, 221), true),
|
||||||
|
ColorEntry(QColor(104, 104, 104), false), ColorEntry(QColor( 255, 84, 84), false),
|
||||||
|
ColorEntry(QColor( 84, 255, 84), false), ColorEntry(QColor( 255, 255, 84), false),
|
||||||
|
ColorEntry(QColor( 84, 84, 255), false), ColorEntry(QColor( 255, 84, 255), false),
|
||||||
|
ColorEntry(QColor( 84, 255, 255), false), ColorEntry(QColor( 255, 255, 255), false)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
"keyboard \"Fallback Key Translator\"\n"
|
||||||
|
"key Tab : \"\\t\" \0"
|
@ -0,0 +1,460 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007-2008 Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
Copyright 1996 by Matthias Ettrich <ettrich@kde.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "Emulation.h"
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <kdebug.h>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "KeyboardTranslator.h"
|
||||||
|
#include "Screen.h"
|
||||||
|
#include "TerminalCharacterDecoder.h"
|
||||||
|
#include "ScreenWindow.h"
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
Emulation::Emulation() :
|
||||||
|
_currentScreen(0),
|
||||||
|
_codec(0),
|
||||||
|
_decoder(0),
|
||||||
|
_keyTranslator(0),
|
||||||
|
_usesMouse(false)
|
||||||
|
{
|
||||||
|
// create screens with a default size
|
||||||
|
_screen[0] = new Screen(40,80);
|
||||||
|
_screen[1] = new Screen(40,80);
|
||||||
|
_currentScreen = _screen[0];
|
||||||
|
|
||||||
|
QObject::connect(&_bulkTimer1, SIGNAL(timeout()), this, SLOT(showBulk()) );
|
||||||
|
QObject::connect(&_bulkTimer2, SIGNAL(timeout()), this, SLOT(showBulk()) );
|
||||||
|
|
||||||
|
// listen for mouse status changes
|
||||||
|
connect( this , SIGNAL(programUsesMouseChanged(bool)) ,
|
||||||
|
SLOT(usesMouseChanged(bool)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Emulation::programUsesMouse() const
|
||||||
|
{
|
||||||
|
return _usesMouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::usesMouseChanged(bool usesMouse)
|
||||||
|
{
|
||||||
|
_usesMouse = usesMouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenWindow* Emulation::createWindow()
|
||||||
|
{
|
||||||
|
ScreenWindow* window = new ScreenWindow();
|
||||||
|
window->setScreen(_currentScreen);
|
||||||
|
_windows << window;
|
||||||
|
|
||||||
|
connect(window , SIGNAL(selectionChanged()),
|
||||||
|
this , SLOT(bufferedUpdate()));
|
||||||
|
|
||||||
|
connect(this , SIGNAL(outputChanged()),
|
||||||
|
window , SLOT(notifyOutputChanged()) );
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
Emulation::~Emulation()
|
||||||
|
{
|
||||||
|
QListIterator<ScreenWindow*> windowIter(_windows);
|
||||||
|
|
||||||
|
while (windowIter.hasNext())
|
||||||
|
{
|
||||||
|
delete windowIter.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete _screen[0];
|
||||||
|
delete _screen[1];
|
||||||
|
delete _decoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::setScreen(int n)
|
||||||
|
{
|
||||||
|
Screen *old = _currentScreen;
|
||||||
|
_currentScreen = _screen[n & 1];
|
||||||
|
if (_currentScreen != old)
|
||||||
|
{
|
||||||
|
// tell all windows onto this emulation to switch to the newly active screen
|
||||||
|
foreach(ScreenWindow* window,_windows)
|
||||||
|
window->setScreen(_currentScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::clearHistory()
|
||||||
|
{
|
||||||
|
_screen[0]->setScroll( _screen[0]->getScroll() , false );
|
||||||
|
}
|
||||||
|
void Emulation::setHistory(const HistoryType& t)
|
||||||
|
{
|
||||||
|
_screen[0]->setScroll(t);
|
||||||
|
|
||||||
|
showBulk();
|
||||||
|
}
|
||||||
|
|
||||||
|
const HistoryType& Emulation::history() const
|
||||||
|
{
|
||||||
|
return _screen[0]->getScroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::setCodec(const QTextCodec * qtc)
|
||||||
|
{
|
||||||
|
if (qtc)
|
||||||
|
_codec = qtc;
|
||||||
|
else
|
||||||
|
setCodec(LocaleCodec);
|
||||||
|
|
||||||
|
delete _decoder;
|
||||||
|
_decoder = _codec->makeDecoder();
|
||||||
|
|
||||||
|
emit useUtf8Request(utf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::setCodec(EmulationCodec codec)
|
||||||
|
{
|
||||||
|
if ( codec == Utf8Codec )
|
||||||
|
setCodec( QTextCodec::codecForName("utf8") );
|
||||||
|
else if ( codec == LocaleCodec )
|
||||||
|
setCodec( QTextCodec::codecForLocale() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::setKeyBindings(const QString& name)
|
||||||
|
{
|
||||||
|
_keyTranslator = KeyboardTranslatorManager::instance()->findTranslator(name);
|
||||||
|
if (!_keyTranslator)
|
||||||
|
{
|
||||||
|
_keyTranslator = KeyboardTranslatorManager::instance()->defaultTranslator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Emulation::keyBindings() const
|
||||||
|
{
|
||||||
|
return _keyTranslator->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::receiveChar(int c)
|
||||||
|
// process application unicode input to terminal
|
||||||
|
// this is a trivial scanner
|
||||||
|
{
|
||||||
|
c &= 0xff;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\b' : _currentScreen->backspace(); break;
|
||||||
|
case '\t' : _currentScreen->tab(); break;
|
||||||
|
case '\n' : _currentScreen->newLine(); break;
|
||||||
|
case '\r' : _currentScreen->toStartOfLine(); break;
|
||||||
|
case 0x07 : emit stateSet(NOTIFYBELL);
|
||||||
|
break;
|
||||||
|
default : _currentScreen->displayCharacter(c); break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::sendKeyEvent( QKeyEvent* ev )
|
||||||
|
{
|
||||||
|
emit stateSet(NOTIFYNORMAL);
|
||||||
|
|
||||||
|
if (!ev->text().isEmpty())
|
||||||
|
{ // A block of text
|
||||||
|
// Note that the text is proper unicode.
|
||||||
|
// We should do a conversion here
|
||||||
|
emit sendData(ev->text().toUtf8(),ev->text().length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::sendString(const char*,int)
|
||||||
|
{
|
||||||
|
// default implementation does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int /*eventType*/)
|
||||||
|
{
|
||||||
|
// default implementation does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
We are doing code conversion from locale to unicode first.
|
||||||
|
TODO: Character composition from the old code. See #96536
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Emulation::receiveData(const char* text, int length)
|
||||||
|
{
|
||||||
|
emit stateSet(NOTIFYACTIVITY);
|
||||||
|
|
||||||
|
bufferedUpdate();
|
||||||
|
|
||||||
|
QString unicodeText = _decoder->toUnicode(text,length);
|
||||||
|
|
||||||
|
//send characters to terminal emulator
|
||||||
|
for (int i=0;i<unicodeText.length();i++)
|
||||||
|
receiveChar(unicodeText[i].unicode());
|
||||||
|
|
||||||
|
//look for z-modem indicator
|
||||||
|
//-- someone who understands more about z-modems that I do may be able to move
|
||||||
|
//this check into the above for loop?
|
||||||
|
for (int i=0;i<length;i++)
|
||||||
|
{
|
||||||
|
if (text[i] == '\030')
|
||||||
|
{
|
||||||
|
if ((length-i-1 > 3) && (strncmp(text+i+1, "B00", 3) == 0))
|
||||||
|
emit zmodemDetected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//OLDER VERSION
|
||||||
|
//This version of onRcvBlock was commented out because
|
||||||
|
// a) It decoded incoming characters one-by-one, which is slow in the current version of Qt (4.2 tech preview)
|
||||||
|
// b) It messed up decoding of non-ASCII characters, with the result that (for example) chinese characters
|
||||||
|
// were not printed properly.
|
||||||
|
//
|
||||||
|
//There is something about stopping the _decoder if "we get a control code halfway a multi-byte sequence" (see below)
|
||||||
|
//which hasn't been ported into the newer function (above). Hopefully someone who understands this better
|
||||||
|
//can find an alternative way of handling the check.
|
||||||
|
|
||||||
|
|
||||||
|
/*void Emulation::onRcvBlock(const char *s, int len)
|
||||||
|
{
|
||||||
|
emit notifySessionState(NOTIFYACTIVITY);
|
||||||
|
|
||||||
|
bufferedUpdate();
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
QString result = _decoder->toUnicode(&s[i],1);
|
||||||
|
int reslen = result.length();
|
||||||
|
|
||||||
|
// If we get a control code halfway a multi-byte sequence
|
||||||
|
// we flush the _decoder and continue with the control code.
|
||||||
|
if ((s[i] < 32) && (s[i] > 0))
|
||||||
|
{
|
||||||
|
// Flush _decoder
|
||||||
|
while(!result.length())
|
||||||
|
result = _decoder->toUnicode(&s[i],1);
|
||||||
|
reslen = 1;
|
||||||
|
result.resize(reslen);
|
||||||
|
result[0] = QChar(s[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < reslen; j++)
|
||||||
|
{
|
||||||
|
if (result[j].characterategory() == QChar::Mark_NonSpacing)
|
||||||
|
_currentScreen->compose(result.mid(j,1));
|
||||||
|
else
|
||||||
|
onRcvChar(result[j].unicode());
|
||||||
|
}
|
||||||
|
if (s[i] == '\030')
|
||||||
|
{
|
||||||
|
if ((len-i-1 > 3) && (strncmp(s+i+1, "B00", 3) == 0))
|
||||||
|
emit zmodemDetected();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void Emulation::writeToStream( TerminalCharacterDecoder* _decoder ,
|
||||||
|
int startLine ,
|
||||||
|
int endLine)
|
||||||
|
{
|
||||||
|
_currentScreen->writeLinesToStream(_decoder,startLine,endLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Emulation::lineCount() const
|
||||||
|
{
|
||||||
|
// sum number of lines currently on _screen plus number of lines in history
|
||||||
|
return _currentScreen->getLines() + _currentScreen->getHistLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BULK_TIMEOUT1 10
|
||||||
|
#define BULK_TIMEOUT2 40
|
||||||
|
|
||||||
|
void Emulation::showBulk()
|
||||||
|
{
|
||||||
|
_bulkTimer1.stop();
|
||||||
|
_bulkTimer2.stop();
|
||||||
|
|
||||||
|
emit outputChanged();
|
||||||
|
|
||||||
|
_currentScreen->resetScrolledLines();
|
||||||
|
_currentScreen->resetDroppedLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::bufferedUpdate()
|
||||||
|
{
|
||||||
|
_bulkTimer1.setSingleShot(true);
|
||||||
|
_bulkTimer1.start(BULK_TIMEOUT1);
|
||||||
|
if (!_bulkTimer2.isActive())
|
||||||
|
{
|
||||||
|
_bulkTimer2.setSingleShot(true);
|
||||||
|
_bulkTimer2.start(BULK_TIMEOUT2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Emulation::eraseChar() const
|
||||||
|
{
|
||||||
|
return '\b';
|
||||||
|
}
|
||||||
|
|
||||||
|
void Emulation::setImageSize(int lines, int columns)
|
||||||
|
{
|
||||||
|
if ((lines < 1) || (columns < 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
QSize screenSize[2] = { QSize(_screen[0]->getColumns(),
|
||||||
|
_screen[0]->getLines()),
|
||||||
|
QSize(_screen[1]->getColumns(),
|
||||||
|
_screen[1]->getLines()) };
|
||||||
|
QSize newSize(columns,lines);
|
||||||
|
|
||||||
|
if (newSize == screenSize[0] && newSize == screenSize[1])
|
||||||
|
return;
|
||||||
|
|
||||||
|
_screen[0]->resizeImage(lines,columns);
|
||||||
|
_screen[1]->resizeImage(lines,columns);
|
||||||
|
|
||||||
|
emit imageSizeChanged(lines,columns);
|
||||||
|
|
||||||
|
bufferedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize Emulation::imageSize() const
|
||||||
|
{
|
||||||
|
return QSize(_currentScreen->getColumns(), _currentScreen->getLines());
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort ExtendedCharTable::extendedCharHash(ushort* unicodePoints , ushort length) const
|
||||||
|
{
|
||||||
|
ushort hash = 0;
|
||||||
|
for ( ushort i = 0 ; i < length ; i++ )
|
||||||
|
{
|
||||||
|
hash = 31*hash + unicodePoints[i];
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
bool ExtendedCharTable::extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const
|
||||||
|
{
|
||||||
|
ushort* entry = extendedCharTable[hash];
|
||||||
|
|
||||||
|
// compare given length with stored sequence length ( given as the first ushort in the
|
||||||
|
// stored buffer )
|
||||||
|
if ( entry == 0 || entry[0] != length )
|
||||||
|
return false;
|
||||||
|
// if the lengths match, each character must be checked. the stored buffer starts at
|
||||||
|
// entry[1]
|
||||||
|
for ( int i = 0 ; i < length ; i++ )
|
||||||
|
{
|
||||||
|
if ( entry[i+1] != unicodePoints[i] )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ushort ExtendedCharTable::createExtendedChar(ushort* unicodePoints , ushort length)
|
||||||
|
{
|
||||||
|
// look for this sequence of points in the table
|
||||||
|
ushort hash = extendedCharHash(unicodePoints,length);
|
||||||
|
|
||||||
|
// check existing entry for match
|
||||||
|
while ( extendedCharTable.contains(hash) )
|
||||||
|
{
|
||||||
|
if ( extendedCharMatch(hash,unicodePoints,length) )
|
||||||
|
{
|
||||||
|
// this sequence already has an entry in the table,
|
||||||
|
// return its hash
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if hash is already used by another, different sequence of unicode character
|
||||||
|
// points then try next hash
|
||||||
|
hash++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// add the new sequence to the table and
|
||||||
|
// return that index
|
||||||
|
ushort* buffer = new ushort[length+1];
|
||||||
|
buffer[0] = length;
|
||||||
|
for ( int i = 0 ; i < length ; i++ )
|
||||||
|
buffer[i+1] = unicodePoints[i];
|
||||||
|
|
||||||
|
extendedCharTable.insert(hash,buffer);
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort* ExtendedCharTable::lookupExtendedChar(ushort hash , ushort& length) const
|
||||||
|
{
|
||||||
|
// lookup index in table and if found, set the length
|
||||||
|
// argument and return a pointer to the character sequence
|
||||||
|
|
||||||
|
ushort* buffer = extendedCharTable[hash];
|
||||||
|
if ( buffer )
|
||||||
|
{
|
||||||
|
length = buffer[0];
|
||||||
|
return buffer+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedCharTable::ExtendedCharTable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ExtendedCharTable::~ExtendedCharTable()
|
||||||
|
{
|
||||||
|
// free all allocated character buffers
|
||||||
|
QHashIterator<ushort,ushort*> iter(extendedCharTable);
|
||||||
|
while ( iter.hasNext() )
|
||||||
|
{
|
||||||
|
iter.next();
|
||||||
|
delete[] iter.value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// global instance
|
||||||
|
ExtendedCharTable ExtendedCharTable::instance;
|
||||||
|
|
||||||
|
|
||||||
|
//#include "Emulation.moc"
|
||||||
|
|
@ -0,0 +1,471 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EMULATION_H
|
||||||
|
#define EMULATION_H
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QKeyEvent>
|
||||||
|
//#include <QPointer>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
//#include "konsole_export.h"
|
||||||
|
#define KONSOLEPRIVATE_EXPORT
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
class KeyboardTranslator;
|
||||||
|
class HistoryType;
|
||||||
|
class Screen;
|
||||||
|
class ScreenWindow;
|
||||||
|
class TerminalCharacterDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the available states which
|
||||||
|
* the terminal emulation may be set to.
|
||||||
|
*
|
||||||
|
* These are the values used by Emulation::stateChanged()
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/** The emulation is currently receiving user input. */
|
||||||
|
NOTIFYNORMAL=0,
|
||||||
|
/**
|
||||||
|
* The terminal program has triggered a bell event
|
||||||
|
* to get the user's attention.
|
||||||
|
*/
|
||||||
|
NOTIFYBELL=1,
|
||||||
|
/**
|
||||||
|
* The emulation is currently receiving data from its
|
||||||
|
* terminal input.
|
||||||
|
*/
|
||||||
|
NOTIFYACTIVITY=2,
|
||||||
|
|
||||||
|
// unused here?
|
||||||
|
NOTIFYSILENCE=3
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for terminal emulation back-ends.
|
||||||
|
*
|
||||||
|
* The back-end is responsible for decoding an incoming character stream and
|
||||||
|
* producing an output image of characters.
|
||||||
|
*
|
||||||
|
* When input from the terminal is received, the receiveData() slot should be called with
|
||||||
|
* the data which has arrived. The emulation will process the data and update the
|
||||||
|
* screen image accordingly. The codec used to decode the incoming character stream
|
||||||
|
* into the unicode characters used internally can be specified using setCodec()
|
||||||
|
*
|
||||||
|
* The size of the screen image can be specified by calling setImageSize() with the
|
||||||
|
* desired number of lines and columns. When new lines are added, old content
|
||||||
|
* is moved into a history store, which can be set by calling setHistory().
|
||||||
|
*
|
||||||
|
* The screen image can be accessed by creating a ScreenWindow onto this emulation
|
||||||
|
* by calling createWindow(). Screen windows provide access to a section of the
|
||||||
|
* output. Each screen window covers the same number of lines and columns as the
|
||||||
|
* image size returned by imageSize(). The screen window can be moved up and down
|
||||||
|
* and provides transparent access to both the current on-screen image and the
|
||||||
|
* previous output. The screen windows emit an outputChanged signal
|
||||||
|
* when the section of the image they are looking at changes.
|
||||||
|
* Graphical views can then render the contents of a screen window, listening for notifications
|
||||||
|
* of output changes from the screen window which they are associated with and updating
|
||||||
|
* accordingly.
|
||||||
|
*
|
||||||
|
* The emulation also is also responsible for converting input from the connected views such
|
||||||
|
* as keypresses and mouse activity into a character string which can be sent
|
||||||
|
* to the terminal program. Key presses can be processed by calling the sendKeyEvent() slot,
|
||||||
|
* while mouse events can be processed using the sendMouseEvent() slot. When the character
|
||||||
|
* stream has been produced, the emulation will emit a sendData() signal with a pointer
|
||||||
|
* to the character buffer. This data should be fed to the standard input of the terminal
|
||||||
|
* process. The translation of key presses into an output character stream is performed
|
||||||
|
* using a lookup in a set of key bindings which map key sequences to output
|
||||||
|
* character sequences. The name of the key bindings set used can be specified using
|
||||||
|
* setKeyBindings()
|
||||||
|
*
|
||||||
|
* The emulation maintains certain state information which changes depending on the
|
||||||
|
* input received. The emulation can be reset back to its starting state by calling
|
||||||
|
* reset().
|
||||||
|
*
|
||||||
|
* The emulation also maintains an activity state, which specifies whether
|
||||||
|
* terminal is currently active ( when data is received ), normal
|
||||||
|
* ( when the terminal is idle or receiving user input ) or trying
|
||||||
|
* to alert the user ( also known as a "Bell" event ). The stateSet() signal
|
||||||
|
* is emitted whenever the activity state is set. This can be used to determine
|
||||||
|
* how long the emulation has been active/idle for and also respond to
|
||||||
|
* a 'bell' event in different ways.
|
||||||
|
*/
|
||||||
|
class KONSOLEPRIVATE_EXPORT Emulation : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** Constructs a new terminal emulation */
|
||||||
|
Emulation();
|
||||||
|
~Emulation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new window onto the output from this emulation. The contents
|
||||||
|
* of the window are then rendered by views which are set to use this window using the
|
||||||
|
* TerminalDisplay::setScreenWindow() method.
|
||||||
|
*/
|
||||||
|
ScreenWindow* createWindow();
|
||||||
|
|
||||||
|
/** Returns the size of the screen image which the emulation produces */
|
||||||
|
QSize imageSize() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the total number of lines, including those stored in the history.
|
||||||
|
*/
|
||||||
|
int lineCount() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the history store used by this emulation. When new lines
|
||||||
|
* are added to the output, older lines at the top of the screen are transferred to a history
|
||||||
|
* store.
|
||||||
|
*
|
||||||
|
* The number of lines which are kept and the storage location depend on the
|
||||||
|
* type of store.
|
||||||
|
*/
|
||||||
|
void setHistory(const HistoryType&);
|
||||||
|
/** Returns the history store used by this emulation. See setHistory() */
|
||||||
|
const HistoryType& history() const;
|
||||||
|
/** Clears the history scroll. */
|
||||||
|
void clearHistory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the output history from @p startLine to @p endLine
|
||||||
|
* into @p stream, using @p decoder to convert the terminal
|
||||||
|
* characters into text.
|
||||||
|
*
|
||||||
|
* @param decoder A decoder which converts lines of terminal characters with
|
||||||
|
* appearance attributes into output text. PlainTextDecoder is the most commonly
|
||||||
|
* used decoder.
|
||||||
|
* @param startLine Index of first line to copy
|
||||||
|
* @param endLine Index of last line to copy
|
||||||
|
*/
|
||||||
|
virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine);
|
||||||
|
|
||||||
|
/** Returns the codec used to decode incoming characters. See setCodec() */
|
||||||
|
const QTextCodec* codec() const { return _codec; }
|
||||||
|
/** Sets the codec used to decode incoming characters. */
|
||||||
|
void setCodec(const QTextCodec*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method.
|
||||||
|
* Returns true if the current codec used to decode incoming
|
||||||
|
* characters is UTF-8
|
||||||
|
*/
|
||||||
|
bool utf8() const
|
||||||
|
{ Q_ASSERT(_codec); return _codec->mibEnum() == 106; }
|
||||||
|
|
||||||
|
|
||||||
|
/** TODO Document me */
|
||||||
|
virtual char eraseChar() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key bindings used to key events
|
||||||
|
* ( received through sendKeyEvent() ) into character
|
||||||
|
* streams to send to the terminal.
|
||||||
|
*/
|
||||||
|
void setKeyBindings(const QString& name);
|
||||||
|
/**
|
||||||
|
* Returns the name of the emulation's current key bindings.
|
||||||
|
* See setKeyBindings()
|
||||||
|
*/
|
||||||
|
QString keyBindings() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the current image into the history and clears the screen.
|
||||||
|
*/
|
||||||
|
virtual void clearEntireScreen() =0;
|
||||||
|
|
||||||
|
/** Resets the state of the terminal. */
|
||||||
|
virtual void reset() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the active terminal program wants
|
||||||
|
* mouse input events.
|
||||||
|
*
|
||||||
|
* The programUsesMouseChanged() signal is emitted when this
|
||||||
|
* changes.
|
||||||
|
*/
|
||||||
|
bool programUsesMouse() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/** Change the size of the emulation's image */
|
||||||
|
virtual void setImageSize(int lines, int columns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interprets a sequence of characters and sends the result to the terminal.
|
||||||
|
* This is equivalent to calling sendKeyEvent() for each character in @p text in succession.
|
||||||
|
*/
|
||||||
|
virtual void sendText(const QString& text) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interprets a key press event and emits the sendData() signal with
|
||||||
|
* the resulting character stream.
|
||||||
|
*/
|
||||||
|
virtual void sendKeyEvent(QKeyEvent*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts information about a mouse event into an xterm-compatible escape
|
||||||
|
* sequence and emits the character sequence via sendData()
|
||||||
|
*/
|
||||||
|
virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a string of characters to the foreground terminal process.
|
||||||
|
*
|
||||||
|
* @param string The characters to send.
|
||||||
|
* @param length Length of @p string or if set to a negative value, @p string will
|
||||||
|
* be treated as a null-terminated string and its length will be determined automatically.
|
||||||
|
*/
|
||||||
|
virtual void sendString(const char* string, int length = -1) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes an incoming stream of characters. receiveData() decodes the incoming
|
||||||
|
* character buffer using the current codec(), and then calls receiveChar() for
|
||||||
|
* each unicode character in the resulting buffer.
|
||||||
|
*
|
||||||
|
* receiveData() also starts a timer which causes the outputChanged() signal
|
||||||
|
* to be emitted when it expires. The timer allows multiple updates in quick
|
||||||
|
* succession to be buffered into a single outputChanged() signal emission.
|
||||||
|
*
|
||||||
|
* @param buffer A string of characters received from the terminal program.
|
||||||
|
* @param len The length of @p buffer
|
||||||
|
*/
|
||||||
|
void receiveData(const char* buffer,int len);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when a buffer of data is ready to send to the
|
||||||
|
* standard input of the terminal.
|
||||||
|
*
|
||||||
|
* @param data The buffer of data ready to be sent
|
||||||
|
* @param len The length of @p data in bytes
|
||||||
|
*/
|
||||||
|
void sendData(const char* data,int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that sending of input to the emulation
|
||||||
|
* from the terminal process be suspended or resumed.
|
||||||
|
*
|
||||||
|
* @param suspend If true, requests that sending of
|
||||||
|
* input from the terminal process' stdout be
|
||||||
|
* suspended. Otherwise requests that sending of
|
||||||
|
* input be resumed.
|
||||||
|
*/
|
||||||
|
void lockPtyRequest(bool suspend);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the pty used by the terminal process
|
||||||
|
* be set to UTF 8 mode.
|
||||||
|
*
|
||||||
|
* TODO: More documentation
|
||||||
|
*/
|
||||||
|
void useUtf8Request(bool);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the activity state of the emulation is set.
|
||||||
|
*
|
||||||
|
* @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY
|
||||||
|
* or NOTIFYBELL
|
||||||
|
*/
|
||||||
|
void stateSet(int state);
|
||||||
|
|
||||||
|
/** TODO Document me */
|
||||||
|
void zmodemDetected();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the color of the text used
|
||||||
|
* to represent the tabs associated with this
|
||||||
|
* emulation be changed. This is a Konsole-specific
|
||||||
|
* extension from pre-KDE 4 times.
|
||||||
|
*
|
||||||
|
* TODO: Document how the parameter works.
|
||||||
|
*/
|
||||||
|
void changeTabTextColorRequest(int color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is emitted when the program running in the shell indicates whether or
|
||||||
|
* not it is interested in mouse events.
|
||||||
|
*
|
||||||
|
* @param usesMouse This will be true if the program wants to be informed about
|
||||||
|
* mouse events or false otherwise.
|
||||||
|
*/
|
||||||
|
void programUsesMouseChanged(bool usesMouse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the contents of the screen image change.
|
||||||
|
* The emulation buffers the updates from successive image changes,
|
||||||
|
* and only emits outputChanged() at sensible intervals when
|
||||||
|
* there is a lot of terminal activity.
|
||||||
|
*
|
||||||
|
* Normally there is no need for objects other than the screen windows
|
||||||
|
* created with createWindow() to listen for this signal.
|
||||||
|
*
|
||||||
|
* ScreenWindow objects created using createWindow() will emit their
|
||||||
|
* own outputChanged() signal in response to this signal.
|
||||||
|
*/
|
||||||
|
void outputChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the program running in the terminal wishes to update the
|
||||||
|
* session's title. This also allows terminal programs to customize other
|
||||||
|
* aspects of the terminal emulation display.
|
||||||
|
*
|
||||||
|
* This signal is emitted when the escape sequence "\033]ARG;VALUE\007"
|
||||||
|
* is received in the input string, where ARG is a number specifying what
|
||||||
|
* should change and VALUE is a string specifying the new value.
|
||||||
|
*
|
||||||
|
* TODO: The name of this method is not very accurate since this method
|
||||||
|
* is used to perform a whole range of tasks besides just setting
|
||||||
|
* the user-title of the session.
|
||||||
|
*
|
||||||
|
* @param title Specifies what to change.
|
||||||
|
* <ul>
|
||||||
|
* <li>0 - Set window icon text and session title to @p newTitle</li>
|
||||||
|
* <li>1 - Set window icon text to @p newTitle</li>
|
||||||
|
* <li>2 - Set session title to @p newTitle</li>
|
||||||
|
* <li>11 - Set the session's default background color to @p newTitle,
|
||||||
|
* where @p newTitle can be an HTML-style string ("#RRGGBB") or a named
|
||||||
|
* color (eg 'red', 'blue').
|
||||||
|
* See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more
|
||||||
|
* details.
|
||||||
|
* </li>
|
||||||
|
* <li>31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)</li>
|
||||||
|
* <li>32 - Sets the icon associated with the session. @p newTitle is the name
|
||||||
|
* of the icon to use, which can be the name of any icon in the current KDE icon
|
||||||
|
* theme (eg: 'konsole', 'kate', 'folder_home')</li>
|
||||||
|
* </ul>
|
||||||
|
* @param newTitle Specifies the new title
|
||||||
|
*/
|
||||||
|
|
||||||
|
void titleChanged(int title,const QString& newTitle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the program running in the terminal changes the
|
||||||
|
* screen size.
|
||||||
|
*/
|
||||||
|
void imageSizeChanged(int lineCount , int columnCount);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the terminal program requests to change various properties
|
||||||
|
* of the terminal display.
|
||||||
|
*
|
||||||
|
* A profile change command occurs when a special escape sequence, followed
|
||||||
|
* by a string containing a series of name and value pairs is received.
|
||||||
|
* This string can be parsed using a ProfileCommandParser instance.
|
||||||
|
*
|
||||||
|
* @param text A string expected to contain a series of key and value pairs in
|
||||||
|
* the form: name=value;name2=value2 ...
|
||||||
|
*/
|
||||||
|
void profileChangeCommandReceived(const QString& text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when a flow control key combination ( Ctrl+S or Ctrl+Q ) is pressed.
|
||||||
|
* @param suspendKeyPressed True if Ctrl+S was pressed to suspend output or Ctrl+Q to
|
||||||
|
* resume output.
|
||||||
|
*/
|
||||||
|
void flowControlKeyPressed(bool suspendKeyPressed);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setMode(int mode) = 0;
|
||||||
|
virtual void resetMode(int mode) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes an incoming character. See receiveData()
|
||||||
|
* @p ch A unicode character code.
|
||||||
|
*/
|
||||||
|
virtual void receiveChar(int ch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the active screen. The terminal has two screens, primary and alternate.
|
||||||
|
* The primary screen is used by default. When certain interactive programs such
|
||||||
|
* as Vim are run, they trigger a switch to the alternate screen.
|
||||||
|
*
|
||||||
|
* @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen
|
||||||
|
*/
|
||||||
|
void setScreen(int index);
|
||||||
|
|
||||||
|
enum EmulationCodec
|
||||||
|
{
|
||||||
|
LocaleCodec = 0,
|
||||||
|
Utf8Codec = 1
|
||||||
|
};
|
||||||
|
void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8
|
||||||
|
|
||||||
|
|
||||||
|
QList<ScreenWindow*> _windows;
|
||||||
|
|
||||||
|
Screen* _currentScreen; // pointer to the screen which is currently active,
|
||||||
|
// this is one of the elements in the screen[] array
|
||||||
|
|
||||||
|
Screen* _screen[2]; // 0 = primary screen ( used by most programs, including the shell
|
||||||
|
// scrollbars are enabled in this mode )
|
||||||
|
// 1 = alternate ( used by vi , emacs etc.
|
||||||
|
// scrollbars are not enabled in this mode )
|
||||||
|
|
||||||
|
|
||||||
|
//decodes an incoming C-style character stream into a unicode QString using
|
||||||
|
//the current text codec. (this allows for rendering of non-ASCII characters in text files etc.)
|
||||||
|
const QTextCodec* _codec;
|
||||||
|
QTextDecoder* _decoder;
|
||||||
|
const KeyboardTranslator* _keyTranslator; // the keyboard layout
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
/**
|
||||||
|
* Schedules an update of attached views.
|
||||||
|
* Repeated calls to bufferedUpdate() in close succession will result in only a single update,
|
||||||
|
* much like the Qt buffered update of widgets.
|
||||||
|
*/
|
||||||
|
void bufferedUpdate();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
// triggered by timer, causes the emulation to send an updated screen image to each
|
||||||
|
// view
|
||||||
|
void showBulk();
|
||||||
|
|
||||||
|
void usesMouseChanged(bool usesMouse);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _usesMouse;
|
||||||
|
QTimer _bulkTimer1;
|
||||||
|
QTimer _bulkTimer2;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ifndef EMULATION_H
|
@ -0,0 +1,74 @@
|
|||||||
|
"keyboard \"Default (XFree 4)\""
|
||||||
|
"key Escape : \"\\E\""
|
||||||
|
"key Tab -Shift : \"\\t\"\n"
|
||||||
|
"key Tab +Shift+Ansi : \"\\E[Z\"\n"
|
||||||
|
"key Tab +Shift-Ansi : \"\\t\"\n"
|
||||||
|
"key Backtab +Ansi : \"\\E[Z\"\n"
|
||||||
|
"key Backtab -Ansi : \"\\t\"\n"
|
||||||
|
"key Return-Shift-NewLine : \"\\r\"\n"
|
||||||
|
"key Return-Shift+NewLine : \"\\r\\n\"\n"
|
||||||
|
"key Return+Shift : \"\\EOM\"\n"
|
||||||
|
"key Backspace : \"\\x7f\"\n"
|
||||||
|
"key Up -Shift-Ansi : \"\\EA\"\n"
|
||||||
|
"key Down -Shift-Ansi : \"\\EB\"\n"
|
||||||
|
"key Right-Shift-Ansi : \"\\EC\"\n"
|
||||||
|
"key Left -Shift-Ansi : \"\\ED\"\n"
|
||||||
|
"key Up -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOA\"\n"
|
||||||
|
"key Down -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOB\"\n"
|
||||||
|
"key Right -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOC\"\n"
|
||||||
|
"key Left -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOD\"\n"
|
||||||
|
"key Up -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[A\"\n"
|
||||||
|
"key Down -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[B\"\n"
|
||||||
|
"key Right -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[C\"\n"
|
||||||
|
"key Left -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[D\"\n"
|
||||||
|
"key Up -Shift+AnyMod+Ansi : \"\\E[1;*A\"\n"
|
||||||
|
"key Down -Shift+AnyMod+Ansi : \"\\E[1;*B\"\n"
|
||||||
|
"key Right -Shift+AnyMod+Ansi : \"\\E[1;*C\"\n"
|
||||||
|
"key Left -Shift+AnyMod+Ansi : \"\\E[1;*D\"\n"
|
||||||
|
"key Enter+NewLine : \"\\r\\n\"\n"
|
||||||
|
"key Enter-NewLine : \"\\r\"\n"
|
||||||
|
"key Home -AnyMod -AppCuKeys : \"\\E[H\" \n"
|
||||||
|
"key End -AnyMod -AppCuKeys : \"\\E[F\" \n"
|
||||||
|
"key Home -AnyMod +AppCuKeys : \"\\EOH\" \n"
|
||||||
|
"key End -AnyMod +AppCuKeys : \"\\EOF\" \n"
|
||||||
|
"key Home +AnyMod : \"\\E[1;*H\"\n"
|
||||||
|
"key End +AnyMod : \"\\E[1;*F\"\n"
|
||||||
|
"key Insert -AnyMod : \"\\E[2~\"\n"
|
||||||
|
"key Delete -AnyMod : \"\\E[3~\"\n"
|
||||||
|
"key Insert +AnyMod : \"\\E[2;*~\"\n"
|
||||||
|
"key Delete +AnyMod : \"\\E[3;*~\"\n"
|
||||||
|
"key Prior -Shift-AnyMod : \"\\E[5~\"\n"
|
||||||
|
"key Next -Shift-AnyMod : \"\\E[6~\"\n"
|
||||||
|
"key Prior -Shift+AnyMod : \"\\E[5;*~\"\n"
|
||||||
|
"key Next -Shift+AnyMod : \"\\E[6;*~\"\n"
|
||||||
|
"key F1 -AnyMod : \"\\EOP\"\n"
|
||||||
|
"key F2 -AnyMod : \"\\EOQ\"\n"
|
||||||
|
"key F3 -AnyMod : \"\\EOR\"\n"
|
||||||
|
"key F4 -AnyMod : \"\\EOS\"\n"
|
||||||
|
"key F5 -AnyMod : \"\\E[15~\"\n"
|
||||||
|
"key F6 -AnyMod : \"\\E[17~\"\n"
|
||||||
|
"key F7 -AnyMod : \"\\E[18~\"\n"
|
||||||
|
"key F8 -AnyMod : \"\\E[19~\"\n"
|
||||||
|
"key F9 -AnyMod : \"\\E[20~\"\n"
|
||||||
|
"key F10 -AnyMod : \"\\E[21~\"\n"
|
||||||
|
"key F11 -AnyMod : \"\\E[23~\"\n"
|
||||||
|
"key F12 -AnyMod : \"\\E[24~\"\n"
|
||||||
|
"key F1 +AnyMod : \"\\EO*P\"\n"
|
||||||
|
"key F2 +AnyMod : \"\\EO*Q\"\n"
|
||||||
|
"key F3 +AnyMod : \"\\EO*R\"\n"
|
||||||
|
"key F4 +AnyMod : \"\\EO*S\"\n"
|
||||||
|
"key F5 +AnyMod : \"\\E[15;*~\"\n"
|
||||||
|
"key F6 +AnyMod : \"\\E[17;*~\"\n"
|
||||||
|
"key F7 +AnyMod : \"\\E[18;*~\"\n"
|
||||||
|
"key F8 +AnyMod : \"\\E[19;*~\"\n"
|
||||||
|
"key F9 +AnyMod : \"\\E[20;*~\"\n"
|
||||||
|
"key F10 +AnyMod : \"\\E[21;*~\"\n"
|
||||||
|
"key F11 +AnyMod : \"\\E[23;*~\"\n"
|
||||||
|
"key F12 +AnyMod : \"\\E[24;*~\"\n"
|
||||||
|
"key Space +Control : \"\\x00\"\n"
|
||||||
|
"key Up +Shift-AppScreen : scrollLineUp\n"
|
||||||
|
"key Prior +Shift-AppScreen : scrollPageUp\n"
|
||||||
|
"key Down +Shift-AppScreen : scrollLineDown\n"
|
||||||
|
"key Next +Shift-AppScreen : scrollPageDown\n"
|
||||||
|
"key ScrollLock : scrollLock\n"
|
||||||
|
"\0"
|
@ -0,0 +1,557 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "Filter.h"
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QSharedData>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <KLocale>
|
||||||
|
//#include <KRun>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "TerminalCharacterDecoder.h"
|
||||||
|
#include "konsole_wcwidth.h"
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
FilterChain::~FilterChain()
|
||||||
|
{
|
||||||
|
QMutableListIterator<Filter*> iter(*this);
|
||||||
|
|
||||||
|
while ( iter.hasNext() )
|
||||||
|
{
|
||||||
|
Filter* filter = iter.next();
|
||||||
|
iter.remove();
|
||||||
|
delete filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterChain::addFilter(Filter* filter)
|
||||||
|
{
|
||||||
|
append(filter);
|
||||||
|
}
|
||||||
|
void FilterChain::removeFilter(Filter* filter)
|
||||||
|
{
|
||||||
|
removeAll(filter);
|
||||||
|
}
|
||||||
|
bool FilterChain::containsFilter(Filter* filter)
|
||||||
|
{
|
||||||
|
return contains(filter);
|
||||||
|
}
|
||||||
|
void FilterChain::reset()
|
||||||
|
{
|
||||||
|
QListIterator<Filter*> iter(*this);
|
||||||
|
while (iter.hasNext())
|
||||||
|
iter.next()->reset();
|
||||||
|
}
|
||||||
|
void FilterChain::setBuffer(const QString* buffer , const QList<int>* linePositions)
|
||||||
|
{
|
||||||
|
QListIterator<Filter*> iter(*this);
|
||||||
|
while (iter.hasNext())
|
||||||
|
iter.next()->setBuffer(buffer,linePositions);
|
||||||
|
}
|
||||||
|
void FilterChain::process()
|
||||||
|
{
|
||||||
|
QListIterator<Filter*> iter(*this);
|
||||||
|
while (iter.hasNext())
|
||||||
|
iter.next()->process();
|
||||||
|
}
|
||||||
|
void FilterChain::clear()
|
||||||
|
{
|
||||||
|
QList<Filter*>::clear();
|
||||||
|
}
|
||||||
|
Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const
|
||||||
|
{
|
||||||
|
QListIterator<Filter*> iter(*this);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
Filter* filter = iter.next();
|
||||||
|
Filter::HotSpot* spot = filter->hotSpotAt(line,column);
|
||||||
|
if ( spot != 0 )
|
||||||
|
{
|
||||||
|
return spot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Filter::HotSpot*> FilterChain::hotSpots() const
|
||||||
|
{
|
||||||
|
QList<Filter::HotSpot*> list;
|
||||||
|
QListIterator<Filter*> iter(*this);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
Filter* filter = iter.next();
|
||||||
|
list << filter->hotSpots();
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
//QList<Filter::HotSpot*> FilterChain::hotSpotsAtLine(int line) const;
|
||||||
|
|
||||||
|
TerminalImageFilterChain::TerminalImageFilterChain()
|
||||||
|
: _buffer(0)
|
||||||
|
, _linePositions(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalImageFilterChain::~TerminalImageFilterChain()
|
||||||
|
{
|
||||||
|
delete _buffer;
|
||||||
|
delete _linePositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalImageFilterChain::setImage(const Character* const image , int lines , int columns, const QVector<LineProperty>& lineProperties)
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// reset all filters and hotspots
|
||||||
|
reset();
|
||||||
|
|
||||||
|
PlainTextDecoder decoder;
|
||||||
|
decoder.setTrailingWhitespace(false);
|
||||||
|
|
||||||
|
// setup new shared buffers for the filters to process on
|
||||||
|
QString* newBuffer = new QString();
|
||||||
|
QList<int>* newLinePositions = new QList<int>();
|
||||||
|
setBuffer( newBuffer , newLinePositions );
|
||||||
|
|
||||||
|
// free the old buffers
|
||||||
|
delete _buffer;
|
||||||
|
delete _linePositions;
|
||||||
|
|
||||||
|
_buffer = newBuffer;
|
||||||
|
_linePositions = newLinePositions;
|
||||||
|
|
||||||
|
QTextStream lineStream(_buffer);
|
||||||
|
decoder.begin(&lineStream);
|
||||||
|
|
||||||
|
for (int i=0 ; i < lines ; i++)
|
||||||
|
{
|
||||||
|
_linePositions->append(_buffer->length());
|
||||||
|
decoder.decodeLine(image + i*columns,columns,LINE_DEFAULT);
|
||||||
|
|
||||||
|
// pretend that each line ends with a newline character.
|
||||||
|
// this prevents a link that occurs at the end of one line
|
||||||
|
// being treated as part of a link that occurs at the start of the next line
|
||||||
|
//
|
||||||
|
// the downside is that links which are spread over more than one line are not
|
||||||
|
// highlighted.
|
||||||
|
//
|
||||||
|
// TODO - Use the "line wrapped" attribute associated with lines in a
|
||||||
|
// terminal image to avoid adding this imaginary character for wrapped
|
||||||
|
// lines
|
||||||
|
if ( !(lineProperties.value(i,LINE_DEFAULT) & LINE_WRAPPED) )
|
||||||
|
lineStream << QChar('\n');
|
||||||
|
}
|
||||||
|
decoder.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter::Filter() :
|
||||||
|
_linePositions(0),
|
||||||
|
_buffer(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter::~Filter()
|
||||||
|
{
|
||||||
|
QListIterator<HotSpot*> iter(_hotspotList);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
delete iter.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Filter::reset()
|
||||||
|
{
|
||||||
|
_hotspots.clear();
|
||||||
|
_hotspotList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Filter::setBuffer(const QString* buffer , const QList<int>* linePositions)
|
||||||
|
{
|
||||||
|
_buffer = buffer;
|
||||||
|
_linePositions = linePositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Filter::getLineColumn(int position , int& startLine , int& startColumn)
|
||||||
|
{
|
||||||
|
Q_ASSERT( _linePositions );
|
||||||
|
Q_ASSERT( _buffer );
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0 ; i < _linePositions->count() ; i++)
|
||||||
|
{
|
||||||
|
int nextLine = 0;
|
||||||
|
|
||||||
|
if ( i == _linePositions->count()-1 )
|
||||||
|
nextLine = _buffer->length() + 1;
|
||||||
|
else
|
||||||
|
nextLine = _linePositions->value(i+1);
|
||||||
|
|
||||||
|
if ( _linePositions->value(i) <= position && position < nextLine )
|
||||||
|
{
|
||||||
|
startLine = i;
|
||||||
|
startColumn = string_width(buffer()->mid(_linePositions->value(i),position - _linePositions->value(i)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*void Filter::addLine(const QString& text)
|
||||||
|
{
|
||||||
|
_linePositions << _buffer.length();
|
||||||
|
_buffer.append(text);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
const QString* Filter::buffer()
|
||||||
|
{
|
||||||
|
return _buffer;
|
||||||
|
}
|
||||||
|
Filter::HotSpot::~HotSpot()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Filter::addHotSpot(HotSpot* spot)
|
||||||
|
{
|
||||||
|
_hotspotList << spot;
|
||||||
|
|
||||||
|
for (int line = spot->startLine() ; line <= spot->endLine() ; line++)
|
||||||
|
{
|
||||||
|
_hotspots.insert(line,spot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QList<Filter::HotSpot*> Filter::hotSpots() const
|
||||||
|
{
|
||||||
|
return _hotspotList;
|
||||||
|
}
|
||||||
|
QList<Filter::HotSpot*> Filter::hotSpotsAtLine(int line) const
|
||||||
|
{
|
||||||
|
return _hotspots.values(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter::HotSpot* Filter::hotSpotAt(int line , int column) const
|
||||||
|
{
|
||||||
|
QListIterator<HotSpot*> spotIter(_hotspots.values(line));
|
||||||
|
|
||||||
|
while (spotIter.hasNext())
|
||||||
|
{
|
||||||
|
HotSpot* spot = spotIter.next();
|
||||||
|
|
||||||
|
if ( spot->startLine() == line && spot->startColumn() > column )
|
||||||
|
continue;
|
||||||
|
if ( spot->endLine() == line && spot->endColumn() < column )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return spot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int endColumn)
|
||||||
|
: _startLine(startLine)
|
||||||
|
, _startColumn(startColumn)
|
||||||
|
, _endLine(endLine)
|
||||||
|
, _endColumn(endColumn)
|
||||||
|
, _type(NotSpecified)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QString Filter::HotSpot::tooltip() const
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
QList<QAction*> Filter::HotSpot::actions()
|
||||||
|
{
|
||||||
|
return QList<QAction*>();
|
||||||
|
}
|
||||||
|
int Filter::HotSpot::startLine() const
|
||||||
|
{
|
||||||
|
return _startLine;
|
||||||
|
}
|
||||||
|
int Filter::HotSpot::endLine() const
|
||||||
|
{
|
||||||
|
return _endLine;
|
||||||
|
}
|
||||||
|
int Filter::HotSpot::startColumn() const
|
||||||
|
{
|
||||||
|
return _startColumn;
|
||||||
|
}
|
||||||
|
int Filter::HotSpot::endColumn() const
|
||||||
|
{
|
||||||
|
return _endColumn;
|
||||||
|
}
|
||||||
|
Filter::HotSpot::Type Filter::HotSpot::type() const
|
||||||
|
{
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
void Filter::HotSpot::setType(Type type)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegExpFilter::RegExpFilter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
|
||||||
|
: Filter::HotSpot(startLine,startColumn,endLine,endColumn)
|
||||||
|
{
|
||||||
|
setType(Marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegExpFilter::HotSpot::activate(const QString&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts)
|
||||||
|
{
|
||||||
|
_capturedTexts = texts;
|
||||||
|
}
|
||||||
|
QStringList RegExpFilter::HotSpot::capturedTexts() const
|
||||||
|
{
|
||||||
|
return _capturedTexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegExpFilter::setRegExp(const QRegExp& regExp)
|
||||||
|
{
|
||||||
|
_searchText = regExp;
|
||||||
|
}
|
||||||
|
QRegExp RegExpFilter::regExp() const
|
||||||
|
{
|
||||||
|
return _searchText;
|
||||||
|
}
|
||||||
|
/*void RegExpFilter::reset(int)
|
||||||
|
{
|
||||||
|
_buffer = QString();
|
||||||
|
}*/
|
||||||
|
void RegExpFilter::process()
|
||||||
|
{
|
||||||
|
int pos = 0;
|
||||||
|
const QString* text = buffer();
|
||||||
|
|
||||||
|
Q_ASSERT( text );
|
||||||
|
|
||||||
|
// ignore any regular expressions which match an empty string.
|
||||||
|
// otherwise the while loop below will run indefinitely
|
||||||
|
static const QString emptyString("");
|
||||||
|
if ( _searchText.exactMatch(emptyString) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
while(pos >= 0)
|
||||||
|
{
|
||||||
|
pos = _searchText.indexIn(*text,pos);
|
||||||
|
|
||||||
|
if ( pos >= 0 )
|
||||||
|
{
|
||||||
|
int startLine = 0;
|
||||||
|
int endLine = 0;
|
||||||
|
int startColumn = 0;
|
||||||
|
int endColumn = 0;
|
||||||
|
|
||||||
|
getLineColumn(pos,startLine,startColumn);
|
||||||
|
getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn);
|
||||||
|
|
||||||
|
RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn,
|
||||||
|
endLine,endColumn);
|
||||||
|
spot->setCapturedTexts(_searchText.capturedTexts());
|
||||||
|
|
||||||
|
addHotSpot( spot );
|
||||||
|
pos += _searchText.matchedLength();
|
||||||
|
|
||||||
|
// if matchedLength == 0, the program will get stuck in an infinite loop
|
||||||
|
if ( _searchText.matchedLength() == 0 )
|
||||||
|
pos = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn,
|
||||||
|
int endLine,int endColumn)
|
||||||
|
{
|
||||||
|
return new RegExpFilter::HotSpot(startLine,startColumn,
|
||||||
|
endLine,endColumn);
|
||||||
|
}
|
||||||
|
RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine,
|
||||||
|
int endColumn)
|
||||||
|
{
|
||||||
|
HotSpot *spot = new UrlFilter::HotSpot(startLine,startColumn,
|
||||||
|
endLine,endColumn);
|
||||||
|
connect(spot->getUrlObject(), SIGNAL(activated(QUrl)), this, SIGNAL(activated(QUrl)));
|
||||||
|
return spot;
|
||||||
|
}
|
||||||
|
|
||||||
|
UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
|
||||||
|
: RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn)
|
||||||
|
, _urlObject(new FilterObject(this))
|
||||||
|
{
|
||||||
|
setType(Link);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UrlFilter::HotSpot::tooltip() const
|
||||||
|
{
|
||||||
|
QString url = capturedTexts().first();
|
||||||
|
|
||||||
|
const UrlType kind = urlType();
|
||||||
|
|
||||||
|
if ( kind == StandardUrl )
|
||||||
|
return QString();
|
||||||
|
else if ( kind == Email )
|
||||||
|
return QString();
|
||||||
|
else
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
UrlFilter::HotSpot::UrlType UrlFilter::HotSpot::urlType() const
|
||||||
|
{
|
||||||
|
QString url = capturedTexts().first();
|
||||||
|
|
||||||
|
if ( FullUrlRegExp.exactMatch(url) )
|
||||||
|
return StandardUrl;
|
||||||
|
else if ( EmailAddressRegExp.exactMatch(url) )
|
||||||
|
return Email;
|
||||||
|
else
|
||||||
|
return Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UrlFilter::HotSpot::activate(const QString& actionName)
|
||||||
|
{
|
||||||
|
QString url = capturedTexts().first();
|
||||||
|
|
||||||
|
const UrlType kind = urlType();
|
||||||
|
|
||||||
|
if ( actionName == "copy-action" )
|
||||||
|
{
|
||||||
|
QApplication::clipboard()->setText(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( actionName.isEmpty() || actionName == "open-action" )
|
||||||
|
{
|
||||||
|
if ( kind == StandardUrl )
|
||||||
|
{
|
||||||
|
// if the URL path does not include the protocol ( eg. "www.kde.org" ) then
|
||||||
|
// prepend http:// ( eg. "www.kde.org" --> "http://www.kde.org" )
|
||||||
|
if (!url.contains("://"))
|
||||||
|
{
|
||||||
|
url.prepend("http://");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( kind == Email )
|
||||||
|
{
|
||||||
|
url.prepend("mailto:");
|
||||||
|
}
|
||||||
|
|
||||||
|
_urlObject->emitActivated(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Altering these regular expressions can have a major effect on the performance of the filters
|
||||||
|
// used for finding URLs in the text, especially if they are very general and could match very long
|
||||||
|
// pieces of text.
|
||||||
|
// Please be careful when altering them.
|
||||||
|
|
||||||
|
//regexp matches:
|
||||||
|
// full url:
|
||||||
|
// protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot
|
||||||
|
const QRegExp UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]");
|
||||||
|
// email address:
|
||||||
|
// [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
|
||||||
|
const QRegExp UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b");
|
||||||
|
|
||||||
|
// matches full url or email address
|
||||||
|
const QRegExp UrlFilter::CompleteUrlRegExp('('+FullUrlRegExp.pattern()+'|'+
|
||||||
|
EmailAddressRegExp.pattern()+')');
|
||||||
|
|
||||||
|
UrlFilter::UrlFilter()
|
||||||
|
{
|
||||||
|
setRegExp( CompleteUrlRegExp );
|
||||||
|
}
|
||||||
|
|
||||||
|
UrlFilter::HotSpot::~HotSpot()
|
||||||
|
{
|
||||||
|
delete _urlObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterObject::emitActivated(const QUrl& url)
|
||||||
|
{
|
||||||
|
emit activated(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterObject::activated()
|
||||||
|
{
|
||||||
|
_filter->activate(sender()->objectName());
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterObject* UrlFilter::HotSpot::getUrlObject() const
|
||||||
|
{
|
||||||
|
return _urlObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QAction*> UrlFilter::HotSpot::actions()
|
||||||
|
{
|
||||||
|
QList<QAction*> list;
|
||||||
|
|
||||||
|
const UrlType kind = urlType();
|
||||||
|
|
||||||
|
QAction* openAction = new QAction(_urlObject);
|
||||||
|
QAction* copyAction = new QAction(_urlObject);;
|
||||||
|
|
||||||
|
Q_ASSERT( kind == StandardUrl || kind == Email );
|
||||||
|
|
||||||
|
if ( kind == StandardUrl )
|
||||||
|
{
|
||||||
|
openAction->setText(QObject::tr("Open Link"));
|
||||||
|
copyAction->setText(QObject::tr("Copy Link Address"));
|
||||||
|
}
|
||||||
|
else if ( kind == Email )
|
||||||
|
{
|
||||||
|
openAction->setText(QObject::tr("Send Email To..."));
|
||||||
|
copyAction->setText(QObject::tr("Copy Email Address"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// object names are set here so that the hotspot performs the
|
||||||
|
// correct action when activated() is called with the triggered
|
||||||
|
// action passed as a parameter.
|
||||||
|
openAction->setObjectName( QLatin1String("open-action" ));
|
||||||
|
copyAction->setObjectName( QLatin1String("copy-action" ));
|
||||||
|
|
||||||
|
QObject::connect( openAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
|
||||||
|
QObject::connect( copyAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
|
||||||
|
|
||||||
|
list << openAction;
|
||||||
|
list << copyAction;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#include "Filter.moc"
|
@ -0,0 +1,396 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FILTER_H
|
||||||
|
#define FILTER_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QAction>
|
||||||
|
#include <QList>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
// Local
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef unsigned char LineProperty;
|
||||||
|
class Character;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
|
||||||
|
* and marks the areas which match the filter's patterns as 'hotspots'.
|
||||||
|
*
|
||||||
|
* Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
|
||||||
|
* and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
|
||||||
|
* action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
|
||||||
|
* activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
|
||||||
|
*
|
||||||
|
* For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
|
||||||
|
* Hotspots may have more than one action, in which case the list of actions can be obtained using the
|
||||||
|
* actions() method.
|
||||||
|
*
|
||||||
|
* Different subclasses of filter will return different types of hotspot.
|
||||||
|
* Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
|
||||||
|
* When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
|
||||||
|
* and add them to the filter's list of hotspots using addHotSpot()
|
||||||
|
*/
|
||||||
|
class Filter : public QObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Represents an area of text which matched the pattern a particular filter has been looking for.
|
||||||
|
*
|
||||||
|
* Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
|
||||||
|
* and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
|
||||||
|
* action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
|
||||||
|
* activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
|
||||||
|
*
|
||||||
|
* For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
|
||||||
|
* Hotspots may have more than one action, in which case the list of actions can be obtained using the
|
||||||
|
* actions() method. These actions may then be displayed in a popup menu or toolbar for example.
|
||||||
|
*/
|
||||||
|
class HotSpot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
|
||||||
|
* in a block of text.
|
||||||
|
*/
|
||||||
|
HotSpot(int startLine , int startColumn , int endLine , int endColumn);
|
||||||
|
virtual ~HotSpot();
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
// the type of the hotspot is not specified
|
||||||
|
NotSpecified,
|
||||||
|
// this hotspot represents a clickable link
|
||||||
|
Link,
|
||||||
|
// this hotspot represents a marker
|
||||||
|
Marker
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Returns the line when the hotspot area starts */
|
||||||
|
int startLine() const;
|
||||||
|
/** Returns the line where the hotspot area ends */
|
||||||
|
int endLine() const;
|
||||||
|
/** Returns the column on startLine() where the hotspot area starts */
|
||||||
|
int startColumn() const;
|
||||||
|
/** Returns the column on endLine() where the hotspot area ends */
|
||||||
|
int endColumn() const;
|
||||||
|
/**
|
||||||
|
* Returns the type of the hotspot. This is usually used as a hint for views on how to represent
|
||||||
|
* the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them
|
||||||
|
*/
|
||||||
|
Type type() const;
|
||||||
|
/**
|
||||||
|
* Causes the an action associated with a hotspot to be triggered.
|
||||||
|
*
|
||||||
|
* @param action The action to trigger. This is
|
||||||
|
* typically empty ( in which case the default action should be performed ) or
|
||||||
|
* one of the object names from the actions() list. In which case the associated
|
||||||
|
* action should be performed.
|
||||||
|
*/
|
||||||
|
virtual void activate(const QString& action = QString()) = 0;
|
||||||
|
/**
|
||||||
|
* Returns a list of actions associated with the hotspot which can be used in a
|
||||||
|
* menu or toolbar
|
||||||
|
*/
|
||||||
|
virtual QList<QAction*> actions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
|
||||||
|
* an empty string if there is no tooltip associated with this hotspot.
|
||||||
|
*
|
||||||
|
* The default implementation returns an empty string.
|
||||||
|
*/
|
||||||
|
virtual QString tooltip() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Sets the type of a hotspot. This should only be set once */
|
||||||
|
void setType(Type type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _startLine;
|
||||||
|
int _startColumn;
|
||||||
|
int _endLine;
|
||||||
|
int _endColumn;
|
||||||
|
Type _type;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Constructs a new filter. */
|
||||||
|
Filter();
|
||||||
|
virtual ~Filter();
|
||||||
|
|
||||||
|
/** Causes the filter to process the block of text currently in its internal buffer */
|
||||||
|
virtual void process() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empties the filters internal buffer and resets the line count back to 0.
|
||||||
|
* All hotspots are deleted.
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/** Adds a new line of text to the filter and increments the line count */
|
||||||
|
//void addLine(const QString& string);
|
||||||
|
|
||||||
|
/** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
|
||||||
|
HotSpot* hotSpotAt(int line , int column) const;
|
||||||
|
|
||||||
|
/** Returns the list of hotspots identified by the filter */
|
||||||
|
QList<HotSpot*> hotSpots() const;
|
||||||
|
|
||||||
|
/** Returns the list of hotspots identified by the filter which occur on a given line */
|
||||||
|
QList<HotSpot*> hotSpotsAtLine(int line) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Document me
|
||||||
|
*/
|
||||||
|
void setBuffer(const QString* buffer , const QList<int>* linePositions);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Adds a new hotspot to the list */
|
||||||
|
void addHotSpot(HotSpot*);
|
||||||
|
/** Returns the internal buffer */
|
||||||
|
const QString* buffer();
|
||||||
|
/** Converts a character position within buffer() to a line and column */
|
||||||
|
void getLineColumn(int position , int& startLine , int& startColumn);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMultiHash<int,HotSpot*> _hotspots;
|
||||||
|
QList<HotSpot*> _hotspotList;
|
||||||
|
|
||||||
|
const QList<int>* _linePositions;
|
||||||
|
const QString* _buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot
|
||||||
|
* instance for them.
|
||||||
|
*
|
||||||
|
* Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
|
||||||
|
* are found.
|
||||||
|
*/
|
||||||
|
class RegExpFilter : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the text
|
||||||
|
* matched by the filter's regular expression.
|
||||||
|
*/
|
||||||
|
class HotSpot : public Filter::HotSpot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HotSpot(int startLine, int startColumn, int endLine , int endColumn);
|
||||||
|
virtual void activate(const QString& action = QString());
|
||||||
|
|
||||||
|
/** Sets the captured texts associated with this hotspot */
|
||||||
|
void setCapturedTexts(const QStringList& texts);
|
||||||
|
/** Returns the texts found by the filter when matching the filter's regular expression */
|
||||||
|
QStringList capturedTexts() const;
|
||||||
|
private:
|
||||||
|
QStringList _capturedTexts;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Constructs a new regular expression filter */
|
||||||
|
RegExpFilter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the regular expression which the filter searches for in blocks of text.
|
||||||
|
*
|
||||||
|
* Regular expressions which match the empty string are treated as not matching
|
||||||
|
* anything.
|
||||||
|
*/
|
||||||
|
void setRegExp(const QRegExp& text);
|
||||||
|
/** Returns the regular expression which the filter searches for in blocks of text */
|
||||||
|
QRegExp regExp() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reimplemented to search the filter's text buffer for text matching regExp()
|
||||||
|
*
|
||||||
|
* If regexp matches the empty string, then process() will return immediately
|
||||||
|
* without finding results.
|
||||||
|
*/
|
||||||
|
virtual void process();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Called when a match for the regular expression is encountered. Subclasses should reimplement this
|
||||||
|
* to return custom hotspot types
|
||||||
|
*/
|
||||||
|
virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
|
||||||
|
int endLine,int endColumn);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QRegExp _searchText;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FilterObject;
|
||||||
|
|
||||||
|
/** A filter which matches URLs in blocks of text */
|
||||||
|
class UrlFilter : public RegExpFilter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Hotspot type created by UrlFilter instances. The activate() method opens a web browser
|
||||||
|
* at the given URL when called.
|
||||||
|
*/
|
||||||
|
class HotSpot : public RegExpFilter::HotSpot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HotSpot(int startLine,int startColumn,int endLine,int endColumn);
|
||||||
|
virtual ~HotSpot();
|
||||||
|
|
||||||
|
FilterObject* getUrlObject() const;
|
||||||
|
|
||||||
|
virtual QList<QAction*> actions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a web browser at the current URL. The url itself can be determined using
|
||||||
|
* the capturedTexts() method.
|
||||||
|
*/
|
||||||
|
virtual void activate(const QString& action = QString());
|
||||||
|
|
||||||
|
virtual QString tooltip() const;
|
||||||
|
private:
|
||||||
|
enum UrlType
|
||||||
|
{
|
||||||
|
StandardUrl,
|
||||||
|
Email,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
UrlType urlType() const;
|
||||||
|
|
||||||
|
FilterObject* _urlObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
UrlFilter();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const QRegExp FullUrlRegExp;
|
||||||
|
static const QRegExp EmailAddressRegExp;
|
||||||
|
|
||||||
|
// combined OR of FullUrlRegExp and EmailAddressRegExp
|
||||||
|
static const QRegExp CompleteUrlRegExp;
|
||||||
|
signals:
|
||||||
|
void activated(const QUrl& url);
|
||||||
|
};
|
||||||
|
|
||||||
|
class FilterObject : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
|
||||||
|
|
||||||
|
void emitActivated(const QUrl& url);
|
||||||
|
private slots:
|
||||||
|
void activated();
|
||||||
|
private:
|
||||||
|
Filter::HotSpot* _filter;
|
||||||
|
signals:
|
||||||
|
void activated(const QUrl& url);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chain which allows a group of filters to be processed as one.
|
||||||
|
* The chain owns the filters added to it and deletes them when the chain itself is destroyed.
|
||||||
|
*
|
||||||
|
* Use addFilter() to add a new filter to the chain.
|
||||||
|
* When new text to be filtered arrives, use addLine() to add each additional
|
||||||
|
* line of text which needs to be processed and then after adding the last line, use
|
||||||
|
* process() to cause each filter in the chain to process the text.
|
||||||
|
*
|
||||||
|
* After processing a block of text, the reset() method can be used to set the filter chain's
|
||||||
|
* internal cursor back to the first line.
|
||||||
|
*
|
||||||
|
* The hotSpotAt() method will return the first hotspot which covers a given position.
|
||||||
|
*
|
||||||
|
* The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
|
||||||
|
* a given line respectively.
|
||||||
|
*/
|
||||||
|
class FilterChain : protected QList<Filter*>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~FilterChain();
|
||||||
|
|
||||||
|
/** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */
|
||||||
|
void addFilter(Filter* filter);
|
||||||
|
/** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */
|
||||||
|
void removeFilter(Filter* filter);
|
||||||
|
/** Returns true if the chain contains @p filter */
|
||||||
|
bool containsFilter(Filter* filter);
|
||||||
|
/** Removes all filters from the chain */
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/** Resets each filter in the chain */
|
||||||
|
void reset();
|
||||||
|
/**
|
||||||
|
* Processes each filter in the chain
|
||||||
|
*/
|
||||||
|
void process();
|
||||||
|
|
||||||
|
/** Sets the buffer for each filter in the chain to process. */
|
||||||
|
void setBuffer(const QString* buffer , const QList<int>* linePositions);
|
||||||
|
|
||||||
|
/** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
|
||||||
|
Filter::HotSpot* hotSpotAt(int line , int column) const;
|
||||||
|
/** Returns a list of all the hotspots in all the chain's filters */
|
||||||
|
QList<Filter::HotSpot*> hotSpots() const;
|
||||||
|
/** Returns a list of all hotspots at the given line in all the chain's filters */
|
||||||
|
QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A filter chain which processes character images from terminal displays */
|
||||||
|
class TerminalImageFilterChain : public FilterChain
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TerminalImageFilterChain();
|
||||||
|
virtual ~TerminalImageFilterChain();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current terminal image to @p image.
|
||||||
|
*
|
||||||
|
* @param image The terminal image
|
||||||
|
* @param lines The number of lines in the terminal image
|
||||||
|
* @param columns The number of columns in the terminal image
|
||||||
|
* @param lineProperties The line properties to set for image
|
||||||
|
*/
|
||||||
|
void setImage(const Character* const image , int lines , int columns,
|
||||||
|
const QVector<LineProperty>& lineProperties);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString* _buffer;
|
||||||
|
QList<int>* _linePositions;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Konsole::Filter Filter;
|
||||||
|
|
||||||
|
#endif //FILTER_H
|
@ -0,0 +1,987 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "History.h"
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <kde_file.h>
|
||||||
|
//#include <kdebug.h>
|
||||||
|
|
||||||
|
// Reasonable line size
|
||||||
|
#define LINE_SIZE 1024
|
||||||
|
#define KDE_lseek lseek
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
/*
|
||||||
|
An arbitrary long scroll.
|
||||||
|
|
||||||
|
One can modify the scroll only by adding either cells
|
||||||
|
or newlines, but access it randomly.
|
||||||
|
|
||||||
|
The model is that of an arbitrary wide typewriter scroll
|
||||||
|
in that the scroll is a serie of lines and each line is
|
||||||
|
a serie of cells with no overwriting permitted.
|
||||||
|
|
||||||
|
The implementation provides arbitrary length and numbers
|
||||||
|
of cells and line/column indexed read access to the scroll
|
||||||
|
at constant costs.
|
||||||
|
|
||||||
|
KDE4: Can we use QTemporaryFile here, instead of KTempFile?
|
||||||
|
|
||||||
|
FIXME: some complain about the history buffer comsuming the
|
||||||
|
memory of their machines. This problem is critical
|
||||||
|
since the history does not behave gracefully in cases
|
||||||
|
where the memory is used up completely.
|
||||||
|
|
||||||
|
I put in a workaround that should handle it problem
|
||||||
|
now gracefully. I'm not satisfied with the solution.
|
||||||
|
|
||||||
|
FIXME: Terminating the history is not properly indicated
|
||||||
|
in the menu. We should throw a signal.
|
||||||
|
|
||||||
|
FIXME: There is noticeable decrease in speed, also. Perhaps,
|
||||||
|
there whole feature needs to be revisited therefore.
|
||||||
|
Disadvantage of a more elaborated, say block-oriented
|
||||||
|
scheme with wrap around would be it's complexity.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//FIXME: tempory replacement for tmpfile
|
||||||
|
// this is here one for debugging purpose.
|
||||||
|
|
||||||
|
//#define tmpfile xTmpFile
|
||||||
|
|
||||||
|
// History File ///////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
A Row(X) data type which allows adding elements to the end.
|
||||||
|
*/
|
||||||
|
|
||||||
|
HistoryFile::HistoryFile()
|
||||||
|
: ion(-1),
|
||||||
|
length(0),
|
||||||
|
fileMap(0)
|
||||||
|
{
|
||||||
|
if (tmpFile.open())
|
||||||
|
{
|
||||||
|
tmpFile.setAutoRemove(true);
|
||||||
|
ion = tmpFile.handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryFile::~HistoryFile()
|
||||||
|
{
|
||||||
|
if (fileMap)
|
||||||
|
unmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Mapping the entire file in will cause problems if the history file becomes exceedingly large,
|
||||||
|
//(ie. larger than available memory). HistoryFile::map() should only map in sections of the file at a time,
|
||||||
|
//to avoid this.
|
||||||
|
void HistoryFile::map()
|
||||||
|
{
|
||||||
|
assert( fileMap == 0 );
|
||||||
|
|
||||||
|
fileMap = (char*)mmap( 0 , length , PROT_READ , MAP_PRIVATE , ion , 0 );
|
||||||
|
|
||||||
|
//if mmap'ing fails, fall back to the read-lseek combination
|
||||||
|
if ( fileMap == MAP_FAILED )
|
||||||
|
{
|
||||||
|
readWriteBalance = 0;
|
||||||
|
fileMap = 0;
|
||||||
|
qDebug() << __FILE__ << __LINE__ << ": mmap'ing history failed. errno = " << errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryFile::unmap()
|
||||||
|
{
|
||||||
|
int result = munmap( fileMap , length );
|
||||||
|
assert( result == 0 ); Q_UNUSED( result );
|
||||||
|
|
||||||
|
fileMap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryFile::isMapped()
|
||||||
|
{
|
||||||
|
return (fileMap != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryFile::add(const unsigned char* bytes, int len)
|
||||||
|
{
|
||||||
|
if ( fileMap )
|
||||||
|
unmap();
|
||||||
|
|
||||||
|
readWriteBalance++;
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = KDE_lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryFile::add.seek"); return; }
|
||||||
|
rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryFile::add.write"); return; }
|
||||||
|
length += rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryFile::get(unsigned char* bytes, int len, int loc)
|
||||||
|
{
|
||||||
|
//count number of get() calls vs. number of add() calls.
|
||||||
|
//If there are many more get() calls compared with add()
|
||||||
|
//calls (decided by using MAP_THRESHOLD) then mmap the log
|
||||||
|
//file to improve performance.
|
||||||
|
readWriteBalance--;
|
||||||
|
if ( !fileMap && readWriteBalance < MAP_THRESHOLD )
|
||||||
|
map();
|
||||||
|
|
||||||
|
if ( fileMap )
|
||||||
|
{
|
||||||
|
for (int i=0;i<len;i++)
|
||||||
|
bytes[i]=fileMap[loc+i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (loc < 0 || len < 0 || loc + len > length)
|
||||||
|
fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
|
||||||
|
rc = KDE_lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryFile::get.seek"); return; }
|
||||||
|
rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryFile::get.read"); return; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryFile::len()
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// History Scroll abstract base class //////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
HistoryScroll::HistoryScroll(HistoryType* t)
|
||||||
|
: m_histType(t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll::~HistoryScroll()
|
||||||
|
{
|
||||||
|
delete m_histType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryScroll::hasScroll()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// History Scroll File //////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
The history scroll makes a Row(Row(Cell)) from
|
||||||
|
two history buffers. The index buffer contains
|
||||||
|
start of line positions which refere to the cells
|
||||||
|
buffer.
|
||||||
|
|
||||||
|
Note that index[0] addresses the second line
|
||||||
|
(line #1), while the first line (line #0) starts
|
||||||
|
at 0 in cells.
|
||||||
|
*/
|
||||||
|
|
||||||
|
HistoryScrollFile::HistoryScrollFile(const QString &logFileName)
|
||||||
|
: HistoryScroll(new HistoryTypeFile(logFileName)),
|
||||||
|
m_logFileName(logFileName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScrollFile::~HistoryScrollFile()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollFile::getLines()
|
||||||
|
{
|
||||||
|
return index.len() / sizeof(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollFile::getLineLen(int lineno)
|
||||||
|
{
|
||||||
|
return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(Character);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryScrollFile::isWrappedLine(int lineno)
|
||||||
|
{
|
||||||
|
if (lineno>=0 && lineno <= getLines()) {
|
||||||
|
unsigned char flag;
|
||||||
|
lineflags.get((unsigned char*)&flag,sizeof(unsigned char),(lineno)*sizeof(unsigned char));
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollFile::startOfLine(int lineno)
|
||||||
|
{
|
||||||
|
if (lineno <= 0) return 0;
|
||||||
|
if (lineno <= getLines())
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!index.isMapped())
|
||||||
|
index.map();
|
||||||
|
|
||||||
|
int res;
|
||||||
|
index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return cells.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollFile::getCells(int lineno, int colno, int count, Character res[])
|
||||||
|
{
|
||||||
|
cells.get((unsigned char*)res,count*sizeof(Character),startOfLine(lineno)+colno*sizeof(Character));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollFile::addCells(const Character text[], int count)
|
||||||
|
{
|
||||||
|
cells.add((unsigned char*)text,count*sizeof(Character));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollFile::addLine(bool previousWrapped)
|
||||||
|
{
|
||||||
|
if (index.isMapped())
|
||||||
|
index.unmap();
|
||||||
|
|
||||||
|
int locn = cells.len();
|
||||||
|
index.add((unsigned char*)&locn,sizeof(int));
|
||||||
|
unsigned char flags = previousWrapped ? 0x01 : 0x00;
|
||||||
|
lineflags.add((unsigned char*)&flags,sizeof(unsigned char));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// History Scroll Buffer //////////////////////////////////////
|
||||||
|
HistoryScrollBuffer::HistoryScrollBuffer(unsigned int maxLineCount)
|
||||||
|
: HistoryScroll(new HistoryTypeBuffer(maxLineCount))
|
||||||
|
,_historyBuffer()
|
||||||
|
,_maxLineCount(0)
|
||||||
|
,_usedLines(0)
|
||||||
|
,_head(0)
|
||||||
|
{
|
||||||
|
setMaxNbLines(maxLineCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScrollBuffer::~HistoryScrollBuffer()
|
||||||
|
{
|
||||||
|
delete[] _historyBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBuffer::addCellsVector(const QVector<Character>& cells)
|
||||||
|
{
|
||||||
|
_head++;
|
||||||
|
if ( _usedLines < _maxLineCount )
|
||||||
|
_usedLines++;
|
||||||
|
|
||||||
|
if ( _head >= _maxLineCount )
|
||||||
|
{
|
||||||
|
_head = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_historyBuffer[bufferIndex(_usedLines-1)] = cells;
|
||||||
|
_wrappedLine[bufferIndex(_usedLines-1)] = false;
|
||||||
|
}
|
||||||
|
void HistoryScrollBuffer::addCells(const Character a[], int count)
|
||||||
|
{
|
||||||
|
HistoryLine newLine(count);
|
||||||
|
qCopy(a,a+count,newLine.begin());
|
||||||
|
|
||||||
|
addCellsVector(newLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBuffer::addLine(bool previousWrapped)
|
||||||
|
{
|
||||||
|
_wrappedLine[bufferIndex(_usedLines-1)] = previousWrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollBuffer::getLines()
|
||||||
|
{
|
||||||
|
return _usedLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollBuffer::getLineLen(int lineNumber)
|
||||||
|
{
|
||||||
|
Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
|
||||||
|
|
||||||
|
if ( lineNumber < _usedLines )
|
||||||
|
{
|
||||||
|
return _historyBuffer[bufferIndex(lineNumber)].size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryScrollBuffer::isWrappedLine(int lineNumber)
|
||||||
|
{
|
||||||
|
Q_ASSERT( lineNumber >= 0 && lineNumber < _maxLineCount );
|
||||||
|
|
||||||
|
if (lineNumber < _usedLines)
|
||||||
|
{
|
||||||
|
//kDebug() << "Line" << lineNumber << "wrapped is" << _wrappedLine[bufferIndex(lineNumber)];
|
||||||
|
return _wrappedLine[bufferIndex(lineNumber)];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBuffer::getCells(int lineNumber, int startColumn, int count, Character buffer[])
|
||||||
|
{
|
||||||
|
if ( count == 0 ) return;
|
||||||
|
|
||||||
|
Q_ASSERT( lineNumber < _maxLineCount );
|
||||||
|
|
||||||
|
if (lineNumber >= _usedLines)
|
||||||
|
{
|
||||||
|
memset(buffer, 0, count * sizeof(Character));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HistoryLine& line = _historyBuffer[bufferIndex(lineNumber)];
|
||||||
|
|
||||||
|
//kDebug() << "startCol " << startColumn;
|
||||||
|
//kDebug() << "line.size() " << line.size();
|
||||||
|
//kDebug() << "count " << count;
|
||||||
|
|
||||||
|
Q_ASSERT( startColumn <= line.size() - count );
|
||||||
|
|
||||||
|
memcpy(buffer, line.constData() + startColumn , count * sizeof(Character));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBuffer::setMaxNbLines(unsigned int lineCount)
|
||||||
|
{
|
||||||
|
HistoryLine* oldBuffer = _historyBuffer;
|
||||||
|
HistoryLine* newBuffer = new HistoryLine[lineCount];
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < qMin(_usedLines,(int)lineCount) ; i++ )
|
||||||
|
{
|
||||||
|
newBuffer[i] = oldBuffer[bufferIndex(i)];
|
||||||
|
}
|
||||||
|
|
||||||
|
_usedLines = qMin(_usedLines,(int)lineCount);
|
||||||
|
_maxLineCount = lineCount;
|
||||||
|
_head = ( _usedLines == _maxLineCount ) ? 0 : _usedLines-1;
|
||||||
|
|
||||||
|
_historyBuffer = newBuffer;
|
||||||
|
delete[] oldBuffer;
|
||||||
|
|
||||||
|
_wrappedLine.resize(lineCount);
|
||||||
|
dynamic_cast<HistoryTypeBuffer*>(m_histType)->m_nbLines = lineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollBuffer::bufferIndex(int lineNumber)
|
||||||
|
{
|
||||||
|
Q_ASSERT( lineNumber >= 0 );
|
||||||
|
Q_ASSERT( lineNumber < _maxLineCount );
|
||||||
|
Q_ASSERT( (_usedLines == _maxLineCount) || lineNumber <= _head );
|
||||||
|
|
||||||
|
if ( _usedLines == _maxLineCount )
|
||||||
|
{
|
||||||
|
return (_head+lineNumber+1) % _maxLineCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return lineNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// History Scroll None //////////////////////////////////////
|
||||||
|
|
||||||
|
HistoryScrollNone::HistoryScrollNone()
|
||||||
|
: HistoryScroll(new HistoryTypeNone())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScrollNone::~HistoryScrollNone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryScrollNone::hasScroll()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollNone::getLines()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollNone::getLineLen(int)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryScrollNone::isWrappedLine(int /*lineno*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollNone::getCells(int, int, int, Character [])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollNone::addCells(const Character [], int)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollNone::addLine(bool)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// History Scroll BlockArray //////////////////////////////////////
|
||||||
|
|
||||||
|
HistoryScrollBlockArray::HistoryScrollBlockArray(size_t size)
|
||||||
|
: HistoryScroll(new HistoryTypeBlockArray(size))
|
||||||
|
{
|
||||||
|
m_blockArray.setHistorySize(size); // nb. of lines.
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScrollBlockArray::~HistoryScrollBlockArray()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollBlockArray::getLines()
|
||||||
|
{
|
||||||
|
return m_lineLengths.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryScrollBlockArray::getLineLen(int lineno)
|
||||||
|
{
|
||||||
|
if ( m_lineLengths.contains(lineno) )
|
||||||
|
return m_lineLengths[lineno];
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryScrollBlockArray::isWrappedLine(int /*lineno*/)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBlockArray::getCells(int lineno, int colno,
|
||||||
|
int count, Character res[])
|
||||||
|
{
|
||||||
|
if (!count) return;
|
||||||
|
|
||||||
|
const Block *b = m_blockArray.at(lineno);
|
||||||
|
|
||||||
|
if (!b) {
|
||||||
|
memset(res, 0, count * sizeof(Character)); // still better than random data
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(((colno + count) * sizeof(Character)) < ENTRIES);
|
||||||
|
memcpy(res, b->data + (colno * sizeof(Character)), count * sizeof(Character));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBlockArray::addCells(const Character a[], int count)
|
||||||
|
{
|
||||||
|
Block *b = m_blockArray.lastBlock();
|
||||||
|
|
||||||
|
if (!b) return;
|
||||||
|
|
||||||
|
// put cells in block's data
|
||||||
|
assert((count * sizeof(Character)) < ENTRIES);
|
||||||
|
|
||||||
|
memset(b->data, 0, ENTRIES);
|
||||||
|
|
||||||
|
memcpy(b->data, a, count * sizeof(Character));
|
||||||
|
b->size = count * sizeof(Character);
|
||||||
|
|
||||||
|
size_t res = m_blockArray.newBlock();
|
||||||
|
assert (res > 0);
|
||||||
|
Q_UNUSED( res );
|
||||||
|
|
||||||
|
m_lineLengths.insert(m_blockArray.getCurrent(), count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryScrollBlockArray::addLine(bool)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
// Compact History Scroll //////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////
|
||||||
|
void* CompactHistoryBlock::allocate ( size_t length )
|
||||||
|
{
|
||||||
|
Q_ASSERT ( length > 0 );
|
||||||
|
if ( tail-blockStart+length > blockLength )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
void* block = tail;
|
||||||
|
tail += length;
|
||||||
|
//kDebug() << "allocated " << length << " bytes at address " << block;
|
||||||
|
allocCount++;
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryBlock::deallocate ( )
|
||||||
|
{
|
||||||
|
allocCount--;
|
||||||
|
Q_ASSERT ( allocCount >= 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CompactHistoryBlockList::allocate(size_t size)
|
||||||
|
{
|
||||||
|
CompactHistoryBlock* block;
|
||||||
|
if ( list.isEmpty() || list.last()->remaining() < size)
|
||||||
|
{
|
||||||
|
block = new CompactHistoryBlock();
|
||||||
|
list.append ( block );
|
||||||
|
//kDebug() << "new block created, remaining " << block->remaining() << "number of blocks=" << list.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block = list.last();
|
||||||
|
//kDebug() << "old block used, remaining " << block->remaining();
|
||||||
|
}
|
||||||
|
return block->allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryBlockList::deallocate(void* ptr)
|
||||||
|
{
|
||||||
|
Q_ASSERT( !list.isEmpty());
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
CompactHistoryBlock *block = list.at(i);
|
||||||
|
while ( i<list.size() && !block->contains(ptr) )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
block=list.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT( i<list.size() );
|
||||||
|
|
||||||
|
block->deallocate();
|
||||||
|
|
||||||
|
if (!block->isInUse())
|
||||||
|
{
|
||||||
|
list.removeAt(i);
|
||||||
|
delete block;
|
||||||
|
//kDebug() << "block deleted, new size = " << list.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactHistoryBlockList::~CompactHistoryBlockList()
|
||||||
|
{
|
||||||
|
qDeleteAll ( list.begin(), list.end() );
|
||||||
|
list.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CompactHistoryLine::operator new (size_t size, CompactHistoryBlockList& blockList)
|
||||||
|
{
|
||||||
|
return blockList.allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactHistoryLine::CompactHistoryLine ( const TextLine& line, CompactHistoryBlockList& bList )
|
||||||
|
: blockList(bList),
|
||||||
|
formatLength(0)
|
||||||
|
{
|
||||||
|
length=line.size();
|
||||||
|
|
||||||
|
if (line.size() > 0) {
|
||||||
|
formatLength=1;
|
||||||
|
int k=1;
|
||||||
|
|
||||||
|
// count number of different formats in this text line
|
||||||
|
Character c = line[0];
|
||||||
|
while ( k<length )
|
||||||
|
{
|
||||||
|
if ( !(line[k].equalsFormat(c)))
|
||||||
|
{
|
||||||
|
formatLength++; // format change detected
|
||||||
|
c=line[k];
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//kDebug() << "number of different formats in string: " << formatLength;
|
||||||
|
formatArray = (CharacterFormat*) blockList.allocate(sizeof(CharacterFormat)*formatLength);
|
||||||
|
Q_ASSERT (formatArray!=NULL);
|
||||||
|
text = (quint16*) blockList.allocate(sizeof(quint16)*line.size());
|
||||||
|
Q_ASSERT (text!=NULL);
|
||||||
|
|
||||||
|
length=line.size();
|
||||||
|
formatLength=formatLength;
|
||||||
|
wrapped=false;
|
||||||
|
|
||||||
|
// record formats and their positions in the format array
|
||||||
|
c=line[0];
|
||||||
|
formatArray[0].setFormat ( c );
|
||||||
|
formatArray[0].startPos=0; // there's always at least 1 format (for the entire line, unless a change happens)
|
||||||
|
|
||||||
|
k=1; // look for possible format changes
|
||||||
|
int j=1;
|
||||||
|
while ( k<length && j<formatLength )
|
||||||
|
{
|
||||||
|
if (!(line[k].equalsFormat(c)))
|
||||||
|
{
|
||||||
|
c=line[k];
|
||||||
|
formatArray[j].setFormat(c);
|
||||||
|
formatArray[j].startPos=k;
|
||||||
|
//kDebug() << "format entry " << j << " at pos " << formatArray[j].startPos << " " << &(formatArray[j].startPos) ;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy character values
|
||||||
|
for ( int i=0; i<line.size(); i++ )
|
||||||
|
{
|
||||||
|
text[i]=line[i].character;
|
||||||
|
//kDebug() << "char " << i << " at mem " << &(text[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//kDebug() << "line created, length " << length << " at " << &(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactHistoryLine::~CompactHistoryLine()
|
||||||
|
{
|
||||||
|
//kDebug() << "~CHL";
|
||||||
|
if (length>0) {
|
||||||
|
blockList.deallocate(text);
|
||||||
|
blockList.deallocate(formatArray);
|
||||||
|
}
|
||||||
|
blockList.deallocate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryLine::getCharacter ( int index, Character &r )
|
||||||
|
{
|
||||||
|
Q_ASSERT ( index < length );
|
||||||
|
int formatPos=0;
|
||||||
|
while ( ( formatPos+1 ) < formatLength && index >= formatArray[formatPos+1].startPos )
|
||||||
|
formatPos++;
|
||||||
|
|
||||||
|
r.character=text[index];
|
||||||
|
r.rendition = formatArray[formatPos].rendition;
|
||||||
|
r.foregroundColor = formatArray[formatPos].fgColor;
|
||||||
|
r.backgroundColor = formatArray[formatPos].bgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryLine::getCharacters ( Character* array, int length, int startColumn )
|
||||||
|
{
|
||||||
|
Q_ASSERT ( startColumn >= 0 && length >= 0 );
|
||||||
|
Q_ASSERT ( startColumn+length <= ( int ) getLength() );
|
||||||
|
|
||||||
|
for ( int i=startColumn; i<length+startColumn; i++ )
|
||||||
|
{
|
||||||
|
getCharacter ( i, array[i-startColumn] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactHistoryScroll::CompactHistoryScroll ( unsigned int maxLineCount )
|
||||||
|
: HistoryScroll ( new CompactHistoryType ( maxLineCount ) )
|
||||||
|
,lines()
|
||||||
|
,blockList()
|
||||||
|
{
|
||||||
|
//kDebug() << "scroll of length " << maxLineCount << " created";
|
||||||
|
setMaxNbLines ( maxLineCount );
|
||||||
|
}
|
||||||
|
|
||||||
|
CompactHistoryScroll::~CompactHistoryScroll()
|
||||||
|
{
|
||||||
|
qDeleteAll ( lines.begin(), lines.end() );
|
||||||
|
lines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryScroll::addCellsVector ( const TextLine& cells )
|
||||||
|
{
|
||||||
|
CompactHistoryLine *line;
|
||||||
|
line = new(blockList) CompactHistoryLine ( cells, blockList );
|
||||||
|
|
||||||
|
if ( lines.size() > ( int ) _maxLineCount )
|
||||||
|
{
|
||||||
|
delete lines.takeAt ( 0 );
|
||||||
|
}
|
||||||
|
lines.append ( line );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryScroll::addCells ( const Character a[], int count )
|
||||||
|
{
|
||||||
|
TextLine newLine ( count );
|
||||||
|
qCopy ( a,a+count,newLine.begin() );
|
||||||
|
addCellsVector ( newLine );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryScroll::addLine ( bool previousWrapped )
|
||||||
|
{
|
||||||
|
CompactHistoryLine *line = lines.last();
|
||||||
|
//kDebug() << "last line at address " << line;
|
||||||
|
line->setWrapped(previousWrapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CompactHistoryScroll::getLines()
|
||||||
|
{
|
||||||
|
return lines.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CompactHistoryScroll::getLineLen ( int lineNumber )
|
||||||
|
{
|
||||||
|
Q_ASSERT ( lineNumber >= 0 && lineNumber < lines.size() );
|
||||||
|
CompactHistoryLine* line = lines[lineNumber];
|
||||||
|
//kDebug() << "request for line at address " << line;
|
||||||
|
return line->getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CompactHistoryScroll::getCells ( int lineNumber, int startColumn, int count, Character buffer[] )
|
||||||
|
{
|
||||||
|
if ( count == 0 ) return;
|
||||||
|
Q_ASSERT ( lineNumber < lines.size() );
|
||||||
|
CompactHistoryLine* line = lines[lineNumber];
|
||||||
|
Q_ASSERT ( startColumn >= 0 );
|
||||||
|
Q_ASSERT ( (unsigned int)startColumn <= line->getLength() - count );
|
||||||
|
line->getCharacters ( buffer, count, startColumn );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompactHistoryScroll::setMaxNbLines ( unsigned int lineCount )
|
||||||
|
{
|
||||||
|
_maxLineCount = lineCount;
|
||||||
|
|
||||||
|
while (lines.size() > (int) lineCount) {
|
||||||
|
delete lines.takeAt(0);
|
||||||
|
}
|
||||||
|
//kDebug() << "set max lines to: " << _maxLineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompactHistoryScroll::isWrappedLine ( int lineNumber )
|
||||||
|
{
|
||||||
|
Q_ASSERT ( lineNumber < lines.size() );
|
||||||
|
return lines[lineNumber]->isWrapped();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// History Types
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
HistoryType::HistoryType()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryType::~HistoryType()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
HistoryTypeNone::HistoryTypeNone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryTypeNone::isEnabled() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll* HistoryTypeNone::scroll(HistoryScroll *old) const
|
||||||
|
{
|
||||||
|
delete old;
|
||||||
|
return new HistoryScrollNone();
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryTypeNone::maximumLineCount() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
HistoryTypeBlockArray::HistoryTypeBlockArray(size_t size)
|
||||||
|
: m_size(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryTypeBlockArray::isEnabled() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryTypeBlockArray::maximumLineCount() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll* HistoryTypeBlockArray::scroll(HistoryScroll *old) const
|
||||||
|
{
|
||||||
|
delete old;
|
||||||
|
return new HistoryScrollBlockArray(m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
HistoryTypeBuffer::HistoryTypeBuffer(unsigned int nbLines)
|
||||||
|
: m_nbLines(nbLines)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryTypeBuffer::isEnabled() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryTypeBuffer::maximumLineCount() const
|
||||||
|
{
|
||||||
|
return m_nbLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll* HistoryTypeBuffer::scroll(HistoryScroll *old) const
|
||||||
|
{
|
||||||
|
if (old)
|
||||||
|
{
|
||||||
|
HistoryScrollBuffer *oldBuffer = dynamic_cast<HistoryScrollBuffer*>(old);
|
||||||
|
if (oldBuffer)
|
||||||
|
{
|
||||||
|
oldBuffer->setMaxNbLines(m_nbLines);
|
||||||
|
return oldBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll *newScroll = new HistoryScrollBuffer(m_nbLines);
|
||||||
|
int lines = old->getLines();
|
||||||
|
int startLine = 0;
|
||||||
|
if (lines > (int) m_nbLines)
|
||||||
|
startLine = lines - m_nbLines;
|
||||||
|
|
||||||
|
Character line[LINE_SIZE];
|
||||||
|
for(int i = startLine; i < lines; i++)
|
||||||
|
{
|
||||||
|
int size = old->getLineLen(i);
|
||||||
|
if (size > LINE_SIZE)
|
||||||
|
{
|
||||||
|
Character *tmp_line = new Character[size];
|
||||||
|
old->getCells(i, 0, size, tmp_line);
|
||||||
|
newScroll->addCells(tmp_line, size);
|
||||||
|
newScroll->addLine(old->isWrappedLine(i));
|
||||||
|
delete [] tmp_line;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
old->getCells(i, 0, size, line);
|
||||||
|
newScroll->addCells(line, size);
|
||||||
|
newScroll->addLine(old->isWrappedLine(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete old;
|
||||||
|
return newScroll;
|
||||||
|
}
|
||||||
|
return new HistoryScrollBuffer(m_nbLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
HistoryTypeFile::HistoryTypeFile(const QString& fileName)
|
||||||
|
: m_fileName(fileName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistoryTypeFile::isEnabled() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& HistoryTypeFile::getFileName() const
|
||||||
|
{
|
||||||
|
return m_fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll* HistoryTypeFile::scroll(HistoryScroll *old) const
|
||||||
|
{
|
||||||
|
if (dynamic_cast<HistoryFile *>(old))
|
||||||
|
return old; // Unchanged.
|
||||||
|
|
||||||
|
HistoryScroll *newScroll = new HistoryScrollFile(m_fileName);
|
||||||
|
|
||||||
|
Character line[LINE_SIZE];
|
||||||
|
int lines = (old != 0) ? old->getLines() : 0;
|
||||||
|
for(int i = 0; i < lines; i++)
|
||||||
|
{
|
||||||
|
int size = old->getLineLen(i);
|
||||||
|
if (size > LINE_SIZE)
|
||||||
|
{
|
||||||
|
Character *tmp_line = new Character[size];
|
||||||
|
old->getCells(i, 0, size, tmp_line);
|
||||||
|
newScroll->addCells(tmp_line, size);
|
||||||
|
newScroll->addLine(old->isWrappedLine(i));
|
||||||
|
delete [] tmp_line;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
old->getCells(i, 0, size, line);
|
||||||
|
newScroll->addCells(line, size);
|
||||||
|
newScroll->addLine(old->isWrappedLine(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete old;
|
||||||
|
return newScroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HistoryTypeFile::maximumLineCount() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
|
||||||
|
CompactHistoryType::CompactHistoryType ( unsigned int nbLines )
|
||||||
|
: m_nbLines ( nbLines )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompactHistoryType::isEnabled() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CompactHistoryType::maximumLineCount() const
|
||||||
|
{
|
||||||
|
return m_nbLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryScroll* CompactHistoryType::scroll ( HistoryScroll *old ) const
|
||||||
|
{
|
||||||
|
if ( old )
|
||||||
|
{
|
||||||
|
CompactHistoryScroll *oldBuffer = dynamic_cast<CompactHistoryScroll*> ( old );
|
||||||
|
if ( oldBuffer )
|
||||||
|
{
|
||||||
|
oldBuffer->setMaxNbLines ( m_nbLines );
|
||||||
|
return oldBuffer;
|
||||||
|
}
|
||||||
|
delete old;
|
||||||
|
}
|
||||||
|
return new CompactHistoryScroll ( m_nbLines );
|
||||||
|
}
|
@ -0,0 +1,493 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEHISTORY_H
|
||||||
|
#define TEHISTORY_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QBitRef>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <ktemporaryfile.h>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "BlockArray.h"
|
||||||
|
#include "Character.h"
|
||||||
|
|
||||||
|
// map
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/*
|
||||||
|
An extendable tmpfile(1) based buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class HistoryFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryFile();
|
||||||
|
virtual ~HistoryFile();
|
||||||
|
|
||||||
|
virtual void add(const unsigned char* bytes, int len);
|
||||||
|
virtual void get(unsigned char* bytes, int len, int loc);
|
||||||
|
virtual int len();
|
||||||
|
|
||||||
|
//mmaps the file in read-only mode
|
||||||
|
void map();
|
||||||
|
//un-mmaps the file
|
||||||
|
void unmap();
|
||||||
|
//returns true if the file is mmap'ed
|
||||||
|
bool isMapped();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
int ion;
|
||||||
|
int length;
|
||||||
|
QTemporaryFile tmpFile;
|
||||||
|
|
||||||
|
//pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed
|
||||||
|
char* fileMap;
|
||||||
|
|
||||||
|
//incremented whenver 'add' is called and decremented whenever
|
||||||
|
//'get' is called.
|
||||||
|
//this is used to detect when a large number of lines are being read and processed from the history
|
||||||
|
//and automatically mmap the file for better performance (saves the overhead of many lseek-read calls).
|
||||||
|
int readWriteBalance;
|
||||||
|
|
||||||
|
//when readWriteBalance goes below this threshold, the file will be mmap'ed automatically
|
||||||
|
static const int MAP_THRESHOLD = -1000;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Abstract base class for file and buffer versions
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
class HistoryType;
|
||||||
|
|
||||||
|
class HistoryScroll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryScroll(HistoryType*);
|
||||||
|
virtual ~HistoryScroll();
|
||||||
|
|
||||||
|
virtual bool hasScroll();
|
||||||
|
|
||||||
|
// access to history
|
||||||
|
virtual int getLines() = 0;
|
||||||
|
virtual int getLineLen(int lineno) = 0;
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]) = 0;
|
||||||
|
virtual bool isWrappedLine(int lineno) = 0;
|
||||||
|
|
||||||
|
// backward compatibility (obsolete)
|
||||||
|
Character getCell(int lineno, int colno) { Character res; getCells(lineno,colno,1,&res); return res; }
|
||||||
|
|
||||||
|
// adding lines.
|
||||||
|
virtual void addCells(const Character a[], int count) = 0;
|
||||||
|
// convenience method - this is virtual so that subclasses can take advantage
|
||||||
|
// of QVector's implicit copying
|
||||||
|
virtual void addCellsVector(const QVector<Character>& cells)
|
||||||
|
{
|
||||||
|
addCells(cells.data(),cells.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void addLine(bool previousWrapped=false) = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: Passing around constant references to HistoryType instances
|
||||||
|
// is very unsafe, because those references will no longer
|
||||||
|
// be valid if the history scroll is deleted.
|
||||||
|
//
|
||||||
|
const HistoryType& getType() { return *m_histType; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HistoryType* m_histType;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// File-based history (e.g. file log, no limitation in length)
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class HistoryScrollFile : public HistoryScroll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryScrollFile(const QString &logFileName);
|
||||||
|
virtual ~HistoryScrollFile();
|
||||||
|
|
||||||
|
virtual int getLines();
|
||||||
|
virtual int getLineLen(int lineno);
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]);
|
||||||
|
virtual bool isWrappedLine(int lineno);
|
||||||
|
|
||||||
|
virtual void addCells(const Character a[], int count);
|
||||||
|
virtual void addLine(bool previousWrapped=false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int startOfLine(int lineno);
|
||||||
|
|
||||||
|
QString m_logFileName;
|
||||||
|
HistoryFile index; // lines Row(int)
|
||||||
|
HistoryFile cells; // text Row(Character)
|
||||||
|
HistoryFile lineflags; // flags Row(unsigned char)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Buffer-based history (limited to a fixed nb of lines)
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
class HistoryScrollBuffer : public HistoryScroll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef QVector<Character> HistoryLine;
|
||||||
|
|
||||||
|
HistoryScrollBuffer(unsigned int maxNbLines = 1000);
|
||||||
|
virtual ~HistoryScrollBuffer();
|
||||||
|
|
||||||
|
virtual int getLines();
|
||||||
|
virtual int getLineLen(int lineno);
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]);
|
||||||
|
virtual bool isWrappedLine(int lineno);
|
||||||
|
|
||||||
|
virtual void addCells(const Character a[], int count);
|
||||||
|
virtual void addCellsVector(const QVector<Character>& cells);
|
||||||
|
virtual void addLine(bool previousWrapped=false);
|
||||||
|
|
||||||
|
void setMaxNbLines(unsigned int nbLines);
|
||||||
|
unsigned int maxNbLines() { return _maxLineCount; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
int bufferIndex(int lineNumber);
|
||||||
|
|
||||||
|
HistoryLine* _historyBuffer;
|
||||||
|
QBitArray _wrappedLine;
|
||||||
|
int _maxLineCount;
|
||||||
|
int _usedLines;
|
||||||
|
int _head;
|
||||||
|
|
||||||
|
//QVector<histline*> m_histBuffer;
|
||||||
|
//QBitArray m_wrappedLine;
|
||||||
|
//unsigned int m_maxNbLines;
|
||||||
|
//unsigned int m_nbLines;
|
||||||
|
//unsigned int m_arrayIndex;
|
||||||
|
//bool m_buffFilled;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*class HistoryScrollBufferV2 : public HistoryScroll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int getLines();
|
||||||
|
virtual int getLineLen(int lineno);
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]);
|
||||||
|
virtual bool isWrappedLine(int lineno);
|
||||||
|
|
||||||
|
virtual void addCells(const Character a[], int count);
|
||||||
|
virtual void addCells(const QVector<Character>& cells);
|
||||||
|
virtual void addLine(bool previousWrapped=false);
|
||||||
|
|
||||||
|
};*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// Nothing-based history (no history :-)
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
class HistoryScrollNone : public HistoryScroll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryScrollNone();
|
||||||
|
virtual ~HistoryScrollNone();
|
||||||
|
|
||||||
|
virtual bool hasScroll();
|
||||||
|
|
||||||
|
virtual int getLines();
|
||||||
|
virtual int getLineLen(int lineno);
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]);
|
||||||
|
virtual bool isWrappedLine(int lineno);
|
||||||
|
|
||||||
|
virtual void addCells(const Character a[], int count);
|
||||||
|
virtual void addLine(bool previousWrapped=false);
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// BlockArray-based history
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
class HistoryScrollBlockArray : public HistoryScroll
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryScrollBlockArray(size_t size);
|
||||||
|
virtual ~HistoryScrollBlockArray();
|
||||||
|
|
||||||
|
virtual int getLines();
|
||||||
|
virtual int getLineLen(int lineno);
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]);
|
||||||
|
virtual bool isWrappedLine(int lineno);
|
||||||
|
|
||||||
|
virtual void addCells(const Character a[], int count);
|
||||||
|
virtual void addLine(bool previousWrapped=false);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BlockArray m_blockArray;
|
||||||
|
QHash<int,size_t> m_lineLengths;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// History using compact storage
|
||||||
|
// This implementation uses a list of fixed-sized blocks
|
||||||
|
// where history lines are allocated in (avoids heap fragmentation)
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
typedef QVector<Character> TextLine;
|
||||||
|
|
||||||
|
class CharacterFormat
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool equalsFormat(const CharacterFormat &other) const {
|
||||||
|
return other.rendition==rendition && other.fgColor==fgColor && other.bgColor==bgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equalsFormat(const Character &c) const {
|
||||||
|
return c.rendition==rendition && c.foregroundColor==fgColor && c.backgroundColor==bgColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFormat(const Character& c) {
|
||||||
|
rendition=c.rendition;
|
||||||
|
fgColor=c.foregroundColor;
|
||||||
|
bgColor=c.backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterColor fgColor, bgColor;
|
||||||
|
quint16 startPos;
|
||||||
|
quint8 rendition;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompactHistoryBlock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CompactHistoryBlock(){
|
||||||
|
blockLength = 4096*64; // 256kb
|
||||||
|
head = (quint8*) mmap(0, blockLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||||
|
//head = (quint8*) malloc(blockLength);
|
||||||
|
Q_ASSERT(head != MAP_FAILED);
|
||||||
|
tail = blockStart = head;
|
||||||
|
allocCount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CompactHistoryBlock(){
|
||||||
|
//free(blockStart);
|
||||||
|
munmap(blockStart, blockLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual unsigned int remaining(){ return blockStart+blockLength-tail;}
|
||||||
|
virtual unsigned length() { return blockLength; }
|
||||||
|
virtual void* allocate(size_t length);
|
||||||
|
virtual bool contains(void *addr) {return addr>=blockStart && addr<(blockStart+blockLength);}
|
||||||
|
virtual void deallocate();
|
||||||
|
virtual bool isInUse(){ return allocCount!=0; } ;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t blockLength;
|
||||||
|
quint8* head;
|
||||||
|
quint8* tail;
|
||||||
|
quint8* blockStart;
|
||||||
|
int allocCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompactHistoryBlockList {
|
||||||
|
public:
|
||||||
|
CompactHistoryBlockList() {};
|
||||||
|
~CompactHistoryBlockList();
|
||||||
|
|
||||||
|
void *allocate( size_t size );
|
||||||
|
void deallocate(void *);
|
||||||
|
int length() {return list.size();}
|
||||||
|
private:
|
||||||
|
QList<CompactHistoryBlock*> list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompactHistoryLine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CompactHistoryLine(const TextLine&, CompactHistoryBlockList& blockList);
|
||||||
|
virtual ~CompactHistoryLine();
|
||||||
|
|
||||||
|
// custom new operator to allocate memory from custom pool instead of heap
|
||||||
|
static void *operator new( size_t size, CompactHistoryBlockList& blockList);
|
||||||
|
static void operator delete( void *) { /* do nothing, deallocation from pool is done in destructor*/ } ;
|
||||||
|
|
||||||
|
virtual void getCharacters(Character* array, int length, int startColumn) ;
|
||||||
|
virtual void getCharacter(int index, Character &r) ;
|
||||||
|
virtual bool isWrapped() const {return wrapped;};
|
||||||
|
virtual void setWrapped(bool isWrapped) { wrapped=isWrapped;};
|
||||||
|
virtual unsigned int getLength() const {return length;};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CompactHistoryBlockList& blockList;
|
||||||
|
CharacterFormat* formatArray;
|
||||||
|
quint16 length;
|
||||||
|
quint16* text;
|
||||||
|
quint16 formatLength;
|
||||||
|
bool wrapped;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompactHistoryScroll : public HistoryScroll
|
||||||
|
{
|
||||||
|
typedef QList<CompactHistoryLine*> HistoryArray;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CompactHistoryScroll(unsigned int maxNbLines = 1000);
|
||||||
|
virtual ~CompactHistoryScroll();
|
||||||
|
|
||||||
|
virtual int getLines();
|
||||||
|
virtual int getLineLen(int lineno);
|
||||||
|
virtual void getCells(int lineno, int colno, int count, Character res[]);
|
||||||
|
virtual bool isWrappedLine(int lineno);
|
||||||
|
|
||||||
|
virtual void addCells(const Character a[], int count);
|
||||||
|
virtual void addCellsVector(const TextLine& cells);
|
||||||
|
virtual void addLine(bool previousWrapped=false);
|
||||||
|
|
||||||
|
void setMaxNbLines(unsigned int nbLines);
|
||||||
|
unsigned int maxNbLines() const { return _maxLineCount; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool hasDifferentColors(const TextLine& line) const;
|
||||||
|
HistoryArray lines;
|
||||||
|
CompactHistoryBlockList blockList;
|
||||||
|
|
||||||
|
unsigned int _maxLineCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// History type
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class HistoryType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryType();
|
||||||
|
virtual ~HistoryType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the history is enabled ( can store lines of output )
|
||||||
|
* or false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool isEnabled() const = 0;
|
||||||
|
/**
|
||||||
|
* Returns true if the history size is unlimited.
|
||||||
|
*/
|
||||||
|
bool isUnlimited() const { return maximumLineCount() == 0; }
|
||||||
|
/**
|
||||||
|
* Returns the maximum number of lines which this history type
|
||||||
|
* can store or 0 if the history can store an unlimited number of lines.
|
||||||
|
*/
|
||||||
|
virtual int maximumLineCount() const = 0;
|
||||||
|
|
||||||
|
virtual HistoryScroll* scroll(HistoryScroll *) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HistoryTypeNone : public HistoryType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryTypeNone();
|
||||||
|
|
||||||
|
virtual bool isEnabled() const;
|
||||||
|
virtual int maximumLineCount() const;
|
||||||
|
|
||||||
|
virtual HistoryScroll* scroll(HistoryScroll *) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HistoryTypeBlockArray : public HistoryType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryTypeBlockArray(size_t size);
|
||||||
|
|
||||||
|
virtual bool isEnabled() const;
|
||||||
|
virtual int maximumLineCount() const;
|
||||||
|
|
||||||
|
virtual HistoryScroll* scroll(HistoryScroll *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
class HistoryTypeFile : public HistoryType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HistoryTypeFile(const QString& fileName=QString());
|
||||||
|
|
||||||
|
virtual bool isEnabled() const;
|
||||||
|
virtual const QString& getFileName() const;
|
||||||
|
virtual int maximumLineCount() const;
|
||||||
|
|
||||||
|
virtual HistoryScroll* scroll(HistoryScroll *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString m_fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class HistoryTypeBuffer : public HistoryType
|
||||||
|
{
|
||||||
|
friend class HistoryScrollBuffer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HistoryTypeBuffer(unsigned int nbLines);
|
||||||
|
|
||||||
|
virtual bool isEnabled() const;
|
||||||
|
virtual int maximumLineCount() const;
|
||||||
|
|
||||||
|
virtual HistoryScroll* scroll(HistoryScroll *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
unsigned int m_nbLines;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompactHistoryType : public HistoryType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CompactHistoryType(unsigned int size);
|
||||||
|
|
||||||
|
virtual bool isEnabled() const;
|
||||||
|
virtual int maximumLineCount() const;
|
||||||
|
|
||||||
|
virtual HistoryScroll* scroll(HistoryScroll *) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
unsigned int m_nbLines;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEHISTORY_H
|
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013 Christian Surlykke
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "TerminalCharacterDecoder.h"
|
||||||
|
#include "Emulation.h"
|
||||||
|
#include "HistorySearch.h"
|
||||||
|
|
||||||
|
HistorySearch::HistorySearch(EmulationPtr emulation, QRegExp regExp,
|
||||||
|
bool forwards, int startColumn, int startLine,
|
||||||
|
QObject* parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_emulation(emulation),
|
||||||
|
m_regExp(regExp),
|
||||||
|
m_forwards(forwards),
|
||||||
|
m_startColumn(startColumn),
|
||||||
|
m_startLine(startLine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
HistorySearch::~HistorySearch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistorySearch::search() {
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (! m_regExp.isEmpty())
|
||||||
|
{
|
||||||
|
if (m_forwards) {
|
||||||
|
found = search(m_startColumn, m_startLine, -1, m_emulation->lineCount()) || search(0, 0, m_startColumn, m_startLine);
|
||||||
|
} else {
|
||||||
|
found = search(0, 0, m_startColumn, m_startLine) || search(m_startColumn, m_startLine, -1, m_emulation->lineCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
emit matchFound(m_foundStartColumn, m_foundStartLine, m_foundEndColumn, m_foundEndLine);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emit noMatchFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HistorySearch::search(int startColumn, int startLine, int endColumn, int endLine) {
|
||||||
|
qDebug() << "search from" << startColumn << "," << startLine
|
||||||
|
<< "to" << endColumn << "," << endLine;
|
||||||
|
|
||||||
|
int linesRead = 0;
|
||||||
|
int linesToRead = endLine - startLine + 1;
|
||||||
|
|
||||||
|
qDebug() << "linesToRead:" << linesToRead;
|
||||||
|
|
||||||
|
// We read process history from (and including) startLine to (and including) endLine in
|
||||||
|
// blocks of at most 10K lines so that we do not use unhealthy amounts of memory
|
||||||
|
int blockSize;
|
||||||
|
while ((blockSize = qMin(10000, linesToRead - linesRead)) > 0) {
|
||||||
|
|
||||||
|
QString string;
|
||||||
|
QTextStream searchStream(&string);
|
||||||
|
PlainTextDecoder decoder;
|
||||||
|
decoder.begin(&searchStream);
|
||||||
|
decoder.setRecordLinePositions(true);
|
||||||
|
|
||||||
|
// Calculate lines to read and read them
|
||||||
|
int blockStartLine = m_forwards ? startLine + linesRead : endLine - linesRead - blockSize + 1;
|
||||||
|
int chunkEndLine = blockStartLine + blockSize - 1;
|
||||||
|
m_emulation->writeToStream(&decoder, blockStartLine, chunkEndLine);
|
||||||
|
|
||||||
|
// We search between startColumn in the first line of the string and endColumn in the last
|
||||||
|
// line of the string. First we calculate the position (in the string) of endColumn in the
|
||||||
|
// last line of the string
|
||||||
|
int endPosition;
|
||||||
|
|
||||||
|
// The String that Emulator.writeToStream produces has a newline at the end, and so ends with an
|
||||||
|
// empty line - we ignore that.
|
||||||
|
int numberOfLinesInString = decoder.linePositions().size() - 1;
|
||||||
|
if (numberOfLinesInString > 0 && endColumn > -1 )
|
||||||
|
{
|
||||||
|
endPosition = decoder.linePositions().at(numberOfLinesInString - 1) + endColumn;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
endPosition = string.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// So now we can log for m_regExp in the string between startColumn and endPosition
|
||||||
|
int matchStart;
|
||||||
|
if (m_forwards)
|
||||||
|
{
|
||||||
|
matchStart = string.indexOf(m_regExp, startColumn);
|
||||||
|
if (matchStart >= endPosition)
|
||||||
|
matchStart = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
matchStart = string.lastIndexOf(m_regExp, endPosition - 1);
|
||||||
|
if (matchStart < startColumn)
|
||||||
|
matchStart = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchStart > -1)
|
||||||
|
{
|
||||||
|
int matchEnd = matchStart + m_regExp.matchedLength() - 1;
|
||||||
|
qDebug() << "Found in string from" << matchStart << "to" << matchEnd;
|
||||||
|
|
||||||
|
// Translate startPos and endPos to startColum, startLine, endColumn and endLine in history.
|
||||||
|
int startLineNumberInString = findLineNumberInString(decoder.linePositions(), matchStart);
|
||||||
|
m_foundStartColumn = matchStart - decoder.linePositions().at(startLineNumberInString);
|
||||||
|
m_foundStartLine = startLineNumberInString + startLine + linesRead;
|
||||||
|
|
||||||
|
int endLineNumberInString = findLineNumberInString(decoder.linePositions(), matchEnd);
|
||||||
|
m_foundEndColumn = matchEnd - decoder.linePositions().at(endLineNumberInString);
|
||||||
|
m_foundEndLine = endLineNumberInString + startLine + linesRead;
|
||||||
|
|
||||||
|
qDebug() << "m_foundStartColumn" << m_foundStartColumn
|
||||||
|
<< "m_foundStartLine" << m_foundEndLine
|
||||||
|
<< "m_foundEndColumn" << m_foundEndColumn
|
||||||
|
<< "m_foundEndLine" << m_foundEndLine;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
linesRead += blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "Not found";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int HistorySearch::findLineNumberInString(QList<int> linePositions, int position) {
|
||||||
|
int lineNum = 0;
|
||||||
|
while (lineNum + 1 < linePositions.size() && linePositions[lineNum + 1] <= position)
|
||||||
|
lineNum++;
|
||||||
|
|
||||||
|
return lineNum;
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013 Christian Surlykke
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef TASK_H
|
||||||
|
#define TASK_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
#include <Session.h>
|
||||||
|
#include <ScreenWindow.h>
|
||||||
|
|
||||||
|
#include "Emulation.h"
|
||||||
|
#include "TerminalCharacterDecoder.h"
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
typedef QPointer<Emulation> EmulationPtr;
|
||||||
|
|
||||||
|
class HistorySearch : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit HistorySearch(EmulationPtr emulation, QRegExp regExp, bool forwards,
|
||||||
|
int startColumn, int startLine, QObject* parent);
|
||||||
|
|
||||||
|
~HistorySearch();
|
||||||
|
|
||||||
|
void search();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void matchFound(int startColumn, int startLine, int endColumn, int endLine);
|
||||||
|
void noMatchFound();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool search(int startColumn, int startLine, int endColumn, int endLine);
|
||||||
|
int findLineNumberInString(QList<int> linePositions, int position);
|
||||||
|
|
||||||
|
|
||||||
|
EmulationPtr m_emulation;
|
||||||
|
QRegExp m_regExp;
|
||||||
|
bool m_forwards;
|
||||||
|
int m_startColumn;
|
||||||
|
int m_startLine;
|
||||||
|
|
||||||
|
int m_foundStartColumn;
|
||||||
|
int m_foundStartLine;
|
||||||
|
int m_foundEndColumn;
|
||||||
|
int m_foundEndLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* TASK_H */
|
||||||
|
|
@ -0,0 +1,894 @@
|
|||||||
|
/*
|
||||||
|
This source file is part of Konsole, a terminal emulator.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "KeyboardTranslator.h"
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QKeySequence>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <KDebug>
|
||||||
|
//#include <KLocale>
|
||||||
|
//#include <KStandardDirs>
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
|
||||||
|
const QByteArray KeyboardTranslatorManager::defaultTranslatorText(
|
||||||
|
"keyboard \"Fallback Key Translator\"\n"
|
||||||
|
"key Tab : \"\\t\""
|
||||||
|
);
|
||||||
|
|
||||||
|
KeyboardTranslatorManager::KeyboardTranslatorManager()
|
||||||
|
: _haveLoadedAll(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
KeyboardTranslatorManager::~KeyboardTranslatorManager()
|
||||||
|
{
|
||||||
|
qDeleteAll(_translators);
|
||||||
|
}
|
||||||
|
QString KeyboardTranslatorManager::findTranslatorPath(const QString& name)
|
||||||
|
{
|
||||||
|
return QString(get_kb_layout_dir() + name + ".keytab");
|
||||||
|
//return KGlobal::dirs()->findResource("data","konsole/"+name+".keytab");
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardTranslatorManager::findTranslators()
|
||||||
|
{
|
||||||
|
QDir dir(get_kb_layout_dir());
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.keytab";
|
||||||
|
dir.setNameFilters(filters);
|
||||||
|
QStringList list = dir.entryList(filters);
|
||||||
|
list = dir.entryList(filters);
|
||||||
|
// QStringList list = KGlobal::dirs()->findAllResources("data",
|
||||||
|
// "konsole/*.keytab",
|
||||||
|
// KStandardDirs::NoDuplicates);
|
||||||
|
|
||||||
|
// add the name of each translator to the list and associated
|
||||||
|
// the name with a null pointer to indicate that the translator
|
||||||
|
// has not yet been loaded from disk
|
||||||
|
QStringListIterator listIter(list);
|
||||||
|
while (listIter.hasNext())
|
||||||
|
{
|
||||||
|
QString translatorPath = listIter.next();
|
||||||
|
|
||||||
|
QString name = QFileInfo(translatorPath).baseName();
|
||||||
|
|
||||||
|
if ( !_translators.contains(name) )
|
||||||
|
_translators.insert(name,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
_haveLoadedAll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KeyboardTranslator* KeyboardTranslatorManager::findTranslator(const QString& name)
|
||||||
|
{
|
||||||
|
if ( name.isEmpty() )
|
||||||
|
return defaultTranslator();
|
||||||
|
|
||||||
|
if ( _translators.contains(name) && _translators[name] != 0 )
|
||||||
|
return _translators[name];
|
||||||
|
|
||||||
|
KeyboardTranslator* translator = loadTranslator(name);
|
||||||
|
|
||||||
|
if ( translator != 0 )
|
||||||
|
_translators[name] = translator;
|
||||||
|
else if ( !name.isEmpty() )
|
||||||
|
qDebug() << "Unable to load translator" << name;
|
||||||
|
|
||||||
|
return translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardTranslatorManager::saveTranslator(const KeyboardTranslator* translator)
|
||||||
|
{
|
||||||
|
qDebug() << "KeyboardTranslatorManager::saveTranslator" << "unimplemented";
|
||||||
|
Q_UNUSED(translator);
|
||||||
|
#if 0
|
||||||
|
const QString path = KGlobal::dirs()->saveLocation("data","konsole/")+translator->name()
|
||||||
|
+".keytab";
|
||||||
|
|
||||||
|
//kDebug() << "Saving translator to" << path;
|
||||||
|
|
||||||
|
QFile destination(path);
|
||||||
|
if (!destination.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
qDebug() << "Unable to save keyboard translation:"
|
||||||
|
<< destination.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
KeyboardTranslatorWriter writer(&destination);
|
||||||
|
writer.writeHeader(translator->description());
|
||||||
|
|
||||||
|
QListIterator<KeyboardTranslator::Entry> iter(translator->entries());
|
||||||
|
while ( iter.hasNext() )
|
||||||
|
writer.writeEntry(iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.close();
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(const QString& name)
|
||||||
|
{
|
||||||
|
const QString& path = findTranslatorPath(name);
|
||||||
|
|
||||||
|
QFile source(path);
|
||||||
|
if (name.isEmpty() || !source.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return loadTranslator(&source,name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const KeyboardTranslator* KeyboardTranslatorManager::defaultTranslator()
|
||||||
|
{
|
||||||
|
// Try to find the default.keytab file if it exists, otherwise
|
||||||
|
// fall back to the hard-coded one
|
||||||
|
const KeyboardTranslator* translator = findTranslator("default");
|
||||||
|
if (!translator)
|
||||||
|
{
|
||||||
|
QBuffer textBuffer;
|
||||||
|
textBuffer.setData(defaultTranslatorText);
|
||||||
|
textBuffer.open(QIODevice::ReadOnly);
|
||||||
|
translator = loadTranslator(&textBuffer,"fallback");
|
||||||
|
}
|
||||||
|
return translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslator* KeyboardTranslatorManager::loadTranslator(QIODevice* source,const QString& name)
|
||||||
|
{
|
||||||
|
KeyboardTranslator* translator = new KeyboardTranslator(name);
|
||||||
|
KeyboardTranslatorReader reader(source);
|
||||||
|
translator->setDescription( reader.description() );
|
||||||
|
while ( reader.hasNextEntry() )
|
||||||
|
translator->addEntry(reader.nextEntry());
|
||||||
|
|
||||||
|
source->close();
|
||||||
|
|
||||||
|
if ( !reader.parseError() )
|
||||||
|
{
|
||||||
|
return translator;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete translator;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslatorWriter::KeyboardTranslatorWriter(QIODevice* destination)
|
||||||
|
: _destination(destination)
|
||||||
|
{
|
||||||
|
Q_ASSERT( destination && destination->isWritable() );
|
||||||
|
|
||||||
|
_writer = new QTextStream(_destination);
|
||||||
|
}
|
||||||
|
KeyboardTranslatorWriter::~KeyboardTranslatorWriter()
|
||||||
|
{
|
||||||
|
delete _writer;
|
||||||
|
}
|
||||||
|
void KeyboardTranslatorWriter::writeHeader( const QString& description )
|
||||||
|
{
|
||||||
|
*_writer << "keyboard \"" << description << '\"' << '\n';
|
||||||
|
}
|
||||||
|
void KeyboardTranslatorWriter::writeEntry( const KeyboardTranslator::Entry& entry )
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
if ( entry.command() != KeyboardTranslator::NoCommand )
|
||||||
|
result = entry.resultToString();
|
||||||
|
else
|
||||||
|
result = '\"' + entry.resultToString() + '\"';
|
||||||
|
|
||||||
|
*_writer << "key " << entry.conditionToString() << " : " << result << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// each line of the keyboard translation file is one of:
|
||||||
|
//
|
||||||
|
// - keyboard "name"
|
||||||
|
// - key KeySequence : "characters"
|
||||||
|
// - key KeySequence : CommandName
|
||||||
|
//
|
||||||
|
// KeySequence begins with the name of the key ( taken from the Qt::Key enum )
|
||||||
|
// and is followed by the keyboard modifiers and state flags ( with + or - in front
|
||||||
|
// of each modifier or flag to indicate whether it is required ). All keyboard modifiers
|
||||||
|
// and flags are optional, if a particular modifier or state is not specified it is
|
||||||
|
// assumed not to be a part of the sequence. The key sequence may contain whitespace
|
||||||
|
//
|
||||||
|
// eg: "key Up+Shift : scrollLineUp"
|
||||||
|
// "key Next-Shift : "\E[6~"
|
||||||
|
//
|
||||||
|
// (lines containing only whitespace are ignored, parseLine assumes that comments have
|
||||||
|
// already been removed)
|
||||||
|
//
|
||||||
|
|
||||||
|
KeyboardTranslatorReader::KeyboardTranslatorReader( QIODevice* source )
|
||||||
|
: _source(source)
|
||||||
|
, _hasNext(false)
|
||||||
|
{
|
||||||
|
// read input until we find the description
|
||||||
|
while ( _description.isEmpty() && !source->atEnd() )
|
||||||
|
{
|
||||||
|
QList<Token> tokens = tokenize( QString(source->readLine()) );
|
||||||
|
if ( !tokens.isEmpty() && tokens.first().type == Token::TitleKeyword )
|
||||||
|
_description = tokens[1].text.toUtf8();
|
||||||
|
}
|
||||||
|
// read first entry (if any)
|
||||||
|
readNext();
|
||||||
|
}
|
||||||
|
void KeyboardTranslatorReader::readNext()
|
||||||
|
{
|
||||||
|
// find next entry
|
||||||
|
while ( !_source->atEnd() )
|
||||||
|
{
|
||||||
|
const QList<Token>& tokens = tokenize( QString(_source->readLine()) );
|
||||||
|
if ( !tokens.isEmpty() && tokens.first().type == Token::KeyKeyword )
|
||||||
|
{
|
||||||
|
KeyboardTranslator::States flags = KeyboardTranslator::NoState;
|
||||||
|
KeyboardTranslator::States flagMask = KeyboardTranslator::NoState;
|
||||||
|
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
|
||||||
|
Qt::KeyboardModifiers modifierMask = Qt::NoModifier;
|
||||||
|
|
||||||
|
int keyCode = Qt::Key_unknown;
|
||||||
|
|
||||||
|
decodeSequence(tokens[1].text.toLower(),
|
||||||
|
keyCode,
|
||||||
|
modifiers,
|
||||||
|
modifierMask,
|
||||||
|
flags,
|
||||||
|
flagMask);
|
||||||
|
|
||||||
|
KeyboardTranslator::Command command = KeyboardTranslator::NoCommand;
|
||||||
|
QByteArray text;
|
||||||
|
|
||||||
|
// get text or command
|
||||||
|
if ( tokens[2].type == Token::OutputText )
|
||||||
|
{
|
||||||
|
text = tokens[2].text.toLocal8Bit();
|
||||||
|
}
|
||||||
|
else if ( tokens[2].type == Token::Command )
|
||||||
|
{
|
||||||
|
// identify command
|
||||||
|
if (!parseAsCommand(tokens[2].text,command))
|
||||||
|
qDebug() << "Command" << tokens[2].text << "not understood.";
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslator::Entry newEntry;
|
||||||
|
newEntry.setKeyCode( keyCode );
|
||||||
|
newEntry.setState( flags );
|
||||||
|
newEntry.setStateMask( flagMask );
|
||||||
|
newEntry.setModifiers( modifiers );
|
||||||
|
newEntry.setModifierMask( modifierMask );
|
||||||
|
newEntry.setText( text );
|
||||||
|
newEntry.setCommand( command );
|
||||||
|
|
||||||
|
_nextEntry = newEntry;
|
||||||
|
|
||||||
|
_hasNext = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasNext = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardTranslatorReader::parseAsCommand(const QString& text,KeyboardTranslator::Command& command)
|
||||||
|
{
|
||||||
|
if ( text.compare("erase",Qt::CaseInsensitive) == 0 )
|
||||||
|
command = KeyboardTranslator::EraseCommand;
|
||||||
|
else if ( text.compare("scrollpageup",Qt::CaseInsensitive) == 0 )
|
||||||
|
command = KeyboardTranslator::ScrollPageUpCommand;
|
||||||
|
else if ( text.compare("scrollpagedown",Qt::CaseInsensitive) == 0 )
|
||||||
|
command = KeyboardTranslator::ScrollPageDownCommand;
|
||||||
|
else if ( text.compare("scrolllineup",Qt::CaseInsensitive) == 0 )
|
||||||
|
command = KeyboardTranslator::ScrollLineUpCommand;
|
||||||
|
else if ( text.compare("scrolllinedown",Qt::CaseInsensitive) == 0 )
|
||||||
|
command = KeyboardTranslator::ScrollLineDownCommand;
|
||||||
|
else if ( text.compare("scrolllock",Qt::CaseInsensitive) == 0 )
|
||||||
|
command = KeyboardTranslator::ScrollLockCommand;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardTranslatorReader::decodeSequence(const QString& text,
|
||||||
|
int& keyCode,
|
||||||
|
Qt::KeyboardModifiers& modifiers,
|
||||||
|
Qt::KeyboardModifiers& modifierMask,
|
||||||
|
KeyboardTranslator::States& flags,
|
||||||
|
KeyboardTranslator::States& flagMask)
|
||||||
|
{
|
||||||
|
bool isWanted = true;
|
||||||
|
bool endOfItem = false;
|
||||||
|
QString buffer;
|
||||||
|
|
||||||
|
Qt::KeyboardModifiers tempModifiers = modifiers;
|
||||||
|
Qt::KeyboardModifiers tempModifierMask = modifierMask;
|
||||||
|
KeyboardTranslator::States tempFlags = flags;
|
||||||
|
KeyboardTranslator::States tempFlagMask = flagMask;
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < text.count() ; i++ )
|
||||||
|
{
|
||||||
|
const QChar& ch = text[i];
|
||||||
|
bool isFirstLetter = i == 0;
|
||||||
|
bool isLastLetter = ( i == text.count()-1 );
|
||||||
|
endOfItem = true;
|
||||||
|
if ( ch.isLetterOrNumber() )
|
||||||
|
{
|
||||||
|
endOfItem = false;
|
||||||
|
buffer.append(ch);
|
||||||
|
} else if ( isFirstLetter )
|
||||||
|
{
|
||||||
|
buffer.append(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (endOfItem || isLastLetter) && !buffer.isEmpty() )
|
||||||
|
{
|
||||||
|
Qt::KeyboardModifier itemModifier = Qt::NoModifier;
|
||||||
|
int itemKeyCode = 0;
|
||||||
|
KeyboardTranslator::State itemFlag = KeyboardTranslator::NoState;
|
||||||
|
|
||||||
|
if ( parseAsModifier(buffer,itemModifier) )
|
||||||
|
{
|
||||||
|
tempModifierMask |= itemModifier;
|
||||||
|
|
||||||
|
if ( isWanted )
|
||||||
|
tempModifiers |= itemModifier;
|
||||||
|
}
|
||||||
|
else if ( parseAsStateFlag(buffer,itemFlag) )
|
||||||
|
{
|
||||||
|
tempFlagMask |= itemFlag;
|
||||||
|
|
||||||
|
if ( isWanted )
|
||||||
|
tempFlags |= itemFlag;
|
||||||
|
}
|
||||||
|
else if ( parseAsKeyCode(buffer,itemKeyCode) )
|
||||||
|
keyCode = itemKeyCode;
|
||||||
|
else
|
||||||
|
qDebug() << "Unable to parse key binding item:" << buffer;
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if this is a wanted / not-wanted flag and update the
|
||||||
|
// state ready for the next item
|
||||||
|
if ( ch == '+' )
|
||||||
|
isWanted = true;
|
||||||
|
else if ( ch == '-' )
|
||||||
|
isWanted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiers = tempModifiers;
|
||||||
|
modifierMask = tempModifierMask;
|
||||||
|
flags = tempFlags;
|
||||||
|
flagMask = tempFlagMask;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardTranslatorReader::parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier)
|
||||||
|
{
|
||||||
|
if ( item == "shift" )
|
||||||
|
modifier = Qt::ShiftModifier;
|
||||||
|
else if ( item == "ctrl" || item == "control" )
|
||||||
|
modifier = Qt::ControlModifier;
|
||||||
|
else if ( item == "alt" )
|
||||||
|
modifier = Qt::AltModifier;
|
||||||
|
else if ( item == "meta" )
|
||||||
|
modifier = Qt::MetaModifier;
|
||||||
|
else if ( item == "keypad" )
|
||||||
|
modifier = Qt::KeypadModifier;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool KeyboardTranslatorReader::parseAsStateFlag(const QString& item , KeyboardTranslator::State& flag)
|
||||||
|
{
|
||||||
|
if ( item == "appcukeys" || item == "appcursorkeys" )
|
||||||
|
flag = KeyboardTranslator::CursorKeysState;
|
||||||
|
else if ( item == "ansi" )
|
||||||
|
flag = KeyboardTranslator::AnsiState;
|
||||||
|
else if ( item == "newline" )
|
||||||
|
flag = KeyboardTranslator::NewLineState;
|
||||||
|
else if ( item == "appscreen" )
|
||||||
|
flag = KeyboardTranslator::AlternateScreenState;
|
||||||
|
else if ( item == "anymod" || item == "anymodifier" )
|
||||||
|
flag = KeyboardTranslator::AnyModifierState;
|
||||||
|
else if ( item == "appkeypad" )
|
||||||
|
flag = KeyboardTranslator::ApplicationKeypadState;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool KeyboardTranslatorReader::parseAsKeyCode(const QString& item , int& keyCode)
|
||||||
|
{
|
||||||
|
QKeySequence sequence = QKeySequence::fromString(item);
|
||||||
|
if ( !sequence.isEmpty() )
|
||||||
|
{
|
||||||
|
keyCode = sequence[0];
|
||||||
|
|
||||||
|
if ( sequence.count() > 1 )
|
||||||
|
{
|
||||||
|
qDebug() << "Unhandled key codes in sequence: " << item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// additional cases implemented for backwards compatibility with KDE 3
|
||||||
|
else if ( item == "prior" )
|
||||||
|
keyCode = Qt::Key_PageUp;
|
||||||
|
else if ( item == "next" )
|
||||||
|
keyCode = Qt::Key_PageDown;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString KeyboardTranslatorReader::description() const
|
||||||
|
{
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
bool KeyboardTranslatorReader::hasNextEntry()
|
||||||
|
{
|
||||||
|
return _hasNext;
|
||||||
|
}
|
||||||
|
KeyboardTranslator::Entry KeyboardTranslatorReader::createEntry( const QString& condition ,
|
||||||
|
const QString& result )
|
||||||
|
{
|
||||||
|
QString entryString("keyboard \"temporary\"\nkey ");
|
||||||
|
entryString.append(condition);
|
||||||
|
entryString.append(" : ");
|
||||||
|
|
||||||
|
// if 'result' is the name of a command then the entry result will be that command,
|
||||||
|
// otherwise the result will be treated as a string to echo when the key sequence
|
||||||
|
// specified by 'condition' is pressed
|
||||||
|
KeyboardTranslator::Command command;
|
||||||
|
if (parseAsCommand(result,command))
|
||||||
|
entryString.append(result);
|
||||||
|
else
|
||||||
|
entryString.append('\"' + result + '\"');
|
||||||
|
|
||||||
|
QByteArray array = entryString.toUtf8();
|
||||||
|
QBuffer buffer(&array);
|
||||||
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
KeyboardTranslatorReader reader(&buffer);
|
||||||
|
|
||||||
|
KeyboardTranslator::Entry entry;
|
||||||
|
if ( reader.hasNextEntry() )
|
||||||
|
entry = reader.nextEntry();
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslator::Entry KeyboardTranslatorReader::nextEntry()
|
||||||
|
{
|
||||||
|
Q_ASSERT( _hasNext );
|
||||||
|
KeyboardTranslator::Entry entry = _nextEntry;
|
||||||
|
readNext();
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
bool KeyboardTranslatorReader::parseError()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QList<KeyboardTranslatorReader::Token> KeyboardTranslatorReader::tokenize(const QString& line)
|
||||||
|
{
|
||||||
|
QString text = line;
|
||||||
|
|
||||||
|
// remove comments
|
||||||
|
bool inQuotes = false;
|
||||||
|
int commentPos = -1;
|
||||||
|
for (int i=text.length()-1;i>=0;i--)
|
||||||
|
{
|
||||||
|
QChar ch = text[i];
|
||||||
|
if (ch == '\"')
|
||||||
|
inQuotes = !inQuotes;
|
||||||
|
else if (ch == '#' && !inQuotes)
|
||||||
|
commentPos = i;
|
||||||
|
}
|
||||||
|
if (commentPos != -1)
|
||||||
|
text.remove(commentPos,text.length());
|
||||||
|
|
||||||
|
text = text.simplified();
|
||||||
|
|
||||||
|
// title line: keyboard "title"
|
||||||
|
static QRegExp title("keyboard\\s+\"(.*)\"");
|
||||||
|
// key line: key KeySequence : "output"
|
||||||
|
// key line: key KeySequence : command
|
||||||
|
static QRegExp key("key\\s+([\\w\\+\\s\\-\\*\\.]+)\\s*:\\s*(\"(.*)\"|\\w+)");
|
||||||
|
|
||||||
|
QList<Token> list;
|
||||||
|
if ( text.isEmpty() )
|
||||||
|
{
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( title.exactMatch(text) )
|
||||||
|
{
|
||||||
|
Token titleToken = { Token::TitleKeyword , QString() };
|
||||||
|
Token textToken = { Token::TitleText , title.capturedTexts()[1] };
|
||||||
|
|
||||||
|
list << titleToken << textToken;
|
||||||
|
}
|
||||||
|
else if ( key.exactMatch(text) )
|
||||||
|
{
|
||||||
|
Token keyToken = { Token::KeyKeyword , QString() };
|
||||||
|
Token sequenceToken = { Token::KeySequence , key.capturedTexts()[1].remove(' ') };
|
||||||
|
|
||||||
|
list << keyToken << sequenceToken;
|
||||||
|
|
||||||
|
if ( key.capturedTexts()[3].isEmpty() )
|
||||||
|
{
|
||||||
|
// capturedTexts()[2] is a command
|
||||||
|
Token commandToken = { Token::Command , key.capturedTexts()[2] };
|
||||||
|
list << commandToken;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// capturedTexts()[3] is the output string
|
||||||
|
Token outputToken = { Token::OutputText , key.capturedTexts()[3] };
|
||||||
|
list << outputToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Line in keyboard translator file could not be understood:" << text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> KeyboardTranslatorManager::allTranslators()
|
||||||
|
{
|
||||||
|
if ( !_haveLoadedAll )
|
||||||
|
{
|
||||||
|
findTranslators();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _translators.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslator::Entry::Entry()
|
||||||
|
: _keyCode(0)
|
||||||
|
, _modifiers(Qt::NoModifier)
|
||||||
|
, _modifierMask(Qt::NoModifier)
|
||||||
|
, _state(NoState)
|
||||||
|
, _stateMask(NoState)
|
||||||
|
, _command(NoCommand)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardTranslator::Entry::operator==(const Entry& rhs) const
|
||||||
|
{
|
||||||
|
return _keyCode == rhs._keyCode &&
|
||||||
|
_modifiers == rhs._modifiers &&
|
||||||
|
_modifierMask == rhs._modifierMask &&
|
||||||
|
_state == rhs._state &&
|
||||||
|
_stateMask == rhs._stateMask &&
|
||||||
|
_command == rhs._command &&
|
||||||
|
_text == rhs._text;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardTranslator::Entry::matches(int keyCode ,
|
||||||
|
Qt::KeyboardModifiers modifiers,
|
||||||
|
States testState) const
|
||||||
|
{
|
||||||
|
if ( _keyCode != keyCode )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( (modifiers & _modifierMask) != (_modifiers & _modifierMask) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// if modifiers is non-zero, the 'any modifier' state is implicit
|
||||||
|
if ( modifiers != 0 )
|
||||||
|
testState |= AnyModifierState;
|
||||||
|
|
||||||
|
if ( (testState & _stateMask) != (_state & _stateMask) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// special handling for the 'Any Modifier' state, which checks for the presence of
|
||||||
|
// any or no modifiers. In this context, the 'keypad' modifier does not count.
|
||||||
|
bool anyModifiersSet = modifiers != 0 && modifiers != Qt::KeypadModifier;
|
||||||
|
bool wantAnyModifier = _state & KeyboardTranslator::AnyModifierState;
|
||||||
|
if ( _stateMask & KeyboardTranslator::AnyModifierState )
|
||||||
|
{
|
||||||
|
if ( wantAnyModifier != anyModifiersSet )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
QByteArray KeyboardTranslator::Entry::escapedText(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
|
||||||
|
{
|
||||||
|
QByteArray result(text(expandWildCards,modifiers));
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < result.count() ; i++ )
|
||||||
|
{
|
||||||
|
char ch = result[i];
|
||||||
|
char replacement = 0;
|
||||||
|
|
||||||
|
switch ( ch )
|
||||||
|
{
|
||||||
|
case 27 : replacement = 'E'; break;
|
||||||
|
case 8 : replacement = 'b'; break;
|
||||||
|
case 12 : replacement = 'f'; break;
|
||||||
|
case 9 : replacement = 't'; break;
|
||||||
|
case 13 : replacement = 'r'; break;
|
||||||
|
case 10 : replacement = 'n'; break;
|
||||||
|
default:
|
||||||
|
// any character which is not printable is replaced by an equivalent
|
||||||
|
// \xhh escape sequence (where 'hh' are the corresponding hex digits)
|
||||||
|
if ( !QChar(ch).isPrint() )
|
||||||
|
replacement = 'x';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( replacement == 'x' )
|
||||||
|
{
|
||||||
|
result.replace(i,1,"\\x"+QByteArray(1,ch).toHex());
|
||||||
|
} else if ( replacement != 0 )
|
||||||
|
{
|
||||||
|
result.remove(i,1);
|
||||||
|
result.insert(i,'\\');
|
||||||
|
result.insert(i+1,replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
QByteArray KeyboardTranslator::Entry::unescape(const QByteArray& input) const
|
||||||
|
{
|
||||||
|
QByteArray result(input);
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < result.count()-1 ; i++ )
|
||||||
|
{
|
||||||
|
|
||||||
|
QByteRef ch = result[i];
|
||||||
|
if ( ch == '\\' )
|
||||||
|
{
|
||||||
|
char replacement[2] = {0,0};
|
||||||
|
int charsToRemove = 2;
|
||||||
|
bool escapedChar = true;
|
||||||
|
|
||||||
|
switch ( result[i+1] )
|
||||||
|
{
|
||||||
|
case 'E' : replacement[0] = 27; break;
|
||||||
|
case 'b' : replacement[0] = 8 ; break;
|
||||||
|
case 'f' : replacement[0] = 12; break;
|
||||||
|
case 't' : replacement[0] = 9 ; break;
|
||||||
|
case 'r' : replacement[0] = 13; break;
|
||||||
|
case 'n' : replacement[0] = 10; break;
|
||||||
|
case 'x' :
|
||||||
|
{
|
||||||
|
// format is \xh or \xhh where 'h' is a hexadecimal
|
||||||
|
// digit from 0-9 or A-F which should be replaced
|
||||||
|
// with the corresponding character value
|
||||||
|
char hexDigits[3] = {0};
|
||||||
|
|
||||||
|
if ( (i < result.count()-2) && isxdigit(result[i+2]) )
|
||||||
|
hexDigits[0] = result[i+2];
|
||||||
|
if ( (i < result.count()-3) && isxdigit(result[i+3]) )
|
||||||
|
hexDigits[1] = result[i+3];
|
||||||
|
|
||||||
|
unsigned charValue = 0;
|
||||||
|
sscanf(hexDigits,"%x",&charValue);
|
||||||
|
|
||||||
|
replacement[0] = (char)charValue;
|
||||||
|
charsToRemove = 2 + strlen(hexDigits);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
escapedChar = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( escapedChar )
|
||||||
|
result.replace(i,charsToRemove,replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardTranslator::Entry::insertModifier( QString& item , int modifier ) const
|
||||||
|
{
|
||||||
|
if ( !(modifier & _modifierMask) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( modifier & _modifiers )
|
||||||
|
item += '+';
|
||||||
|
else
|
||||||
|
item += '-';
|
||||||
|
|
||||||
|
if ( modifier == Qt::ShiftModifier )
|
||||||
|
item += "Shift";
|
||||||
|
else if ( modifier == Qt::ControlModifier )
|
||||||
|
item += "Ctrl";
|
||||||
|
else if ( modifier == Qt::AltModifier )
|
||||||
|
item += "Alt";
|
||||||
|
else if ( modifier == Qt::MetaModifier )
|
||||||
|
item += "Meta";
|
||||||
|
else if ( modifier == Qt::KeypadModifier )
|
||||||
|
item += "KeyPad";
|
||||||
|
}
|
||||||
|
void KeyboardTranslator::Entry::insertState( QString& item , int state ) const
|
||||||
|
{
|
||||||
|
if ( !(state & _stateMask) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( state & _state )
|
||||||
|
item += '+' ;
|
||||||
|
else
|
||||||
|
item += '-' ;
|
||||||
|
|
||||||
|
if ( state == KeyboardTranslator::AlternateScreenState )
|
||||||
|
item += "AppScreen";
|
||||||
|
else if ( state == KeyboardTranslator::NewLineState )
|
||||||
|
item += "NewLine";
|
||||||
|
else if ( state == KeyboardTranslator::AnsiState )
|
||||||
|
item += "Ansi";
|
||||||
|
else if ( state == KeyboardTranslator::CursorKeysState )
|
||||||
|
item += "AppCursorKeys";
|
||||||
|
else if ( state == KeyboardTranslator::AnyModifierState )
|
||||||
|
item += "AnyModifier";
|
||||||
|
else if ( state == KeyboardTranslator::ApplicationKeypadState )
|
||||||
|
item += "AppKeypad";
|
||||||
|
}
|
||||||
|
QString KeyboardTranslator::Entry::resultToString(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
|
||||||
|
{
|
||||||
|
if ( !_text.isEmpty() )
|
||||||
|
return escapedText(expandWildCards,modifiers);
|
||||||
|
else if ( _command == EraseCommand )
|
||||||
|
return "Erase";
|
||||||
|
else if ( _command == ScrollPageUpCommand )
|
||||||
|
return "ScrollPageUp";
|
||||||
|
else if ( _command == ScrollPageDownCommand )
|
||||||
|
return "ScrollPageDown";
|
||||||
|
else if ( _command == ScrollLineUpCommand )
|
||||||
|
return "ScrollLineUp";
|
||||||
|
else if ( _command == ScrollLineDownCommand )
|
||||||
|
return "ScrollLineDown";
|
||||||
|
else if ( _command == ScrollLockCommand )
|
||||||
|
return "ScrollLock";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
QString KeyboardTranslator::Entry::conditionToString() const
|
||||||
|
{
|
||||||
|
QString result = QKeySequence(_keyCode).toString();
|
||||||
|
|
||||||
|
insertModifier( result , Qt::ShiftModifier );
|
||||||
|
insertModifier( result , Qt::ControlModifier );
|
||||||
|
insertModifier( result , Qt::AltModifier );
|
||||||
|
insertModifier( result , Qt::MetaModifier );
|
||||||
|
insertModifier( result , Qt::KeypadModifier );
|
||||||
|
|
||||||
|
insertState( result , KeyboardTranslator::AlternateScreenState );
|
||||||
|
insertState( result , KeyboardTranslator::NewLineState );
|
||||||
|
insertState( result , KeyboardTranslator::AnsiState );
|
||||||
|
insertState( result , KeyboardTranslator::CursorKeysState );
|
||||||
|
insertState( result , KeyboardTranslator::AnyModifierState );
|
||||||
|
insertState( result , KeyboardTranslator::ApplicationKeypadState );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyboardTranslator::KeyboardTranslator(const QString& name)
|
||||||
|
: _name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardTranslator::setDescription(const QString& description)
|
||||||
|
{
|
||||||
|
_description = description;
|
||||||
|
}
|
||||||
|
QString KeyboardTranslator::description() const
|
||||||
|
{
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
void KeyboardTranslator::setName(const QString& name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
QString KeyboardTranslator::name() const
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<KeyboardTranslator::Entry> KeyboardTranslator::entries() const
|
||||||
|
{
|
||||||
|
return _entries.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardTranslator::addEntry(const Entry& entry)
|
||||||
|
{
|
||||||
|
const int keyCode = entry.keyCode();
|
||||||
|
_entries.insert(keyCode,entry);
|
||||||
|
}
|
||||||
|
void KeyboardTranslator::replaceEntry(const Entry& existing , const Entry& replacement)
|
||||||
|
{
|
||||||
|
if ( !existing.isNull() )
|
||||||
|
_entries.remove(existing.keyCode(),existing);
|
||||||
|
_entries.insert(replacement.keyCode(),replacement);
|
||||||
|
}
|
||||||
|
void KeyboardTranslator::removeEntry(const Entry& entry)
|
||||||
|
{
|
||||||
|
_entries.remove(entry.keyCode(),entry);
|
||||||
|
}
|
||||||
|
KeyboardTranslator::Entry KeyboardTranslator::findEntry(int keyCode, Qt::KeyboardModifiers modifiers, States state) const
|
||||||
|
{
|
||||||
|
foreach(const Entry& entry, _entries.values(keyCode))
|
||||||
|
{
|
||||||
|
if ( entry.matches(keyCode,modifiers,state) )
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
return Entry(); // entry not found
|
||||||
|
}
|
||||||
|
void KeyboardTranslatorManager::addTranslator(KeyboardTranslator* translator)
|
||||||
|
{
|
||||||
|
_translators.insert(translator->name(),translator);
|
||||||
|
|
||||||
|
if ( !saveTranslator(translator) )
|
||||||
|
qDebug() << "Unable to save translator" << translator->name()
|
||||||
|
<< "to disk.";
|
||||||
|
}
|
||||||
|
bool KeyboardTranslatorManager::deleteTranslator(const QString& name)
|
||||||
|
{
|
||||||
|
Q_ASSERT( _translators.contains(name) );
|
||||||
|
|
||||||
|
// locate and delete
|
||||||
|
QString path = findTranslatorPath(name);
|
||||||
|
if ( QFile::remove(path) )
|
||||||
|
{
|
||||||
|
_translators.remove(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Failed to remove translator - " << path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//K_GLOBAL_STATIC( KeyboardTranslatorManager , theKeyboardTranslatorManager )
|
||||||
|
KeyboardTranslatorManager* KeyboardTranslatorManager::theKeyboardTranslatorManager = 0;
|
||||||
|
KeyboardTranslatorManager* KeyboardTranslatorManager::instance()
|
||||||
|
{
|
||||||
|
if (! theKeyboardTranslatorManager)
|
||||||
|
theKeyboardTranslatorManager = new KeyboardTranslatorManager();
|
||||||
|
return theKeyboardTranslatorManager;
|
||||||
|
}
|
@ -0,0 +1,587 @@
|
|||||||
|
/*
|
||||||
|
This source file is part of Konsole, a terminal emulator.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KEYBOARDTRANSLATOR_H
|
||||||
|
#define KEYBOARDTRANSLATOR_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QHash>
|
||||||
|
#include <QList>
|
||||||
|
#include <QKeySequence>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QVarLengthArray>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
//#include "konsole_export.h"
|
||||||
|
#define KONSOLEPRIVATE_EXPORT
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convertor which maps between key sequences pressed by the user and the
|
||||||
|
* character strings which should be sent to the terminal and commands
|
||||||
|
* which should be invoked when those character sequences are pressed.
|
||||||
|
*
|
||||||
|
* Konsole supports multiple keyboard translators, allowing the user to
|
||||||
|
* specify the character sequences which are sent to the terminal
|
||||||
|
* when particular key sequences are pressed.
|
||||||
|
*
|
||||||
|
* A key sequence is defined as a key code, associated keyboard modifiers
|
||||||
|
* (Shift,Ctrl,Alt,Meta etc.) and state flags which indicate the state
|
||||||
|
* which the terminal must be in for the key sequence to apply.
|
||||||
|
*/
|
||||||
|
class KeyboardTranslator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The meaning of a particular key sequence may depend upon the state which
|
||||||
|
* the terminal emulation is in. Therefore findEntry() may return a different
|
||||||
|
* Entry depending upon the state flags supplied.
|
||||||
|
*
|
||||||
|
* This enum describes the states which may be associated with with a particular
|
||||||
|
* entry in the keyboard translation entry.
|
||||||
|
*/
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
/** Indicates that no special state is active */
|
||||||
|
NoState = 0,
|
||||||
|
/**
|
||||||
|
* TODO More documentation
|
||||||
|
*/
|
||||||
|
NewLineState = 1,
|
||||||
|
/**
|
||||||
|
* Indicates that the terminal is in 'Ansi' mode.
|
||||||
|
* TODO: More documentation
|
||||||
|
*/
|
||||||
|
AnsiState = 2,
|
||||||
|
/**
|
||||||
|
* TODO More documentation
|
||||||
|
*/
|
||||||
|
CursorKeysState = 4,
|
||||||
|
/**
|
||||||
|
* Indicates that the alternate screen ( typically used by interactive programs
|
||||||
|
* such as screen or vim ) is active
|
||||||
|
*/
|
||||||
|
AlternateScreenState = 8,
|
||||||
|
/** Indicates that any of the modifier keys is active. */
|
||||||
|
AnyModifierState = 16,
|
||||||
|
/** Indicates that the numpad is in application mode. */
|
||||||
|
ApplicationKeypadState = 32
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(States,State)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes commands which are associated with particular key sequences.
|
||||||
|
*/
|
||||||
|
enum Command
|
||||||
|
{
|
||||||
|
/** Indicates that no command is associated with this command sequence */
|
||||||
|
NoCommand = 0,
|
||||||
|
/** TODO Document me */
|
||||||
|
SendCommand = 1,
|
||||||
|
/** Scroll the terminal display up one page */
|
||||||
|
ScrollPageUpCommand = 2,
|
||||||
|
/** Scroll the terminal display down one page */
|
||||||
|
ScrollPageDownCommand = 4,
|
||||||
|
/** Scroll the terminal display up one line */
|
||||||
|
ScrollLineUpCommand = 8,
|
||||||
|
/** Scroll the terminal display down one line */
|
||||||
|
ScrollLineDownCommand = 16,
|
||||||
|
/** Toggles scroll lock mode */
|
||||||
|
ScrollLockCommand = 32,
|
||||||
|
/** Echos the operating system specific erase character. */
|
||||||
|
EraseCommand = 64
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(Commands,Command)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an association between a key sequence pressed by the user
|
||||||
|
* and the character sequence and commands associated with it for a particular
|
||||||
|
* KeyboardTranslator.
|
||||||
|
*/
|
||||||
|
class Entry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new entry for a keyboard translator.
|
||||||
|
*/
|
||||||
|
Entry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this entry is null.
|
||||||
|
* This is true for newly constructed entries which have no properties set.
|
||||||
|
*/
|
||||||
|
bool isNull() const;
|
||||||
|
|
||||||
|
/** Returns the commands associated with this entry */
|
||||||
|
Command command() const;
|
||||||
|
/** Sets the command associated with this entry. */
|
||||||
|
void setCommand(Command command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the character sequence associated with this entry, optionally replacing
|
||||||
|
* wildcard '*' characters with numbers to indicate the keyboard modifiers being pressed.
|
||||||
|
*
|
||||||
|
* TODO: The numbers used to replace '*' characters are taken from the Konsole/KDE 3 code.
|
||||||
|
* Document them.
|
||||||
|
*
|
||||||
|
* @param expandWildCards Specifies whether wild cards (occurrences of the '*' character) in
|
||||||
|
* the entry should be replaced with a number to indicate the modifier keys being pressed.
|
||||||
|
*
|
||||||
|
* @param modifiers The keyboard modifiers being pressed.
|
||||||
|
*/
|
||||||
|
QByteArray text(bool expandWildCards = false,
|
||||||
|
Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
|
||||||
|
|
||||||
|
/** Sets the character sequence associated with this entry */
|
||||||
|
void setText(const QByteArray& text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the character sequence associated with this entry,
|
||||||
|
* with any non-printable characters replaced with escape sequences.
|
||||||
|
*
|
||||||
|
* eg. \\E for Escape, \\t for tab, \\n for new line.
|
||||||
|
*
|
||||||
|
* @param expandWildCards See text()
|
||||||
|
* @param modifiers See text()
|
||||||
|
*/
|
||||||
|
QByteArray escapedText(bool expandWildCards = false,
|
||||||
|
Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
|
||||||
|
|
||||||
|
/** Returns the character code ( from the Qt::Key enum ) associated with this entry */
|
||||||
|
int keyCode() const;
|
||||||
|
/** Sets the character code associated with this entry */
|
||||||
|
void setKeyCode(int keyCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry.
|
||||||
|
* If a modifier is set in modifierMask() but not in modifiers(), this means that the entry
|
||||||
|
* only matches when that modifier is NOT pressed.
|
||||||
|
*
|
||||||
|
* If a modifier is not set in modifierMask() then the entry matches whether the modifier
|
||||||
|
* is pressed or not.
|
||||||
|
*/
|
||||||
|
Qt::KeyboardModifiers modifiers() const;
|
||||||
|
|
||||||
|
/** Returns the keyboard modifiers which are valid in this entry. See modifiers() */
|
||||||
|
Qt::KeyboardModifiers modifierMask() const;
|
||||||
|
|
||||||
|
/** See modifiers() */
|
||||||
|
void setModifiers( Qt::KeyboardModifiers modifiers );
|
||||||
|
/** See modifierMask() and modifiers() */
|
||||||
|
void setModifierMask( Qt::KeyboardModifiers modifiers );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a bitwise-OR of the enabled state flags associated with this entry.
|
||||||
|
* If flag is set in stateMask() but not in state(), this means that the entry only
|
||||||
|
* matches when the terminal is NOT in that state.
|
||||||
|
*
|
||||||
|
* If a state is not set in stateMask() then the entry matches whether the terminal
|
||||||
|
* is in that state or not.
|
||||||
|
*/
|
||||||
|
States state() const;
|
||||||
|
|
||||||
|
/** Returns the state flags which are valid in this entry. See state() */
|
||||||
|
States stateMask() const;
|
||||||
|
|
||||||
|
/** See state() */
|
||||||
|
void setState( States state );
|
||||||
|
/** See stateMask() */
|
||||||
|
void setStateMask( States mask );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key code and modifiers associated with this entry
|
||||||
|
* as a QKeySequence
|
||||||
|
*/
|
||||||
|
//QKeySequence keySequence() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this entry's conditions ( ie. its key code, modifier and state criteria )
|
||||||
|
* as a string.
|
||||||
|
*/
|
||||||
|
QString conditionToString() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this entry's result ( ie. its command or character sequence )
|
||||||
|
* as a string.
|
||||||
|
*
|
||||||
|
* @param expandWildCards See text()
|
||||||
|
* @param modifiers See text()
|
||||||
|
*/
|
||||||
|
QString resultToString(bool expandWildCards = false,
|
||||||
|
Qt::KeyboardModifiers modifiers = Qt::NoModifier) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this entry matches the given key sequence, specified
|
||||||
|
* as a combination of @p keyCode , @p modifiers and @p state.
|
||||||
|
*/
|
||||||
|
bool matches( int keyCode ,
|
||||||
|
Qt::KeyboardModifiers modifiers ,
|
||||||
|
States flags ) const;
|
||||||
|
|
||||||
|
bool operator==(const Entry& rhs) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void insertModifier( QString& item , int modifier ) const;
|
||||||
|
void insertState( QString& item , int state ) const;
|
||||||
|
QByteArray unescape(const QByteArray& text) const;
|
||||||
|
|
||||||
|
int _keyCode;
|
||||||
|
Qt::KeyboardModifiers _modifiers;
|
||||||
|
Qt::KeyboardModifiers _modifierMask;
|
||||||
|
States _state;
|
||||||
|
States _stateMask;
|
||||||
|
|
||||||
|
Command _command;
|
||||||
|
QByteArray _text;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Constructs a new keyboard translator with the given @p name */
|
||||||
|
KeyboardTranslator(const QString& name);
|
||||||
|
|
||||||
|
//KeyboardTranslator(const KeyboardTranslator& other);
|
||||||
|
|
||||||
|
/** Returns the name of this keyboard translator */
|
||||||
|
QString name() const;
|
||||||
|
|
||||||
|
/** Sets the name of this keyboard translator */
|
||||||
|
void setName(const QString& name);
|
||||||
|
|
||||||
|
/** Returns the descriptive name of this keyboard translator */
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
/** Sets the descriptive name of this keyboard translator */
|
||||||
|
void setDescription(const QString& description);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks for an entry in this keyboard translator which matches the given
|
||||||
|
* key code, keyboard modifiers and state flags.
|
||||||
|
*
|
||||||
|
* Returns the matching entry if found or a null Entry otherwise ( ie.
|
||||||
|
* entry.isNull() will return true )
|
||||||
|
*
|
||||||
|
* @param keyCode A key code from the Qt::Key enum
|
||||||
|
* @param modifiers A combination of modifiers
|
||||||
|
* @param state Optional flags which specify the current state of the terminal
|
||||||
|
*/
|
||||||
|
Entry findEntry(int keyCode ,
|
||||||
|
Qt::KeyboardModifiers modifiers ,
|
||||||
|
States state = NoState) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an entry to this keyboard translator's table. Entries can be looked up according
|
||||||
|
* to their key sequence using findEntry()
|
||||||
|
*/
|
||||||
|
void addEntry(const Entry& entry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces an entry in the translator. If the @p existing entry is null,
|
||||||
|
* then this is equivalent to calling addEntry(@p replacement)
|
||||||
|
*/
|
||||||
|
void replaceEntry(const Entry& existing , const Entry& replacement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an entry from the table.
|
||||||
|
*/
|
||||||
|
void removeEntry(const Entry& entry);
|
||||||
|
|
||||||
|
/** Returns a list of all entries in the translator. */
|
||||||
|
QList<Entry> entries() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QMultiHash<int,Entry> _entries; // entries in this keyboard translation,
|
||||||
|
// entries are indexed according to
|
||||||
|
// their keycode
|
||||||
|
QString _name;
|
||||||
|
QString _description;
|
||||||
|
};
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::States)
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::Commands)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the contents of a Keyboard Translator (.keytab) file and
|
||||||
|
* returns the entries found in it.
|
||||||
|
*
|
||||||
|
* Usage example:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* QFile source( "/path/to/keytab" );
|
||||||
|
* source.open( QIODevice::ReadOnly );
|
||||||
|
*
|
||||||
|
* KeyboardTranslator* translator = new KeyboardTranslator( "name-of-translator" );
|
||||||
|
*
|
||||||
|
* KeyboardTranslatorReader reader(source);
|
||||||
|
* while ( reader.hasNextEntry() )
|
||||||
|
* translator->addEntry(reader.nextEntry());
|
||||||
|
*
|
||||||
|
* source.close();
|
||||||
|
*
|
||||||
|
* if ( !reader.parseError() )
|
||||||
|
* {
|
||||||
|
* // parsing succeeded, do something with the translator
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // parsing failed
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
class KeyboardTranslatorReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Constructs a new reader which parses the given @p source */
|
||||||
|
KeyboardTranslatorReader( QIODevice* source );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the description text.
|
||||||
|
* TODO: More documentation
|
||||||
|
*/
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
/** Returns true if there is another entry in the source stream */
|
||||||
|
bool hasNextEntry();
|
||||||
|
/** Returns the next entry found in the source stream */
|
||||||
|
KeyboardTranslator::Entry nextEntry();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if an error occurred whilst parsing the input or
|
||||||
|
* false if no error occurred.
|
||||||
|
*/
|
||||||
|
bool parseError();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a condition and result string for a translator entry
|
||||||
|
* and produces a keyboard translator entry.
|
||||||
|
*
|
||||||
|
* The condition and result strings are in the same format as in
|
||||||
|
*/
|
||||||
|
static KeyboardTranslator::Entry createEntry( const QString& condition ,
|
||||||
|
const QString& result );
|
||||||
|
private:
|
||||||
|
struct Token
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
TitleKeyword,
|
||||||
|
TitleText,
|
||||||
|
KeyKeyword,
|
||||||
|
KeySequence,
|
||||||
|
Command,
|
||||||
|
OutputText
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
QList<Token> tokenize(const QString&);
|
||||||
|
void readNext();
|
||||||
|
bool decodeSequence(const QString& ,
|
||||||
|
int& keyCode,
|
||||||
|
Qt::KeyboardModifiers& modifiers,
|
||||||
|
Qt::KeyboardModifiers& modifierMask,
|
||||||
|
KeyboardTranslator::States& state,
|
||||||
|
KeyboardTranslator::States& stateFlags);
|
||||||
|
|
||||||
|
static bool parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier);
|
||||||
|
static bool parseAsStateFlag(const QString& item , KeyboardTranslator::State& state);
|
||||||
|
static bool parseAsKeyCode(const QString& item , int& keyCode);
|
||||||
|
static bool parseAsCommand(const QString& text , KeyboardTranslator::Command& command);
|
||||||
|
|
||||||
|
QIODevice* _source;
|
||||||
|
QString _description;
|
||||||
|
KeyboardTranslator::Entry _nextEntry;
|
||||||
|
bool _hasNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Writes a keyboard translation to disk. */
|
||||||
|
class KeyboardTranslatorWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new writer which saves data into @p destination.
|
||||||
|
* The caller is responsible for closing the device when writing is complete.
|
||||||
|
*/
|
||||||
|
KeyboardTranslatorWriter(QIODevice* destination);
|
||||||
|
~KeyboardTranslatorWriter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the header for the keyboard translator.
|
||||||
|
* @param description Description of the keyboard translator.
|
||||||
|
*/
|
||||||
|
void writeHeader( const QString& description );
|
||||||
|
/** Writes a translator entry. */
|
||||||
|
void writeEntry( const KeyboardTranslator::Entry& entry );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QIODevice* _destination;
|
||||||
|
QTextStream* _writer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the keyboard translations available for use by terminal sessions,
|
||||||
|
* see KeyboardTranslator.
|
||||||
|
*/
|
||||||
|
class KONSOLEPRIVATE_EXPORT KeyboardTranslatorManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new KeyboardTranslatorManager and loads the list of
|
||||||
|
* available keyboard translations.
|
||||||
|
*
|
||||||
|
* The keyboard translations themselves are not loaded until they are
|
||||||
|
* first requested via a call to findTranslator()
|
||||||
|
*/
|
||||||
|
KeyboardTranslatorManager();
|
||||||
|
~KeyboardTranslatorManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new translator. If a translator with the same name
|
||||||
|
* already exists, it will be replaced by the new translator.
|
||||||
|
*
|
||||||
|
* TODO: More documentation.
|
||||||
|
*/
|
||||||
|
void addTranslator(KeyboardTranslator* translator);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a translator. Returns true on successful deletion or false otherwise.
|
||||||
|
*
|
||||||
|
* TODO: More documentation
|
||||||
|
*/
|
||||||
|
bool deleteTranslator(const QString& name);
|
||||||
|
|
||||||
|
/** Returns the default translator for Konsole. */
|
||||||
|
const KeyboardTranslator* defaultTranslator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the keyboard translator with the given name or 0 if no translator
|
||||||
|
* with that name exists.
|
||||||
|
*
|
||||||
|
* The first time that a translator with a particular name is requested,
|
||||||
|
* the on-disk .keyboard file is loaded and parsed.
|
||||||
|
*/
|
||||||
|
const KeyboardTranslator* findTranslator(const QString& name);
|
||||||
|
/**
|
||||||
|
* Returns a list of the names of available keyboard translators.
|
||||||
|
*
|
||||||
|
* The first time this is called, a search for available
|
||||||
|
* translators is started.
|
||||||
|
*/
|
||||||
|
QList<QString> allTranslators();
|
||||||
|
|
||||||
|
/** Returns the global KeyboardTranslatorManager instance. */
|
||||||
|
static KeyboardTranslatorManager* instance();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const QByteArray defaultTranslatorText;
|
||||||
|
|
||||||
|
void findTranslators(); // locate the available translators
|
||||||
|
KeyboardTranslator* loadTranslator(const QString& name); // loads the translator
|
||||||
|
// with the given name
|
||||||
|
KeyboardTranslator* loadTranslator(QIODevice* device,const QString& name);
|
||||||
|
|
||||||
|
bool saveTranslator(const KeyboardTranslator* translator);
|
||||||
|
QString findTranslatorPath(const QString& name);
|
||||||
|
|
||||||
|
QHash<QString,KeyboardTranslator*> _translators; // maps translator-name -> KeyboardTranslator
|
||||||
|
// instance
|
||||||
|
bool _haveLoadedAll;
|
||||||
|
|
||||||
|
static KeyboardTranslatorManager * theKeyboardTranslatorManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int KeyboardTranslator::Entry::keyCode() const { return _keyCode; }
|
||||||
|
inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) { _keyCode = keyCode; }
|
||||||
|
|
||||||
|
inline void KeyboardTranslator::Entry::setModifiers( Qt::KeyboardModifiers modifier )
|
||||||
|
{
|
||||||
|
_modifiers = modifier;
|
||||||
|
}
|
||||||
|
inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const { return _modifiers; }
|
||||||
|
|
||||||
|
inline void KeyboardTranslator::Entry::setModifierMask( Qt::KeyboardModifiers mask )
|
||||||
|
{
|
||||||
|
_modifierMask = mask;
|
||||||
|
}
|
||||||
|
inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { return _modifierMask; }
|
||||||
|
|
||||||
|
inline bool KeyboardTranslator::Entry::isNull() const
|
||||||
|
{
|
||||||
|
return ( *this == Entry() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void KeyboardTranslator::Entry::setCommand( Command command )
|
||||||
|
{
|
||||||
|
_command = command;
|
||||||
|
}
|
||||||
|
inline KeyboardTranslator::Command KeyboardTranslator::Entry::command() const { return _command; }
|
||||||
|
|
||||||
|
inline void KeyboardTranslator::Entry::setText( const QByteArray& text )
|
||||||
|
{
|
||||||
|
_text = unescape(text);
|
||||||
|
}
|
||||||
|
inline int oneOrZero(int value)
|
||||||
|
{
|
||||||
|
return value ? 1 : 0;
|
||||||
|
}
|
||||||
|
inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::KeyboardModifiers modifiers) const
|
||||||
|
{
|
||||||
|
QByteArray expandedText = _text;
|
||||||
|
|
||||||
|
if (expandWildCards)
|
||||||
|
{
|
||||||
|
int modifierValue = 1;
|
||||||
|
modifierValue += oneOrZero(modifiers & Qt::ShiftModifier);
|
||||||
|
modifierValue += oneOrZero(modifiers & Qt::AltModifier) << 1;
|
||||||
|
modifierValue += oneOrZero(modifiers & Qt::ControlModifier) << 2;
|
||||||
|
|
||||||
|
for (int i=0;i<_text.length();i++)
|
||||||
|
{
|
||||||
|
if (expandedText[i] == '*')
|
||||||
|
expandedText[i] = '0' + modifierValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expandedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void KeyboardTranslator::Entry::setState( States state )
|
||||||
|
{
|
||||||
|
_state = state;
|
||||||
|
}
|
||||||
|
inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const { return _state; }
|
||||||
|
|
||||||
|
inline void KeyboardTranslator::Entry::setStateMask( States stateMask )
|
||||||
|
{
|
||||||
|
_stateMask = stateMask;
|
||||||
|
}
|
||||||
|
inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const { return _stateMask; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Konsole::KeyboardTranslator::Entry)
|
||||||
|
Q_DECLARE_METATYPE(const Konsole::KeyboardTranslator*)
|
||||||
|
|
||||||
|
#endif // KEYBOARDTRANSLATOR_H
|
||||||
|
|
@ -0,0 +1,21 @@
|
|||||||
|
// WARNING: Autogenerated by "fontembedder ./linefont.src".
|
||||||
|
// You probably do not want to hand-edit this!
|
||||||
|
|
||||||
|
static const quint32 LineChars[] = {
|
||||||
|
0x00007c00, 0x000fffe0, 0x00421084, 0x00e739ce, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00427000, 0x004e7380, 0x00e77800, 0x00ef7bc0,
|
||||||
|
0x00421c00, 0x00439ce0, 0x00e73c00, 0x00e7bde0, 0x00007084, 0x000e7384, 0x000079ce, 0x000f7bce,
|
||||||
|
0x00001c84, 0x00039ce4, 0x00003dce, 0x0007bdee, 0x00427084, 0x004e7384, 0x004279ce, 0x00e77884,
|
||||||
|
0x00e779ce, 0x004f7bce, 0x00ef7bc4, 0x00ef7bce, 0x00421c84, 0x00439ce4, 0x00423dce, 0x00e73c84,
|
||||||
|
0x00e73dce, 0x0047bdee, 0x00e7bde4, 0x00e7bdee, 0x00427c00, 0x0043fce0, 0x004e7f80, 0x004fffe0,
|
||||||
|
0x004fffe0, 0x00e7fde0, 0x006f7fc0, 0x00efffe0, 0x00007c84, 0x0003fce4, 0x000e7f84, 0x000fffe4,
|
||||||
|
0x00007dce, 0x0007fdee, 0x000f7fce, 0x000fffee, 0x00427c84, 0x0043fce4, 0x004e7f84, 0x004fffe4,
|
||||||
|
0x00427dce, 0x00e77c84, 0x00e77dce, 0x0047fdee, 0x004e7fce, 0x00e7fde4, 0x00ef7f84, 0x004fffee,
|
||||||
|
0x00efffe4, 0x00e7fdee, 0x00ef7fce, 0x00efffee, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0x000f83e0, 0x00a5294a, 0x004e1380, 0x00a57800, 0x00ad0bc0, 0x004390e0, 0x00a53c00, 0x00a5a1e0,
|
||||||
|
0x000e1384, 0x0000794a, 0x000f0b4a, 0x000390e4, 0x00003d4a, 0x0007a16a, 0x004e1384, 0x00a5694a,
|
||||||
|
0x00ad2b4a, 0x004390e4, 0x00a52d4a, 0x00a5a16a, 0x004f83e0, 0x00a57c00, 0x00ad83e0, 0x000f83e4,
|
||||||
|
0x00007d4a, 0x000f836a, 0x004f93e4, 0x00a57d4a, 0x00ad836a, 0x00000000, 0x00000000, 0x00000000,
|
||||||
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00001c00, 0x00001084, 0x00007000, 0x00421000,
|
||||||
|
0x00039ce0, 0x000039ce, 0x000e7380, 0x00e73800, 0x000e7f80, 0x00e73884, 0x0003fce0, 0x004239ce
|
||||||
|
};
|
@ -0,0 +1,786 @@
|
|||||||
|
#2500: single horizontal line
|
||||||
|
2500
|
||||||
|
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#2501: triple horizontal line
|
||||||
|
2501
|
||||||
|
|
||||||
|
-----
|
||||||
|
-----
|
||||||
|
-----
|
||||||
|
|
||||||
|
|
||||||
|
#2502: single vertical line
|
||||||
|
2502
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
#2503: triple vertical line
|
||||||
|
2503
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
#2504-250B are dashed - not handled
|
||||||
|
|
||||||
|
#250C: top-left corner (lines on bottom + right)
|
||||||
|
250C
|
||||||
|
|
||||||
|
|
||||||
|
.--
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
#250D: as above, but top line triple-width
|
||||||
|
250D
|
||||||
|
|
||||||
|
.--
|
||||||
|
.--
|
||||||
|
|--
|
||||||
|
|
|
||||||
|
|
||||||
|
#250E: now the vert line triple-width
|
||||||
|
250E
|
||||||
|
|
||||||
|
|
||||||
|
..--
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
#250F: and now both lines triple-width
|
||||||
|
250F
|
||||||
|
|
||||||
|
.___
|
||||||
|
|.--
|
||||||
|
||._
|
||||||
|
|||
|
||||||
|
|
||||||
|
#2510: top-right corner
|
||||||
|
2510
|
||||||
|
|
||||||
|
|
||||||
|
--.
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
2511
|
||||||
|
|
||||||
|
==.
|
||||||
|
==.
|
||||||
|
==|
|
||||||
|
|
|
||||||
|
|
||||||
|
2512
|
||||||
|
|
||||||
|
|
||||||
|
==..
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2513
|
||||||
|
|
||||||
|
===.
|
||||||
|
==.|
|
||||||
|
=.||
|
||||||
|
|||
|
||||||
|
|
||||||
|
#2514: bottom-left corner
|
||||||
|
2514
|
||||||
|
|
|
||||||
|
|
|
||||||
|
.==
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2515
|
||||||
|
|
|
||||||
|
|==
|
||||||
|
|==
|
||||||
|
===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2516
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|.==
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2517
|
||||||
|
|||
|
||||||
|
||.=
|
||||||
|
|.==
|
||||||
|
.===
|
||||||
|
|
||||||
|
|
||||||
|
#2518: bottm-right corner
|
||||||
|
2518
|
||||||
|
|
|
||||||
|
|
|
||||||
|
==.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2519
|
||||||
|
|
|
||||||
|
==|
|
||||||
|
==|
|
||||||
|
===
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
251A
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
251B
|
||||||
|
|||
|
||||||
|
=.||
|
||||||
|
==.|
|
||||||
|
===.
|
||||||
|
|
||||||
|
|
||||||
|
#251C: Join of vertical line and one from the right
|
||||||
|
251C
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|==
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
251D
|
||||||
|
|
|
||||||
|
|==
|
||||||
|
|==
|
||||||
|
|==
|
||||||
|
|
|
||||||
|
|
||||||
|
251E
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
||==
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
251F
|
||||||
|
|
|
||||||
|
|
|
||||||
|
||==
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
|
||||||
|
2520
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
||==
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2521
|
||||||
|
|||
|
||||||
|
|||=
|
||||||
|
||==
|
||||||
|
.|==
|
||||||
|
|
|
||||||
|
|
||||||
|
2522
|
||||||
|
|
|
||||||
|
.|==
|
||||||
|
||==
|
||||||
|
|||=
|
||||||
|
|||
|
||||||
|
|
||||||
|
2523
|
||||||
|
|||
|
||||||
|
||.=
|
||||||
|
||==
|
||||||
|
||.=
|
||||||
|
|||
|
||||||
|
|
||||||
|
#2524: Join of vertical line and one from the left
|
||||||
|
2524
|
||||||
|
|
|
||||||
|
|
|
||||||
|
==|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
2525
|
||||||
|
|
|
||||||
|
==|
|
||||||
|
==|
|
||||||
|
==|
|
||||||
|
|
|
||||||
|
|
||||||
|
2526
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
==+|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
2527
|
||||||
|
|
|
||||||
|
|
|
||||||
|
==+|
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2528
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
==+|
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2529
|
||||||
|
|||
|
||||||
|
=+||
|
||||||
|
==+|
|
||||||
|
===+
|
||||||
|
|
|
||||||
|
|
||||||
|
252A
|
||||||
|
|
|
||||||
|
=+||
|
||||||
|
==+|
|
||||||
|
===+
|
||||||
|
|||
|
||||||
|
|
||||||
|
252B
|
||||||
|
|||
|
||||||
|
=+||
|
||||||
|
==+|
|
||||||
|
=+||
|
||||||
|
|||
|
||||||
|
|
||||||
|
#252C: horizontal line joined to from below
|
||||||
|
252C
|
||||||
|
|
||||||
|
|
||||||
|
=====
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
252D
|
||||||
|
|
||||||
|
===
|
||||||
|
==|==
|
||||||
|
==|
|
||||||
|
|
|
||||||
|
|
||||||
|
252E
|
||||||
|
|
||||||
|
===
|
||||||
|
==|==
|
||||||
|
|==
|
||||||
|
|
|
||||||
|
|
||||||
|
252F
|
||||||
|
|
||||||
|
==+==
|
||||||
|
==|==
|
||||||
|
==|==
|
||||||
|
|
|
||||||
|
|
||||||
|
2530
|
||||||
|
|
||||||
|
=====
|
||||||
|
=====
|
||||||
|
==|==
|
||||||
|
|
|
||||||
|
|
||||||
|
2531
|
||||||
|
|
||||||
|
===|
|
||||||
|
==||=
|
||||||
|
=|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2532
|
||||||
|
|
||||||
|
|===
|
||||||
|
=||==
|
||||||
|
||==
|
||||||
|
||
|
||||||
|
|
||||||
|
2533
|
||||||
|
|
||||||
|
=====
|
||||||
|
==|==
|
||||||
|
=+|+=
|
||||||
|
|||
|
||||||
|
|
||||||
|
#2534: bottom line, connected to from top
|
||||||
|
2534
|
||||||
|
|
|
||||||
|
|
|
||||||
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2535
|
||||||
|
|
|
||||||
|
==|
|
||||||
|
=====
|
||||||
|
===
|
||||||
|
|
||||||
|
|
||||||
|
2536
|
||||||
|
|
|
||||||
|
|==
|
||||||
|
=====
|
||||||
|
===
|
||||||
|
|
||||||
|
|
||||||
|
2537
|
||||||
|
|
|
||||||
|
==|==
|
||||||
|
=====
|
||||||
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
2538
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2539
|
||||||
|
|||
|
||||||
|
==||
|
||||||
|
=====
|
||||||
|
===|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
253A
|
||||||
|
|||
|
||||||
|
||==
|
||||||
|
=|===
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
253B
|
||||||
|
|||
|
||||||
|
==|==
|
||||||
|
=====
|
||||||
|
=====
|
||||||
|
|
||||||
|
|
||||||
|
#253C: vertical + horizontal lines intersecting
|
||||||
|
253C
|
||||||
|
|
|
||||||
|
|
|
||||||
|
=====
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
253D
|
||||||
|
|
|
||||||
|
==|
|
||||||
|
=====
|
||||||
|
==|
|
||||||
|
|
|
||||||
|
|
||||||
|
253E
|
||||||
|
|
|
||||||
|
|==
|
||||||
|
=====
|
||||||
|
|==
|
||||||
|
|
|
||||||
|
|
||||||
|
253F
|
||||||
|
|
|
||||||
|
==|==
|
||||||
|
=====
|
||||||
|
==|==
|
||||||
|
|
|
||||||
|
|
||||||
|
2540
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
=====
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
2541
|
||||||
|
|
|
||||||
|
|
|
||||||
|
=====
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2542
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
=====
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2543
|
||||||
|
|||
|
||||||
|
=|||
|
||||||
|
=====
|
||||||
|
==|+
|
||||||
|
|
|
||||||
|
|
||||||
|
2544
|
||||||
|
|||
|
||||||
|
||==
|
||||||
|
=====
|
||||||
|
|==
|
||||||
|
|
|
||||||
|
|
||||||
|
2545
|
||||||
|
|
|
||||||
|
==|+
|
||||||
|
=====
|
||||||
|
=|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
2546
|
||||||
|
|
|
||||||
|
|==
|
||||||
|
=====
|
||||||
|
||==
|
||||||
|
|||
|
||||||
|
|
||||||
|
2547
|
||||||
|
|||
|
||||||
|
=|||=
|
||||||
|
=====
|
||||||
|
=|||=
|
||||||
|
|
|
||||||
|
|
||||||
|
2548
|
||||||
|
|
|
||||||
|
=|||=
|
||||||
|
=====
|
||||||
|
=|||=
|
||||||
|
|||
|
||||||
|
|
||||||
|
2549
|
||||||
|
|||
|
||||||
|
=|||
|
||||||
|
=====
|
||||||
|
=|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
254A
|
||||||
|
|||
|
||||||
|
|||=
|
||||||
|
=====
|
||||||
|
|||=
|
||||||
|
|||
|
||||||
|
|
||||||
|
254B
|
||||||
|
|||
|
||||||
|
=|||=
|
||||||
|
=====
|
||||||
|
=|||=
|
||||||
|
|||
|
||||||
|
|
||||||
|
#254C-254F are dashed
|
||||||
|
2550
|
||||||
|
|
||||||
|
_____
|
||||||
|
|
||||||
|
_____
|
||||||
|
|
||||||
|
|
||||||
|
2551
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2552
|
||||||
|
|
||||||
|
|--
|
||||||
|
|
|
||||||
|
|--
|
||||||
|
|
|
||||||
|
|
||||||
|
2553
|
||||||
|
|
||||||
|
|
||||||
|
----
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2554
|
||||||
|
|
||||||
|
+---
|
||||||
|
|
|
||||||
|
+ +-
|
||||||
|
| |
|
||||||
|
|
||||||
|
2555
|
||||||
|
|
||||||
|
--+
|
||||||
|
|
|
||||||
|
--+
|
||||||
|
|
|
||||||
|
|
||||||
|
2556
|
||||||
|
|
||||||
|
|
||||||
|
-+-+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2557
|
||||||
|
|
||||||
|
---+
|
||||||
|
|
|
||||||
|
-+ |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2558
|
||||||
|
|
|
||||||
|
+--
|
||||||
|
|
|
||||||
|
+--
|
||||||
|
|
||||||
|
2559
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+-+-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
255A
|
||||||
|
| |
|
||||||
|
| +-
|
||||||
|
|
|
||||||
|
+---
|
||||||
|
|
||||||
|
|
||||||
|
255B
|
||||||
|
|
|
||||||
|
--+
|
||||||
|
|
|
||||||
|
--+
|
||||||
|
|
||||||
|
|
||||||
|
255C
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
-+-+
|
||||||
|
|
||||||
|
|
||||||
|
255D
|
||||||
|
| |
|
||||||
|
-+ |
|
||||||
|
|
|
||||||
|
---+
|
||||||
|
|
||||||
|
|
||||||
|
255E
|
||||||
|
|
|
||||||
|
+--
|
||||||
|
|
|
||||||
|
+--
|
||||||
|
|
|
||||||
|
|
||||||
|
255F
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| +-
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2560
|
||||||
|
| |
|
||||||
|
| +-
|
||||||
|
| |
|
||||||
|
| +-
|
||||||
|
| |
|
||||||
|
|
||||||
|
2561
|
||||||
|
|
|
||||||
|
--+
|
||||||
|
|
|
||||||
|
--+
|
||||||
|
|
|
||||||
|
|
||||||
|
2562
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
-+ +
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2563
|
||||||
|
| |
|
||||||
|
-+ |
|
||||||
|
|
|
||||||
|
-+ |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2564
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
--+--
|
||||||
|
|
|
||||||
|
|
||||||
|
2565
|
||||||
|
|
||||||
|
|
||||||
|
-+-+-
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
2566
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
-+ +-
|
||||||
|
| |
|
||||||
|
|
||||||
|
2567
|
||||||
|
|
|
||||||
|
--+--
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
|
||||||
|
2568
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
-+-+-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2569
|
||||||
|
| |
|
||||||
|
-+ +-
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
|
||||||
|
256A
|
||||||
|
|
|
||||||
|
--+--
|
||||||
|
|
|
||||||
|
--+--
|
||||||
|
|
|
||||||
|
|
||||||
|
256B
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
-+-+-
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|
||||||
|
256C
|
||||||
|
| |
|
||||||
|
-+ +-
|
||||||
|
|
||||||
|
-+ +-
|
||||||
|
| |
|
||||||
|
|
||||||
|
#256F-2570 are curly,
|
||||||
|
#2571-2573 are slashes and X
|
||||||
|
|
||||||
|
2574
|
||||||
|
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2575
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2576
|
||||||
|
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2577
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
2578
|
||||||
|
|
||||||
|
___
|
||||||
|
___
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
2579
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
257A
|
||||||
|
|
||||||
|
___
|
||||||
|
___
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
257B
|
||||||
|
|
||||||
|
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
257C
|
||||||
|
|
||||||
|
___
|
||||||
|
_____
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
257D
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
||||||
|
257E
|
||||||
|
|
||||||
|
___
|
||||||
|
_____
|
||||||
|
___
|
||||||
|
|
||||||
|
|
||||||
|
257F
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|||
|
||||||
|
|
|
||||||
|
|
|
@ -0,0 +1,316 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of QTerminal - http://gitorious.org/qterminal
|
||||||
|
*
|
||||||
|
* This file was un-linked from KDE and modified
|
||||||
|
* by Maxim Bourmistrov <maxim@unixconn.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "Pty.h"
|
||||||
|
|
||||||
|
// System
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "kpty.h"
|
||||||
|
#include "kptydevice.h"
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
void Pty::setWindowSize(int lines, int cols)
|
||||||
|
{
|
||||||
|
_windowColumns = cols;
|
||||||
|
_windowLines = lines;
|
||||||
|
|
||||||
|
if (pty()->masterFd() >= 0)
|
||||||
|
pty()->setWinSize(lines, cols);
|
||||||
|
}
|
||||||
|
QSize Pty::windowSize() const
|
||||||
|
{
|
||||||
|
return QSize(_windowColumns,_windowLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::setFlowControlEnabled(bool enable)
|
||||||
|
{
|
||||||
|
_xonXoff = enable;
|
||||||
|
|
||||||
|
if (pty()->masterFd() >= 0)
|
||||||
|
{
|
||||||
|
struct ::termios ttmode;
|
||||||
|
pty()->tcGetAttr(&ttmode);
|
||||||
|
if (!enable)
|
||||||
|
ttmode.c_iflag &= ~(IXOFF | IXON);
|
||||||
|
else
|
||||||
|
ttmode.c_iflag |= (IXOFF | IXON);
|
||||||
|
if (!pty()->tcSetAttr(&ttmode))
|
||||||
|
qWarning() << "Unable to set terminal attributes.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool Pty::flowControlEnabled() const
|
||||||
|
{
|
||||||
|
if (pty()->masterFd() >= 0)
|
||||||
|
{
|
||||||
|
struct ::termios ttmode;
|
||||||
|
pty()->tcGetAttr(&ttmode);
|
||||||
|
return ttmode.c_iflag & IXOFF &&
|
||||||
|
ttmode.c_iflag & IXON;
|
||||||
|
}
|
||||||
|
qWarning() << "Unable to get flow control status, terminal not connected.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::setUtf8Mode(bool enable)
|
||||||
|
{
|
||||||
|
#ifdef IUTF8 // XXX not a reasonable place to check it.
|
||||||
|
_utf8 = enable;
|
||||||
|
|
||||||
|
if (pty()->masterFd() >= 0)
|
||||||
|
{
|
||||||
|
struct ::termios ttmode;
|
||||||
|
pty()->tcGetAttr(&ttmode);
|
||||||
|
if (!enable)
|
||||||
|
ttmode.c_iflag &= ~IUTF8;
|
||||||
|
else
|
||||||
|
ttmode.c_iflag |= IUTF8;
|
||||||
|
if (!pty()->tcSetAttr(&ttmode))
|
||||||
|
qWarning() << "Unable to set terminal attributes.";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::setErase(char erase)
|
||||||
|
{
|
||||||
|
_eraseChar = erase;
|
||||||
|
|
||||||
|
if (pty()->masterFd() >= 0)
|
||||||
|
{
|
||||||
|
struct ::termios ttmode;
|
||||||
|
pty()->tcGetAttr(&ttmode);
|
||||||
|
ttmode.c_cc[VERASE] = erase;
|
||||||
|
if (!pty()->tcSetAttr(&ttmode))
|
||||||
|
qWarning() << "Unable to set terminal attributes.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Pty::erase() const
|
||||||
|
{
|
||||||
|
if (pty()->masterFd() >= 0)
|
||||||
|
{
|
||||||
|
struct ::termios ttyAttributes;
|
||||||
|
pty()->tcGetAttr(&ttyAttributes);
|
||||||
|
return ttyAttributes.c_cc[VERASE];
|
||||||
|
}
|
||||||
|
|
||||||
|
return _eraseChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::addEnvironmentVariables(const QStringList& environment)
|
||||||
|
{
|
||||||
|
QListIterator<QString> iter(environment);
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
QString pair = iter.next();
|
||||||
|
|
||||||
|
// split on the first '=' character
|
||||||
|
int pos = pair.indexOf('=');
|
||||||
|
|
||||||
|
if ( pos >= 0 )
|
||||||
|
{
|
||||||
|
QString variable = pair.left(pos);
|
||||||
|
QString value = pair.mid(pos+1);
|
||||||
|
|
||||||
|
setEnv(variable,value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pty::start(const QString& program,
|
||||||
|
const QStringList& programArguments,
|
||||||
|
const QStringList& environment,
|
||||||
|
ulong winid,
|
||||||
|
bool addToUtmp
|
||||||
|
//const QString& dbusService,
|
||||||
|
//const QString& dbusSession
|
||||||
|
)
|
||||||
|
{
|
||||||
|
clearProgram();
|
||||||
|
|
||||||
|
// For historical reasons, the first argument in programArguments is the
|
||||||
|
// name of the program to execute, so create a list consisting of all
|
||||||
|
// but the first argument to pass to setProgram()
|
||||||
|
Q_ASSERT(programArguments.count() >= 1);
|
||||||
|
setProgram(program.toLatin1(),programArguments.mid(1));
|
||||||
|
|
||||||
|
addEnvironmentVariables(environment);
|
||||||
|
|
||||||
|
setEnv("WINDOWID", QString::number(winid));
|
||||||
|
|
||||||
|
// unless the LANGUAGE environment variable has been set explicitly
|
||||||
|
// set it to a null string
|
||||||
|
// this fixes the problem where KCatalog sets the LANGUAGE environment
|
||||||
|
// variable during the application's startup to something which
|
||||||
|
// differs from LANG,LC_* etc. and causes programs run from
|
||||||
|
// the terminal to display messages in the wrong language
|
||||||
|
//
|
||||||
|
// this can happen if LANG contains a language which KDE
|
||||||
|
// does not have a translation for
|
||||||
|
//
|
||||||
|
// BR:149300
|
||||||
|
setEnv("LANGUAGE",QString(),false /* do not overwrite existing value if any */);
|
||||||
|
|
||||||
|
setUseUtmp(addToUtmp);
|
||||||
|
|
||||||
|
struct ::termios ttmode;
|
||||||
|
pty()->tcGetAttr(&ttmode);
|
||||||
|
if (!_xonXoff)
|
||||||
|
ttmode.c_iflag &= ~(IXOFF | IXON);
|
||||||
|
else
|
||||||
|
ttmode.c_iflag |= (IXOFF | IXON);
|
||||||
|
#ifdef IUTF8 // XXX not a reasonable place to check it.
|
||||||
|
if (!_utf8)
|
||||||
|
ttmode.c_iflag &= ~IUTF8;
|
||||||
|
else
|
||||||
|
ttmode.c_iflag |= IUTF8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_eraseChar != 0)
|
||||||
|
ttmode.c_cc[VERASE] = _eraseChar;
|
||||||
|
|
||||||
|
if (!pty()->tcSetAttr(&ttmode))
|
||||||
|
qWarning() << "Unable to set terminal attributes.";
|
||||||
|
|
||||||
|
pty()->setWinSize(_windowLines, _windowColumns);
|
||||||
|
|
||||||
|
KProcess::start();
|
||||||
|
|
||||||
|
if (!waitForStarted())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::setWriteable(bool writeable)
|
||||||
|
{
|
||||||
|
struct stat sbuf;
|
||||||
|
stat(pty()->ttyName(), &sbuf);
|
||||||
|
if (writeable)
|
||||||
|
chmod(pty()->ttyName(), sbuf.st_mode | S_IWGRP);
|
||||||
|
else
|
||||||
|
chmod(pty()->ttyName(), sbuf.st_mode & ~(S_IWGRP|S_IWOTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
Pty::Pty(int masterFd, QObject* parent)
|
||||||
|
: KPtyProcess(masterFd,parent)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
Pty::Pty(QObject* parent)
|
||||||
|
: KPtyProcess(parent)
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
void Pty::init()
|
||||||
|
{
|
||||||
|
_windowColumns = 0;
|
||||||
|
_windowLines = 0;
|
||||||
|
_eraseChar = 0;
|
||||||
|
_xonXoff = true;
|
||||||
|
_utf8 =true;
|
||||||
|
|
||||||
|
connect(pty(), SIGNAL(readyRead()) , this , SLOT(dataReceived()));
|
||||||
|
setPtyChannels(KPtyProcess::AllChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pty::~Pty()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::sendData(const char* data, int length)
|
||||||
|
{
|
||||||
|
if (!length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pty()->write(data,length))
|
||||||
|
{
|
||||||
|
qWarning() << "Pty::doSendJobs - Could not send input data to terminal process.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::dataReceived()
|
||||||
|
{
|
||||||
|
QByteArray data = pty()->readAll();
|
||||||
|
emit receivedData(data.constData(),data.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::lockPty(bool lock)
|
||||||
|
{
|
||||||
|
Q_UNUSED(lock);
|
||||||
|
|
||||||
|
// TODO: Support for locking the Pty
|
||||||
|
//if (lock)
|
||||||
|
//suspend();
|
||||||
|
//else
|
||||||
|
//resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Pty::foregroundProcessGroup() const
|
||||||
|
{
|
||||||
|
int pid = tcgetpgrp(pty()->masterFd());
|
||||||
|
|
||||||
|
if ( pid != -1 )
|
||||||
|
{
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pty::setupChildProcess()
|
||||||
|
{
|
||||||
|
KPtyProcess::setupChildProcess();
|
||||||
|
|
||||||
|
// reset all signal handlers
|
||||||
|
// this ensures that terminal applications respond to
|
||||||
|
// signals generated via key sequences such as Ctrl+C
|
||||||
|
// (which sends SIGINT)
|
||||||
|
struct sigaction action;
|
||||||
|
sigset_t sigset;
|
||||||
|
sigemptyset(&action.sa_mask);
|
||||||
|
action.sa_handler = SIG_DFL;
|
||||||
|
action.sa_flags = 0;
|
||||||
|
for (int signal=1;signal < NSIG; signal++) {
|
||||||
|
sigaction(signal,&action,0L);
|
||||||
|
sigaddset(&sigset, signal);
|
||||||
|
}
|
||||||
|
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of QTerminal - http://gitorious.org/qterminal
|
||||||
|
*
|
||||||
|
* This file was un-linked from KDE and modified
|
||||||
|
* by Maxim Bourmistrov <maxim@unixconn.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is part of Konsole, KDE's terminal emulator.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PTY_H
|
||||||
|
#define PTY_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QList>
|
||||||
|
#include <QSize>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
#include "kptyprocess.h"
|
||||||
|
|
||||||
|
namespace Konsole {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Pty class is used to start the terminal process,
|
||||||
|
* send data to it, receive data from it and manipulate
|
||||||
|
* various properties of the pseudo-teletype interface
|
||||||
|
* used to communicate with the process.
|
||||||
|
*
|
||||||
|
* To use this class, construct an instance and connect
|
||||||
|
* to the sendData slot and receivedData signal to
|
||||||
|
* send data to or receive data from the process.
|
||||||
|
*
|
||||||
|
* To start the terminal process, call the start() method
|
||||||
|
* with the program name and appropriate arguments.
|
||||||
|
*/
|
||||||
|
class Pty: public KPtyProcess
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new Pty.
|
||||||
|
*
|
||||||
|
* Connect to the sendData() slot and receivedData() signal to prepare
|
||||||
|
* for sending and receiving data from the terminal process.
|
||||||
|
*
|
||||||
|
* To start the terminal process, call the run() method with the
|
||||||
|
* name of the program to start and appropriate arguments.
|
||||||
|
*/
|
||||||
|
explicit Pty(QObject* parent = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a process using an open pty master.
|
||||||
|
* See KPtyProcess::KPtyProcess()
|
||||||
|
*/
|
||||||
|
explicit Pty(int ptyMasterFd, QObject* parent = 0);
|
||||||
|
|
||||||
|
~Pty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the terminal process.
|
||||||
|
*
|
||||||
|
* Returns 0 if the process was started successfully or non-zero
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
|
* @param program Path to the program to start
|
||||||
|
* @param arguments Arguments to pass to the program being started
|
||||||
|
* @param environment A list of key=value pairs which will be added
|
||||||
|
* to the environment for the new process. At the very least this
|
||||||
|
* should include an assignment for the TERM environment variable.
|
||||||
|
* @param winid Specifies the value of the WINDOWID environment variable
|
||||||
|
* in the process's environment.
|
||||||
|
* @param addToUtmp Specifies whether a utmp entry should be created for
|
||||||
|
* the pty used. See K3Process::setUsePty()
|
||||||
|
* @param dbusService Specifies the value of the KONSOLE_DBUS_SERVICE
|
||||||
|
* environment variable in the process's environment.
|
||||||
|
* @param dbusSession Specifies the value of the KONSOLE_DBUS_SESSION
|
||||||
|
* environment variable in the process's environment.
|
||||||
|
*/
|
||||||
|
int start( const QString& program,
|
||||||
|
const QStringList& arguments,
|
||||||
|
const QStringList& environment,
|
||||||
|
ulong winid,
|
||||||
|
bool addToUtmp
|
||||||
|
);
|
||||||
|
|
||||||
|
/** TODO: Document me */
|
||||||
|
void setWriteable(bool writeable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables or disables Xon/Xoff flow control. The flow control setting
|
||||||
|
* may be changed later by a terminal application, so flowControlEnabled()
|
||||||
|
* may not equal the value of @p on in the previous call to setFlowControlEnabled()
|
||||||
|
*/
|
||||||
|
void setFlowControlEnabled(bool on);
|
||||||
|
|
||||||
|
/** Queries the terminal state and returns true if Xon/Xoff flow control is enabled. */
|
||||||
|
bool flowControlEnabled() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the size of the window (in lines and columns of characters)
|
||||||
|
* used by this teletype.
|
||||||
|
*/
|
||||||
|
void setWindowSize(int lines, int cols);
|
||||||
|
|
||||||
|
/** Returns the size of the window used by this teletype. See setWindowSize() */
|
||||||
|
QSize windowSize() const;
|
||||||
|
|
||||||
|
/** TODO Document me */
|
||||||
|
void setErase(char erase);
|
||||||
|
|
||||||
|
/** */
|
||||||
|
char erase() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the process id of the teletype's current foreground
|
||||||
|
* process. This is the process which is currently reading
|
||||||
|
* input sent to the terminal via. sendData()
|
||||||
|
*
|
||||||
|
* If there is a problem reading the foreground process group,
|
||||||
|
* 0 will be returned.
|
||||||
|
*/
|
||||||
|
int foregroundProcessGroup() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put the pty into UTF-8 mode on systems which support it.
|
||||||
|
*/
|
||||||
|
void setUtf8Mode(bool on);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend or resume processing of data from the standard
|
||||||
|
* output of the terminal process.
|
||||||
|
*
|
||||||
|
* See K3Process::suspend() and K3Process::resume()
|
||||||
|
*
|
||||||
|
* @param lock If true, processing of output is suspended,
|
||||||
|
* otherwise processing is resumed.
|
||||||
|
*/
|
||||||
|
void lockPty(bool lock);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends data to the process currently controlling the
|
||||||
|
* teletype ( whose id is returned by foregroundProcessGroup() )
|
||||||
|
*
|
||||||
|
* @param buffer Pointer to the data to send.
|
||||||
|
* @param length Length of @p buffer.
|
||||||
|
*/
|
||||||
|
void sendData(const char* buffer, int length);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when a new block of data is received from
|
||||||
|
* the teletype.
|
||||||
|
*
|
||||||
|
* @param buffer Pointer to the data received.
|
||||||
|
* @param length Length of @p buffer
|
||||||
|
*/
|
||||||
|
void receivedData(const char* buffer, int length);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setupChildProcess();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// called when data is received from the terminal process
|
||||||
|
void dataReceived();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
// takes a list of key=value pairs and adds them
|
||||||
|
// to the environment for the process
|
||||||
|
void addEnvironmentVariables(const QStringList& environment);
|
||||||
|
|
||||||
|
int _windowColumns;
|
||||||
|
int _windowLines;
|
||||||
|
char _eraseChar;
|
||||||
|
bool _xonXoff;
|
||||||
|
bool _utf8;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PTY_H
|
@ -0,0 +1,7 @@
|
|||||||
|
lib.pro is a *.pro-file for qmake
|
||||||
|
|
||||||
|
It produces static lib (libqtermwidget.a) only.
|
||||||
|
For creating shared lib (*.so) uncomment "dll" in "CONFIG" line in *.pro-file
|
||||||
|
|
||||||
|
Library was tested both with HAVE_POSIX_OPENPT and HAVE_GETPT precompiler directives,
|
||||||
|
defined in "DEFINES" line. You should select variant which would be correct for your system.
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,675 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, KDE's terminal.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SCREEN_H
|
||||||
|
#define SCREEN_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QRect>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QVarLengthArray>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "Character.h"
|
||||||
|
#include "History.h"
|
||||||
|
|
||||||
|
#define MODE_Origin 0
|
||||||
|
#define MODE_Wrap 1
|
||||||
|
#define MODE_Insert 2
|
||||||
|
#define MODE_Screen 3
|
||||||
|
#define MODE_Cursor 4
|
||||||
|
#define MODE_NewLine 5
|
||||||
|
#define MODES_SCREEN 6
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
class TerminalCharacterDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief An image of characters with associated attributes.
|
||||||
|
|
||||||
|
The terminal emulation ( Emulation ) receives a serial stream of
|
||||||
|
characters from the program currently running in the terminal.
|
||||||
|
From this stream it creates an image of characters which is ultimately
|
||||||
|
rendered by the display widget ( TerminalDisplay ). Some types of emulation
|
||||||
|
may have more than one screen image.
|
||||||
|
|
||||||
|
getImage() is used to retrieve the currently visible image
|
||||||
|
which is then used by the display widget to draw the output from the
|
||||||
|
terminal.
|
||||||
|
|
||||||
|
The number of lines of output history which are kept in addition to the current
|
||||||
|
screen image depends on the history scroll being used to store the output.
|
||||||
|
The scroll is specified using setScroll()
|
||||||
|
The output history can be retrieved using writeToStream()
|
||||||
|
|
||||||
|
The screen image has a selection associated with it, specified using
|
||||||
|
setSelectionStart() and setSelectionEnd(). The selected text can be retrieved
|
||||||
|
using selectedText(). When getImage() is used to retrieve the visible image,
|
||||||
|
characters which are part of the selection have their colours inverted.
|
||||||
|
*/
|
||||||
|
class Screen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Construct a new screen image of size @p lines by @p columns. */
|
||||||
|
Screen(int lines, int columns);
|
||||||
|
~Screen();
|
||||||
|
|
||||||
|
// VT100/2 Operations
|
||||||
|
// Cursor Movement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the cursor up by @p n lines. The cursor will stop at the
|
||||||
|
* top margin.
|
||||||
|
*/
|
||||||
|
void cursorUp(int n);
|
||||||
|
/**
|
||||||
|
* Move the cursor down by @p n lines. The cursor will stop at the
|
||||||
|
* bottom margin.
|
||||||
|
*/
|
||||||
|
void cursorDown(int n);
|
||||||
|
/**
|
||||||
|
* Move the cursor to the left by @p n columns.
|
||||||
|
* The cursor will stop at the first column.
|
||||||
|
*/
|
||||||
|
void cursorLeft(int n);
|
||||||
|
/**
|
||||||
|
* Move the cursor to the right by @p n columns.
|
||||||
|
* The cursor will stop at the right-most column.
|
||||||
|
*/
|
||||||
|
void cursorRight(int n);
|
||||||
|
/** Position the cursor on line @p y. */
|
||||||
|
void setCursorY(int y);
|
||||||
|
/** Position the cursor at column @p x. */
|
||||||
|
void setCursorX(int x);
|
||||||
|
/** Position the cursor at line @p y, column @p x. */
|
||||||
|
void setCursorYX(int y, int x);
|
||||||
|
/**
|
||||||
|
* Sets the margins for scrolling the screen.
|
||||||
|
*
|
||||||
|
* @param topLine The top line of the new scrolling margin.
|
||||||
|
* @param bottomLine The bottom line of the new scrolling margin.
|
||||||
|
*/
|
||||||
|
void setMargins(int topLine , int bottomLine);
|
||||||
|
/** Returns the top line of the scrolling region. */
|
||||||
|
int topMargin() const;
|
||||||
|
/** Returns the bottom line of the scrolling region. */
|
||||||
|
int bottomMargin() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the scrolling margins back to the top and bottom lines
|
||||||
|
* of the screen.
|
||||||
|
*/
|
||||||
|
void setDefaultMargins();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the cursor down one line, if the MODE_NewLine mode
|
||||||
|
* flag is enabled then the cursor is returned to the leftmost
|
||||||
|
* column first.
|
||||||
|
*
|
||||||
|
* Equivalent to NextLine() if the MODE_NewLine flag is set
|
||||||
|
* or index() otherwise.
|
||||||
|
*/
|
||||||
|
void newLine();
|
||||||
|
/**
|
||||||
|
* Moves the cursor down one line and positions it at the beginning
|
||||||
|
* of the line. Equivalent to calling Return() followed by index()
|
||||||
|
*/
|
||||||
|
void nextLine();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the cursor down one line. If the cursor is on the bottom
|
||||||
|
* line of the scrolling region (as returned by bottomMargin()) the
|
||||||
|
* scrolling region is scrolled up by one line instead.
|
||||||
|
*/
|
||||||
|
void index();
|
||||||
|
/**
|
||||||
|
* Move the cursor up one line. If the cursor is on the top line
|
||||||
|
* of the scrolling region (as returned by topMargin()) the scrolling
|
||||||
|
* region is scrolled down by one line instead.
|
||||||
|
*/
|
||||||
|
void reverseIndex();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll the scrolling region of the screen up by @p n lines.
|
||||||
|
* The scrolling region is initially the whole screen, but can be changed
|
||||||
|
* using setMargins()
|
||||||
|
*/
|
||||||
|
void scrollUp(int n);
|
||||||
|
/**
|
||||||
|
* Scroll the scrolling region of the screen down by @p n lines.
|
||||||
|
* The scrolling region is initially the whole screen, but can be changed
|
||||||
|
* using setMargins()
|
||||||
|
*/
|
||||||
|
void scrollDown(int n);
|
||||||
|
/**
|
||||||
|
* Moves the cursor to the beginning of the current line.
|
||||||
|
* Equivalent to setCursorX(0)
|
||||||
|
*/
|
||||||
|
void toStartOfLine();
|
||||||
|
/**
|
||||||
|
* Moves the cursor one column to the left and erases the character
|
||||||
|
* at the new cursor position.
|
||||||
|
*/
|
||||||
|
void backspace();
|
||||||
|
/** Moves the cursor @p n tab-stops to the right. */
|
||||||
|
void tab(int n = 1);
|
||||||
|
/** Moves the cursor @p n tab-stops to the left. */
|
||||||
|
void backtab(int n);
|
||||||
|
|
||||||
|
// Editing
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erase @p n characters beginning from the current cursor position.
|
||||||
|
* This is equivalent to over-writing @p n characters starting with the current
|
||||||
|
* cursor position with spaces.
|
||||||
|
* If @p n is 0 then one character is erased.
|
||||||
|
*/
|
||||||
|
void eraseChars(int n);
|
||||||
|
/**
|
||||||
|
* Delete @p n characters beginning from the current cursor position.
|
||||||
|
* If @p n is 0 then one character is deleted.
|
||||||
|
*/
|
||||||
|
void deleteChars(int n);
|
||||||
|
/**
|
||||||
|
* Insert @p n blank characters beginning from the current cursor position.
|
||||||
|
* The position of the cursor is not altered.
|
||||||
|
* If @p n is 0 then one character is inserted.
|
||||||
|
*/
|
||||||
|
void insertChars(int n);
|
||||||
|
/**
|
||||||
|
* Removes @p n lines beginning from the current cursor position.
|
||||||
|
* The position of the cursor is not altered.
|
||||||
|
* If @p n is 0 then one line is removed.
|
||||||
|
*/
|
||||||
|
void deleteLines(int n);
|
||||||
|
/**
|
||||||
|
* Inserts @p lines beginning from the current cursor position.
|
||||||
|
* The position of the cursor is not altered.
|
||||||
|
* If @p n is 0 then one line is inserted.
|
||||||
|
*/
|
||||||
|
void insertLines(int n);
|
||||||
|
/** Clears all the tab stops. */
|
||||||
|
void clearTabStops();
|
||||||
|
/** Sets or removes a tab stop at the cursor's current column. */
|
||||||
|
void changeTabStop(bool set);
|
||||||
|
|
||||||
|
/** Resets (clears) the specified screen @p mode. */
|
||||||
|
void resetMode(int mode);
|
||||||
|
/** Sets (enables) the specified screen @p mode. */
|
||||||
|
void setMode(int mode);
|
||||||
|
/**
|
||||||
|
* Saves the state of the specified screen @p mode. It can be restored
|
||||||
|
* using restoreMode()
|
||||||
|
*/
|
||||||
|
void saveMode(int mode);
|
||||||
|
/** Restores the state of a screen @p mode saved by calling saveMode() */
|
||||||
|
void restoreMode(int mode);
|
||||||
|
/** Returns whether the specified screen @p mode is enabled or not .*/
|
||||||
|
bool getMode(int mode) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the current position and appearance (text color and style) of the cursor.
|
||||||
|
* It can be restored by calling restoreCursor()
|
||||||
|
*/
|
||||||
|
void saveCursor();
|
||||||
|
/** Restores the position and appearance of the cursor. See saveCursor() */
|
||||||
|
void restoreCursor();
|
||||||
|
|
||||||
|
/** Clear the whole screen, moving the current screen contents into the history first. */
|
||||||
|
void clearEntireScreen();
|
||||||
|
/**
|
||||||
|
* Clear the area of the screen from the current cursor position to the end of
|
||||||
|
* the screen.
|
||||||
|
*/
|
||||||
|
void clearToEndOfScreen();
|
||||||
|
/**
|
||||||
|
* Clear the area of the screen from the current cursor position to the start
|
||||||
|
* of the screen.
|
||||||
|
*/
|
||||||
|
void clearToBeginOfScreen();
|
||||||
|
/** Clears the whole of the line on which the cursor is currently positioned. */
|
||||||
|
void clearEntireLine();
|
||||||
|
/** Clears from the current cursor position to the end of the line. */
|
||||||
|
void clearToEndOfLine();
|
||||||
|
/** Clears from the current cursor position to the beginning of the line. */
|
||||||
|
void clearToBeginOfLine();
|
||||||
|
|
||||||
|
/** Fills the entire screen with the letter 'E' */
|
||||||
|
void helpAlign();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables the given @p rendition flag. Rendition flags control the appearance
|
||||||
|
* of characters on the screen.
|
||||||
|
*
|
||||||
|
* @see Character::rendition
|
||||||
|
*/
|
||||||
|
void setRendition(int rendition);
|
||||||
|
/**
|
||||||
|
* Disables the given @p rendition flag. Rendition flags control the appearance
|
||||||
|
* of characters on the screen.
|
||||||
|
*
|
||||||
|
* @see Character::rendition
|
||||||
|
*/
|
||||||
|
void resetRendition(int rendition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cursor's foreground color.
|
||||||
|
* @param space The color space used by the @p color argument
|
||||||
|
* @param color The new foreground color. The meaning of this depends on
|
||||||
|
* the color @p space used.
|
||||||
|
*
|
||||||
|
* @see CharacterColor
|
||||||
|
*/
|
||||||
|
void setForeColor(int space, int color);
|
||||||
|
/**
|
||||||
|
* Sets the cursor's background color.
|
||||||
|
* @param space The color space used by the @p color argumnet.
|
||||||
|
* @param color The new background color. The meaning of this depends on
|
||||||
|
* the color @p space used.
|
||||||
|
*
|
||||||
|
* @see CharacterColor
|
||||||
|
*/
|
||||||
|
void setBackColor(int space, int color);
|
||||||
|
/**
|
||||||
|
* Resets the cursor's color back to the default and sets the
|
||||||
|
* character's rendition flags back to the default settings.
|
||||||
|
*/
|
||||||
|
void setDefaultRendition();
|
||||||
|
|
||||||
|
/** Returns the column which the cursor is positioned at. */
|
||||||
|
int getCursorX() const;
|
||||||
|
/** Returns the line which the cursor is positioned on. */
|
||||||
|
int getCursorY() const;
|
||||||
|
|
||||||
|
/** Clear the entire screen and move the cursor to the home position.
|
||||||
|
* Equivalent to calling clearEntireScreen() followed by home().
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
/**
|
||||||
|
* Sets the position of the cursor to the 'home' position at the top-left
|
||||||
|
* corner of the screen (0,0)
|
||||||
|
*/
|
||||||
|
void home();
|
||||||
|
/**
|
||||||
|
* Resets the state of the screen. This resets the various screen modes
|
||||||
|
* back to their default states. The cursor style and colors are reset
|
||||||
|
* (as if setDefaultRendition() had been called)
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Line wrapping is enabled.</li>
|
||||||
|
* <li>Origin mode is disabled.</li>
|
||||||
|
* <li>Insert mode is disabled.</li>
|
||||||
|
* <li>Cursor mode is enabled. TODO Document me</li>
|
||||||
|
* <li>Screen mode is disabled. TODO Document me</li>
|
||||||
|
* <li>New line mode is disabled. TODO Document me</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* If @p clearScreen is true then the screen contents are erased entirely,
|
||||||
|
* otherwise they are unaltered.
|
||||||
|
*/
|
||||||
|
void reset(bool clearScreen = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a new character at the current cursor position.
|
||||||
|
*
|
||||||
|
* If the cursor is currently positioned at the right-edge of the screen and
|
||||||
|
* line wrapping is enabled then the character is added at the start of a new
|
||||||
|
* line below the current one.
|
||||||
|
*
|
||||||
|
* If the MODE_Insert screen mode is currently enabled then the character
|
||||||
|
* is inserted at the current cursor position, otherwise it will replace the
|
||||||
|
* character already at the current cursor position.
|
||||||
|
*/
|
||||||
|
void displayCharacter(unsigned short c);
|
||||||
|
|
||||||
|
// Do composition with last shown character FIXME: Not implemented yet for KDE 4
|
||||||
|
void compose(const QString& compose);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resizes the image to a new fixed size of @p new_lines by @p new_columns.
|
||||||
|
* In the case that @p new_columns is smaller than the current number of columns,
|
||||||
|
* existing lines are not truncated. This prevents characters from being lost
|
||||||
|
* if the terminal display is resized smaller and then larger again.
|
||||||
|
*
|
||||||
|
* The top and bottom margins are reset to the top and bottom of the new
|
||||||
|
* screen size. Tab stops are also reset and the current selection is
|
||||||
|
* cleared.
|
||||||
|
*/
|
||||||
|
void resizeImage(int new_lines, int new_columns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current screen image.
|
||||||
|
* The result is an array of Characters of size [getLines()][getColumns()] which
|
||||||
|
* must be freed by the caller after use.
|
||||||
|
*
|
||||||
|
* @param dest Buffer to copy the characters into
|
||||||
|
* @param size Size of @p dest in Characters
|
||||||
|
* @param startLine Index of first line to copy
|
||||||
|
* @param endLine Index of last line to copy
|
||||||
|
*/
|
||||||
|
void getImage( Character* dest , int size , int startLine , int endLine ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the additional attributes associated with lines in the image.
|
||||||
|
* The most important attribute is LINE_WRAPPED which specifies that the
|
||||||
|
* line is wrapped,
|
||||||
|
* other attributes control the size of characters in the line.
|
||||||
|
*/
|
||||||
|
QVector<LineProperty> getLineProperties( int startLine , int endLine ) const;
|
||||||
|
|
||||||
|
|
||||||
|
/** Return the number of lines. */
|
||||||
|
int getLines() const
|
||||||
|
{ return lines; }
|
||||||
|
/** Return the number of columns. */
|
||||||
|
int getColumns() const
|
||||||
|
{ return columns; }
|
||||||
|
/** Return the number of lines in the history buffer. */
|
||||||
|
int getHistLines() const;
|
||||||
|
/**
|
||||||
|
* Sets the type of storage used to keep lines in the history.
|
||||||
|
* If @p copyPreviousScroll is true then the contents of the previous
|
||||||
|
* history buffer are copied into the new scroll.
|
||||||
|
*/
|
||||||
|
void setScroll(const HistoryType& , bool copyPreviousScroll = true);
|
||||||
|
/** Returns the type of storage used to keep lines in the history. */
|
||||||
|
const HistoryType& getScroll() const;
|
||||||
|
/**
|
||||||
|
* Returns true if this screen keeps lines that are scrolled off the screen
|
||||||
|
* in a history buffer.
|
||||||
|
*/
|
||||||
|
bool hasScroll() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the start of the selection.
|
||||||
|
*
|
||||||
|
* @param column The column index of the first character in the selection.
|
||||||
|
* @param line The line index of the first character in the selection.
|
||||||
|
* @param blockSelectionMode True if the selection is in column mode.
|
||||||
|
*/
|
||||||
|
void setSelectionStart(const int column, const int line, const bool blockSelectionMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the end of the current selection.
|
||||||
|
*
|
||||||
|
* @param column The column index of the last character in the selection.
|
||||||
|
* @param line The line index of the last character in the selection.
|
||||||
|
*/
|
||||||
|
void setSelectionEnd(const int column, const int line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the start of the selection or the cursor position if there
|
||||||
|
* is no selection.
|
||||||
|
*/
|
||||||
|
void getSelectionStart(int& column , int& line) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the end of the selection or the cursor position if there
|
||||||
|
* is no selection.
|
||||||
|
*/
|
||||||
|
void getSelectionEnd(int& column , int& line) const;
|
||||||
|
|
||||||
|
/** Clears the current selection */
|
||||||
|
void clearSelection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the character at (@p column, @p line) is part of the
|
||||||
|
* current selection.
|
||||||
|
*/
|
||||||
|
bool isSelected(const int column,const int line) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method. Returns the currently selected text.
|
||||||
|
* @param preserveLineBreaks Specifies whether new line characters should
|
||||||
|
* be inserted into the returned text at the end of each terminal line.
|
||||||
|
*/
|
||||||
|
QString selectedText(bool preserveLineBreaks) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies part of the output to a stream.
|
||||||
|
*
|
||||||
|
* @param decoder A decoder which converts terminal characters into text
|
||||||
|
* @param fromLine The first line in the history to retrieve
|
||||||
|
* @param toLine The last line in the history to retrieve
|
||||||
|
*/
|
||||||
|
void writeLinesToStream(TerminalCharacterDecoder* decoder, int fromLine, int toLine) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY
|
||||||
|
* into a stream.
|
||||||
|
*
|
||||||
|
* @param decoder A decoder which converts terminal characters into text.
|
||||||
|
* PlainTextDecoder is the most commonly used decoder which converts characters
|
||||||
|
* into plain text with no formatting.
|
||||||
|
* @param preserveLineBreaks Specifies whether new line characters should
|
||||||
|
* be inserted into the returned text at the end of each terminal line.
|
||||||
|
*/
|
||||||
|
void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool
|
||||||
|
preserveLineBreaks = true) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the text between from and to is inside the current
|
||||||
|
* selection. If this is the case, the selection is cleared. The
|
||||||
|
* from and to are coordinates in the current viewable window.
|
||||||
|
* The loc(x,y) macro can be used to generate these values from a
|
||||||
|
* column,line pair.
|
||||||
|
*
|
||||||
|
* @param from The start of the area to check.
|
||||||
|
* @param to The end of the area to check
|
||||||
|
*/
|
||||||
|
void checkSelection(int from, int to);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets or clears an attribute of the current line.
|
||||||
|
*
|
||||||
|
* @param property The attribute to set or clear
|
||||||
|
* Possible properties are:
|
||||||
|
* LINE_WRAPPED: Specifies that the line is wrapped.
|
||||||
|
* LINE_DOUBLEWIDTH: Specifies that the characters in the current line
|
||||||
|
* should be double the normal width.
|
||||||
|
* LINE_DOUBLEHEIGHT:Specifies that the characters in the current line
|
||||||
|
* should be double the normal height.
|
||||||
|
* Double-height lines are formed of two lines containing the same characters,
|
||||||
|
* with both having the LINE_DOUBLEHEIGHT attribute.
|
||||||
|
* This allows other parts of the code to work on the
|
||||||
|
* assumption that all lines are the same height.
|
||||||
|
*
|
||||||
|
* @param enable true to apply the attribute to the current line or false to remove it
|
||||||
|
*/
|
||||||
|
void setLineProperty(LineProperty property , bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of lines that the image has been scrolled up or down by,
|
||||||
|
* since the last call to resetScrolledLines().
|
||||||
|
*
|
||||||
|
* a positive return value indicates that the image has been scrolled up,
|
||||||
|
* a negative return value indicates that the image has been scrolled down.
|
||||||
|
*/
|
||||||
|
int scrolledLines() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the region of the image which was last scrolled.
|
||||||
|
*
|
||||||
|
* This is the area of the image from the top margin to the
|
||||||
|
* bottom margin when the last scroll occurred.
|
||||||
|
*/
|
||||||
|
QRect lastScrolledRegion() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the count of the number of lines that the image has been scrolled up or down by,
|
||||||
|
* see scrolledLines()
|
||||||
|
*/
|
||||||
|
void resetScrolledLines();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of lines of output which have been
|
||||||
|
* dropped from the history since the last call
|
||||||
|
* to resetDroppedLines()
|
||||||
|
*
|
||||||
|
* If the history is not unlimited then it will drop
|
||||||
|
* the oldest lines of output if new lines are added when
|
||||||
|
* it is full.
|
||||||
|
*/
|
||||||
|
int droppedLines() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the count of the number of lines dropped from
|
||||||
|
* the history.
|
||||||
|
*/
|
||||||
|
void resetDroppedLines();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the buffer @p dest with @p count instances of the default (ie. blank)
|
||||||
|
* Character style.
|
||||||
|
*/
|
||||||
|
static void fillWithDefaultChar(Character* dest, int count);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//copies a line of text from the screen or history into a stream using a
|
||||||
|
//specified character decoder. Returns the number of lines actually copied,
|
||||||
|
//which may be less than 'count' if (start+count) is more than the number of characters on
|
||||||
|
//the line
|
||||||
|
//
|
||||||
|
//line - the line number to copy, from 0 (the earliest line in the history) up to
|
||||||
|
// history->getLines() + lines - 1
|
||||||
|
//start - the first column on the line to copy
|
||||||
|
//count - the number of characters on the line to copy
|
||||||
|
//decoder - a decoder which converts terminal characters (an Character array) into text
|
||||||
|
//appendNewLine - if true a new line character (\n) is appended to the end of the line
|
||||||
|
int copyLineToStream(int line,
|
||||||
|
int start,
|
||||||
|
int count,
|
||||||
|
TerminalCharacterDecoder* decoder,
|
||||||
|
bool appendNewLine,
|
||||||
|
bool preserveLineBreaks) const;
|
||||||
|
|
||||||
|
//fills a section of the screen image with the character 'c'
|
||||||
|
//the parameters are specified as offsets from the start of the screen image.
|
||||||
|
//the loc(x,y) macro can be used to generate these values from a column,line pair.
|
||||||
|
void clearImage(int loca, int loce, char c);
|
||||||
|
|
||||||
|
//move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'.
|
||||||
|
//the parameters are specified as offsets from the start of the screen image.
|
||||||
|
//the loc(x,y) macro can be used to generate these values from a column,line pair.
|
||||||
|
//
|
||||||
|
//NOTE: moveImage() can only move whole lines
|
||||||
|
void moveImage(int dest, int sourceBegin, int sourceEnd);
|
||||||
|
// scroll up 'i' lines in current region, clearing the bottom 'i' lines
|
||||||
|
void scrollUp(int from, int i);
|
||||||
|
// scroll down 'i' lines in current region, clearing the top 'i' lines
|
||||||
|
void scrollDown(int from, int i);
|
||||||
|
|
||||||
|
void addHistLine();
|
||||||
|
|
||||||
|
void initTabStops();
|
||||||
|
|
||||||
|
void updateEffectiveRendition();
|
||||||
|
void reverseRendition(Character& p) const;
|
||||||
|
|
||||||
|
bool isSelectionValid() const;
|
||||||
|
// copies text from 'startIndex' to 'endIndex' to a stream
|
||||||
|
// startIndex and endIndex are positions generated using the loc(x,y) macro
|
||||||
|
void writeToStream(TerminalCharacterDecoder* decoder, int startIndex,
|
||||||
|
int endIndex, bool preserveLineBreaks = true) const;
|
||||||
|
// copies 'count' lines from the screen buffer into 'dest',
|
||||||
|
// starting from 'startLine', where 0 is the first line in the screen buffer
|
||||||
|
void copyFromScreen(Character* dest, int startLine, int count) const;
|
||||||
|
// copies 'count' lines from the history buffer into 'dest',
|
||||||
|
// starting from 'startLine', where 0 is the first line in the history
|
||||||
|
void copyFromHistory(Character* dest, int startLine, int count) const;
|
||||||
|
|
||||||
|
|
||||||
|
// screen image ----------------
|
||||||
|
int lines;
|
||||||
|
int columns;
|
||||||
|
|
||||||
|
typedef QVector<Character> ImageLine; // [0..columns]
|
||||||
|
ImageLine* screenLines; // [lines]
|
||||||
|
|
||||||
|
int _scrolledLines;
|
||||||
|
QRect _lastScrolledRegion;
|
||||||
|
|
||||||
|
int _droppedLines;
|
||||||
|
|
||||||
|
QVarLengthArray<LineProperty,64> lineProperties;
|
||||||
|
|
||||||
|
// history buffer ---------------
|
||||||
|
HistoryScroll* history;
|
||||||
|
|
||||||
|
// cursor location
|
||||||
|
int cuX;
|
||||||
|
int cuY;
|
||||||
|
|
||||||
|
// cursor color and rendition info
|
||||||
|
CharacterColor currentForeground;
|
||||||
|
CharacterColor currentBackground;
|
||||||
|
quint8 currentRendition;
|
||||||
|
|
||||||
|
// margins ----------------
|
||||||
|
int _topMargin;
|
||||||
|
int _bottomMargin;
|
||||||
|
|
||||||
|
// states ----------------
|
||||||
|
int currentModes[MODES_SCREEN];
|
||||||
|
int savedModes[MODES_SCREEN];
|
||||||
|
|
||||||
|
// ----------------------------
|
||||||
|
|
||||||
|
QBitArray tabStops;
|
||||||
|
|
||||||
|
// selection -------------------
|
||||||
|
int selBegin; // The first location selected.
|
||||||
|
int selTopLeft; // TopLeft Location.
|
||||||
|
int selBottomRight; // Bottom Right Location.
|
||||||
|
bool blockSelectionMode; // Column selection mode
|
||||||
|
|
||||||
|
// effective colors and rendition ------------
|
||||||
|
CharacterColor effectiveForeground; // These are derived from
|
||||||
|
CharacterColor effectiveBackground; // the cu_* variables above
|
||||||
|
quint8 effectiveRendition; // to speed up operation
|
||||||
|
|
||||||
|
class SavedState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SavedState()
|
||||||
|
: cursorColumn(0),cursorLine(0),rendition(0) {}
|
||||||
|
|
||||||
|
int cursorColumn;
|
||||||
|
int cursorLine;
|
||||||
|
quint8 rendition;
|
||||||
|
CharacterColor foreground;
|
||||||
|
CharacterColor background;
|
||||||
|
};
|
||||||
|
SavedState savedState;
|
||||||
|
|
||||||
|
// last position where we added a character
|
||||||
|
int lastPos;
|
||||||
|
|
||||||
|
static Character defaultChar;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SCREEN_H
|
@ -0,0 +1,294 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "ScreenWindow.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "Screen.h"
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
ScreenWindow::ScreenWindow(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, _windowBuffer(0)
|
||||||
|
, _windowBufferSize(0)
|
||||||
|
, _bufferNeedsUpdate(true)
|
||||||
|
, _windowLines(1)
|
||||||
|
, _currentLine(0)
|
||||||
|
, _trackOutput(true)
|
||||||
|
, _scrollCount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ScreenWindow::~ScreenWindow()
|
||||||
|
{
|
||||||
|
delete[] _windowBuffer;
|
||||||
|
}
|
||||||
|
void ScreenWindow::setScreen(Screen* screen)
|
||||||
|
{
|
||||||
|
Q_ASSERT( screen );
|
||||||
|
|
||||||
|
_screen = screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
Screen* ScreenWindow::screen() const
|
||||||
|
{
|
||||||
|
return _screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
Character* ScreenWindow::getImage()
|
||||||
|
{
|
||||||
|
// reallocate internal buffer if the window size has changed
|
||||||
|
int size = windowLines() * windowColumns();
|
||||||
|
if (_windowBuffer == 0 || _windowBufferSize != size)
|
||||||
|
{
|
||||||
|
delete[] _windowBuffer;
|
||||||
|
_windowBufferSize = size;
|
||||||
|
_windowBuffer = new Character[size];
|
||||||
|
_bufferNeedsUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_bufferNeedsUpdate)
|
||||||
|
return _windowBuffer;
|
||||||
|
|
||||||
|
_screen->getImage(_windowBuffer,size,
|
||||||
|
currentLine(),endWindowLine());
|
||||||
|
|
||||||
|
// this window may look beyond the end of the screen, in which
|
||||||
|
// case there will be an unused area which needs to be filled
|
||||||
|
// with blank characters
|
||||||
|
fillUnusedArea();
|
||||||
|
|
||||||
|
_bufferNeedsUpdate = false;
|
||||||
|
return _windowBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::fillUnusedArea()
|
||||||
|
{
|
||||||
|
int screenEndLine = _screen->getHistLines() + _screen->getLines() - 1;
|
||||||
|
int windowEndLine = currentLine() + windowLines() - 1;
|
||||||
|
|
||||||
|
int unusedLines = windowEndLine - screenEndLine;
|
||||||
|
int charsToFill = unusedLines * windowColumns();
|
||||||
|
|
||||||
|
Screen::fillWithDefaultChar(_windowBuffer + _windowBufferSize - charsToFill,charsToFill);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the index of the line at the end of this window, or if this window
|
||||||
|
// goes beyond the end of the screen, the index of the line at the end
|
||||||
|
// of the screen.
|
||||||
|
//
|
||||||
|
// when passing a line number to a Screen method, the line number should
|
||||||
|
// never be more than endWindowLine()
|
||||||
|
//
|
||||||
|
int ScreenWindow::endWindowLine() const
|
||||||
|
{
|
||||||
|
return qMin(currentLine() + windowLines() - 1,
|
||||||
|
lineCount() - 1);
|
||||||
|
}
|
||||||
|
QVector<LineProperty> ScreenWindow::getLineProperties()
|
||||||
|
{
|
||||||
|
QVector<LineProperty> result = _screen->getLineProperties(currentLine(),endWindowLine());
|
||||||
|
|
||||||
|
if (result.count() != windowLines())
|
||||||
|
result.resize(windowLines());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ScreenWindow::selectedText( bool preserveLineBreaks ) const
|
||||||
|
{
|
||||||
|
return _screen->selectedText( preserveLineBreaks );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::getSelectionStart( int& column , int& line )
|
||||||
|
{
|
||||||
|
_screen->getSelectionStart(column,line);
|
||||||
|
line -= currentLine();
|
||||||
|
}
|
||||||
|
void ScreenWindow::getSelectionEnd( int& column , int& line )
|
||||||
|
{
|
||||||
|
_screen->getSelectionEnd(column,line);
|
||||||
|
line -= currentLine();
|
||||||
|
}
|
||||||
|
void ScreenWindow::setSelectionStart( int column , int line , bool columnMode )
|
||||||
|
{
|
||||||
|
_screen->setSelectionStart( column , qMin(line + currentLine(),endWindowLine()) , columnMode);
|
||||||
|
|
||||||
|
_bufferNeedsUpdate = true;
|
||||||
|
emit selectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::setSelectionEnd( int column , int line )
|
||||||
|
{
|
||||||
|
_screen->setSelectionEnd( column , qMin(line + currentLine(),endWindowLine()) );
|
||||||
|
|
||||||
|
_bufferNeedsUpdate = true;
|
||||||
|
emit selectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenWindow::isSelected( int column , int line )
|
||||||
|
{
|
||||||
|
return _screen->isSelected( column , qMin(line + currentLine(),endWindowLine()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::clearSelection()
|
||||||
|
{
|
||||||
|
_screen->clearSelection();
|
||||||
|
|
||||||
|
emit selectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::setWindowLines(int lines)
|
||||||
|
{
|
||||||
|
Q_ASSERT(lines > 0);
|
||||||
|
_windowLines = lines;
|
||||||
|
}
|
||||||
|
int ScreenWindow::windowLines() const
|
||||||
|
{
|
||||||
|
return _windowLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenWindow::windowColumns() const
|
||||||
|
{
|
||||||
|
return _screen->getColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenWindow::lineCount() const
|
||||||
|
{
|
||||||
|
return _screen->getHistLines() + _screen->getLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenWindow::columnCount() const
|
||||||
|
{
|
||||||
|
return _screen->getColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint ScreenWindow::cursorPosition() const
|
||||||
|
{
|
||||||
|
QPoint position;
|
||||||
|
|
||||||
|
position.setX( _screen->getCursorX() );
|
||||||
|
position.setY( _screen->getCursorY() );
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenWindow::currentLine() const
|
||||||
|
{
|
||||||
|
return qBound(0,_currentLine,lineCount()-windowLines());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::scrollBy( RelativeScrollMode mode , int amount )
|
||||||
|
{
|
||||||
|
if ( mode == ScrollLines )
|
||||||
|
{
|
||||||
|
scrollTo( currentLine() + amount );
|
||||||
|
}
|
||||||
|
else if ( mode == ScrollPages )
|
||||||
|
{
|
||||||
|
scrollTo( currentLine() + amount * ( windowLines() / 2 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenWindow::atEndOfOutput() const
|
||||||
|
{
|
||||||
|
return currentLine() == (lineCount()-windowLines());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::scrollTo( int line )
|
||||||
|
{
|
||||||
|
int maxCurrentLineNumber = lineCount() - windowLines();
|
||||||
|
line = qBound(0,line,maxCurrentLineNumber);
|
||||||
|
|
||||||
|
const int delta = line - _currentLine;
|
||||||
|
_currentLine = line;
|
||||||
|
|
||||||
|
// keep track of number of lines scrolled by,
|
||||||
|
// this can be reset by calling resetScrollCount()
|
||||||
|
_scrollCount += delta;
|
||||||
|
|
||||||
|
_bufferNeedsUpdate = true;
|
||||||
|
|
||||||
|
emit scrolled(_currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::setTrackOutput(bool trackOutput)
|
||||||
|
{
|
||||||
|
_trackOutput = trackOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenWindow::trackOutput() const
|
||||||
|
{
|
||||||
|
return _trackOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScreenWindow::scrollCount() const
|
||||||
|
{
|
||||||
|
return _scrollCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::resetScrollCount()
|
||||||
|
{
|
||||||
|
_scrollCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect ScreenWindow::scrollRegion() const
|
||||||
|
{
|
||||||
|
bool equalToScreenSize = windowLines() == _screen->getLines();
|
||||||
|
|
||||||
|
if ( atEndOfOutput() && equalToScreenSize )
|
||||||
|
return _screen->lastScrolledRegion();
|
||||||
|
else
|
||||||
|
return QRect(0,0,windowColumns(),windowLines());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenWindow::notifyOutputChanged()
|
||||||
|
{
|
||||||
|
// move window to the bottom of the screen and update scroll count
|
||||||
|
// if this window is currently tracking the bottom of the screen
|
||||||
|
if ( _trackOutput )
|
||||||
|
{
|
||||||
|
_scrollCount -= _screen->scrolledLines();
|
||||||
|
_currentLine = qMax(0,_screen->getHistLines() - (windowLines()-_screen->getLines()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if the history is not unlimited then it may
|
||||||
|
// have run out of space and dropped the oldest
|
||||||
|
// lines of output - in this case the screen
|
||||||
|
// window's current line number will need to
|
||||||
|
// be adjusted - otherwise the output will scroll
|
||||||
|
_currentLine = qMax(0,_currentLine -
|
||||||
|
_screen->droppedLines());
|
||||||
|
|
||||||
|
// ensure that the screen window's current position does
|
||||||
|
// not go beyond the bottom of the screen
|
||||||
|
_currentLine = qMin( _currentLine , _screen->getHistLines() );
|
||||||
|
}
|
||||||
|
|
||||||
|
_bufferNeedsUpdate = true;
|
||||||
|
|
||||||
|
emit outputChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#include "ScreenWindow.moc"
|
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SCREENWINDOW_H
|
||||||
|
#define SCREENWINDOW_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPoint>
|
||||||
|
#include <QRect>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "Character.h"
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
class Screen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a window onto a section of a terminal screen. A terminal widget can then render
|
||||||
|
* the contents of the window and use the window to change the terminal screen's selection
|
||||||
|
* in response to mouse or keyboard input.
|
||||||
|
*
|
||||||
|
* A new ScreenWindow for a terminal session can be created by calling Emulation::createWindow()
|
||||||
|
*
|
||||||
|
* Use the scrollTo() method to scroll the window up and down on the screen.
|
||||||
|
* Use the getImage() method to retrieve the character image which is currently visible in the window.
|
||||||
|
*
|
||||||
|
* setTrackOutput() controls whether the window moves to the bottom of the associated screen when new
|
||||||
|
* lines are added to it.
|
||||||
|
*
|
||||||
|
* Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should
|
||||||
|
* be called. This in turn will update the window's position and emit the outputChanged() signal
|
||||||
|
* if necessary.
|
||||||
|
*/
|
||||||
|
class ScreenWindow : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a new screen window with the given parent.
|
||||||
|
* A screen must be specified by calling setScreen() before calling getImage() or getLineProperties().
|
||||||
|
*
|
||||||
|
* You should not call this constructor directly, instead use the Emulation::createWindow() method
|
||||||
|
* to create a window on the emulation which you wish to view. This allows the emulation
|
||||||
|
* to notify the window when the associated screen has changed and synchronize selection updates
|
||||||
|
* between all views on a session.
|
||||||
|
*/
|
||||||
|
ScreenWindow(QObject* parent = 0);
|
||||||
|
virtual ~ScreenWindow();
|
||||||
|
|
||||||
|
/** Sets the screen which this window looks onto */
|
||||||
|
void setScreen(Screen* screen);
|
||||||
|
/** Returns the screen which this window looks onto */
|
||||||
|
Screen* screen() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the image of characters which are currently visible through this window
|
||||||
|
* onto the screen.
|
||||||
|
*
|
||||||
|
* The returned buffer is managed by the ScreenWindow instance and does not need to be
|
||||||
|
* deleted by the caller.
|
||||||
|
*/
|
||||||
|
Character* getImage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the line attributes associated with the lines of characters which
|
||||||
|
* are currently visible through this window
|
||||||
|
*/
|
||||||
|
QVector<LineProperty> getLineProperties();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of lines which the region of the window
|
||||||
|
* specified by scrollRegion() has been scrolled by since the last call
|
||||||
|
* to resetScrollCount(). scrollRegion() is in most cases the
|
||||||
|
* whole window, but will be a smaller area in, for example, applications
|
||||||
|
* which provide split-screen facilities.
|
||||||
|
*
|
||||||
|
* This is not guaranteed to be accurate, but allows views to optimize
|
||||||
|
* rendering by reducing the amount of costly text rendering that
|
||||||
|
* needs to be done when the output is scrolled.
|
||||||
|
*/
|
||||||
|
int scrollCount() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the count of scrolled lines returned by scrollCount()
|
||||||
|
*/
|
||||||
|
void resetScrollCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the area of the window which was last scrolled, this is
|
||||||
|
* usually the whole window area.
|
||||||
|
*
|
||||||
|
* Like scrollCount(), this is not guaranteed to be accurate,
|
||||||
|
* but allows views to optimize rendering.
|
||||||
|
*/
|
||||||
|
QRect scrollRegion() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the start of the selection to the given @p line and @p column within
|
||||||
|
* the window.
|
||||||
|
*/
|
||||||
|
void setSelectionStart( int column , int line , bool columnMode );
|
||||||
|
/**
|
||||||
|
* Sets the end of the selection to the given @p line and @p column within
|
||||||
|
* the window.
|
||||||
|
*/
|
||||||
|
void setSelectionEnd( int column , int line );
|
||||||
|
/**
|
||||||
|
* Retrieves the start of the selection within the window.
|
||||||
|
*/
|
||||||
|
void getSelectionStart( int& column , int& line );
|
||||||
|
/**
|
||||||
|
* Retrieves the end of the selection within the window.
|
||||||
|
*/
|
||||||
|
void getSelectionEnd( int& column , int& line );
|
||||||
|
/**
|
||||||
|
* Returns true if the character at @p line , @p column is part of the selection.
|
||||||
|
*/
|
||||||
|
bool isSelected( int column , int line );
|
||||||
|
/**
|
||||||
|
* Clears the current selection
|
||||||
|
*/
|
||||||
|
void clearSelection();
|
||||||
|
|
||||||
|
/** Sets the number of lines in the window */
|
||||||
|
void setWindowLines(int lines);
|
||||||
|
/** Returns the number of lines in the window */
|
||||||
|
int windowLines() const;
|
||||||
|
/** Returns the number of columns in the window */
|
||||||
|
int windowColumns() const;
|
||||||
|
|
||||||
|
/** Returns the total number of lines in the screen */
|
||||||
|
int lineCount() const;
|
||||||
|
/** Returns the total number of columns in the screen */
|
||||||
|
int columnCount() const;
|
||||||
|
|
||||||
|
/** Returns the index of the line which is currently at the top of this window */
|
||||||
|
int currentLine() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the cursor
|
||||||
|
* within the window.
|
||||||
|
*/
|
||||||
|
QPoint cursorPosition() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method. Returns true if the window is currently at the bottom
|
||||||
|
* of the screen.
|
||||||
|
*/
|
||||||
|
bool atEndOfOutput() const;
|
||||||
|
|
||||||
|
/** Scrolls the window so that @p line is at the top of the window */
|
||||||
|
void scrollTo( int line );
|
||||||
|
|
||||||
|
/** Describes the units which scrollBy() moves the window by. */
|
||||||
|
enum RelativeScrollMode
|
||||||
|
{
|
||||||
|
/** Scroll the window down by a given number of lines. */
|
||||||
|
ScrollLines,
|
||||||
|
/**
|
||||||
|
* Scroll the window down by a given number of pages, where
|
||||||
|
* one page is windowLines() lines
|
||||||
|
*/
|
||||||
|
ScrollPages
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls the window relative to its current position on the screen.
|
||||||
|
*
|
||||||
|
* @param mode Specifies whether @p amount refers to the number of lines or the number
|
||||||
|
* of pages to scroll.
|
||||||
|
* @param amount The number of lines or pages ( depending on @p mode ) to scroll by. If
|
||||||
|
* this number is positive, the view is scrolled down. If this number is negative, the view
|
||||||
|
* is scrolled up.
|
||||||
|
*/
|
||||||
|
void scrollBy( RelativeScrollMode mode , int amount );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the window should automatically move to the bottom
|
||||||
|
* of the screen when new output is added.
|
||||||
|
*
|
||||||
|
* If this is set to true, the window will be moved to the bottom of the associated screen ( see
|
||||||
|
* screen() ) when the notifyOutputChanged() method is called.
|
||||||
|
*/
|
||||||
|
void setTrackOutput(bool trackOutput);
|
||||||
|
/**
|
||||||
|
* Returns whether the window automatically moves to the bottom of the screen as
|
||||||
|
* new output is added. See setTrackOutput()
|
||||||
|
*/
|
||||||
|
bool trackOutput() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the text which is currently selected.
|
||||||
|
*
|
||||||
|
* @param preserveLineBreaks See Screen::selectedText()
|
||||||
|
*/
|
||||||
|
QString selectedText( bool preserveLineBreaks ) const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/**
|
||||||
|
* Notifies the window that the contents of the associated terminal screen have changed.
|
||||||
|
* This moves the window to the bottom of the screen if trackOutput() is true and causes
|
||||||
|
* the outputChanged() signal to be emitted.
|
||||||
|
*/
|
||||||
|
void notifyOutputChanged();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/**
|
||||||
|
* Emitted when the contents of the associated terminal screen (see screen()) changes.
|
||||||
|
*/
|
||||||
|
void outputChanged();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the screen window is scrolled to a different position.
|
||||||
|
*
|
||||||
|
* @param line The line which is now at the top of the window.
|
||||||
|
*/
|
||||||
|
void scrolled(int line);
|
||||||
|
|
||||||
|
/** Emitted when the selection is changed. */
|
||||||
|
void selectionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int endWindowLine() const;
|
||||||
|
void fillUnusedArea();
|
||||||
|
|
||||||
|
Screen* _screen; // see setScreen() , screen()
|
||||||
|
Character* _windowBuffer;
|
||||||
|
int _windowBufferSize;
|
||||||
|
bool _bufferNeedsUpdate;
|
||||||
|
|
||||||
|
int _windowLines;
|
||||||
|
int _currentLine; // see scrollTo() , currentLine()
|
||||||
|
bool _trackOutput; // see setTrackOutput() , trackOutput()
|
||||||
|
int _scrollCount; // count of lines which the window has been scrolled by since
|
||||||
|
// the last call to resetScrollCount()
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // SCREENWINDOW_H
|
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013 Christian Surlykke
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "SearchBar.h"
|
||||||
|
|
||||||
|
SearchBar::SearchBar(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
widget.setupUi(this);
|
||||||
|
connect(widget.closeButton, SIGNAL(clicked()), this, SLOT(hide()));
|
||||||
|
connect(widget.searchTextEdit, SIGNAL(textChanged(QString)), this, SIGNAL(searchCriteriaChanged()));
|
||||||
|
connect(widget.findPreviousButton, SIGNAL(clicked()), this, SIGNAL(findPrevious()));
|
||||||
|
connect(widget.findNextButton, SIGNAL(clicked()), this, SIGNAL(findNext()));
|
||||||
|
|
||||||
|
connect(this, SIGNAL(searchCriteriaChanged()), this, SLOT(clearBackgroundColor()));
|
||||||
|
|
||||||
|
QMenu *optionsMenu = new QMenu(widget.optionsButton);
|
||||||
|
widget.optionsButton->setMenu(optionsMenu);
|
||||||
|
|
||||||
|
m_matchCaseMenuEntry = optionsMenu->addAction(tr("Match case"));
|
||||||
|
m_matchCaseMenuEntry->setCheckable(true);
|
||||||
|
m_matchCaseMenuEntry->setChecked(true);
|
||||||
|
connect(m_matchCaseMenuEntry, SIGNAL(toggled(bool)), this, SIGNAL(searchCriteriaChanged()));
|
||||||
|
|
||||||
|
|
||||||
|
m_useRegularExpressionMenuEntry = optionsMenu->addAction(tr("Regular expression"));
|
||||||
|
m_useRegularExpressionMenuEntry->setCheckable(true);
|
||||||
|
connect(m_useRegularExpressionMenuEntry, SIGNAL(toggled(bool)), this, SIGNAL(searchCriteriaChanged()));
|
||||||
|
|
||||||
|
m_highlightMatchesMenuEntry = optionsMenu->addAction(tr("Higlight all matches"));
|
||||||
|
m_highlightMatchesMenuEntry->setCheckable(true);
|
||||||
|
m_highlightMatchesMenuEntry->setChecked(true);
|
||||||
|
connect(m_highlightMatchesMenuEntry, SIGNAL(toggled(bool)), this, SIGNAL(highlightMatchesChanged(bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchBar::~SearchBar() {
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SearchBar::searchText()
|
||||||
|
{
|
||||||
|
return widget.searchTextEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SearchBar::useRegularExpression()
|
||||||
|
{
|
||||||
|
return m_useRegularExpressionMenuEntry->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SearchBar::matchCase()
|
||||||
|
{
|
||||||
|
return m_matchCaseMenuEntry->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SearchBar::highlightAllMatches()
|
||||||
|
{
|
||||||
|
return m_highlightMatchesMenuEntry->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchBar::show()
|
||||||
|
{
|
||||||
|
QWidget::show();
|
||||||
|
widget.searchTextEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchBar::noMatchFound()
|
||||||
|
{
|
||||||
|
QPalette palette;
|
||||||
|
palette.setColor(widget.searchTextEdit->backgroundRole(), QColor(255, 128, 128));
|
||||||
|
widget.searchTextEdit->setPalette(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SearchBar::keyReleaseEvent(QKeyEvent* keyEvent)
|
||||||
|
{
|
||||||
|
if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter)
|
||||||
|
{
|
||||||
|
if (keyEvent->modifiers() == Qt::ShiftModifier)
|
||||||
|
{
|
||||||
|
findPrevious();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
findNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyEvent->key() == Qt::Key_Escape)
|
||||||
|
{
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchBar::clearBackgroundColor()
|
||||||
|
{
|
||||||
|
QPalette p;
|
||||||
|
p.setColor(QPalette::Base, Qt::white);
|
||||||
|
widget.searchTextEdit->setPalette(p);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013 Christian Surlykke
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef _SEARCHBAR_H
|
||||||
|
#define _SEARCHBAR_H
|
||||||
|
|
||||||
|
#include <QRegExp>
|
||||||
|
|
||||||
|
#include "ui_SearchBar.h"
|
||||||
|
#include "HistorySearch.h"
|
||||||
|
|
||||||
|
class SearchBar : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SearchBar(QWidget* parent = 0);
|
||||||
|
virtual ~SearchBar();
|
||||||
|
virtual void show();
|
||||||
|
QString searchText();
|
||||||
|
bool useRegularExpression();
|
||||||
|
bool matchCase();
|
||||||
|
bool highlightAllMatches();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void noMatchFound();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void searchCriteriaChanged();
|
||||||
|
void highlightMatchesChanged(bool highlightMatches);
|
||||||
|
void findNext();
|
||||||
|
void findPrevious();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void keyReleaseEvent(QKeyEvent* keyEvent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void clearBackgroundColor();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::SearchBar widget;
|
||||||
|
QAction *m_matchCaseMenuEntry;
|
||||||
|
QAction *m_useRegularExpressionMenuEntry;
|
||||||
|
QAction *m_highlightMatchesMenuEntry;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* _SEARCHBAR_H */
|
@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SearchBar</class>
|
||||||
|
<widget class="QWidget" name="SearchBar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>399</width>
|
||||||
|
<height>40</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>SearchBar</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="closeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>X</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-close">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="findLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Find:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="searchTextEdit"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="findPreviousButton">
|
||||||
|
<property name="text">
|
||||||
|
<string><</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-previous">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="findNextButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>></string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-next">
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="optionsButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff/>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="popupMode">
|
||||||
|
<enum>QToolButton::InstantPopup</enum>
|
||||||
|
</property>
|
||||||
|
<property name="arrowType">
|
||||||
|
<enum>Qt::DownArrow</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,622 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
|
||||||
|
Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SESSION_H
|
||||||
|
#define SESSION_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "History.h"
|
||||||
|
|
||||||
|
class KProcess;
|
||||||
|
|
||||||
|
namespace Konsole {
|
||||||
|
|
||||||
|
class Emulation;
|
||||||
|
class Pty;
|
||||||
|
class TerminalDisplay;
|
||||||
|
//class ZModemDialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a terminal session consisting of a pseudo-teletype and a terminal emulation.
|
||||||
|
* The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole.
|
||||||
|
* The terminal emulation ( Emulation and subclasses ) processes the output stream from the
|
||||||
|
* PTY and produces a character image which is then shown on views connected to the session.
|
||||||
|
*
|
||||||
|
* Each Session can be connected to one or more views by using the addView() method.
|
||||||
|
* The attached views can then display output from the program running in the terminal
|
||||||
|
* or send input to the program in the terminal in the form of keypresses and mouse
|
||||||
|
* activity.
|
||||||
|
*/
|
||||||
|
class Session : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_PROPERTY(QString name READ nameTitle)
|
||||||
|
Q_PROPERTY(int processId READ processId)
|
||||||
|
Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings)
|
||||||
|
Q_PROPERTY(QSize size READ size WRITE setSize)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new session.
|
||||||
|
*
|
||||||
|
* To start the terminal process, call the run() method,
|
||||||
|
* after specifying the program and arguments
|
||||||
|
* using setProgram() and setArguments()
|
||||||
|
*
|
||||||
|
* If no program or arguments are specified explicitly, the Session
|
||||||
|
* falls back to using the program specified in the SHELL environment
|
||||||
|
* variable.
|
||||||
|
*/
|
||||||
|
Session(QObject* parent = 0);
|
||||||
|
virtual ~Session();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the session is currently running. This will be true
|
||||||
|
* after run() has been called successfully.
|
||||||
|
*/
|
||||||
|
bool isRunning() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the profile associated with this session.
|
||||||
|
*
|
||||||
|
* @param profileKey A key which can be used to obtain the current
|
||||||
|
* profile settings from the SessionManager
|
||||||
|
*/
|
||||||
|
void setProfileKey(const QString & profileKey);
|
||||||
|
/**
|
||||||
|
* Returns the profile key associated with this session.
|
||||||
|
* This can be passed to the SessionManager to obtain the current
|
||||||
|
* profile settings.
|
||||||
|
*/
|
||||||
|
QString profileKey() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new view for this session.
|
||||||
|
*
|
||||||
|
* The viewing widget will display the output from the terminal and
|
||||||
|
* input from the viewing widget (key presses, mouse activity etc.)
|
||||||
|
* will be sent to the terminal.
|
||||||
|
*
|
||||||
|
* Views can be removed using removeView(). The session is automatically
|
||||||
|
* closed when the last view is removed.
|
||||||
|
*/
|
||||||
|
void addView(TerminalDisplay * widget);
|
||||||
|
/**
|
||||||
|
* Removes a view from this session. When the last view is removed,
|
||||||
|
* the session will be closed automatically.
|
||||||
|
*
|
||||||
|
* @p widget will no longer display output from or send input
|
||||||
|
* to the terminal
|
||||||
|
*/
|
||||||
|
void removeView(TerminalDisplay * widget);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the views connected to this session
|
||||||
|
*/
|
||||||
|
QList<TerminalDisplay *> views() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the terminal emulation instance being used to encode / decode
|
||||||
|
* characters to / from the process.
|
||||||
|
*/
|
||||||
|
Emulation * emulation() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the environment of this session as a list of strings like
|
||||||
|
* VARIABLE=VALUE
|
||||||
|
*/
|
||||||
|
QStringList environment() const;
|
||||||
|
/**
|
||||||
|
* Sets the environment for this session.
|
||||||
|
* @p environment should be a list of strings like
|
||||||
|
* VARIABLE=VALUE
|
||||||
|
*/
|
||||||
|
void setEnvironment(const QStringList & environment);
|
||||||
|
|
||||||
|
/** Returns the unique ID for this session. */
|
||||||
|
int sessionId() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the session title set by the user (ie. the program running
|
||||||
|
* in the terminal), or an empty string if the user has not set a custom title
|
||||||
|
*/
|
||||||
|
QString userTitle() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the contexts for which separate
|
||||||
|
* tab title formats may be specified.
|
||||||
|
*/
|
||||||
|
enum TabTitleContext {
|
||||||
|
/** Default tab title format */
|
||||||
|
LocalTabTitle,
|
||||||
|
/**
|
||||||
|
* Tab title format used session currently contains
|
||||||
|
* a connection to a remote computer (via SSH)
|
||||||
|
*/
|
||||||
|
RemoteTabTitle
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Sets the format used by this session for tab titles.
|
||||||
|
*
|
||||||
|
* @param context The context whoose format should be set.
|
||||||
|
* @param format The tab title format. This may be a mixture
|
||||||
|
* of plain text and dynamic elements denoted by a '%' character
|
||||||
|
* followed by a letter. (eg. %d for directory). The dynamic
|
||||||
|
* elements available depend on the @p context
|
||||||
|
*/
|
||||||
|
void setTabTitleFormat(TabTitleContext context , const QString & format);
|
||||||
|
/** Returns the format used by this session for tab titles. */
|
||||||
|
QString tabTitleFormat(TabTitleContext context) const;
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the arguments passed to the shell process when run() is called. */
|
||||||
|
QStringList arguments() const;
|
||||||
|
/** Returns the program name of the shell process started when run() is called. */
|
||||||
|
QString program() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the command line arguments which the session's program will be passed when
|
||||||
|
* run() is called.
|
||||||
|
*/
|
||||||
|
void setArguments(const QStringList & arguments);
|
||||||
|
/** Sets the program to be executed when run() is called. */
|
||||||
|
void setProgram(const QString & program);
|
||||||
|
|
||||||
|
/** Returns the session's current working directory. */
|
||||||
|
QString initialWorkingDirectory() {
|
||||||
|
return _initialWorkingDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the initial working directory for the session when it is run
|
||||||
|
* This has no effect once the session has been started.
|
||||||
|
*/
|
||||||
|
void setInitialWorkingDirectory( const QString & dir );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of history store used by this session.
|
||||||
|
* Lines of output produced by the terminal are added
|
||||||
|
* to the history store. The type of history store
|
||||||
|
* used affects the number of lines which can be
|
||||||
|
* remembered before they are lost and the storage
|
||||||
|
* (in memory, on-disk etc.) used.
|
||||||
|
*/
|
||||||
|
void setHistoryType(const HistoryType & type);
|
||||||
|
/**
|
||||||
|
* Returns the type of history store used by this session.
|
||||||
|
*/
|
||||||
|
const HistoryType & historyType() const;
|
||||||
|
/**
|
||||||
|
* Clears the history store used by this session.
|
||||||
|
*/
|
||||||
|
void clearHistory();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables monitoring for activity in the session.
|
||||||
|
* This will cause notifySessionState() to be emitted
|
||||||
|
* with the NOTIFYACTIVITY state flag when output is
|
||||||
|
* received from the terminal.
|
||||||
|
*/
|
||||||
|
void setMonitorActivity(bool);
|
||||||
|
/** Returns true if monitoring for activity is enabled. */
|
||||||
|
bool isMonitorActivity() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables monitoring for silence in the session.
|
||||||
|
* This will cause notifySessionState() to be emitted
|
||||||
|
* with the NOTIFYSILENCE state flag when output is not
|
||||||
|
* received from the terminal for a certain period of
|
||||||
|
* time, specified with setMonitorSilenceSeconds()
|
||||||
|
*/
|
||||||
|
void setMonitorSilence(bool);
|
||||||
|
/**
|
||||||
|
* Returns true if monitoring for inactivity (silence)
|
||||||
|
* in the session is enabled.
|
||||||
|
*/
|
||||||
|
bool isMonitorSilence() const;
|
||||||
|
/** See setMonitorSilence() */
|
||||||
|
void setMonitorSilenceSeconds(int seconds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key bindings used by this session. The bindings
|
||||||
|
* specify how input key sequences are translated into
|
||||||
|
* the character stream which is sent to the terminal.
|
||||||
|
*
|
||||||
|
* @param id The name of the key bindings to use. The
|
||||||
|
* names of available key bindings can be determined using the
|
||||||
|
* KeyboardTranslatorManager class.
|
||||||
|
*/
|
||||||
|
void setKeyBindings(const QString & id);
|
||||||
|
/** Returns the name of the key bindings used by this session. */
|
||||||
|
QString keyBindings() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the available title roles.
|
||||||
|
*/
|
||||||
|
enum TitleRole {
|
||||||
|
/** The name of the session. */
|
||||||
|
NameRole,
|
||||||
|
/** The title of the session which is displayed in tabs etc. */
|
||||||
|
DisplayedTitleRole
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Sets the session's title for the specified @p role to @p title. */
|
||||||
|
void setTitle(TitleRole role , const QString & title);
|
||||||
|
/** Returns the session's title for the specified @p role. */
|
||||||
|
QString title(TitleRole role) const;
|
||||||
|
/** Convenience method used to read the name property. Returns title(Session::NameRole). */
|
||||||
|
QString nameTitle() const {
|
||||||
|
return title(Session::NameRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the name of the icon associated with this session. */
|
||||||
|
void setIconName(const QString & iconName);
|
||||||
|
/** Returns the name of the icon associated with this session. */
|
||||||
|
QString iconName() const;
|
||||||
|
|
||||||
|
/** Sets the text of the icon associated with this session. */
|
||||||
|
void setIconText(const QString & iconText);
|
||||||
|
/** Returns the text of the icon associated with this session. */
|
||||||
|
QString iconText() const;
|
||||||
|
|
||||||
|
/** Specifies whether a utmp entry should be created for the pty used by this session. */
|
||||||
|
void setAddToUtmp(bool);
|
||||||
|
|
||||||
|
/** Sends the specified @p signal to the terminal process. */
|
||||||
|
bool sendSignal(int signal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether to close the session automatically when the terminal
|
||||||
|
* process terminates.
|
||||||
|
*/
|
||||||
|
void setAutoClose(bool b) {
|
||||||
|
_autoClose = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether flow control is enabled for this terminal
|
||||||
|
* session.
|
||||||
|
*/
|
||||||
|
void setFlowControlEnabled(bool enabled);
|
||||||
|
|
||||||
|
/** Returns whether flow control is enabled for this terminal session. */
|
||||||
|
bool flowControlEnabled() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends @p text to the current foreground terminal program.
|
||||||
|
*/
|
||||||
|
void sendText(const QString & text) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the process id of the terminal process.
|
||||||
|
* This is the id used by the system API to refer to the process.
|
||||||
|
*/
|
||||||
|
int processId() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the process id of the terminal's foreground process.
|
||||||
|
* This is initially the same as processId() but can change
|
||||||
|
* as the user starts other programs inside the terminal.
|
||||||
|
*/
|
||||||
|
int foregroundProcessId() const;
|
||||||
|
|
||||||
|
/** Returns the terminal session's window size in lines and columns. */
|
||||||
|
QSize size();
|
||||||
|
/**
|
||||||
|
* Emits a request to resize the session to accommodate
|
||||||
|
* the specified window size.
|
||||||
|
*
|
||||||
|
* @param size The size in lines and columns to request.
|
||||||
|
*/
|
||||||
|
void setSize(const QSize & size);
|
||||||
|
|
||||||
|
/** Sets the text codec used by this session's terminal emulation. */
|
||||||
|
void setCodec(QTextCodec * codec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the session has a dark background or not. The session
|
||||||
|
* uses this information to set the COLORFGBG variable in the process's
|
||||||
|
* environment, which allows the programs running in the terminal to determine
|
||||||
|
* whether the background is light or dark and use appropriate colors by default.
|
||||||
|
*
|
||||||
|
* This has no effect once the session is running.
|
||||||
|
*/
|
||||||
|
void setDarkBackground(bool darkBackground);
|
||||||
|
/**
|
||||||
|
* Returns true if the session has a dark background.
|
||||||
|
* See setDarkBackground()
|
||||||
|
*/
|
||||||
|
bool hasDarkBackground() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to get the shell program to redraw the current display area.
|
||||||
|
* This can be used after clearing the screen, for example, to get the
|
||||||
|
* shell to redraw the prompt line.
|
||||||
|
*/
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
// void startZModem(const QString &rz, const QString &dir, const QStringList &list);
|
||||||
|
// void cancelZModem();
|
||||||
|
// bool isZModemBusy() { return _zmodemBusy; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the terminal session.
|
||||||
|
*
|
||||||
|
* This creates the terminal process and connects the teletype to it.
|
||||||
|
*/
|
||||||
|
void run();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the terminal session. This sends a hangup signal
|
||||||
|
* (SIGHUP) to the terminal process and causes the done(Session*)
|
||||||
|
* signal to be emitted.
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the session title or other customizable aspects of the terminal
|
||||||
|
* emulation display. For a list of what may be changed see the
|
||||||
|
* Emulation::titleChanged() signal.
|
||||||
|
*/
|
||||||
|
void setUserTitle( int, const QString & caption );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/** Emitted when the terminal process starts. */
|
||||||
|
void started();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the terminal process exits.
|
||||||
|
*/
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when output is received from the terminal process.
|
||||||
|
*/
|
||||||
|
void receivedData( const QString & text );
|
||||||
|
|
||||||
|
/** Emitted when the session's title has changed. */
|
||||||
|
void titleChanged();
|
||||||
|
|
||||||
|
/** Emitted when the session's profile has changed. */
|
||||||
|
void profileChanged(const QString & profile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the activity state of this session changes.
|
||||||
|
*
|
||||||
|
* @param state The new state of the session. This may be one
|
||||||
|
* of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY
|
||||||
|
*/
|
||||||
|
void stateChanged(int state);
|
||||||
|
|
||||||
|
/** Emitted when a bell event occurs in the session. */
|
||||||
|
void bellRequest( const QString & message );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the color the text for any tabs associated with
|
||||||
|
* this session should be changed;
|
||||||
|
*
|
||||||
|
* TODO: Document what the parameter does
|
||||||
|
*/
|
||||||
|
void changeTabTextColorRequest(int);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that the background color of views on this session
|
||||||
|
* should be changed.
|
||||||
|
*/
|
||||||
|
void changeBackgroundColorRequest(const QColor &);
|
||||||
|
|
||||||
|
/** TODO: Document me. */
|
||||||
|
void openUrlRequest(const QString & url);
|
||||||
|
|
||||||
|
/** TODO: Document me. */
|
||||||
|
// void zmodemDetected();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the terminal process requests a change
|
||||||
|
* in the size of the terminal window.
|
||||||
|
*
|
||||||
|
* @param size The requested window size in terms of lines and columns.
|
||||||
|
*/
|
||||||
|
void resizeRequest(const QSize & size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when a profile change command is received from the terminal.
|
||||||
|
*
|
||||||
|
* @param text The text of the command. This is a string of the form
|
||||||
|
* "PropertyName=Value;PropertyName=Value ..."
|
||||||
|
*/
|
||||||
|
void profileChangeCommandReceived(const QString & text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the flow control state changes.
|
||||||
|
*
|
||||||
|
* @param enabled True if flow control is enabled or false otherwise.
|
||||||
|
*/
|
||||||
|
void flowControlEnabledChanged(bool enabled);
|
||||||
|
|
||||||
|
void silence();
|
||||||
|
void activity();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void done(int);
|
||||||
|
|
||||||
|
// void fireZModemDetected();
|
||||||
|
|
||||||
|
void onReceiveBlock( const char * buffer, int len );
|
||||||
|
void monitorTimerDone();
|
||||||
|
|
||||||
|
void onViewSizeChange(int height, int width);
|
||||||
|
void onEmulationSizeChange(int lines , int columns);
|
||||||
|
|
||||||
|
void activityStateSet(int);
|
||||||
|
|
||||||
|
//automatically detach views from sessions when view is destroyed
|
||||||
|
void viewDestroyed(QObject * view);
|
||||||
|
|
||||||
|
// void zmodemReadStatus();
|
||||||
|
// void zmodemReadAndSendBlock();
|
||||||
|
// void zmodemRcvBlock(const char *data, int len);
|
||||||
|
// void zmodemFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateTerminalSize();
|
||||||
|
WId windowId() const;
|
||||||
|
|
||||||
|
int _uniqueIdentifier;
|
||||||
|
|
||||||
|
Pty *_shellProcess;
|
||||||
|
Emulation * _emulation;
|
||||||
|
|
||||||
|
QList<TerminalDisplay *> _views;
|
||||||
|
|
||||||
|
bool _monitorActivity;
|
||||||
|
bool _monitorSilence;
|
||||||
|
bool _notifiedActivity;
|
||||||
|
bool _masterMode;
|
||||||
|
bool _autoClose;
|
||||||
|
bool _wantedClose;
|
||||||
|
QTimer * _monitorTimer;
|
||||||
|
|
||||||
|
int _silenceSeconds;
|
||||||
|
|
||||||
|
QString _nameTitle;
|
||||||
|
QString _displayTitle;
|
||||||
|
QString _userTitle;
|
||||||
|
|
||||||
|
QString _localTabTitleFormat;
|
||||||
|
QString _remoteTabTitleFormat;
|
||||||
|
|
||||||
|
QString _iconName;
|
||||||
|
QString _iconText; // as set by: echo -en '\033]1;IconText\007
|
||||||
|
bool _addToUtmp;
|
||||||
|
bool _flowControl;
|
||||||
|
bool _fullScripting;
|
||||||
|
|
||||||
|
QString _program;
|
||||||
|
QStringList _arguments;
|
||||||
|
|
||||||
|
QStringList _environment;
|
||||||
|
int _sessionId;
|
||||||
|
|
||||||
|
QString _initialWorkingDir;
|
||||||
|
|
||||||
|
// ZModem
|
||||||
|
// bool _zmodemBusy;
|
||||||
|
// KProcess* _zmodemProc;
|
||||||
|
// ZModemDialog* _zmodemProgress;
|
||||||
|
|
||||||
|
// Color/Font Changes by ESC Sequences
|
||||||
|
|
||||||
|
QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007
|
||||||
|
|
||||||
|
QString _profileKey;
|
||||||
|
|
||||||
|
bool _hasDarkBackground;
|
||||||
|
|
||||||
|
static int lastSessionId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a group of sessions which is divided into master and slave sessions.
|
||||||
|
* Activity in master sessions can be propagated to all sessions within the group.
|
||||||
|
* The type of activity which is propagated and method of propagation is controlled
|
||||||
|
* by the masterMode() flags.
|
||||||
|
*/
|
||||||
|
class SessionGroup : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructs an empty session group. */
|
||||||
|
SessionGroup();
|
||||||
|
/** Destroys the session group and removes all connections between master and slave sessions. */
|
||||||
|
~SessionGroup();
|
||||||
|
|
||||||
|
/** Adds a session to the group. */
|
||||||
|
void addSession( Session * session );
|
||||||
|
/** Removes a session from the group. */
|
||||||
|
void removeSession( Session * session );
|
||||||
|
|
||||||
|
/** Returns the list of sessions currently in the group. */
|
||||||
|
QList<Session *> sessions() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether a particular session is a master within the group.
|
||||||
|
* Changes or activity in the group's master sessions may be propagated
|
||||||
|
* to all the sessions in the group, depending on the current masterMode()
|
||||||
|
*
|
||||||
|
* @param session The session whoose master status should be changed.
|
||||||
|
* @param master True to make this session a master or false otherwise
|
||||||
|
*/
|
||||||
|
void setMasterStatus( Session * session , bool master );
|
||||||
|
/** Returns the master status of a session. See setMasterStatus() */
|
||||||
|
bool masterStatus( Session * session ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the options for propagating certain activity or
|
||||||
|
* changes in the group's master sessions to all sessions in the group.
|
||||||
|
*/
|
||||||
|
enum MasterMode {
|
||||||
|
/**
|
||||||
|
* Any input key presses in the master sessions are sent to all
|
||||||
|
* sessions in the group.
|
||||||
|
*/
|
||||||
|
CopyInputToAll = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies which activity in the group's master sessions is propagated
|
||||||
|
* to all sessions in the group.
|
||||||
|
*
|
||||||
|
* @param mode A bitwise OR of MasterMode flags.
|
||||||
|
*/
|
||||||
|
void setMasterMode( int mode );
|
||||||
|
/**
|
||||||
|
* Returns a bitwise OR of the active MasterMode flags for this group.
|
||||||
|
* See setMasterMode()
|
||||||
|
*/
|
||||||
|
int masterMode() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void connectPair(Session * master , Session * other);
|
||||||
|
void disconnectPair(Session * master , Session * other);
|
||||||
|
void connectAll(bool connect);
|
||||||
|
QList<Session *> masters() const;
|
||||||
|
|
||||||
|
// maps sessions to their master status
|
||||||
|
QHash<Session *,bool> _sessions;
|
||||||
|
|
||||||
|
int _masterMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "ShellCommand.h"
|
||||||
|
|
||||||
|
//some versions of gcc(4.3) require explicit include
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
|
||||||
|
// expands environment variables in 'text'
|
||||||
|
// function copied from kdelibs/kio/kio/kurlcompletion.cpp
|
||||||
|
static bool expandEnv(QString & text);
|
||||||
|
|
||||||
|
ShellCommand::ShellCommand(const QString & fullCommand)
|
||||||
|
{
|
||||||
|
bool inQuotes = false;
|
||||||
|
|
||||||
|
QString builder;
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < fullCommand.count() ; i++ ) {
|
||||||
|
QChar ch = fullCommand[i];
|
||||||
|
|
||||||
|
const bool isLastChar = ( i == fullCommand.count() - 1 );
|
||||||
|
const bool isQuote = ( ch == '\'' || ch == '\"' );
|
||||||
|
|
||||||
|
if ( !isLastChar && isQuote ) {
|
||||||
|
inQuotes = !inQuotes;
|
||||||
|
} else {
|
||||||
|
if ( (!ch.isSpace() || inQuotes) && !isQuote ) {
|
||||||
|
builder.append(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (ch.isSpace() && !inQuotes) || ( i == fullCommand.count()-1 ) ) {
|
||||||
|
_arguments << builder;
|
||||||
|
builder.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ShellCommand::ShellCommand(const QString & command , const QStringList & arguments)
|
||||||
|
{
|
||||||
|
_arguments = arguments;
|
||||||
|
|
||||||
|
if ( !_arguments.isEmpty() ) {
|
||||||
|
_arguments[0] = command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString ShellCommand::fullCommand() const
|
||||||
|
{
|
||||||
|
return _arguments.join(QChar(' '));
|
||||||
|
}
|
||||||
|
QString ShellCommand::command() const
|
||||||
|
{
|
||||||
|
if ( !_arguments.isEmpty() ) {
|
||||||
|
return _arguments[0];
|
||||||
|
} else {
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QStringList ShellCommand::arguments() const
|
||||||
|
{
|
||||||
|
return _arguments;
|
||||||
|
}
|
||||||
|
bool ShellCommand::isRootCommand() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(0); // not implemented yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ShellCommand::isAvailable() const
|
||||||
|
{
|
||||||
|
Q_ASSERT(0); // not implemented yet
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QStringList ShellCommand::expand(const QStringList & items)
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
|
||||||
|
foreach( QString item , items )
|
||||||
|
result << expand(item);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
QString ShellCommand::expand(const QString & text)
|
||||||
|
{
|
||||||
|
QString result = text;
|
||||||
|
expandEnv(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* expandEnv
|
||||||
|
*
|
||||||
|
* Expand environment variables in text. Escaped '$' characters are ignored.
|
||||||
|
* Return true if any variables were expanded
|
||||||
|
*/
|
||||||
|
static bool expandEnv( QString & text )
|
||||||
|
{
|
||||||
|
// Find all environment variables beginning with '$'
|
||||||
|
//
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
bool expanded = false;
|
||||||
|
|
||||||
|
while ( (pos = text.indexOf(QLatin1Char('$'), pos)) != -1 ) {
|
||||||
|
|
||||||
|
// Skip escaped '$'
|
||||||
|
//
|
||||||
|
if ( pos > 0 && text.at(pos-1) == QLatin1Char('\\') ) {
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
// Variable found => expand
|
||||||
|
//
|
||||||
|
else {
|
||||||
|
// Find the end of the variable = next '/' or ' '
|
||||||
|
//
|
||||||
|
int pos2 = text.indexOf( QLatin1Char(' '), pos+1 );
|
||||||
|
int pos_tmp = text.indexOf( QLatin1Char('/'), pos+1 );
|
||||||
|
|
||||||
|
if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) ) {
|
||||||
|
pos2 = pos_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pos2 == -1 ) {
|
||||||
|
pos2 = text.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace if the variable is terminated by '/' or ' '
|
||||||
|
// and defined
|
||||||
|
//
|
||||||
|
if ( pos2 >= 0 ) {
|
||||||
|
int len = pos2 - pos;
|
||||||
|
QString key = text.mid( pos+1, len-1);
|
||||||
|
QString value =
|
||||||
|
QString::fromLocal8Bit( ::getenv(key.toLocal8Bit()) );
|
||||||
|
|
||||||
|
if ( !value.isEmpty() ) {
|
||||||
|
expanded = true;
|
||||||
|
text.replace( pos, len, value );
|
||||||
|
pos = pos + value.length();
|
||||||
|
} else {
|
||||||
|
pos = pos2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expanded;
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHELLCOMMAND_H
|
||||||
|
#define SHELLCOMMAND_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace Konsole {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to parse and extract information about shell commands.
|
||||||
|
*
|
||||||
|
* ShellCommand can be used to:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Take a command-line (eg "/bin/sh -c /path/to/my/script") and split it
|
||||||
|
* into its component parts (eg. the command "/bin/sh" and the arguments
|
||||||
|
* "-c","/path/to/my/script")
|
||||||
|
* </li>
|
||||||
|
* <li>Take a command and a list of arguments and combine them to
|
||||||
|
* form a complete command line.
|
||||||
|
* </li>
|
||||||
|
* <li>Determine whether the binary specified by a command exists in the
|
||||||
|
* user's PATH.
|
||||||
|
* </li>
|
||||||
|
* <li>Determine whether a command-line specifies the execution of
|
||||||
|
* another command as the root user using su/sudo etc.
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
class ShellCommand {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs a ShellCommand from a command line.
|
||||||
|
*
|
||||||
|
* @param fullCommand The command line to parse.
|
||||||
|
*/
|
||||||
|
ShellCommand(const QString & fullCommand);
|
||||||
|
/**
|
||||||
|
* Constructs a ShellCommand with the specified @p command and @p arguments.
|
||||||
|
*/
|
||||||
|
ShellCommand(const QString & command , const QStringList & arguments);
|
||||||
|
|
||||||
|
/** Returns the command. */
|
||||||
|
QString command() const;
|
||||||
|
/** Returns the arguments. */
|
||||||
|
QStringList arguments() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the full command line.
|
||||||
|
*/
|
||||||
|
QString fullCommand() const;
|
||||||
|
|
||||||
|
/** Returns true if this is a root command. */
|
||||||
|
bool isRootCommand() const;
|
||||||
|
/** Returns true if the program specified by @p command() exists. */
|
||||||
|
bool isAvailable() const;
|
||||||
|
|
||||||
|
/** Expands environment variables in @p text .*/
|
||||||
|
static QString expand(const QString & text);
|
||||||
|
|
||||||
|
/** Expands environment variables in each string in @p list. */
|
||||||
|
static QStringList expand(const QStringList & items);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QStringList _arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SHELLCOMMAND_H
|
||||||
|
|
@ -0,0 +1,251 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
|
||||||
|
Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Own
|
||||||
|
#include "TerminalCharacterDecoder.h"
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
//#include <kdebug.h>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "konsole_wcwidth.h"
|
||||||
|
|
||||||
|
using namespace Konsole;
|
||||||
|
PlainTextDecoder::PlainTextDecoder()
|
||||||
|
: _output(0)
|
||||||
|
, _includeTrailingWhitespace(true)
|
||||||
|
, _recordLinePositions(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void PlainTextDecoder::setTrailingWhitespace(bool enable)
|
||||||
|
{
|
||||||
|
_includeTrailingWhitespace = enable;
|
||||||
|
}
|
||||||
|
bool PlainTextDecoder::trailingWhitespace() const
|
||||||
|
{
|
||||||
|
return _includeTrailingWhitespace;
|
||||||
|
}
|
||||||
|
void PlainTextDecoder::begin(QTextStream* output)
|
||||||
|
{
|
||||||
|
_output = output;
|
||||||
|
if (!_linePositions.isEmpty())
|
||||||
|
_linePositions.clear();
|
||||||
|
}
|
||||||
|
void PlainTextDecoder::end()
|
||||||
|
{
|
||||||
|
_output = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlainTextDecoder::setRecordLinePositions(bool record)
|
||||||
|
{
|
||||||
|
_recordLinePositions = record;
|
||||||
|
}
|
||||||
|
QList<int> PlainTextDecoder::linePositions() const
|
||||||
|
{
|
||||||
|
return _linePositions;
|
||||||
|
}
|
||||||
|
void PlainTextDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_ASSERT( _output );
|
||||||
|
|
||||||
|
if (_recordLinePositions && _output->string())
|
||||||
|
{
|
||||||
|
int pos = _output->string()->count();
|
||||||
|
_linePositions << pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO should we ignore or respect the LINE_WRAPPED line property?
|
||||||
|
|
||||||
|
//note: we build up a QString and send it to the text stream rather writing into the text
|
||||||
|
//stream a character at a time because it is more efficient.
|
||||||
|
//(since QTextStream always deals with QStrings internally anyway)
|
||||||
|
QString plainText;
|
||||||
|
plainText.reserve(count);
|
||||||
|
|
||||||
|
int outputCount = count;
|
||||||
|
|
||||||
|
// if inclusion of trailing whitespace is disabled then find the end of the
|
||||||
|
// line
|
||||||
|
if ( !_includeTrailingWhitespace )
|
||||||
|
{
|
||||||
|
for (int i = count-1 ; i >= 0 ; i--)
|
||||||
|
{
|
||||||
|
if ( characters[i].character != ' ' )
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
outputCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0;i<outputCount;)
|
||||||
|
{
|
||||||
|
plainText.append( QChar(characters[i].character) );
|
||||||
|
i += qMax(1,konsole_wcwidth(characters[i].character));
|
||||||
|
}
|
||||||
|
*_output << plainText;
|
||||||
|
}
|
||||||
|
|
||||||
|
HTMLDecoder::HTMLDecoder() :
|
||||||
|
_output(0)
|
||||||
|
,_colorTable(base_color_table)
|
||||||
|
,_innerSpanOpen(false)
|
||||||
|
,_lastRendition(DEFAULT_RENDITION)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLDecoder::begin(QTextStream* output)
|
||||||
|
{
|
||||||
|
_output = output;
|
||||||
|
|
||||||
|
QString text;
|
||||||
|
|
||||||
|
//open monospace span
|
||||||
|
openSpan(text,"font-family:monospace");
|
||||||
|
|
||||||
|
*output << text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLDecoder::end()
|
||||||
|
{
|
||||||
|
Q_ASSERT( _output );
|
||||||
|
|
||||||
|
QString text;
|
||||||
|
|
||||||
|
closeSpan(text);
|
||||||
|
|
||||||
|
*_output << text;
|
||||||
|
|
||||||
|
_output = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Support for LineProperty (mainly double width , double height)
|
||||||
|
void HTMLDecoder::decodeLine(const Character* const characters, int count, LineProperty /*properties*/
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Q_ASSERT( _output );
|
||||||
|
|
||||||
|
QString text;
|
||||||
|
|
||||||
|
int spaceCount = 0;
|
||||||
|
|
||||||
|
for (int i=0;i<count;i++)
|
||||||
|
{
|
||||||
|
QChar ch(characters[i].character);
|
||||||
|
|
||||||
|
//check if appearance of character is different from previous char
|
||||||
|
if ( characters[i].rendition != _lastRendition ||
|
||||||
|
characters[i].foregroundColor != _lastForeColor ||
|
||||||
|
characters[i].backgroundColor != _lastBackColor )
|
||||||
|
{
|
||||||
|
if ( _innerSpanOpen )
|
||||||
|
closeSpan(text);
|
||||||
|
|
||||||
|
_lastRendition = characters[i].rendition;
|
||||||
|
_lastForeColor = characters[i].foregroundColor;
|
||||||
|
_lastBackColor = characters[i].backgroundColor;
|
||||||
|
|
||||||
|
//build up style string
|
||||||
|
QString style;
|
||||||
|
|
||||||
|
bool useBold;
|
||||||
|
ColorEntry::FontWeight weight = characters[i].fontWeight(_colorTable);
|
||||||
|
if (weight == ColorEntry::UseCurrentFormat)
|
||||||
|
useBold = _lastRendition & RE_BOLD;
|
||||||
|
else
|
||||||
|
useBold = weight == ColorEntry::Bold;
|
||||||
|
|
||||||
|
if (useBold)
|
||||||
|
style.append("font-weight:bold;");
|
||||||
|
|
||||||
|
if ( _lastRendition & RE_UNDERLINE )
|
||||||
|
style.append("font-decoration:underline;");
|
||||||
|
|
||||||
|
//colours - a colour table must have been defined first
|
||||||
|
if ( _colorTable )
|
||||||
|
{
|
||||||
|
style.append( QString("color:%1;").arg(_lastForeColor.color(_colorTable).name() ) );
|
||||||
|
|
||||||
|
if (!characters[i].isTransparent(_colorTable))
|
||||||
|
{
|
||||||
|
style.append( QString("background-color:%1;").arg(_lastBackColor.color(_colorTable).name() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//open the span with the current style
|
||||||
|
openSpan(text,style);
|
||||||
|
_innerSpanOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle whitespace
|
||||||
|
if (ch.isSpace())
|
||||||
|
spaceCount++;
|
||||||
|
else
|
||||||
|
spaceCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
//output current character
|
||||||
|
if (spaceCount < 2)
|
||||||
|
{
|
||||||
|
//escape HTML tag characters and just display others as they are
|
||||||
|
if ( ch == '<' )
|
||||||
|
text.append("<");
|
||||||
|
else if (ch == '>')
|
||||||
|
text.append(">");
|
||||||
|
else
|
||||||
|
text.append(ch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text.append(" "); //HTML truncates multiple spaces, so use a space marker instead
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//close any remaining open inner spans
|
||||||
|
if ( _innerSpanOpen )
|
||||||
|
closeSpan(text);
|
||||||
|
|
||||||
|
//start new line
|
||||||
|
text.append("<br>");
|
||||||
|
|
||||||
|
*_output << text;
|
||||||
|
}
|
||||||
|
void HTMLDecoder::openSpan(QString& text , const QString& style)
|
||||||
|
{
|
||||||
|
text.append( QString("<span style=\"%1\">").arg(style) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLDecoder::closeSpan(QString& text)
|
||||||
|
{
|
||||||
|
text.append("</span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void HTMLDecoder::setColorTable(const ColorEntry* table)
|
||||||
|
{
|
||||||
|
_colorTable = table;
|
||||||
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
|
||||||
|
Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TERMINAL_CHARACTER_DECODER_H
|
||||||
|
#define TERMINAL_CHARACTER_DECODER_H
|
||||||
|
|
||||||
|
#include "Character.h"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
class QTextStream;
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for terminal character decoders
|
||||||
|
*
|
||||||
|
* The decoder converts lines of terminal characters which consist of a unicode character, foreground
|
||||||
|
* and background colours and other appearance-related properties into text strings.
|
||||||
|
*
|
||||||
|
* Derived classes may produce either plain text with no other colour or appearance information, or
|
||||||
|
* they may produce text which incorporates these additional properties.
|
||||||
|
*/
|
||||||
|
class TerminalCharacterDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TerminalCharacterDecoder() {}
|
||||||
|
|
||||||
|
/** Begin decoding characters. The resulting text is appended to @p output. */
|
||||||
|
virtual void begin(QTextStream* output) = 0;
|
||||||
|
/** End decoding. */
|
||||||
|
virtual void end() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a line of terminal characters with associated properties into a text string
|
||||||
|
* and writes the string into an output QTextStream.
|
||||||
|
*
|
||||||
|
* @param characters An array of characters of length @p count.
|
||||||
|
* @param count The number of characters
|
||||||
|
* @param properties Additional properties which affect all characters in the line
|
||||||
|
*/
|
||||||
|
virtual void decodeLine(const Character* const characters,
|
||||||
|
int count,
|
||||||
|
LineProperty properties) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A terminal character decoder which produces plain text, ignoring colours and other appearance-related
|
||||||
|
* properties of the original characters.
|
||||||
|
*/
|
||||||
|
class PlainTextDecoder : public TerminalCharacterDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlainTextDecoder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether trailing whitespace at the end of lines should be included
|
||||||
|
* in the output.
|
||||||
|
* Defaults to true.
|
||||||
|
*/
|
||||||
|
void setTrailingWhitespace(bool enable);
|
||||||
|
/**
|
||||||
|
* Returns whether trailing whitespace at the end of lines is included
|
||||||
|
* in the output.
|
||||||
|
*/
|
||||||
|
bool trailingWhitespace() const;
|
||||||
|
/**
|
||||||
|
* Returns of character positions in the output stream
|
||||||
|
* at which new lines where added. Returns an empty if setTrackLinePositions() is false or if
|
||||||
|
* the output device is not a string.
|
||||||
|
*/
|
||||||
|
QList<int> linePositions() const;
|
||||||
|
/** Enables recording of character positions at which new lines are added. See linePositions() */
|
||||||
|
void setRecordLinePositions(bool record);
|
||||||
|
|
||||||
|
virtual void begin(QTextStream* output);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
virtual void decodeLine(const Character* const characters,
|
||||||
|
int count,
|
||||||
|
LineProperty properties);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTextStream* _output;
|
||||||
|
bool _includeTrailingWhitespace;
|
||||||
|
|
||||||
|
bool _recordLinePositions;
|
||||||
|
QList<int> _linePositions;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A terminal character decoder which produces pretty HTML markup
|
||||||
|
*/
|
||||||
|
class HTMLDecoder : public TerminalCharacterDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs an HTML decoder using a default black-on-white color scheme.
|
||||||
|
*/
|
||||||
|
HTMLDecoder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the colour table which the decoder uses to produce the HTML colour codes in its
|
||||||
|
* output
|
||||||
|
*/
|
||||||
|
void setColorTable( const ColorEntry* table );
|
||||||
|
|
||||||
|
virtual void decodeLine(const Character* const characters,
|
||||||
|
int count,
|
||||||
|
LineProperty properties);
|
||||||
|
|
||||||
|
virtual void begin(QTextStream* output);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void openSpan(QString& text , const QString& style);
|
||||||
|
void closeSpan(QString& text);
|
||||||
|
|
||||||
|
QTextStream* _output;
|
||||||
|
const ColorEntry* _colorTable;
|
||||||
|
bool _innerSpanOpen;
|
||||||
|
quint8 _lastRendition;
|
||||||
|
CharacterColor _lastForeColor;
|
||||||
|
CharacterColor _lastBackColor;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,857 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TERMINALDISPLAY_H
|
||||||
|
#define TERMINALDISPLAY_H
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QColor>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "Filter.h"
|
||||||
|
#include "Character.h"
|
||||||
|
//#include "konsole_export.h"
|
||||||
|
#define KONSOLEPRIVATE_EXPORT
|
||||||
|
|
||||||
|
class QDrag;
|
||||||
|
class QDragEnterEvent;
|
||||||
|
class QDropEvent;
|
||||||
|
class QLabel;
|
||||||
|
class QTimer;
|
||||||
|
class QEvent;
|
||||||
|
class QGridLayout;
|
||||||
|
class QKeyEvent;
|
||||||
|
class QScrollBar;
|
||||||
|
class QShowEvent;
|
||||||
|
class QHideEvent;
|
||||||
|
class QTimerEvent;
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
//class KMenu;
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
enum MotionAfterPasting
|
||||||
|
{
|
||||||
|
// No move screenwindow after pasting
|
||||||
|
NoMoveScreenWindow = 0,
|
||||||
|
// Move start of screenwindow after pasting
|
||||||
|
MoveStartScreenWindow = 1,
|
||||||
|
// Move end of screenwindow after pasting
|
||||||
|
MoveEndScreenWindow = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern unsigned short vt100_graphics[32];
|
||||||
|
|
||||||
|
class ScreenWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
|
||||||
|
* to the terminal.
|
||||||
|
*
|
||||||
|
* When the terminal emulation receives new output from the program running in the terminal,
|
||||||
|
* it will update the display by calling updateImage().
|
||||||
|
*
|
||||||
|
* TODO More documentation
|
||||||
|
*/
|
||||||
|
class KONSOLEPRIVATE_EXPORT TerminalDisplay : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructs a new terminal display widget with the specified parent. */
|
||||||
|
TerminalDisplay(QWidget *parent=0);
|
||||||
|
virtual ~TerminalDisplay();
|
||||||
|
|
||||||
|
/** Returns the terminal color palette used by the display. */
|
||||||
|
const ColorEntry* colorTable() const;
|
||||||
|
/** Sets the terminal color palette used by the display. */
|
||||||
|
void setColorTable(const ColorEntry table[]);
|
||||||
|
/**
|
||||||
|
* Sets the seed used to generate random colors for the display
|
||||||
|
* (in color schemes that support them).
|
||||||
|
*/
|
||||||
|
void setRandomSeed(uint seed);
|
||||||
|
/**
|
||||||
|
* Returns the seed used to generate random colors for the display
|
||||||
|
* (in color schemes that support them).
|
||||||
|
*/
|
||||||
|
uint randomSeed() const;
|
||||||
|
|
||||||
|
/** Sets the opacity of the terminal display. */
|
||||||
|
void setOpacity(qreal opacity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the location where the scroll bar is positioned in the display widget.
|
||||||
|
*/
|
||||||
|
enum ScrollBarPosition
|
||||||
|
{
|
||||||
|
/** Do not show the scroll bar. */
|
||||||
|
NoScrollBar=0,
|
||||||
|
/** Show the scroll bar on the left side of the display. */
|
||||||
|
ScrollBarLeft=1,
|
||||||
|
/** Show the scroll bar on the right side of the display. */
|
||||||
|
ScrollBarRight=2
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Specifies whether the terminal display has a vertical scroll bar, and if so whether it
|
||||||
|
* is shown on the left or right side of the display.
|
||||||
|
*/
|
||||||
|
void setScrollBarPosition(ScrollBarPosition position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current position and range of the display's scroll bar.
|
||||||
|
*
|
||||||
|
* @param cursor The position of the scroll bar's thumb.
|
||||||
|
* @param lines The maximum value of the scroll bar.
|
||||||
|
*/
|
||||||
|
void setScroll(int cursor, int lines);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll to the bottom of the terminal (reset scrolling).
|
||||||
|
*/
|
||||||
|
void scrollToEnd();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the display's filter chain. When the image for the display is updated,
|
||||||
|
* the text is passed through each filter in the chain. Each filter can define
|
||||||
|
* hotspots which correspond to certain strings (such as URLs or particular words).
|
||||||
|
* Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() )
|
||||||
|
* the view will draw visual cues such as underlines on mouse-over for links or translucent
|
||||||
|
* rectangles for markers.
|
||||||
|
*
|
||||||
|
* To add a new filter to the view, call:
|
||||||
|
* viewWidget->filterChain()->addFilter( filterObject );
|
||||||
|
*/
|
||||||
|
FilterChain* filterChain() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the filters in the display's filter chain. This will cause
|
||||||
|
* the hotspots to be updated to match the current image.
|
||||||
|
*
|
||||||
|
* WARNING: This function can be expensive depending on the
|
||||||
|
* image size and number of filters in the filterChain()
|
||||||
|
*
|
||||||
|
* TODO - This API does not really allow efficient usage. Revise it so
|
||||||
|
* that the processing can be done in a better way.
|
||||||
|
*
|
||||||
|
* eg:
|
||||||
|
* - Area of interest may be known ( eg. mouse cursor hovering
|
||||||
|
* over an area )
|
||||||
|
*/
|
||||||
|
void processFilters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of menu actions created by the filters for the content
|
||||||
|
* at the given @p position.
|
||||||
|
*/
|
||||||
|
QList<QAction*> filterActions(const QPoint& position);
|
||||||
|
|
||||||
|
/** Returns true if the cursor is set to blink or false otherwise. */
|
||||||
|
bool blinkingCursor() { return _hasBlinkingCursor; }
|
||||||
|
/** Specifies whether or not the cursor blinks. */
|
||||||
|
void setBlinkingCursor(bool blink);
|
||||||
|
|
||||||
|
/** Specifies whether or not text can blink. */
|
||||||
|
void setBlinkingTextEnabled(bool blink);
|
||||||
|
|
||||||
|
void setCtrlDrag(bool enable) { _ctrlDrag=enable; }
|
||||||
|
bool ctrlDrag() { return _ctrlDrag; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the methods for selecting text when
|
||||||
|
* the user triple-clicks within the display.
|
||||||
|
*/
|
||||||
|
enum TripleClickMode
|
||||||
|
{
|
||||||
|
/** Select the whole line underneath the cursor. */
|
||||||
|
SelectWholeLine,
|
||||||
|
/** Select from the current cursor position to the end of the line. */
|
||||||
|
SelectForwardsFromCursor
|
||||||
|
};
|
||||||
|
/** Sets how the text is selected when the user triple clicks within the display. */
|
||||||
|
void setTripleClickMode(TripleClickMode mode) { _tripleClickMode = mode; }
|
||||||
|
/** See setTripleClickSelectionMode() */
|
||||||
|
TripleClickMode tripleClickMode() { return _tripleClickMode; }
|
||||||
|
|
||||||
|
void setLineSpacing(uint);
|
||||||
|
uint lineSpacing() const;
|
||||||
|
|
||||||
|
void emitSelection(bool useXselection,bool appendReturn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the available shapes for the keyboard cursor.
|
||||||
|
* See setKeyboardCursorShape()
|
||||||
|
*/
|
||||||
|
enum KeyboardCursorShape
|
||||||
|
{
|
||||||
|
/** A rectangular block which covers the entire area of the cursor character. */
|
||||||
|
BlockCursor,
|
||||||
|
/**
|
||||||
|
* A single flat line which occupies the space at the bottom of the cursor
|
||||||
|
* character's area.
|
||||||
|
*/
|
||||||
|
UnderlineCursor,
|
||||||
|
/**
|
||||||
|
* An cursor shaped like the capital letter 'I', similar to the IBeam
|
||||||
|
* cursor used in Qt/KDE text editors.
|
||||||
|
*/
|
||||||
|
IBeamCursor
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Sets the shape of the keyboard cursor. This is the cursor drawn
|
||||||
|
* at the position in the terminal where keyboard input will appear.
|
||||||
|
*
|
||||||
|
* In addition the terminal display widget also has a cursor for
|
||||||
|
* the mouse pointer, which can be set using the QWidget::setCursor()
|
||||||
|
* method.
|
||||||
|
*
|
||||||
|
* Defaults to BlockCursor
|
||||||
|
*/
|
||||||
|
void setKeyboardCursorShape(KeyboardCursorShape shape);
|
||||||
|
/**
|
||||||
|
* Returns the shape of the keyboard cursor. See setKeyboardCursorShape()
|
||||||
|
*/
|
||||||
|
KeyboardCursorShape keyboardCursorShape() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the color used to draw the keyboard cursor.
|
||||||
|
*
|
||||||
|
* The keyboard cursor defaults to using the foreground color of the character
|
||||||
|
* underneath it.
|
||||||
|
*
|
||||||
|
* @param useForegroundColor If true, the cursor color will change to match
|
||||||
|
* the foreground color of the character underneath it as it is moved, in this
|
||||||
|
* case, the @p color parameter is ignored and the color of the character
|
||||||
|
* under the cursor is inverted to ensure that it is still readable.
|
||||||
|
* @param color The color to use to draw the cursor. This is only taken into
|
||||||
|
* account if @p useForegroundColor is false.
|
||||||
|
*/
|
||||||
|
void setKeyboardCursorColor(bool useForegroundColor , const QColor& color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the color of the keyboard cursor, or an invalid color if the keyboard
|
||||||
|
* cursor color is set to change according to the foreground color of the character
|
||||||
|
* underneath it.
|
||||||
|
*/
|
||||||
|
QColor keyboardCursorColor() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of lines of text which can be displayed in the widget.
|
||||||
|
*
|
||||||
|
* This will depend upon the height of the widget and the current font.
|
||||||
|
* See fontHeight()
|
||||||
|
*/
|
||||||
|
int lines() { return _lines; }
|
||||||
|
/**
|
||||||
|
* Returns the number of characters of text which can be displayed on
|
||||||
|
* each line in the widget.
|
||||||
|
*
|
||||||
|
* This will depend upon the width of the widget and the current font.
|
||||||
|
* See fontWidth()
|
||||||
|
*/
|
||||||
|
int columns() { return _columns; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the height of the characters in the font used to draw the text in the display.
|
||||||
|
*/
|
||||||
|
int fontHeight() { return _fontHeight; }
|
||||||
|
/**
|
||||||
|
* Returns the width of the characters in the display.
|
||||||
|
* This assumes the use of a fixed-width font.
|
||||||
|
*/
|
||||||
|
int fontWidth() { return _fontWidth; }
|
||||||
|
|
||||||
|
void setSize(int cols, int lins);
|
||||||
|
void setFixedSize(int cols, int lins);
|
||||||
|
|
||||||
|
// reimplemented
|
||||||
|
QSize sizeHint() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which characters, in addition to letters and numbers,
|
||||||
|
* are regarded as being part of a word for the purposes
|
||||||
|
* of selecting words in the display by double clicking on them.
|
||||||
|
*
|
||||||
|
* The word boundaries occur at the first and last characters which
|
||||||
|
* are either a letter, number, or a character in @p wc
|
||||||
|
*
|
||||||
|
* @param wc An array of characters which are to be considered parts
|
||||||
|
* of a word ( in addition to letters and numbers ).
|
||||||
|
*/
|
||||||
|
void setWordCharacters(const QString& wc);
|
||||||
|
/**
|
||||||
|
* Returns the characters which are considered part of a word for the
|
||||||
|
* purpose of selecting words in the display with the mouse.
|
||||||
|
*
|
||||||
|
* @see setWordCharacters()
|
||||||
|
*/
|
||||||
|
QString wordCharacters() { return _wordCharacters; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of effect used to alert the user when a 'bell' occurs in the
|
||||||
|
* terminal session.
|
||||||
|
*
|
||||||
|
* The terminal session can trigger the bell effect by calling bell() with
|
||||||
|
* the alert message.
|
||||||
|
*/
|
||||||
|
void setBellMode(int mode);
|
||||||
|
/**
|
||||||
|
* Returns the type of effect used to alert the user when a 'bell' occurs in
|
||||||
|
* the terminal session.
|
||||||
|
*
|
||||||
|
* See setBellMode()
|
||||||
|
*/
|
||||||
|
int bellMode() { return _bellMode; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enum describes the different types of sounds and visual effects which
|
||||||
|
* can be used to alert the user when a 'bell' occurs in the terminal
|
||||||
|
* session.
|
||||||
|
*/
|
||||||
|
enum BellMode
|
||||||
|
{
|
||||||
|
/** A system beep. */
|
||||||
|
SystemBeepBell=0,
|
||||||
|
/**
|
||||||
|
* KDE notification. This may play a sound, show a passive popup
|
||||||
|
* or perform some other action depending on the user's settings.
|
||||||
|
*/
|
||||||
|
NotifyBell=1,
|
||||||
|
/** A silent, visual bell (eg. inverting the display's colors briefly) */
|
||||||
|
VisualBell=2,
|
||||||
|
/** No bell effects */
|
||||||
|
NoBell=3
|
||||||
|
};
|
||||||
|
|
||||||
|
void setSelection(const QString &t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reimplemented. Has no effect. Use setVTFont() to change the font
|
||||||
|
* used to draw characters in the display.
|
||||||
|
*/
|
||||||
|
virtual void setFont(const QFont &);
|
||||||
|
|
||||||
|
/** Returns the font used to draw characters in the display */
|
||||||
|
QFont getVTFont() { return font(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font used to draw the display. Has no effect if @p font
|
||||||
|
* is larger than the size of the display itself.
|
||||||
|
*/
|
||||||
|
void setVTFont(const QFont& font);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specified whether anti-aliasing of text in the terminal display
|
||||||
|
* is enabled or not. Defaults to enabled.
|
||||||
|
*/
|
||||||
|
static void setAntialias( bool antialias ) { _antialiasText = antialias; }
|
||||||
|
/**
|
||||||
|
* Returns true if anti-aliasing of text in the terminal is enabled.
|
||||||
|
*/
|
||||||
|
static bool antialias() { return _antialiasText; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether characters with intense colors should be rendered
|
||||||
|
* as bold. Defaults to true.
|
||||||
|
*/
|
||||||
|
void setBoldIntense(bool value) { _boldIntense = value; }
|
||||||
|
/**
|
||||||
|
* Returns true if characters with intense colors are rendered in bold.
|
||||||
|
*/
|
||||||
|
bool getBoldIntense() { return _boldIntense; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether or not the current height and width of the
|
||||||
|
* terminal in lines and columns is displayed whilst the widget
|
||||||
|
* is being resized.
|
||||||
|
*/
|
||||||
|
void setTerminalSizeHint(bool on) { _terminalSizeHint=on; }
|
||||||
|
/**
|
||||||
|
* Returns whether or not the current height and width of
|
||||||
|
* the terminal in lines and columns is displayed whilst the widget
|
||||||
|
* is being resized.
|
||||||
|
*/
|
||||||
|
bool terminalSizeHint() { return _terminalSizeHint; }
|
||||||
|
/**
|
||||||
|
* Sets whether the terminal size display is shown briefly
|
||||||
|
* after the widget is first shown.
|
||||||
|
*
|
||||||
|
* See setTerminalSizeHint() , isTerminalSizeHint()
|
||||||
|
*/
|
||||||
|
void setTerminalSizeStartup(bool on) { _terminalSizeStartup=on; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of the BiDi rendering inside the terminal display.
|
||||||
|
* Defaults to disabled.
|
||||||
|
*/
|
||||||
|
void setBidiEnabled(bool set) { _bidiEnabled=set; }
|
||||||
|
/**
|
||||||
|
* Returns the status of the BiDi rendering in this widget.
|
||||||
|
*/
|
||||||
|
bool isBidiEnabled() { return _bidiEnabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the terminal screen section which is displayed in this widget.
|
||||||
|
* When updateImage() is called, the display fetches the latest character image from the
|
||||||
|
* the associated terminal screen window.
|
||||||
|
*
|
||||||
|
* In terms of the model-view paradigm, the ScreenWindow is the model which is rendered
|
||||||
|
* by the TerminalDisplay.
|
||||||
|
*/
|
||||||
|
void setScreenWindow( ScreenWindow* window );
|
||||||
|
/** Returns the terminal screen section which is displayed in this widget. See setScreenWindow() */
|
||||||
|
ScreenWindow* screenWindow() const;
|
||||||
|
|
||||||
|
static bool HAVE_TRANSPARENCY;
|
||||||
|
|
||||||
|
void setMotionAfterPasting(MotionAfterPasting action);
|
||||||
|
int motionAfterPasting();
|
||||||
|
|
||||||
|
// maps a point on the widget to the position ( ie. line and column )
|
||||||
|
// of the character at that point.
|
||||||
|
void getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Causes the terminal display to fetch the latest character image from the associated
|
||||||
|
* terminal screen ( see setScreenWindow() ) and redraw the display.
|
||||||
|
*/
|
||||||
|
void updateImage();
|
||||||
|
|
||||||
|
/** Essentially calles processFilters().
|
||||||
|
*/
|
||||||
|
void updateFilters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Causes the terminal display to fetch the latest line status flags from the
|
||||||
|
* associated terminal screen ( see setScreenWindow() ).
|
||||||
|
*/
|
||||||
|
void updateLineProperties();
|
||||||
|
|
||||||
|
/** Copies the selected text to the clipboard. */
|
||||||
|
void copyClipboard();
|
||||||
|
/**
|
||||||
|
* Pastes the content of the clipboard into the
|
||||||
|
* display.
|
||||||
|
*/
|
||||||
|
void pasteClipboard();
|
||||||
|
/**
|
||||||
|
* Pastes the content of the selection into the
|
||||||
|
* display.
|
||||||
|
*/
|
||||||
|
void pasteSelection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes whether the flow control warning box should be shown when the flow control
|
||||||
|
* stop key (Ctrl+S) are pressed.
|
||||||
|
*/
|
||||||
|
void setFlowControlWarningEnabled(bool enabled);
|
||||||
|
/**
|
||||||
|
* Returns true if the flow control warning box is enabled.
|
||||||
|
* See outputSuspended() and setFlowControlWarningEnabled()
|
||||||
|
*/
|
||||||
|
bool flowControlWarningEnabled() const
|
||||||
|
{ return _flowControlWarningEnabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Causes the widget to display or hide a message informing the user that terminal
|
||||||
|
* output has been suspended (by using the flow control key combination Ctrl+S)
|
||||||
|
*
|
||||||
|
* @param suspended True if terminal output has been suspended and the warning message should
|
||||||
|
* be shown or false to indicate that terminal output has been resumed and that
|
||||||
|
* the warning message should disappear.
|
||||||
|
*/
|
||||||
|
void outputSuspended(bool suspended);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the program whoose output is being displayed in the view
|
||||||
|
* is interested in mouse events.
|
||||||
|
*
|
||||||
|
* If this is set to true, mouse signals will be emitted by the view when the user clicks, drags
|
||||||
|
* or otherwise moves the mouse inside the view.
|
||||||
|
* The user interaction needed to create selections will also change, and the user will be required
|
||||||
|
* to hold down the shift key to create a selection or perform other mouse activities inside the
|
||||||
|
* view area - since the program running in the terminal is being allowed to handle normal mouse
|
||||||
|
* events itself.
|
||||||
|
*
|
||||||
|
* @param usesMouse Set to true if the program running in the terminal is interested in mouse events
|
||||||
|
* or false otherwise.
|
||||||
|
*/
|
||||||
|
void setUsesMouse(bool usesMouse);
|
||||||
|
|
||||||
|
/** See setUsesMouse() */
|
||||||
|
bool usesMouse() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a notification that a bell event has occurred in the terminal.
|
||||||
|
* TODO: More documentation here
|
||||||
|
*/
|
||||||
|
void bell(const QString& message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background of the display to the specified color.
|
||||||
|
* @see setColorTable(), setForegroundColor()
|
||||||
|
*/
|
||||||
|
void setBackgroundColor(const QColor& color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the text of the display to the specified color.
|
||||||
|
* @see setColorTable(), setBackgroundColor()
|
||||||
|
*/
|
||||||
|
void setForegroundColor(const QColor& color);
|
||||||
|
|
||||||
|
void selectionChanged();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the user presses a key whilst the terminal widget has focus.
|
||||||
|
*/
|
||||||
|
void keyPressedSignal(QKeyEvent *e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mouse event occurred.
|
||||||
|
* @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release)
|
||||||
|
* @param column The character column where the event occurred
|
||||||
|
* @param line The character row where the event occurred
|
||||||
|
* @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion
|
||||||
|
*/
|
||||||
|
void mouseSignal(int button, int column, int line, int eventType);
|
||||||
|
void changedFontMetricSignal(int height, int width);
|
||||||
|
void changedContentSizeSignal(int height, int width);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emitted when the user right clicks on the display, or right-clicks with the Shift
|
||||||
|
* key held down if usesMouse() is true.
|
||||||
|
*
|
||||||
|
* This can be used to display a context menu.
|
||||||
|
*/
|
||||||
|
void configureRequest(const QPoint& position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a shortcut which is also a valid terminal key sequence is pressed while
|
||||||
|
* the terminal widget has focus, this signal is emitted to allow the host to decide
|
||||||
|
* whether the shortcut should be overridden.
|
||||||
|
* When the shortcut is overridden, the key sequence will be sent to the terminal emulation instead
|
||||||
|
* and the action associated with the shortcut will not be triggered.
|
||||||
|
*
|
||||||
|
* @p override is set to false by default and the shortcut will be triggered as normal.
|
||||||
|
*/
|
||||||
|
void overrideShortcutCheck(QKeyEvent* keyEvent,bool& override);
|
||||||
|
|
||||||
|
void isBusySelecting(bool);
|
||||||
|
void sendStringToEmu(const char*);
|
||||||
|
|
||||||
|
// qtermwidget signals
|
||||||
|
void copyAvailable(bool);
|
||||||
|
void termGetFocus();
|
||||||
|
void termLostFocus();
|
||||||
|
|
||||||
|
void notifyBell(const QString&);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool event( QEvent * );
|
||||||
|
|
||||||
|
virtual void paintEvent( QPaintEvent * );
|
||||||
|
|
||||||
|
virtual void showEvent(QShowEvent*);
|
||||||
|
virtual void hideEvent(QHideEvent*);
|
||||||
|
virtual void resizeEvent(QResizeEvent*);
|
||||||
|
|
||||||
|
virtual void fontChange(const QFont &font);
|
||||||
|
virtual void focusInEvent(QFocusEvent* event);
|
||||||
|
virtual void focusOutEvent(QFocusEvent* event);
|
||||||
|
virtual void keyPressEvent(QKeyEvent* event);
|
||||||
|
virtual void mouseDoubleClickEvent(QMouseEvent* ev);
|
||||||
|
virtual void mousePressEvent( QMouseEvent* );
|
||||||
|
virtual void mouseReleaseEvent( QMouseEvent* );
|
||||||
|
virtual void mouseMoveEvent( QMouseEvent* );
|
||||||
|
virtual void extendSelection( const QPoint& pos );
|
||||||
|
virtual void wheelEvent( QWheelEvent* );
|
||||||
|
|
||||||
|
virtual bool focusNextPrevChild( bool next );
|
||||||
|
|
||||||
|
// drag and drop
|
||||||
|
virtual void dragEnterEvent(QDragEnterEvent* event);
|
||||||
|
virtual void dropEvent(QDropEvent* event);
|
||||||
|
void doDrag();
|
||||||
|
enum DragState { diNone, diPending, diDragging };
|
||||||
|
|
||||||
|
struct _dragInfo {
|
||||||
|
DragState state;
|
||||||
|
QPoint start;
|
||||||
|
QDrag *dragObject;
|
||||||
|
} dragInfo;
|
||||||
|
|
||||||
|
// classifies the 'ch' into one of three categories
|
||||||
|
// and returns a character to indicate which category it is in
|
||||||
|
//
|
||||||
|
// - A space (returns ' ')
|
||||||
|
// - Part of a word (returns 'a')
|
||||||
|
// - Other characters (returns the input character)
|
||||||
|
QChar charClass(QChar ch) const;
|
||||||
|
|
||||||
|
void clearImage();
|
||||||
|
|
||||||
|
void mouseTripleClickEvent(QMouseEvent* ev);
|
||||||
|
|
||||||
|
// reimplemented
|
||||||
|
virtual void inputMethodEvent ( QInputMethodEvent* event );
|
||||||
|
virtual QVariant inputMethodQuery( Qt::InputMethodQuery query ) const;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
|
||||||
|
void scrollBarPositionChanged(int value);
|
||||||
|
void blinkEvent();
|
||||||
|
void blinkCursorEvent();
|
||||||
|
|
||||||
|
//Renables bell noises and visuals. Used to disable further bells for a short period of time
|
||||||
|
//after emitting the first in a sequence of bell events.
|
||||||
|
void enableBell();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void swapColorTable();
|
||||||
|
void tripleClickTimeout(); // resets possibleTripleClick
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// -- Drawing helpers --
|
||||||
|
|
||||||
|
// divides the part of the display specified by 'rect' into
|
||||||
|
// fragments according to their colors and styles and calls
|
||||||
|
// drawTextFragment() to draw the fragments
|
||||||
|
void drawContents(QPainter &paint, const QRect &rect);
|
||||||
|
// draws a section of text, all the text in this section
|
||||||
|
// has a common color and style
|
||||||
|
void drawTextFragment(QPainter& painter, const QRect& rect,
|
||||||
|
const QString& text, const Character* style);
|
||||||
|
// draws the background for a text fragment
|
||||||
|
// if useOpacitySetting is true then the color's alpha value will be set to
|
||||||
|
// the display's transparency (set with setOpacity()), otherwise the background
|
||||||
|
// will be drawn fully opaque
|
||||||
|
void drawBackground(QPainter& painter, const QRect& rect, const QColor& color,
|
||||||
|
bool useOpacitySetting);
|
||||||
|
// draws the cursor character
|
||||||
|
void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor,
|
||||||
|
const QColor& backgroundColor , bool& invertColors);
|
||||||
|
// draws the characters or line graphics in a text fragment
|
||||||
|
void drawCharacters(QPainter& painter, const QRect& rect, const QString& text,
|
||||||
|
const Character* style, bool invertCharacterColor);
|
||||||
|
// draws a string of line graphics
|
||||||
|
void drawLineCharString(QPainter& painter, int x, int y,
|
||||||
|
const QString& str, const Character* attributes);
|
||||||
|
|
||||||
|
// draws the preedit string for input methods
|
||||||
|
void drawInputMethodPreeditString(QPainter& painter , const QRect& rect);
|
||||||
|
|
||||||
|
// --
|
||||||
|
|
||||||
|
// maps an area in the character image to an area on the widget
|
||||||
|
QRect imageToWidget(const QRect& imageArea) const;
|
||||||
|
|
||||||
|
// the area where the preedit string for input methods will be draw
|
||||||
|
QRect preeditRect() const;
|
||||||
|
|
||||||
|
// shows a notification window in the middle of the widget indicating the terminal's
|
||||||
|
// current size in columns and lines
|
||||||
|
void showResizeNotification();
|
||||||
|
|
||||||
|
// scrolls the image by a number of lines.
|
||||||
|
// 'lines' may be positive ( to scroll the image down )
|
||||||
|
// or negative ( to scroll the image up )
|
||||||
|
// 'region' is the part of the image to scroll - currently only
|
||||||
|
// the top, bottom and height of 'region' are taken into account,
|
||||||
|
// the left and right are ignored.
|
||||||
|
void scrollImage(int lines , const QRect& region);
|
||||||
|
|
||||||
|
void calcGeometry();
|
||||||
|
void propagateSize();
|
||||||
|
void updateImageSize();
|
||||||
|
void makeImage();
|
||||||
|
|
||||||
|
void paintFilters(QPainter& painter);
|
||||||
|
|
||||||
|
// returns a region covering all of the areas of the widget which contain
|
||||||
|
// a hotspot
|
||||||
|
QRegion hotSpotRegion() const;
|
||||||
|
|
||||||
|
// returns the position of the cursor in columns and lines
|
||||||
|
QPoint cursorPosition() const;
|
||||||
|
|
||||||
|
// redraws the cursor
|
||||||
|
void updateCursor();
|
||||||
|
|
||||||
|
bool handleShortcutOverrideEvent(QKeyEvent* event);
|
||||||
|
|
||||||
|
// the window onto the terminal screen which this display
|
||||||
|
// is currently showing.
|
||||||
|
QPointer<ScreenWindow> _screenWindow;
|
||||||
|
|
||||||
|
bool _allowBell;
|
||||||
|
|
||||||
|
QGridLayout* _gridLayout;
|
||||||
|
|
||||||
|
bool _fixedFont; // has fixed pitch
|
||||||
|
int _fontHeight; // height
|
||||||
|
int _fontWidth; // width
|
||||||
|
int _fontAscent; // ascend
|
||||||
|
bool _boldIntense; // Whether intense colors should be rendered with bold font
|
||||||
|
|
||||||
|
int _leftMargin; // offset
|
||||||
|
int _topMargin; // offset
|
||||||
|
|
||||||
|
int _lines; // the number of lines that can be displayed in the widget
|
||||||
|
int _columns; // the number of columns that can be displayed in the widget
|
||||||
|
|
||||||
|
int _usedLines; // the number of lines that are actually being used, this will be less
|
||||||
|
// than 'lines' if the character image provided with setImage() is smaller
|
||||||
|
// than the maximum image size which can be displayed
|
||||||
|
|
||||||
|
int _usedColumns; // the number of columns that are actually being used, this will be less
|
||||||
|
// than 'columns' if the character image provided with setImage() is smaller
|
||||||
|
// than the maximum image size which can be displayed
|
||||||
|
|
||||||
|
int _contentHeight;
|
||||||
|
int _contentWidth;
|
||||||
|
Character* _image; // [lines][columns]
|
||||||
|
// only the area [usedLines][usedColumns] in the image contains valid data
|
||||||
|
|
||||||
|
int _imageSize;
|
||||||
|
QVector<LineProperty> _lineProperties;
|
||||||
|
|
||||||
|
ColorEntry _colorTable[TABLE_COLORS];
|
||||||
|
uint _randomSeed;
|
||||||
|
|
||||||
|
bool _resizing;
|
||||||
|
bool _terminalSizeHint;
|
||||||
|
bool _terminalSizeStartup;
|
||||||
|
bool _bidiEnabled;
|
||||||
|
bool _mouseMarks;
|
||||||
|
|
||||||
|
QPoint _iPntSel; // initial selection point
|
||||||
|
QPoint _pntSel; // current selection point
|
||||||
|
QPoint _tripleSelBegin; // help avoid flicker
|
||||||
|
int _actSel; // selection state
|
||||||
|
bool _wordSelectionMode;
|
||||||
|
bool _lineSelectionMode;
|
||||||
|
bool _preserveLineBreaks;
|
||||||
|
bool _columnSelectionMode;
|
||||||
|
|
||||||
|
QClipboard* _clipboard;
|
||||||
|
QScrollBar* _scrollBar;
|
||||||
|
ScrollBarPosition _scrollbarLocation;
|
||||||
|
QString _wordCharacters;
|
||||||
|
int _bellMode;
|
||||||
|
|
||||||
|
bool _blinking; // hide text in paintEvent
|
||||||
|
bool _hasBlinker; // has characters to blink
|
||||||
|
bool _cursorBlinking; // hide cursor in paintEvent
|
||||||
|
bool _hasBlinkingCursor; // has blinking cursor enabled
|
||||||
|
bool _allowBlinkingText; // allow text to blink
|
||||||
|
bool _ctrlDrag; // require Ctrl key for drag
|
||||||
|
TripleClickMode _tripleClickMode;
|
||||||
|
bool _isFixedSize; //Columns / lines are locked.
|
||||||
|
QTimer* _blinkTimer; // active when hasBlinker
|
||||||
|
QTimer* _blinkCursorTimer; // active when hasBlinkingCursor
|
||||||
|
|
||||||
|
//QMenu* _drop;
|
||||||
|
QString _dropText;
|
||||||
|
int _dndFileCount;
|
||||||
|
|
||||||
|
bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted
|
||||||
|
// after QApplication::doubleClickInterval() delay
|
||||||
|
|
||||||
|
|
||||||
|
QLabel* _resizeWidget;
|
||||||
|
QTimer* _resizeTimer;
|
||||||
|
|
||||||
|
bool _flowControlWarningEnabled;
|
||||||
|
|
||||||
|
//widgets related to the warning message that appears when the user presses Ctrl+S to suspend
|
||||||
|
//terminal output - informing them what has happened and how to resume output
|
||||||
|
QLabel* _outputSuspendedLabel;
|
||||||
|
|
||||||
|
uint _lineSpacing;
|
||||||
|
|
||||||
|
bool _colorsInverted; // true during visual bell
|
||||||
|
|
||||||
|
QSize _size;
|
||||||
|
|
||||||
|
QRgb _blendColor;
|
||||||
|
|
||||||
|
// list of filters currently applied to the display. used for links and
|
||||||
|
// search highlight
|
||||||
|
TerminalImageFilterChain* _filterChain;
|
||||||
|
QRegion _mouseOverHotspotArea;
|
||||||
|
|
||||||
|
KeyboardCursorShape _cursorShape;
|
||||||
|
|
||||||
|
// custom cursor color. if this is invalid then the foreground
|
||||||
|
// color of the character under the cursor is used
|
||||||
|
QColor _cursorColor;
|
||||||
|
|
||||||
|
|
||||||
|
MotionAfterPasting mMotionAfterPasting;
|
||||||
|
|
||||||
|
struct InputMethodData
|
||||||
|
{
|
||||||
|
QString preeditString;
|
||||||
|
QRect previousPreeditRect;
|
||||||
|
};
|
||||||
|
InputMethodData _inputMethodData;
|
||||||
|
|
||||||
|
static bool _antialiasText; // do we antialias or not
|
||||||
|
|
||||||
|
//the delay in milliseconds between redrawing blinking text
|
||||||
|
static const int TEXT_BLINK_DELAY = 500;
|
||||||
|
static const int DEFAULT_LEFT_MARGIN = 1;
|
||||||
|
static const int DEFAULT_TOP_MARGIN = 1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void setTransparencyEnabled(bool enable)
|
||||||
|
{
|
||||||
|
HAVE_TRANSPARENCY = enable;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoScrollHandler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoScrollHandler(QWidget* parent);
|
||||||
|
protected:
|
||||||
|
virtual void timerEvent(QTimerEvent* event);
|
||||||
|
virtual bool eventFilter(QObject* watched,QEvent* event);
|
||||||
|
private:
|
||||||
|
QWidget* widget() const { return static_cast<QWidget*>(parent()); }
|
||||||
|
int _timerId;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TERMINALDISPLAY_H
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Konsole, an X terminal.
|
||||||
|
|
||||||
|
Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
|
||||||
|
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VT102EMULATION_H
|
||||||
|
#define VT102EMULATION_H
|
||||||
|
|
||||||
|
// Standard Library
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
// Konsole
|
||||||
|
#include "Emulation.h"
|
||||||
|
#include "Screen.h"
|
||||||
|
|
||||||
|
#define MODE_AppScreen (MODES_SCREEN+0) // Mode #1
|
||||||
|
#define MODE_AppCuKeys (MODES_SCREEN+1) // Application cursor keys (DECCKM)
|
||||||
|
#define MODE_AppKeyPad (MODES_SCREEN+2) //
|
||||||
|
#define MODE_Mouse1000 (MODES_SCREEN+3) // Send mouse X,Y position on press and release
|
||||||
|
#define MODE_Mouse1001 (MODES_SCREEN+4) // Use Hilight mouse tracking
|
||||||
|
#define MODE_Mouse1002 (MODES_SCREEN+5) // Use cell motion mouse tracking
|
||||||
|
#define MODE_Mouse1003 (MODES_SCREEN+6) // Use all motion mouse tracking
|
||||||
|
#define MODE_Ansi (MODES_SCREEN+7) // Use US Ascii for character sets G0-G3 (DECANM)
|
||||||
|
#define MODE_132Columns (MODES_SCREEN+8) // 80 <-> 132 column mode switch (DECCOLM)
|
||||||
|
#define MODE_Allow132Columns (MODES_SCREEN+9) // Allow DECCOLM mode
|
||||||
|
#define MODE_total (MODES_SCREEN+10)
|
||||||
|
|
||||||
|
namespace Konsole
|
||||||
|
{
|
||||||
|
|
||||||
|
struct CharCodes
|
||||||
|
{
|
||||||
|
// coding info
|
||||||
|
char charset[4]; //
|
||||||
|
int cu_cs; // actual charset.
|
||||||
|
bool graphic; // Some VT100 tricks
|
||||||
|
bool pound ; // Some VT100 tricks
|
||||||
|
bool sa_graphic; // saved graphic
|
||||||
|
bool sa_pound; // saved pound
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an xterm compatible terminal emulation based on the DEC VT102 terminal.
|
||||||
|
* A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/
|
||||||
|
*
|
||||||
|
* In addition, various additional xterm escape sequences are supported to provide
|
||||||
|
* features such as mouse input handling.
|
||||||
|
* See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape
|
||||||
|
* sequences.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Vt102Emulation : public Emulation
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructs a new emulation */
|
||||||
|
Vt102Emulation();
|
||||||
|
~Vt102Emulation();
|
||||||
|
|
||||||
|
// reimplemented from Emulation
|
||||||
|
virtual void clearEntireScreen();
|
||||||
|
virtual void reset();
|
||||||
|
virtual char eraseChar() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
// reimplemented from Emulation
|
||||||
|
virtual void sendString(const char*,int length = -1);
|
||||||
|
virtual void sendText(const QString& text);
|
||||||
|
virtual void sendKeyEvent(QKeyEvent*);
|
||||||
|
virtual void sendMouseEvent(int buttons, int column, int line, int eventType);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// reimplemented from Emulation
|
||||||
|
virtual void setMode(int mode);
|
||||||
|
virtual void resetMode(int mode);
|
||||||
|
virtual void receiveChar(int cc);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
//causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates
|
||||||
|
//used to buffer multiple title updates
|
||||||
|
void updateTitle();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned short applyCharset(unsigned short c);
|
||||||
|
void setCharset(int n, int cs);
|
||||||
|
void useCharset(int n);
|
||||||
|
void setAndUseCharset(int n, int cs);
|
||||||
|
void saveCursor();
|
||||||
|
void restoreCursor();
|
||||||
|
void resetCharset(int scrno);
|
||||||
|
|
||||||
|
void setMargins(int top, int bottom);
|
||||||
|
//set margins for all screens back to their defaults
|
||||||
|
void setDefaultMargins();
|
||||||
|
|
||||||
|
// returns true if 'mode' is set or false otherwise
|
||||||
|
bool getMode (int mode);
|
||||||
|
// saves the current boolean value of 'mode'
|
||||||
|
void saveMode (int mode);
|
||||||
|
// restores the boolean value of 'mode'
|
||||||
|
void restoreMode(int mode);
|
||||||
|
// resets all modes
|
||||||
|
// (except MODE_Allow132Columns)
|
||||||
|
void resetModes();
|
||||||
|
|
||||||
|
void resetTokenizer();
|
||||||
|
#define MAX_TOKEN_LENGTH 80
|
||||||
|
void addToCurrentToken(int cc);
|
||||||
|
int tokenBuffer[MAX_TOKEN_LENGTH]; //FIXME: overflow?
|
||||||
|
int tokenBufferPos;
|
||||||
|
#define MAXARGS 15
|
||||||
|
void addDigit(int dig);
|
||||||
|
void addArgument();
|
||||||
|
int argv[MAXARGS];
|
||||||
|
int argc;
|
||||||
|
void initTokenizer();
|
||||||
|
|
||||||
|
// Set of flags for each of the ASCII characters which indicates
|
||||||
|
// what category they fall into (printable character, control, digit etc.)
|
||||||
|
// for the purposes of decoding terminal output
|
||||||
|
int charClass[256];
|
||||||
|
|
||||||
|
void reportDecodingError();
|
||||||
|
|
||||||
|
void processToken(int code, int p, int q);
|
||||||
|
void processWindowAttributeChange();
|
||||||
|
|
||||||
|
void reportTerminalType();
|
||||||
|
void reportSecondaryAttributes();
|
||||||
|
void reportStatus();
|
||||||
|
void reportAnswerBack();
|
||||||
|
void reportCursorPosition();
|
||||||
|
void reportTerminalParms(int p);
|
||||||
|
|
||||||
|
void onScrollLock();
|
||||||
|
void scrollLock(const bool lock);
|
||||||
|
|
||||||
|
// clears the screen and resizes it to the specified
|
||||||
|
// number of columns
|
||||||
|
void clearScreenAndSetColumns(int columnCount);
|
||||||
|
|
||||||
|
CharCodes _charset[2];
|
||||||
|
|
||||||
|
class TerminalState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Initializes all modes to false
|
||||||
|
TerminalState()
|
||||||
|
{ memset(&mode,false,MODE_total * sizeof(bool)); }
|
||||||
|
|
||||||
|
bool mode[MODE_total];
|
||||||
|
};
|
||||||
|
|
||||||
|
TerminalState _currentModes;
|
||||||
|
TerminalState _savedModes;
|
||||||
|
|
||||||
|
//hash table and timer for buffering calls to the session instance
|
||||||
|
//to update the name of the session
|
||||||
|
//or window title.
|
||||||
|
//these calls occur when certain escape sequences are seen in the
|
||||||
|
//output from the terminal
|
||||||
|
QHash<int,QString> _pendingTitleUpdates;
|
||||||
|
QTimer* _titleUpdateTimer;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VT102EMULATION_H
|
@ -0,0 +1,42 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Black on Light Yellow
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 221 1 0 # regular background color (Light Yellow)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 221 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,104 @@
|
|||||||
|
[Background]
|
||||||
|
Bold=false
|
||||||
|
Color=247,247,214
|
||||||
|
Transparency=true
|
||||||
|
MaxRandomHue=340
|
||||||
|
|
||||||
|
[BackgroundIntense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,221
|
||||||
|
Transparency=true
|
||||||
|
|
||||||
|
[Color0]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color0Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=104,104,104
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color1]
|
||||||
|
Bold=false
|
||||||
|
Color=178,24,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color1Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,84,84
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color2]
|
||||||
|
Bold=false
|
||||||
|
Color=24,178,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color2Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,255,84
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color3]
|
||||||
|
Bold=false
|
||||||
|
Color=178,104,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color3Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,84
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color4]
|
||||||
|
Bold=false
|
||||||
|
Color=24,24,178
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color4Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,84,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color5]
|
||||||
|
Bold=false
|
||||||
|
Color=178,24,178
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color5Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,84,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color6]
|
||||||
|
Bold=false
|
||||||
|
Color=24,178,178
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color6Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,255,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color7]
|
||||||
|
Bold=false
|
||||||
|
Color=178,178,178
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color7Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Foreground]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[ForegroundIntense]
|
||||||
|
Bold=true
|
||||||
|
Color=0,0,0
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[General]
|
||||||
|
Description=Black on Random Light
|
||||||
|
Opacity=1
|
@ -0,0 +1,42 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Black on White
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 255 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,103 @@
|
|||||||
|
[Background]
|
||||||
|
Bold=false
|
||||||
|
Color=44,44,44
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[BackgroundIntense]
|
||||||
|
Bold=true
|
||||||
|
Color=44,44,44
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color0]
|
||||||
|
Bold=false
|
||||||
|
Color=63,63,63
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color0Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=112,144,128
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color1]
|
||||||
|
Bold=false
|
||||||
|
Color=112,80,80
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color1Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=220,163,163
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color2]
|
||||||
|
Bold=false
|
||||||
|
Color=96,180,138
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color2Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=114,213,163
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color3]
|
||||||
|
Bold=false
|
||||||
|
Color=223,175,143
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color3Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=240,223,175
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color4]
|
||||||
|
Bold=false
|
||||||
|
Color=154,184,215
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color4Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=148,191,243
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color5]
|
||||||
|
Bold=false
|
||||||
|
Color=220,140,195
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color5Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=236,147,211
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color6]
|
||||||
|
Bold=false
|
||||||
|
Color=140,208,211
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color6Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=147,224,227
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color7]
|
||||||
|
Bold=false
|
||||||
|
Color=220,220,204
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color7Intense]
|
||||||
|
Bold=true
|
||||||
|
Color=255,255,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Foreground]
|
||||||
|
Bold=false
|
||||||
|
Color=220,220,204
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[ForegroundIntense]
|
||||||
|
Bold=true
|
||||||
|
Color=220,220,204
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[General]
|
||||||
|
Description=Dark Pastels
|
||||||
|
Opacity=1
|
@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
[Background]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[BackgroundIntense]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color0]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color0Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=104,104,104
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color1]
|
||||||
|
Bold=false
|
||||||
|
Color=250,75,75
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color1Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,84,84
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color2]
|
||||||
|
Bold=false
|
||||||
|
Color=24,178,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color2Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,255,84
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color3]
|
||||||
|
Bold=false
|
||||||
|
Color=178,104,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color3Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,84
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color4]
|
||||||
|
Bold=false
|
||||||
|
Color=92,167,251
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color4Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,84,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color5]
|
||||||
|
Bold=false
|
||||||
|
Color=225,30,225
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color5Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,84,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color6]
|
||||||
|
Bold=false
|
||||||
|
Color=24,178,178
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color6Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,255,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color7]
|
||||||
|
Bold=false
|
||||||
|
Color=178,178,178
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Color7Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,255
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[Foreground]
|
||||||
|
Bold=false
|
||||||
|
Color=24,240,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[ForegroundIntense]
|
||||||
|
Bold=true
|
||||||
|
Color=24,240,24
|
||||||
|
Transparency=false
|
||||||
|
|
||||||
|
[General]
|
||||||
|
Description=Green on Black
|
||||||
|
Opacity=1
|
@ -0,0 +1,100 @@
|
|||||||
|
[Background]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
|
||||||
|
[BackgroundIntense]
|
||||||
|
Bold=false
|
||||||
|
Color=104,104,104
|
||||||
|
|
||||||
|
[Color0]
|
||||||
|
Bold=false
|
||||||
|
Color=0,0,0
|
||||||
|
|
||||||
|
|
||||||
|
[Color0Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=104,104,104
|
||||||
|
|
||||||
|
|
||||||
|
[Color1]
|
||||||
|
Bold=false
|
||||||
|
Color=178,24,24
|
||||||
|
|
||||||
|
|
||||||
|
[Color1Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,84,84
|
||||||
|
|
||||||
|
|
||||||
|
[Color2]
|
||||||
|
Bold=false
|
||||||
|
Color=24,178,24
|
||||||
|
|
||||||
|
|
||||||
|
[Color2Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,255,84
|
||||||
|
|
||||||
|
|
||||||
|
[Color3]
|
||||||
|
Bold=false
|
||||||
|
Color=178,104,24
|
||||||
|
|
||||||
|
|
||||||
|
[Color3Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,84
|
||||||
|
|
||||||
|
|
||||||
|
[Color4]
|
||||||
|
Bold=false
|
||||||
|
Color=24,24,178
|
||||||
|
|
||||||
|
|
||||||
|
[Color4Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,84,255
|
||||||
|
|
||||||
|
|
||||||
|
[Color5]
|
||||||
|
Bold=false
|
||||||
|
Color=178,24,178
|
||||||
|
|
||||||
|
|
||||||
|
[Color5Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,84,255
|
||||||
|
|
||||||
|
|
||||||
|
[Color6]
|
||||||
|
Bold=false
|
||||||
|
Color=24,178,178
|
||||||
|
|
||||||
|
|
||||||
|
[Color6Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=84,255,255
|
||||||
|
|
||||||
|
|
||||||
|
[Color7]
|
||||||
|
Bold=false
|
||||||
|
Color=178,178,178
|
||||||
|
|
||||||
|
|
||||||
|
[Color7Intense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,255
|
||||||
|
|
||||||
|
|
||||||
|
[Foreground]
|
||||||
|
Bold=false
|
||||||
|
Color=178,178,178
|
||||||
|
|
||||||
|
|
||||||
|
[ForegroundIntense]
|
||||||
|
Bold=false
|
||||||
|
Color=255,255,255
|
||||||
|
|
||||||
|
|
||||||
|
[General]
|
||||||
|
Description=Linux Colors
|
@ -0,0 +1,42 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title White on Black
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 255 255 255 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 1 # intensive foreground color
|
||||||
|
color 11 0 0 0 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE RCC>
|
||||||
|
<RCC version="1.0">
|
||||||
|
<qresource><file>BlackOnLightYellow.schema</file></qresource>
|
||||||
|
<qresource><file>BlackOnRandomLight.colorscheme</file></qresource>
|
||||||
|
<qresource><file>Linux.colorscheme</file></qresource>
|
||||||
|
<qresource><file>BlackOnWhite.schema</file></qresource>
|
||||||
|
<qresource><file>DarkPastels.colorscheme</file></qresource>
|
||||||
|
<qresource><file>GreenOnBlack.colorscheme</file></qresource>
|
||||||
|
<qresource><file>WhiteOnBlack.schema</file></qresource>
|
||||||
|
<qresource><file>historic/vim.schema</file></qresource>
|
||||||
|
<qresource><file>historic/Transparent.schema</file></qresource>
|
||||||
|
<qresource><file>historic/Transparent_MC.schema</file></qresource>
|
||||||
|
<qresource><file>historic/Linux.schema</file></qresource>
|
||||||
|
<qresource><file>historic/Transparent_darkbg.schema</file></qresource>
|
||||||
|
<qresource><file>historic/GreenTint.schema</file></qresource>
|
||||||
|
<qresource><file>historic/Transparent_lightbg.schema</file></qresource>
|
||||||
|
<qresource><file>historic/LightPicture.schema</file></qresource>
|
||||||
|
<qresource><file>historic/DarkPicture.schema</file></qresource>
|
||||||
|
<qresource><file>historic/syscolor.schema</file></qresource>
|
||||||
|
<qresource><file>historic/XTerm.schema</file></qresource>
|
||||||
|
<qresource><file>historic/BlackOnLightColor.schema</file></qresource>
|
||||||
|
<qresource><file>historic/GreenTint_MC.schema</file></qresource>
|
||||||
|
<qresource><file>historic/GreenOnBlack.schema</file></qresource>
|
||||||
|
</RCC>
|
@ -0,0 +1,42 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Black on Light Color
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
rcolor 1 30 255 1 0 # regular background color (Light Color)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 221 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,44 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Marble
|
||||||
|
|
||||||
|
image tile Blkmarble.jpg
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 255 255 255 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 1 # intensive foreground color
|
||||||
|
color 11 0 0 0 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,47 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Ugly 1
|
||||||
|
|
||||||
|
# add a wallpaper, if you like. Second word one of { tile,center,full }
|
||||||
|
|
||||||
|
image tile /opt/kde/share/wallpapers/dancy_pants.jpg
|
||||||
|
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 255 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 255 0 0 0 0 # regular color 1 Red
|
||||||
|
color 4 0 255 0 0 0 # regular color 2 Green
|
||||||
|
color 5 255 255 0 0 0 # regular color 3 Yellow
|
||||||
|
color 6 0 0 255 0 0 # regular color 4 Blue
|
||||||
|
color 7 255 0 255 0 0 # regular color 5 Magenta
|
||||||
|
color 8 0 255 255 0 0 # regular color 6 Cyan
|
||||||
|
color 9 255 255 255 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 1 # intensive background color
|
||||||
|
|
||||||
|
color 12 0 0 0 0 1 # intensive color 0
|
||||||
|
color 13 255 0 0 0 1 # intensive color 1
|
||||||
|
color 14 0 255 0 0 1 # intensive color 2
|
||||||
|
color 15 255 255 0 0 1 # intensive color 3
|
||||||
|
color 16 0 0 255 0 1 # intensive color 4
|
||||||
|
color 17 255 0 255 0 1 # intensive color 5
|
||||||
|
color 18 0 255 255 0 1 # intensive color 6
|
||||||
|
color 19 255 255 255 0 1 # intensive color 7
|
@ -0,0 +1,42 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Green on Black
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 24 240 24 0 0 # regular foreground color (Green)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 24 240 24 0 1 # intensive foreground color
|
||||||
|
color 11 0 0 0 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,49 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Green Tint
|
||||||
|
|
||||||
|
transparency 0.3 0 150 0
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
#
|
||||||
|
# The flaw in this schema is that "blick" comes out on the
|
||||||
|
# Linux console as intensive background, really.
|
||||||
|
# Since this is not used in clients you'll hardly notice
|
||||||
|
# it in practice.
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 178 178 178 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 0 # intensive foreground color
|
||||||
|
color 11 104 104 104 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,49 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Green Tint with Transparent MC
|
||||||
|
|
||||||
|
transparency 0.3 0 150 0
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
#
|
||||||
|
# The flaw in this schema is that "blick" comes out on the
|
||||||
|
# Linux console as intensive background, really.
|
||||||
|
# Since this is not used in clients you'll hardly notice
|
||||||
|
# it in practice.
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 178 178 178 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 0 0 0 1 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 0 # intensive foreground color
|
||||||
|
color 11 104 104 104 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,44 @@
|
|||||||
|
# example scheme for konsole
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Paper
|
||||||
|
|
||||||
|
image tile Paper01.jpg
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 255 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,47 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Linux Colors
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
#
|
||||||
|
# The flaw in this schema is that "blick" comes out on the
|
||||||
|
# Linux console as intensive background, really.
|
||||||
|
# Since this is not used in clients you'll hardly notice
|
||||||
|
# it in practice.
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 178 178 178 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 0 # intensive foreground color
|
||||||
|
color 11 104 104 104 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,132 @@
|
|||||||
|
[README.Schema]
|
||||||
|
|
||||||
|
The schemata offered in the Options/Schema menu are
|
||||||
|
taken from from configurations files with a *.schema
|
||||||
|
pattern either located in $KDEDIR/share/apps/konsole
|
||||||
|
or ~/.kde/share/apps/konsole.
|
||||||
|
|
||||||
|
Schemata allow to configure the color set that konsole
|
||||||
|
uses, together with some more information on rendition
|
||||||
|
processing.
|
||||||
|
|
||||||
|
Syntax
|
||||||
|
|
||||||
|
File
|
||||||
|
:: { [Line] ['#' Comment] '\n' }
|
||||||
|
|
||||||
|
Line
|
||||||
|
:: "title" Title
|
||||||
|
:: "image" Usage PathToPictureFile
|
||||||
|
:: "transparency" Fade Red Green Blue
|
||||||
|
:: "color" Slot Red Green Blue Transparent Bold
|
||||||
|
:: "rcolor" Slot Saturation Value Transparent Bold
|
||||||
|
:: "sysfg" Slot Transparent Bold
|
||||||
|
:: "sysbg" Slot Transparent Bold
|
||||||
|
|
||||||
|
Meaning
|
||||||
|
|
||||||
|
- Title is the text to appear in the Option/Schema menu.
|
||||||
|
It should be unique among all other schemata therefore.
|
||||||
|
|
||||||
|
- The "image" clause allows to place an image on the
|
||||||
|
konsole's background.
|
||||||
|
|
||||||
|
- Usage can be either
|
||||||
|
- "tile" - the image is tilewise replicated.
|
||||||
|
- "center" - the image is centered.
|
||||||
|
- "full" - the image is stretched to fit the window size.
|
||||||
|
|
||||||
|
- The Path of the picture can both be relative
|
||||||
|
(to kde wallpapers) or absolute.
|
||||||
|
|
||||||
|
When a schema uses a background image (or transparency)
|
||||||
|
one has to make at least one color slot transparent to
|
||||||
|
achive any visible effect. Please read below about the
|
||||||
|
"Transparent" field in color,sysbg,sysfg.
|
||||||
|
|
||||||
|
- The "transparency" clause picks and uses the background
|
||||||
|
of the desktop as if it where an image together with
|
||||||
|
a fade effect. This effect will fade the background
|
||||||
|
to the specified color.
|
||||||
|
|
||||||
|
The "Fade" is a real value between 0 and 1, indicating
|
||||||
|
the strength of the fade. A value of 0 will not change
|
||||||
|
the image, a value of 1 will make it the fade color
|
||||||
|
everywhere, and in between. This will make the "glas"
|
||||||
|
of the window be of the color given in the clause and
|
||||||
|
being more(1) or less(0) intransparent.
|
||||||
|
|
||||||
|
- The remaining clauses (color,sysbg,sysfg) are used
|
||||||
|
to setup konsoles rendition system.
|
||||||
|
|
||||||
|
To this end, konsole offers 20 color slots.
|
||||||
|
|
||||||
|
Slot Meaning
|
||||||
|
----- --------------------------
|
||||||
|
0 regular foreground color
|
||||||
|
1 regular background color
|
||||||
|
2-9 regular bgr color 0-7
|
||||||
|
10 intensive foreground color
|
||||||
|
11 intensive background color
|
||||||
|
12-19 intensive bgr color 0-7
|
||||||
|
|
||||||
|
The traditional meaning of the "bgr" color codes
|
||||||
|
has a bitwise interpretation of an additive three
|
||||||
|
primary color scheme inherited from early EGA
|
||||||
|
color terminals.
|
||||||
|
|
||||||
|
Color Bits Colors
|
||||||
|
----- ---- -------
|
||||||
|
0 000 Black
|
||||||
|
1 001 Red
|
||||||
|
2 010 Green
|
||||||
|
3 011 Yellow
|
||||||
|
4 100 Blue
|
||||||
|
5 101 Magenta
|
||||||
|
6 110 Cyan
|
||||||
|
7 111 White
|
||||||
|
|
||||||
|
One may or may not stick to this tradition.
|
||||||
|
Konsole allows to assign colors freely to slots.
|
||||||
|
|
||||||
|
The slots fall apart into two groups, regular
|
||||||
|
and intensive colors. The later are used when
|
||||||
|
BOLD rendition is used by the client.
|
||||||
|
|
||||||
|
Each of the groups have a default fore- and
|
||||||
|
background color and the said bgr colors.
|
||||||
|
Normal terminal processing will simply use
|
||||||
|
the default colors.
|
||||||
|
|
||||||
|
The color desired for a slot is indicated
|
||||||
|
in the Red Green Blue fields of the color
|
||||||
|
clause. Use the sysfg or the sysbg clause
|
||||||
|
to indicate the default fore and background
|
||||||
|
colors of the desktop.
|
||||||
|
|
||||||
|
To specify randomized color for a slot use
|
||||||
|
the clause rcolor. The two parameters to it
|
||||||
|
being Saturation - the amount of colour,
|
||||||
|
and Value, the darkness of the colour.
|
||||||
|
|
||||||
|
To use transparency/images and to simulate
|
||||||
|
the behavior of the xterm, one can supply
|
||||||
|
two additional tags to each slot:
|
||||||
|
- Transparent (0/1) meaning to show the
|
||||||
|
background picture, if any.
|
||||||
|
- Bold (0/1) to render characters bold.
|
||||||
|
|
||||||
|
|
||||||
|
If you know about the escape codes, you might have
|
||||||
|
noticed that intensive and bold rendition are sort
|
||||||
|
of confused. This is inherited by the xterm which
|
||||||
|
konsole is simulating.
|
||||||
|
|
||||||
|
One can use the colortest.sh script supplied
|
||||||
|
with the konsole source distribution to test
|
||||||
|
a schema.
|
||||||
|
|
||||||
|
The schema installed with konsole are more or
|
||||||
|
less demonstrations and not really beauty,
|
||||||
|
beside the Linux.schema, perhaps, which is
|
||||||
|
made after the VGA colors.
|
@ -0,0 +1,44 @@
|
|||||||
|
# default scheme for konsole (only here for documentation purposes)
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title Konsole Defaults
|
||||||
|
|
||||||
|
# image tile /opt/kde/share/wallpapers/gray2.jpg
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 255 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,49 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Transparent Konsole
|
||||||
|
|
||||||
|
transparency 0.35 0 0 0
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
#
|
||||||
|
# The flaw in this schema is that "blick" comes out on the
|
||||||
|
# Linux console as intensive background, really.
|
||||||
|
# Since this is not used in clients you'll hardly notice
|
||||||
|
# it in practice.
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 178 178 178 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 0 # intensive foreground color
|
||||||
|
color 11 104 104 104 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,51 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Transparent for MC
|
||||||
|
|
||||||
|
transparency 0.35 0 0 0
|
||||||
|
|
||||||
|
# FIXME
|
||||||
|
#
|
||||||
|
# The flaw in this schema is that "blick" comes out on the
|
||||||
|
# Linux console as intensive background, really.
|
||||||
|
# Since this is not used in clients you'll hardly notice
|
||||||
|
# it in practice.
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 178 178 178 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
#color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 6 0 0 0 1 0 # regular color 4 Blue
|
||||||
|
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 0 # intensive foreground color
|
||||||
|
color 11 104 104 104 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,42 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Transparent, Dark Background
|
||||||
|
|
||||||
|
transparency 0.75 0 0 0
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 255 255 255 0 0 # regular foreground color (White)
|
||||||
|
color 1 0 0 0 1 0 # regular background color (Black)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 255 255 255 0 0 # intensive foreground color
|
||||||
|
color 11 104 104 104 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,51 @@
|
|||||||
|
# linux color schema for konsole
|
||||||
|
|
||||||
|
title Transparent, Light Background
|
||||||
|
|
||||||
|
transparency 0.1 0 0 0
|
||||||
|
|
||||||
|
# This is a schema for very light backgrounds. It makes some
|
||||||
|
# hacks about the colors to make Midnight Commander transparent
|
||||||
|
# and with suitable colors.
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 50 50 50 0 0 # regular foreground color (DarkGray)
|
||||||
|
color 1 200 200 200 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
# color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 2 200 200 200 1 0 # regular background color (White)
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
#color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 6 0 0 0 1 0 # regular color 4 Blue
|
||||||
|
# Blue is transparent, to make MC transparent
|
||||||
|
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
# color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
color 9 50 50 50 0 0 # regular foreground color (DarkGray)
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 0 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,46 @@
|
|||||||
|
# xterm color schema for konsole
|
||||||
|
|
||||||
|
# xterm colors can be configured (almost) like
|
||||||
|
# konsole colors can. This is the uncustomized
|
||||||
|
# xterm schema.
|
||||||
|
# Please refere to your local xterm setup files
|
||||||
|
# if this schema differs.
|
||||||
|
|
||||||
|
title XTerm Colors
|
||||||
|
|
||||||
|
# foreground colors -------------------------------
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 255 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 205 0 0 0 0 # regular color 1 Red
|
||||||
|
color 4 0 205 0 0 0 # regular color 2 Green
|
||||||
|
color 5 205 205 0 0 0 # regular color 3 Yellow
|
||||||
|
color 6 0 0 205 0 0 # regular color 4 Blue
|
||||||
|
color 7 205 0 205 0 0 # regular color 5 Magenta
|
||||||
|
color 8 0 205 205 0 0 # regular color 6 Cyan
|
||||||
|
color 9 229 229 229 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors -------------------------------------------
|
||||||
|
|
||||||
|
# for some strange reason, intensive colors are bold, also.
|
||||||
|
|
||||||
|
color 10 77 77 77 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 1 # intensive background color
|
||||||
|
|
||||||
|
color 12 77 77 77 0 1 # intensive color 0
|
||||||
|
color 13 255 0 0 0 1 # intensive color 1
|
||||||
|
color 14 0 255 0 0 1 # intensive color 2
|
||||||
|
color 15 255 255 0 0 1 # intensive color 3
|
||||||
|
color 16 0 0 255 0 1 # intensive color 4
|
||||||
|
color 17 255 0 255 0 1 # intensive color 5
|
||||||
|
color 18 0 255 255 0 1 # intensive color 6
|
||||||
|
color 19 255 255 255 0 1 # intensive color 7
|
@ -0,0 +1,44 @@
|
|||||||
|
# schema that uses system colors
|
||||||
|
|
||||||
|
# the title is to appear in the menu.
|
||||||
|
|
||||||
|
title System Colors
|
||||||
|
|
||||||
|
# image none
|
||||||
|
|
||||||
|
# foreground colors
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
sysfg 0 0 0 # regular foreground color (system)
|
||||||
|
sysbg 1 1 0 # regular background color (system)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 178 24 24 0 0 # regular color 1 Red
|
||||||
|
color 4 24 178 24 0 0 # regular color 2 Green
|
||||||
|
color 5 178 104 24 0 0 # regular color 3 Yellow
|
||||||
|
color 6 24 24 178 0 0 # regular color 4 Blue
|
||||||
|
color 7 178 24 178 0 0 # regular color 5 Magenta
|
||||||
|
color 8 24 178 178 0 0 # regular color 6 Cyan
|
||||||
|
color 9 178 178 178 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors
|
||||||
|
|
||||||
|
# instead of changing the colors, we've flaged the text to become bold
|
||||||
|
|
||||||
|
color 10 0 0 0 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 0 # intensive background color
|
||||||
|
|
||||||
|
color 12 104 104 104 0 0 # intensive color 0
|
||||||
|
color 13 255 84 84 0 0 # intensive color 1
|
||||||
|
color 14 84 255 84 0 0 # intensive color 2
|
||||||
|
color 15 255 255 84 0 0 # intensive color 3
|
||||||
|
color 16 84 84 255 0 0 # intensive color 4
|
||||||
|
color 17 255 84 255 0 0 # intensive color 5
|
||||||
|
color 18 84 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,40 @@
|
|||||||
|
# VIM-recommended color schema for konsole
|
||||||
|
|
||||||
|
# VIM (VI improved) in "help xiterm" recommends these colors for xterm.
|
||||||
|
|
||||||
|
title VIM Colors
|
||||||
|
|
||||||
|
# foreground colors -------------------------------
|
||||||
|
|
||||||
|
# note that the default background color is flagged
|
||||||
|
# to become transparent when an image is present.
|
||||||
|
|
||||||
|
# slot transparent bold
|
||||||
|
# | red grn blu | |
|
||||||
|
# V V--color--V V V
|
||||||
|
|
||||||
|
color 0 0 0 0 0 0 # regular foreground color (Black)
|
||||||
|
color 1 255 255 255 1 0 # regular background color (White)
|
||||||
|
|
||||||
|
color 2 0 0 0 0 0 # regular color 0 Black
|
||||||
|
color 3 192 0 0 0 0 # regular color 1 Red
|
||||||
|
color 4 0 128 0 0 0 # regular color 2 Green
|
||||||
|
color 5 128 128 0 0 0 # regular color 3 Yellow
|
||||||
|
color 6 0 0 192 0 0 # regular color 4 Blue
|
||||||
|
color 7 192 0 192 0 0 # regular color 5 Magenta
|
||||||
|
color 8 0 128 128 0 0 # regular color 6 Cyan
|
||||||
|
color 9 192 192 192 0 0 # regular color 7 White
|
||||||
|
|
||||||
|
# intensive colors -------------------------------------------
|
||||||
|
|
||||||
|
color 10 77 77 77 0 1 # intensive foreground color
|
||||||
|
color 11 255 255 255 1 1 # intensive background color
|
||||||
|
|
||||||
|
color 12 128 128 128 0 0 # intensive color 0
|
||||||
|
color 13 255 96 96 0 0 # intensive color 1
|
||||||
|
color 14 0 255 0 0 0 # intensive color 2
|
||||||
|
color 15 255 255 0 0 0 # intensive color 3
|
||||||
|
color 16 128 128 255 0 0 # intensive color 4
|
||||||
|
color 17 255 64 255 0 0 # intensive color 5
|
||||||
|
color 18 0 255 255 0 0 # intensive color 6
|
||||||
|
color 19 255 255 255 0 0 # intensive color 7
|
@ -0,0 +1,128 @@
|
|||||||
|
# [README.default.Keytab] Buildin Keyboard Table
|
||||||
|
#
|
||||||
|
# To customize your keyboard, copy this file to something
|
||||||
|
# ending with .keytab and change it to meet you needs.
|
||||||
|
# Please read the README.KeyTab and the README.keyboard
|
||||||
|
# in this case.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
keyboard "Default (XFree 4)"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Note that this particular table is a "risc" version made to
|
||||||
|
# ease customization without bothering with obsolete details.
|
||||||
|
# See VT100.keytab for the more hairy stuff.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
# common keys
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
|
||||||
|
key Tab -Shift : "\t"
|
||||||
|
key Tab +Shift+Ansi : "\E[Z"
|
||||||
|
key Tab +Shift-Ansi : "\t"
|
||||||
|
key Backtab +Ansi : "\E[Z"
|
||||||
|
key Backtab -Ansi : "\t"
|
||||||
|
|
||||||
|
key Return-Shift-NewLine : "\r"
|
||||||
|
key Return-Shift+NewLine : "\r\n"
|
||||||
|
|
||||||
|
key Return+Shift : "\EOM"
|
||||||
|
|
||||||
|
# Backspace and Delete codes are preserving CTRL-H.
|
||||||
|
|
||||||
|
key Backspace : "\x7f"
|
||||||
|
|
||||||
|
# Arrow keys in VT52 mode
|
||||||
|
# shift up/down are reserved for scrolling.
|
||||||
|
# shift left/right are reserved for switching between tabs (this is hardcoded).
|
||||||
|
|
||||||
|
key Up -Shift-Ansi : "\EA"
|
||||||
|
key Down -Shift-Ansi : "\EB"
|
||||||
|
key Right-Shift-Ansi : "\EC"
|
||||||
|
key Left -Shift-Ansi : "\ED"
|
||||||
|
|
||||||
|
# Arrow keys in ANSI mode with Application - and Normal Cursor Mode)
|
||||||
|
|
||||||
|
key Up -Shift-AnyMod+Ansi+AppCuKeys : "\EOA"
|
||||||
|
key Down -Shift-AnyMod+Ansi+AppCuKeys : "\EOB"
|
||||||
|
key Right -Shift-AnyMod+Ansi+AppCuKeys : "\EOC"
|
||||||
|
key Left -Shift-AnyMod+Ansi+AppCuKeys : "\EOD"
|
||||||
|
|
||||||
|
key Up -Shift-AnyMod+Ansi-AppCuKeys : "\E[A"
|
||||||
|
key Down -Shift-AnyMod+Ansi-AppCuKeys : "\E[B"
|
||||||
|
key Right -Shift-AnyMod+Ansi-AppCuKeys : "\E[C"
|
||||||
|
key Left -Shift-AnyMod+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
key Up -Shift+AnyMod+Ansi : "\E[1;*A"
|
||||||
|
key Down -Shift+AnyMod+Ansi : "\E[1;*B"
|
||||||
|
key Right -Shift+AnyMod+Ansi : "\E[1;*C"
|
||||||
|
key Left -Shift+AnyMod+Ansi : "\E[1;*D"
|
||||||
|
|
||||||
|
# other grey PC keys
|
||||||
|
|
||||||
|
key Enter+NewLine : "\r\n"
|
||||||
|
key Enter-NewLine : "\r"
|
||||||
|
|
||||||
|
key Home -AnyMod -AppCuKeys : "\E[H"
|
||||||
|
key End -AnyMod -AppCuKeys : "\E[F"
|
||||||
|
key Home -AnyMod +AppCuKeys : "\EOH"
|
||||||
|
key End -AnyMod +AppCuKeys : "\EOF"
|
||||||
|
key Home +AnyMod : "\E[1;*H"
|
||||||
|
key End +AnyMod : "\E[1;*F"
|
||||||
|
|
||||||
|
key Insert -AnyMod : "\E[2~"
|
||||||
|
key Delete -AnyMod : "\E[3~"
|
||||||
|
key Insert +AnyMod : "\E[2;*~"
|
||||||
|
key Delete +AnyMod : "\E[3;*~"
|
||||||
|
|
||||||
|
key Prior -Shift-AnyMod : "\E[5~"
|
||||||
|
key Next -Shift-AnyMod : "\E[6~"
|
||||||
|
key Prior -Shift+AnyMod : "\E[5;*~"
|
||||||
|
key Next -Shift+AnyMod : "\E[6;*~"
|
||||||
|
|
||||||
|
# Function keys
|
||||||
|
key F1 -AnyMod : "\EOP"
|
||||||
|
key F2 -AnyMod : "\EOQ"
|
||||||
|
key F3 -AnyMod : "\EOR"
|
||||||
|
key F4 -AnyMod : "\EOS"
|
||||||
|
key F5 -AnyMod : "\E[15~"
|
||||||
|
key F6 -AnyMod : "\E[17~"
|
||||||
|
key F7 -AnyMod : "\E[18~"
|
||||||
|
key F8 -AnyMod : "\E[19~"
|
||||||
|
key F9 -AnyMod : "\E[20~"
|
||||||
|
key F10 -AnyMod : "\E[21~"
|
||||||
|
key F11 -AnyMod : "\E[23~"
|
||||||
|
key F12 -AnyMod : "\E[24~"
|
||||||
|
|
||||||
|
key F1 +AnyMod : "\EO*P"
|
||||||
|
key F2 +AnyMod : "\EO*Q"
|
||||||
|
key F3 +AnyMod : "\EO*R"
|
||||||
|
key F4 +AnyMod : "\EO*S"
|
||||||
|
key F5 +AnyMod : "\E[15;*~"
|
||||||
|
key F6 +AnyMod : "\E[17;*~"
|
||||||
|
key F7 +AnyMod : "\E[18;*~"
|
||||||
|
key F8 +AnyMod : "\E[19;*~"
|
||||||
|
key F9 +AnyMod : "\E[20;*~"
|
||||||
|
key F10 +AnyMod : "\E[21;*~"
|
||||||
|
key F11 +AnyMod : "\E[23;*~"
|
||||||
|
key F12 +AnyMod : "\E[24;*~"
|
||||||
|
|
||||||
|
# Work around dead keys
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# Some keys are used by konsole to cause operations.
|
||||||
|
# The scroll* operations refer to the history buffer.
|
||||||
|
|
||||||
|
key Up +Shift-AppScreen : scrollLineUp
|
||||||
|
key Prior +Shift-AppScreen : scrollPageUp
|
||||||
|
key Down +Shift-AppScreen : scrollLineDown
|
||||||
|
key Next +Shift-AppScreen : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
||||||
|
# keypad characters are not offered differently by Qt.
|
After Width: | Height: | Size: 2.2 KiB |
@ -0,0 +1,102 @@
|
|||||||
|
|
||||||
|
#include "qtermwidgetplugin.h"
|
||||||
|
|
||||||
|
#include <QtPlugin>
|
||||||
|
|
||||||
|
#include "qtermwidget.h"
|
||||||
|
|
||||||
|
|
||||||
|
QTermWidgetPlugin::QTermWidgetPlugin(QObject *parent)
|
||||||
|
: QObject(parent), initialized(false)
|
||||||
|
{
|
||||||
|
Q_INIT_RESOURCE(qtermwidgetplugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTermWidgetPlugin::~QTermWidgetPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QTermWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */)
|
||||||
|
{
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QTermWidgetPlugin::isInitialized() const
|
||||||
|
{
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QWidget *QTermWidgetPlugin::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
return new QTermWidget(0, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QTermWidgetPlugin::name() const
|
||||||
|
{
|
||||||
|
return "QTermWidget";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QTermWidgetPlugin::group() const
|
||||||
|
{
|
||||||
|
return "Input Widgets";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QIcon QTermWidgetPlugin::icon() const
|
||||||
|
{
|
||||||
|
return QIcon(":qtermwidget.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QTermWidgetPlugin::toolTip() const
|
||||||
|
{
|
||||||
|
return "QTermWidget component/widget";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QTermWidgetPlugin::whatsThis() const
|
||||||
|
{
|
||||||
|
return "Qt based terminal emulator";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QTermWidgetPlugin::isContainer() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QTermWidgetPlugin::domXml() const
|
||||||
|
{
|
||||||
|
return "<widget class=\"QTermWidget\" name=\"termWidget\">\n"
|
||||||
|
" <property name=\"geometry\">\n"
|
||||||
|
" <rect>\n"
|
||||||
|
" <x>0</x>\n"
|
||||||
|
" <y>0</y>\n"
|
||||||
|
" <width>400</width>\n"
|
||||||
|
" <height>200</height>\n"
|
||||||
|
" </rect>\n"
|
||||||
|
" </property>\n"
|
||||||
|
" <property name=\"toolTip\" >\n"
|
||||||
|
" <string></string>\n"
|
||||||
|
" </property>\n"
|
||||||
|
" <property name=\"whatsThis\" >\n"
|
||||||
|
" <string></string>\n"
|
||||||
|
" </property>\n"
|
||||||
|
"</widget>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString QTermWidgetPlugin::includeFile() const
|
||||||
|
{
|
||||||
|
return "qtermwidget.h";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Q_EXPORT_PLUGIN2(QTermWidgetPlugin, QTermWidgetPlugin)
|
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
#ifndef QTERMWIDGETPLUGIN_H
|
||||||
|
#define QTERMWIDGETPLUGIN_H
|
||||||
|
|
||||||
|
#include <QDesignerCustomWidgetInterface>
|
||||||
|
|
||||||
|
|
||||||
|
class QTermWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||||
|
|
||||||
|
public:
|
||||||
|
QTermWidgetPlugin(QObject *parent = 0);
|
||||||
|
virtual ~QTermWidgetPlugin();
|
||||||
|
|
||||||
|
bool isContainer() const;
|
||||||
|
bool isInitialized() const;
|
||||||
|
QIcon icon() const;
|
||||||
|
QString domXml() const;
|
||||||
|
QString group() const;
|
||||||
|
QString includeFile() const;
|
||||||
|
QString name() const;
|
||||||
|
QString toolTip() const;
|
||||||
|
QString whatsThis() const;
|
||||||
|
QWidget *createWidget(QWidget *parent);
|
||||||
|
void initialize(QDesignerFormEditorInterface *core);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,6 @@
|
|||||||
|
<!DOCTYPE RCC>
|
||||||
|
<RCC version="1.0">
|
||||||
|
<qresource>
|
||||||
|
<file>qtermwidget.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
@ -0,0 +1,72 @@
|
|||||||
|
[README.KeyTab]
|
||||||
|
|
||||||
|
The keytabs offered in the Options/Keyboard menu are
|
||||||
|
taken from from configurations files with a *.keytab
|
||||||
|
pattern either located in $KDEDIR/share/apps/konsole
|
||||||
|
or ~/.kde/share/apps/konsole.
|
||||||
|
|
||||||
|
Keytabs allow to configure the behavior of konsole
|
||||||
|
on keyboard events, especially for functions keys.
|
||||||
|
Please have a look into the README.keyboard file, too.
|
||||||
|
|
||||||
|
The syntax is that each entry has the form :
|
||||||
|
|
||||||
|
"key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
|
||||||
|
|
||||||
|
Keynames are those defined in <qnamespace.h> with the
|
||||||
|
"Qt::Key_" prefix removed.
|
||||||
|
|
||||||
|
Mode names are:
|
||||||
|
|
||||||
|
- Shift : Shift Key pressed
|
||||||
|
- Alt : Alt Key pressed
|
||||||
|
- Control : Control Key pressed
|
||||||
|
|
||||||
|
( The VT100 emulation has modes that can affect the
|
||||||
|
sequences emitted by certain keys. These modes are
|
||||||
|
under control of the client program.
|
||||||
|
|
||||||
|
- Newline : effects Return and Enter key.
|
||||||
|
- Application : effects Up and Down key.
|
||||||
|
- Ansi : effects Up and Down key (This is for VT52, really).
|
||||||
|
|
||||||
|
Since sending a state to a program that has set the state
|
||||||
|
itself is positivly wrong and obsolete design, better forget
|
||||||
|
about this nasty detail. I may well remove this "feature"
|
||||||
|
in a future clean up round. )
|
||||||
|
|
||||||
|
A "+" preceeding a Modename means the Key is pressed.
|
||||||
|
A "-" preceeding a Modename means the Key is not pressed.
|
||||||
|
If no mode is given it means don't care.
|
||||||
|
|
||||||
|
Note that the combination of Key and Modes (set/reset)
|
||||||
|
has to be unique. This means, that
|
||||||
|
|
||||||
|
key A + Shift : "A"
|
||||||
|
key A : "a"
|
||||||
|
|
||||||
|
will not accept the small letter "a" rule as expected,
|
||||||
|
one has to add a "- Shift" to the last clause. Use
|
||||||
|
the stdout/stderr dianostics of konsole when modifying
|
||||||
|
keytabs to find problems like this.
|
||||||
|
|
||||||
|
Operations are
|
||||||
|
|
||||||
|
- scrollUpLine : scroll up one line in the history log
|
||||||
|
- scrollUpPage : scroll up one page in the history log
|
||||||
|
- scrollDownLine : scroll down one line in the history log
|
||||||
|
- scrollDownPage : scroll down one page in the history log
|
||||||
|
- emitClipboard : "paste" the current clipboard
|
||||||
|
- emitSelection : "paste" the current selection
|
||||||
|
|
||||||
|
Strings have the syntax of C strings,
|
||||||
|
one may use the following escapes:
|
||||||
|
|
||||||
|
- \E - escape
|
||||||
|
- \\ - backslash
|
||||||
|
- \" - double quote
|
||||||
|
- \t - tab
|
||||||
|
- \r - return
|
||||||
|
- \n - newline
|
||||||
|
- \b - backspace
|
||||||
|
- \xHH - where HH are two hex digits
|
@ -0,0 +1,169 @@
|
|||||||
|
# [README.default.Keytab] Default Keyboard Table
|
||||||
|
#
|
||||||
|
# To customize your keyboard, copy this file to something
|
||||||
|
# ending with .keytab and change it to meet you needs.
|
||||||
|
# Please read the README.KeyTab and the README.keyboard
|
||||||
|
# in this case.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
keyboard "Default (XFree 4)"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Note that this particular table is a "risc" version made to
|
||||||
|
# ease customization without bothering with obsolete details.
|
||||||
|
# See VT100.keytab for the more hairy stuff.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
# common keys
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
|
||||||
|
key Tab -Shift : "\t"
|
||||||
|
key Tab +Shift+Ansi : "\E[Z"
|
||||||
|
key Tab +Shift-Ansi : "\t"
|
||||||
|
key Backtab +Ansi : "\E[Z"
|
||||||
|
key Backtab -Ansi : "\t"
|
||||||
|
|
||||||
|
key Return-Shift-NewLine : "\r"
|
||||||
|
key Return-Shift+NewLine : "\r\n"
|
||||||
|
|
||||||
|
key Return+Shift : "\EOM"
|
||||||
|
|
||||||
|
# Backspace and Delete codes are preserving CTRL-H.
|
||||||
|
|
||||||
|
key Backspace : "\x7f"
|
||||||
|
|
||||||
|
# Arrow keys in VT52 mode
|
||||||
|
# shift up/down are reserved for scrolling.
|
||||||
|
# shift left/right are reserved for switching between tabs (this is hardcoded).
|
||||||
|
|
||||||
|
key Up -Shift-Ansi : "\EA"
|
||||||
|
key Down -Shift-Ansi : "\EB"
|
||||||
|
key Right-Shift-Ansi : "\EC"
|
||||||
|
key Left -Shift-Ansi : "\ED"
|
||||||
|
|
||||||
|
# Arrow keys in ANSI mode with Application - and Normal Cursor Mode)
|
||||||
|
|
||||||
|
key Up -Shift-AnyMod+Ansi+AppCuKeys : "\EOA"
|
||||||
|
key Down -Shift-AnyMod+Ansi+AppCuKeys : "\EOB"
|
||||||
|
key Right -Shift-AnyMod+Ansi+AppCuKeys : "\EOC"
|
||||||
|
key Left -Shift-AnyMod+Ansi+AppCuKeys : "\EOD"
|
||||||
|
|
||||||
|
key Up -Shift-AnyMod+Ansi-AppCuKeys : "\E[A"
|
||||||
|
key Down -Shift-AnyMod+Ansi-AppCuKeys : "\E[B"
|
||||||
|
key Right -Shift-AnyMod+Ansi-AppCuKeys : "\E[C"
|
||||||
|
key Left -Shift-AnyMod+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
key Up -Shift+AnyMod+Ansi : "\E[1;*A"
|
||||||
|
key Down -Shift+AnyMod+Ansi : "\E[1;*B"
|
||||||
|
key Right -Shift+AnyMod+Ansi : "\E[1;*C"
|
||||||
|
key Left -Shift+AnyMod+Ansi : "\E[1;*D"
|
||||||
|
|
||||||
|
# Keypad keys with NumLock ON
|
||||||
|
# (see "Numeric Keypad" section at http://www.nw.com/nw/WWW/products/wizcon/vt100.html )
|
||||||
|
#
|
||||||
|
# Not enabled for now because it breaks the keypad in Vim.
|
||||||
|
#
|
||||||
|
#key 0 +KeyPad+AppKeyPad : "\EOp"
|
||||||
|
#key 1 +KeyPad+AppKeyPad : "\EOq"
|
||||||
|
#key 2 +KeyPad+AppKeyPad : "\EOr"
|
||||||
|
#key 3 +KeyPad+AppKeyPad : "\EOs"
|
||||||
|
#key 4 +KeyPad+AppKeyPad : "\EOt"
|
||||||
|
#key 5 +KeyPad+AppKeyPad : "\EOu"
|
||||||
|
#key 6 +KeyPad+AppKeyPad : "\EOv"
|
||||||
|
#key 7 +KeyPad+AppKeyPad : "\EOw"
|
||||||
|
#key 8 +KeyPad+AppKeyPad : "\EOx"
|
||||||
|
#key 9 +KeyPad+AppKeyPad : "\EOy"
|
||||||
|
#key + +KeyPad+AppKeyPad : "\EOl"
|
||||||
|
#key - +KeyPad+AppKeyPad : "\EOm"
|
||||||
|
#key . +KeyPad+AppKeyPad : "\EOn"
|
||||||
|
#key * +KeyPad+AppKeyPad : "\EOM"
|
||||||
|
#key Enter +KeyPad+AppKeyPad : "\r"
|
||||||
|
|
||||||
|
# Keypad keys with NumLock Off
|
||||||
|
key Up -Shift+Ansi+AppCuKeys+KeyPad : "\EOA"
|
||||||
|
key Down -Shift+Ansi+AppCuKeys+KeyPad : "\EOB"
|
||||||
|
key Right -Shift+Ansi+AppCuKeys+KeyPad : "\EOC"
|
||||||
|
key Left -Shift+Ansi+AppCuKeys+KeyPad : "\EOD"
|
||||||
|
|
||||||
|
key Up -Shift+Ansi-AppCuKeys+KeyPad : "\E[A"
|
||||||
|
key Down -Shift+Ansi-AppCuKeys+KeyPad : "\E[B"
|
||||||
|
key Right -Shift+Ansi-AppCuKeys+KeyPad : "\E[C"
|
||||||
|
key Left -Shift+Ansi-AppCuKeys+KeyPad : "\E[D"
|
||||||
|
|
||||||
|
key Home +AppCuKeys+KeyPad : "\EOH"
|
||||||
|
key End +AppCuKeys+KeyPad : "\EOF"
|
||||||
|
key Home -AppCuKeys+KeyPad : "\E[H"
|
||||||
|
key End -AppCuKeys+KeyPad : "\E[F"
|
||||||
|
|
||||||
|
key Insert +KeyPad : "\E[2~"
|
||||||
|
key Delete +KeyPad : "\E[3~"
|
||||||
|
key Prior -Shift+KeyPad : "\E[5~"
|
||||||
|
key Next -Shift+KeyPad : "\E[6~"
|
||||||
|
|
||||||
|
# other grey PC keys
|
||||||
|
|
||||||
|
key Enter+NewLine : "\r\n"
|
||||||
|
key Enter-NewLine : "\r"
|
||||||
|
|
||||||
|
key Home -AnyMod-AppCuKeys : "\E[H"
|
||||||
|
key End -AnyMod-AppCuKeys : "\E[F"
|
||||||
|
key Home -AnyMod+AppCuKeys : "\EOH"
|
||||||
|
key End -AnyMod+AppCuKeys : "\EOF"
|
||||||
|
key Home +AnyMod : "\E[1;*H"
|
||||||
|
key End +AnyMod : "\E[1;*F"
|
||||||
|
|
||||||
|
key Insert -AnyMod : "\E[2~"
|
||||||
|
key Delete -AnyMod : "\E[3~"
|
||||||
|
key Insert +AnyMod : "\E[2;*~"
|
||||||
|
key Delete +AnyMod : "\E[3;*~"
|
||||||
|
|
||||||
|
key Prior -Shift-AnyMod : "\E[5~"
|
||||||
|
key Next -Shift-AnyMod : "\E[6~"
|
||||||
|
key Prior -Shift+AnyMod : "\E[5;*~"
|
||||||
|
key Next -Shift+AnyMod : "\E[6;*~"
|
||||||
|
|
||||||
|
# Function keys
|
||||||
|
key F1 -AnyMod : "\EOP"
|
||||||
|
key F2 -AnyMod : "\EOQ"
|
||||||
|
key F3 -AnyMod : "\EOR"
|
||||||
|
key F4 -AnyMod : "\EOS"
|
||||||
|
key F5 -AnyMod : "\E[15~"
|
||||||
|
key F6 -AnyMod : "\E[17~"
|
||||||
|
key F7 -AnyMod : "\E[18~"
|
||||||
|
key F8 -AnyMod : "\E[19~"
|
||||||
|
key F9 -AnyMod : "\E[20~"
|
||||||
|
key F10 -AnyMod : "\E[21~"
|
||||||
|
key F11 -AnyMod : "\E[23~"
|
||||||
|
key F12 -AnyMod : "\E[24~"
|
||||||
|
|
||||||
|
key F1 +AnyMod : "\EO*P"
|
||||||
|
key F2 +AnyMod : "\EO*Q"
|
||||||
|
key F3 +AnyMod : "\EO*R"
|
||||||
|
key F4 +AnyMod : "\EO*S"
|
||||||
|
key F5 +AnyMod : "\E[15;*~"
|
||||||
|
key F6 +AnyMod : "\E[17;*~"
|
||||||
|
key F7 +AnyMod : "\E[18;*~"
|
||||||
|
key F8 +AnyMod : "\E[19;*~"
|
||||||
|
key F9 +AnyMod : "\E[20;*~"
|
||||||
|
key F10 +AnyMod : "\E[21;*~"
|
||||||
|
key F11 +AnyMod : "\E[23;*~"
|
||||||
|
key F12 +AnyMod : "\E[24;*~"
|
||||||
|
|
||||||
|
# Work around dead keys
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# Some keys are used by konsole to cause operations.
|
||||||
|
# The scroll* operations refer to the history buffer.
|
||||||
|
|
||||||
|
key Up +Shift-AppScreen : scrollLineUp
|
||||||
|
key Prior +Shift-AppScreen : scrollPageUp
|
||||||
|
key Down +Shift-AppScreen : scrollLineDown
|
||||||
|
key Next +Shift-AppScreen : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
@ -0,0 +1,133 @@
|
|||||||
|
# [vt100.keytab] Konsole Keyboard Table (VT100 keys)
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
keyboard "vt100 (historical)"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This configuration table allows to customize the
|
||||||
|
# meaning of the keys.
|
||||||
|
#
|
||||||
|
# The syntax is that each entry has the form :
|
||||||
|
#
|
||||||
|
# "key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
|
||||||
|
#
|
||||||
|
# Keynames are those defined in <qnamespace.h> with the
|
||||||
|
# "Qt::Key_" removed. (We'd better insert the list here)
|
||||||
|
#
|
||||||
|
# Mode names are :
|
||||||
|
#
|
||||||
|
# - Shift
|
||||||
|
# - Alt
|
||||||
|
# - Control
|
||||||
|
#
|
||||||
|
# The VT100 emulation has two modes that can affect the
|
||||||
|
# sequences emitted by certain keys. These modes are
|
||||||
|
# under control of the client program.
|
||||||
|
#
|
||||||
|
# - Newline : effects Return and Enter key.
|
||||||
|
# - Application : effects Up and Down key.
|
||||||
|
#
|
||||||
|
# - Ansi : effects Up and Down key (This is for VT52, really).
|
||||||
|
#
|
||||||
|
# Operations are
|
||||||
|
#
|
||||||
|
# - scrollUpLine
|
||||||
|
# - scrollUpPage
|
||||||
|
# - scrollDownLine
|
||||||
|
# - scrollDownPage
|
||||||
|
#
|
||||||
|
# - emitSelection
|
||||||
|
#
|
||||||
|
# If the key is not found here, the text of the
|
||||||
|
# key event as provided by QT is emitted, possibly
|
||||||
|
# preceeded by ESC if the Alt key is pressed.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
key Tab : "\t"
|
||||||
|
|
||||||
|
# VT100 can add an extra \n after return.
|
||||||
|
# The NewLine mode is set by an escape sequence.
|
||||||
|
|
||||||
|
key Return-NewLine : "\r"
|
||||||
|
key Return+NewLine : "\r\n"
|
||||||
|
|
||||||
|
# Some desperately try to save the ^H.
|
||||||
|
|
||||||
|
key Backspace : "\x7f"
|
||||||
|
key Delete : "\E[3~"
|
||||||
|
|
||||||
|
# These codes are for the VT52 mode of VT100
|
||||||
|
# The Ansi mode (i.e. VT100 mode) is set by
|
||||||
|
# an escape sequence
|
||||||
|
|
||||||
|
key Up -Shift-Ansi : "\EA"
|
||||||
|
key Down -Shift-Ansi : "\EB"
|
||||||
|
key Right-Shift-Ansi : "\EC"
|
||||||
|
key Left -Shift-Ansi : "\ED"
|
||||||
|
|
||||||
|
# VT100 emits a mode bit together
|
||||||
|
# with the arrow keys.The AppCuKeys
|
||||||
|
# mode is set by an escape sequence.
|
||||||
|
|
||||||
|
key Up -Shift+Ansi+AppCuKeys : "\EOA"
|
||||||
|
key Down -Shift+Ansi+AppCuKeys : "\EOB"
|
||||||
|
key Right-Shift+Ansi+AppCuKeys : "\EOC"
|
||||||
|
key Left -Shift+Ansi+AppCuKeys : "\EOD"
|
||||||
|
|
||||||
|
key Up -Shift+Ansi-AppCuKeys : "\E[A"
|
||||||
|
key Down -Shift+Ansi-AppCuKeys : "\E[B"
|
||||||
|
key Right-Shift+Ansi-AppCuKeys : "\E[C"
|
||||||
|
key Left -Shift+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
# function keys (FIXME: make pf1-pf4)
|
||||||
|
|
||||||
|
key F1 : "\E[11~"
|
||||||
|
key F2 : "\E[12~"
|
||||||
|
key F3 : "\E[13~"
|
||||||
|
key F4 : "\E[14~"
|
||||||
|
key F5 : "\E[15~"
|
||||||
|
|
||||||
|
key F6 : "\E[17~"
|
||||||
|
key F7 : "\E[18~"
|
||||||
|
key F8 : "\E[19~"
|
||||||
|
key F9 : "\E[20~"
|
||||||
|
key F10 : "\E[21~"
|
||||||
|
key F11 : "\E[23~"
|
||||||
|
key F12 : "\E[24~"
|
||||||
|
|
||||||
|
key Home : "\E[H"
|
||||||
|
key End : "\E[F"
|
||||||
|
|
||||||
|
key Prior -Shift : "\E[5~"
|
||||||
|
key Next -Shift : "\E[6~"
|
||||||
|
key Insert-Shift : "\E[2~"
|
||||||
|
|
||||||
|
# Keypad-Enter. See comment on Return above.
|
||||||
|
|
||||||
|
key Enter+NewLine : "\r\n"
|
||||||
|
key Enter-NewLine : "\r"
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# some of keys are used by konsole.
|
||||||
|
|
||||||
|
key Up +Shift : scrollLineUp
|
||||||
|
key Prior +Shift : scrollPageUp
|
||||||
|
key Down +Shift : scrollLineDown
|
||||||
|
key Next +Shift : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
# keypad characters as offered by Qt
|
||||||
|
# cannot be recognized as such.
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
# Following other strings as emitted by konsole.
|
@ -0,0 +1,71 @@
|
|||||||
|
# [x11r5.Keytab] Keyboard Table for X11 R5
|
||||||
|
|
||||||
|
keyboard "XTerm (XFree 3.x.x)"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Note that this particular table is a "risc" version made to
|
||||||
|
# ease customization without bothering with obsolete details.
|
||||||
|
# See VT100.keytab for the more hairy stuff.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
# common keys
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
key Tab : "\t"
|
||||||
|
|
||||||
|
key Return : "\r"
|
||||||
|
|
||||||
|
# Backspace and Delete codes are preserving CTRL-H.
|
||||||
|
|
||||||
|
key Backspace : "\x7f"
|
||||||
|
|
||||||
|
# cursor keys
|
||||||
|
|
||||||
|
key Up -Shift : "\EOA"
|
||||||
|
key Down -Shift : "\EOB"
|
||||||
|
key Right -Shift : "\EOC"
|
||||||
|
key Left -Shift : "\EOD"
|
||||||
|
|
||||||
|
# other grey PC keys
|
||||||
|
|
||||||
|
key Enter : "\r"
|
||||||
|
|
||||||
|
key Home : "\E[1~"
|
||||||
|
key Insert-Shift : "\E[2~"
|
||||||
|
key Delete : "\E[3~"
|
||||||
|
key End : "\E[4~"
|
||||||
|
key Prior -Shift : "\E[5~"
|
||||||
|
key Next -Shift : "\E[6~"
|
||||||
|
|
||||||
|
# function keys
|
||||||
|
|
||||||
|
key F1 : "\E[11~"
|
||||||
|
key F2 : "\E[12~"
|
||||||
|
key F3 : "\E[13~"
|
||||||
|
key F4 : "\E[14~"
|
||||||
|
key F5 : "\E[15~"
|
||||||
|
key F6 : "\E[17~"
|
||||||
|
key F7 : "\E[18~"
|
||||||
|
key F8 : "\E[19~"
|
||||||
|
key F9 : "\E[20~"
|
||||||
|
key F10 : "\E[21~"
|
||||||
|
key F11 : "\E[23~"
|
||||||
|
key F12 : "\E[24~"
|
||||||
|
|
||||||
|
# Work around dead keys
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# Some keys are used by konsole to cause operations.
|
||||||
|
# The scroll* operations refer to the history buffer.
|
||||||
|
|
||||||
|
key Up +Shift : scrollLineUp
|
||||||
|
key Prior +Shift : scrollPageUp
|
||||||
|
key Down +Shift : scrollLineDown
|
||||||
|
key Next +Shift : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
||||||
|
# keypad characters are not offered differently by Qt.
|
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE RCC>
|
||||||
|
<RCC version="1.0">
|
||||||
|
<qresource><file>linux.keytab</file></qresource>
|
||||||
|
<qresource><file>solaris.keytab</file></qresource>
|
||||||
|
<qresource><file>macbook.keytab</file></qresource>
|
||||||
|
<qresource><file>default.keytab</file></qresource>
|
||||||
|
<qresource><file>vt420pc.keytab</file></qresource>
|
||||||
|
<qresource><file>historic/x11r5.keytab</file></qresource>
|
||||||
|
<qresource><file>historic/vt100.keytab</file></qresource>
|
||||||
|
</RCC>
|
@ -0,0 +1,138 @@
|
|||||||
|
# [linux.keytab] Konsole Keyboard Table (Linux console keys)
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
# NOT TESTED, MAY NEED SOME CLEANUPS
|
||||||
|
keyboard "Linux console"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This configuration table allows to customize the
|
||||||
|
# meaning of the keys.
|
||||||
|
#
|
||||||
|
# The syntax is that each entry has the form :
|
||||||
|
#
|
||||||
|
# "key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
|
||||||
|
#
|
||||||
|
# Keynames are those defined in <qnamespace.h> with the
|
||||||
|
# "Qt::Key_" removed. (We'd better insert the list here)
|
||||||
|
#
|
||||||
|
# Mode names are :
|
||||||
|
#
|
||||||
|
# - Shift
|
||||||
|
# - Alt
|
||||||
|
# - Control
|
||||||
|
#
|
||||||
|
# The VT100 emulation has two modes that can affect the
|
||||||
|
# sequences emitted by certain keys. These modes are
|
||||||
|
# under control of the client program.
|
||||||
|
#
|
||||||
|
# - Newline : effects Return and Enter key.
|
||||||
|
# - Application : effects Up and Down key.
|
||||||
|
#
|
||||||
|
# - Ansi : effects Up and Down key (This is for VT52, really).
|
||||||
|
#
|
||||||
|
# Operations are
|
||||||
|
#
|
||||||
|
# - scrollUpLine
|
||||||
|
# - scrollUpPage
|
||||||
|
# - scrollDownLine
|
||||||
|
# - scrollDownPage
|
||||||
|
#
|
||||||
|
# - emitSelection
|
||||||
|
#
|
||||||
|
# If the key is not found here, the text of the
|
||||||
|
# key event as provided by QT is emitted, possibly
|
||||||
|
# preceeded by ESC if the Alt key is pressed.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
key Tab : "\t"
|
||||||
|
|
||||||
|
# VT100 can add an extra \n after return.
|
||||||
|
# The NewLine mode is set by an escape sequence.
|
||||||
|
|
||||||
|
key Return-NewLine : "\r"
|
||||||
|
key Return+NewLine : "\r\n"
|
||||||
|
|
||||||
|
# Some desperately try to save the ^H.
|
||||||
|
|
||||||
|
key Backspace : "\x7f"
|
||||||
|
key Delete : "\E[3~"
|
||||||
|
|
||||||
|
# These codes are for the VT52 mode of VT100
|
||||||
|
# The Ansi mode (i.e. VT100 mode) is set by
|
||||||
|
# an escape sequence
|
||||||
|
|
||||||
|
key Up -Shift-Ansi : "\EA"
|
||||||
|
key Down -Shift-Ansi : "\EB"
|
||||||
|
key Right-Shift-Ansi : "\EC"
|
||||||
|
key Left -Shift-Ansi : "\ED"
|
||||||
|
|
||||||
|
# VT100 emits a mode bit together
|
||||||
|
# with the arrow keys.The AppCuKeys
|
||||||
|
# mode is set by an escape sequence.
|
||||||
|
|
||||||
|
key Up -Shift+Ansi+AppCuKeys : "\EOA"
|
||||||
|
key Down -Shift+Ansi+AppCuKeys : "\EOB"
|
||||||
|
key Right-Shift+Ansi+AppCuKeys : "\EOC"
|
||||||
|
key Left -Shift+Ansi+AppCuKeys : "\EOD"
|
||||||
|
|
||||||
|
key Up -Shift+Ansi-AppCuKeys : "\E[A"
|
||||||
|
key Down -Shift+Ansi-AppCuKeys : "\E[B"
|
||||||
|
key Right-Shift+Ansi-AppCuKeys : "\E[C"
|
||||||
|
key Left -Shift+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
key Up -Shift+AnyMod+Ansi : "\E[1;*A"
|
||||||
|
key Down -Shift+AnyMod+Ansi : "\E[1;*B"
|
||||||
|
key Right -Shift+AnyMod+Ansi : "\E[1;*C"
|
||||||
|
key Left -Shift+AnyMod+Ansi : "\E[1;*D"
|
||||||
|
|
||||||
|
# linux functions keys F1-F5 differ from xterm
|
||||||
|
|
||||||
|
key F1 : "\E[[A"
|
||||||
|
key F2 : "\E[[B"
|
||||||
|
key F3 : "\E[[C"
|
||||||
|
key F4 : "\E[[D"
|
||||||
|
key F5 : "\E[[E"
|
||||||
|
|
||||||
|
key F6 : "\E[17~"
|
||||||
|
key F7 : "\E[18~"
|
||||||
|
key F8 : "\E[19~"
|
||||||
|
key F9 : "\E[20~"
|
||||||
|
key F10 : "\E[21~"
|
||||||
|
key F11 : "\E[23~"
|
||||||
|
key F12 : "\E[24~"
|
||||||
|
|
||||||
|
key Home : "\E[1~"
|
||||||
|
key End : "\E[4~"
|
||||||
|
|
||||||
|
key Prior -Shift : "\E[5~"
|
||||||
|
key Next -Shift : "\E[6~"
|
||||||
|
key Insert-Shift : "\E[2~"
|
||||||
|
|
||||||
|
# Keypad-Enter. See comment on Return above.
|
||||||
|
|
||||||
|
key Enter+NewLine : "\r\n"
|
||||||
|
key Enter-NewLine : "\r"
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# some of keys are used by konsole.
|
||||||
|
|
||||||
|
key Up +Shift : scrollLineUp
|
||||||
|
key Prior +Shift : scrollPageUp
|
||||||
|
key Down +Shift : scrollLineDown
|
||||||
|
key Next +Shift : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
# keypad characters as offered by Qt
|
||||||
|
# cannot be recognized as such.
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
# Following other strings as emitted by konsole.
|
@ -0,0 +1,175 @@
|
|||||||
|
# [README.default.Keytab] Buildin Keyboard Table
|
||||||
|
#
|
||||||
|
# To customize your keyboard, copy this file to something
|
||||||
|
# ending with .keytab and change it to meet you needs.
|
||||||
|
# Please read the README.KeyTab and the README.keyboard
|
||||||
|
# in this case.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
keyboard "Default (XFree 4)"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Note that this particular table is a "risc" version made to
|
||||||
|
# ease customization without bothering with obsolete details.
|
||||||
|
# See VT100.keytab for the more hairy stuff.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
# common keys
|
||||||
|
|
||||||
|
key Escape : "\x1b"
|
||||||
|
|
||||||
|
#key Control : "^"
|
||||||
|
|
||||||
|
key Tab -Shift : "\t"
|
||||||
|
key Tab +Shift+Ansi : "\E[Z"
|
||||||
|
key Tab +Shift-Ansi : "\t"
|
||||||
|
key Backtab +Ansi : "\E[Z"
|
||||||
|
key Backtab -Ansi : "\t"
|
||||||
|
|
||||||
|
key Return-Shift-NewLine : "\r"
|
||||||
|
key Return-Shift+NewLine : "\r\n"
|
||||||
|
|
||||||
|
key Return+Shift : "\EOM"
|
||||||
|
|
||||||
|
# Backspace and Delete codes are preserving CTRL-H.
|
||||||
|
|
||||||
|
key Backspace : "\x7f"
|
||||||
|
|
||||||
|
# Arrow keys in VT52 mode
|
||||||
|
# shift up/down are reserved for scrolling.
|
||||||
|
# shift left/right are reserved for switching between tabs (this is hardcoded).
|
||||||
|
|
||||||
|
|
||||||
|
# Command + C
|
||||||
|
# on mac - Control=Command, Meta=Ctrl
|
||||||
|
# do not use Control+C for interrupt signal - it's used for "Copy to clipboard"
|
||||||
|
#key Control +C : "\x03"
|
||||||
|
key Meta +C: "\x03"
|
||||||
|
|
||||||
|
|
||||||
|
# Arrow keys in ANSI mode with Application - and Normal Cursor Mode)
|
||||||
|
|
||||||
|
key Up -Shift+Ansi-AppCuKeys : "\E[A"
|
||||||
|
key Down -Shift+Ansi-AppCuKeys : "\E[B"
|
||||||
|
key Right-Shift+Ansi-AppCuKeys : "\E[C"
|
||||||
|
key Left -Shift+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
key Up -Ansi : "\E[1;*A"
|
||||||
|
key Down -Ansi : "\E[1;*B"
|
||||||
|
key Right -Ansi : "\E[1;*C"
|
||||||
|
key Left -Ansi : "\E[1;*D"
|
||||||
|
|
||||||
|
#key Up -Shift-Ansi : "\EA"
|
||||||
|
#key Down -Shift-Ansi : "\EB"
|
||||||
|
#key Right-Shift-Ansi : "\EC"
|
||||||
|
#key Left -Shift-Ansi : "\ED"
|
||||||
|
|
||||||
|
#key Up -Shift-AnyMod+Ansi-AppCuKeys : "\E[A"
|
||||||
|
#key Down -Shift-AnyMod+Ansi-AppCuKeys : "\E[B"
|
||||||
|
#key Right -Shift-AnyMod+Ansi-AppCuKeys : "\E[C"
|
||||||
|
#key Left -Shift-AnyMod+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
#key Up -Shift-AnyMod+Ansi-AppCuKeys : "\EOA"
|
||||||
|
#key Down -Shift-AnyMod+Ansi-AppCuKeys : "\EOB"
|
||||||
|
#key Right -Shift-AnyMod+Ansi-AppCuKeys : "\EOC"
|
||||||
|
#key Left -Shift-AnyMod+Ansi-AppCuKeys : "\EOD"
|
||||||
|
|
||||||
|
#key Up -Shift-AnyMod+Ansi : "\E[1;*A"
|
||||||
|
#key Down -Shift-AnyMod+Ansi : "\E[1;*B"
|
||||||
|
#key Right -Shift-AnyMod+Ansi : "\E[1;*C"
|
||||||
|
#key Left -Shift-AnyMod+Ansi : "\E[1;*D"
|
||||||
|
|
||||||
|
# other grey PC keys
|
||||||
|
|
||||||
|
key Enter+NewLine : "\r\n"
|
||||||
|
key Enter-NewLine : "\r"
|
||||||
|
|
||||||
|
key Home -AnyMod -AppCuKeys : "\E[H"
|
||||||
|
key End -AnyMod -AppCuKeys : "\E[F"
|
||||||
|
key Home -AnyMod +AppCuKeys : "\EOH"
|
||||||
|
key End -AnyMod +AppCuKeys : "\EOF"
|
||||||
|
key Home +AnyMod : "\E[1;*H"
|
||||||
|
key End +AnyMod : "\E[1;*F"
|
||||||
|
|
||||||
|
key Insert -AnyMod : "\E[2~"
|
||||||
|
key Delete -AnyMod : "\E[3~"
|
||||||
|
key Insert +AnyMod : "\E[2;*~"
|
||||||
|
key Delete +AnyMod : "\E[3;*~"
|
||||||
|
|
||||||
|
key Prior -Shift-AnyMod : "\E[5~"
|
||||||
|
key Next -Shift-AnyMod : "\E[6~"
|
||||||
|
key Prior -Shift+AnyMod : "\E[5;*~"
|
||||||
|
key Next -Shift+AnyMod : "\E[6;*~"
|
||||||
|
|
||||||
|
# Function keys
|
||||||
|
#key F1 -AnyMod : "\EOP"
|
||||||
|
#key F2 -AnyMod : "\EOQ"
|
||||||
|
#key F3 -AnyMod : "\EOR"
|
||||||
|
#key F4 -AnyMod : "\EOS"
|
||||||
|
#define ALT_KP_0 "\033Op"
|
||||||
|
#define ALT_KP_1 "\033Oq"
|
||||||
|
#define ALT_KP_2 "\033Or"
|
||||||
|
#define ALT_KP_3 "\033Os"
|
||||||
|
#define ALT_KP_4 "\033Ot"
|
||||||
|
#define ALT_KP_5 "\033Ou"
|
||||||
|
#define ALT_KP_6 "\033Ov"
|
||||||
|
#define ALT_KP_7 "\033Ow"
|
||||||
|
#define ALT_KP_8 "\033Ox"
|
||||||
|
#define ALT_KP_9 "\033Oy"
|
||||||
|
|
||||||
|
key F1 -AnyMod : "\EOP"
|
||||||
|
key F2 -AnyMod : "\EOQ"
|
||||||
|
key F3 -AnyMod : "\EOR"
|
||||||
|
key F4 -AnyMod : "\EOS"
|
||||||
|
key F5 -AnyMod : "\EOT"
|
||||||
|
key F6 -AnyMod : "\EOU"
|
||||||
|
key F7 -AnyMod : "\EOV"
|
||||||
|
key F8 -AnyMod : "\EOW"
|
||||||
|
key F9 -AnyMod : "\EOX"
|
||||||
|
key F10 -AnyMod : "\EOY"
|
||||||
|
|
||||||
|
#key F5 -AnyMod : "\E[15~"
|
||||||
|
#key F6 -AnyMod : "\E[17~"
|
||||||
|
#key F7 -AnyMod : "\E[18~"
|
||||||
|
#key F8 -AnyMod : "\E[19~"
|
||||||
|
#key F9 -AnyMod : "\E[20~"
|
||||||
|
#key F10 -AnyMod : "\E[21~"
|
||||||
|
#key F11 -AnyMod : "\E[23~"
|
||||||
|
#key F12 -AnyMod : "\E[24~"
|
||||||
|
|
||||||
|
#key F1 +AnyMod : "\EO*P"
|
||||||
|
#key F2 +AnyMod : "\EO*Q"
|
||||||
|
#key F3 +AnyMod : "\EO*R"
|
||||||
|
#key F4 +AnyMod : "\EO*S"
|
||||||
|
#key F5 +AnyMod : "\E[15;*~"
|
||||||
|
#key F6 +AnyMod : "\E[17;*~"
|
||||||
|
#key F7 +AnyMod : "\E[18;*~"
|
||||||
|
#key F8 +AnyMod : "\E[19;*~"
|
||||||
|
#key F9 +AnyMod : "\E[20;*~"
|
||||||
|
#key F10 +AnyMod : "\E[21;*~"
|
||||||
|
#key F11 +AnyMod : "\E[23;*~"
|
||||||
|
#key F12 +AnyMod : "\E[24;*~"
|
||||||
|
|
||||||
|
# Work around dead keys
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# Some keys are used by konsole to cause operations.
|
||||||
|
# The scroll* operations refer to the history buffer.
|
||||||
|
|
||||||
|
key Up +Shift-AppScreen : scrollLineUp
|
||||||
|
key Prior +Shift-AppScreen : scrollPageUp
|
||||||
|
key Down +Shift-AppScreen : scrollLineDown
|
||||||
|
key Next +Shift-AppScreen : scrollPageDown
|
||||||
|
|
||||||
|
#key Up +Shift : scrollLineUp
|
||||||
|
#key Prior +Shift : scrollPageUp
|
||||||
|
#key Down +Shift : scrollLineDown
|
||||||
|
#key Next +Shift : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
||||||
|
# keypad characters are not offered differently by Qt.
|
@ -0,0 +1,108 @@
|
|||||||
|
# [solaris.keytab] Konsole Keyboard Table
|
||||||
|
#
|
||||||
|
|
||||||
|
keyboard "Solaris console"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This configuration table allows to customize the
|
||||||
|
# meaning of the keys.
|
||||||
|
#
|
||||||
|
# The syntax is that each entry has the form :
|
||||||
|
#
|
||||||
|
# "key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
|
||||||
|
#
|
||||||
|
# Keynames are those defined in <qnamespace.h> with the
|
||||||
|
# "Qt::Key_" removed. (We'd better insert the list here)
|
||||||
|
#
|
||||||
|
# Mode names are :
|
||||||
|
#
|
||||||
|
# - Shift
|
||||||
|
# - Alt
|
||||||
|
# - Control
|
||||||
|
#
|
||||||
|
# The VT100 emulation has two modes that can affect the
|
||||||
|
# sequences emitted by certain keys. These modes are
|
||||||
|
# under control of the client program.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# - Newline : effects Return and Enter key.
|
||||||
|
# - Application : effects Up and Down key.
|
||||||
|
#
|
||||||
|
# - Ansi : effects Up and Down key (This is for VT52, really).
|
||||||
|
#
|
||||||
|
# Operations are
|
||||||
|
#
|
||||||
|
# - scrollUpLine
|
||||||
|
# - scrollUpPage
|
||||||
|
# - scrollDownLine
|
||||||
|
# - scrollDownPage
|
||||||
|
#
|
||||||
|
# - emitSelection
|
||||||
|
#
|
||||||
|
# If the key is not found here, the text of the
|
||||||
|
# key event as provided by QT is emitted, possibly
|
||||||
|
# preceeded by ESC if the Alt key is pressed.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
key Tab : "\t"
|
||||||
|
|
||||||
|
key Return-Alt : "\r"
|
||||||
|
key Return+Alt : "\E\r"
|
||||||
|
|
||||||
|
# Backspace and Delete codes are preserving CTRL-H.
|
||||||
|
|
||||||
|
key Backspace : "\x08"
|
||||||
|
#key Delete : "\x7F"
|
||||||
|
|
||||||
|
# cursor keys
|
||||||
|
|
||||||
|
key Up -Shift : "\EOA"
|
||||||
|
key Down -Shift : "\EOB"
|
||||||
|
key Right -Shift : "\EOC"
|
||||||
|
key Left -Shift : "\EOD"
|
||||||
|
|
||||||
|
# other grey PC keys
|
||||||
|
|
||||||
|
key Enter : "\r"
|
||||||
|
|
||||||
|
key Home : "\E[1~"
|
||||||
|
key Insert-Shift : "\E[2~"
|
||||||
|
key Delete : "\E[3~"
|
||||||
|
key End : "\E[4~"
|
||||||
|
key Prior -Shift : "\E[5~"
|
||||||
|
key Next -Shift : "\E[6~"
|
||||||
|
|
||||||
|
# function keys
|
||||||
|
|
||||||
|
key F1 : "\E[11~"
|
||||||
|
key F2 : "\E[12~"
|
||||||
|
key F3 : "\E[13~"
|
||||||
|
key F4 : "\E[14~"
|
||||||
|
key F5 : "\E[15~"
|
||||||
|
key F6 : "\E[17~"
|
||||||
|
key F7 : "\E[18~"
|
||||||
|
key F8 : "\E[19~"
|
||||||
|
key F9 : "\E[20~"
|
||||||
|
key F10 : "\E[21~"
|
||||||
|
key F11 : "\E[23~"
|
||||||
|
key F12 : "\E[24~"
|
||||||
|
|
||||||
|
# Work around dead keys
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# Some keys are used by konsole to cause operations.
|
||||||
|
# The scroll* operations refer to the history buffer.
|
||||||
|
|
||||||
|
#key Left +Shift : prevSession
|
||||||
|
#key Right +Shift : nextSession
|
||||||
|
key Up +Shift : scrollLineUp
|
||||||
|
key Prior +Shift : scrollPageUp
|
||||||
|
key Down +Shift : scrollLineDown
|
||||||
|
key Next +Shift : scrollPageDown
|
||||||
|
#key Insert+Shift : emitSelection
|
||||||
|
|
||||||
|
# keypad characters are not offered differently by Qt.
|
@ -0,0 +1,168 @@
|
|||||||
|
#
|
||||||
|
# NOTE: This keyboard binding is not installed because it
|
||||||
|
# apparently doesn't work with actual VT420 systems
|
||||||
|
# (see BUG:170220)
|
||||||
|
#
|
||||||
|
# [vt420pc.keytab] Konsole Keyboard Table (VT420pc keys)
|
||||||
|
# adapted by ferdinand gassauer f.gassauer@aon.at
|
||||||
|
# Nov 2000
|
||||||
|
#
|
||||||
|
################################################################
|
||||||
|
#
|
||||||
|
# The escape sequences emmited by the
|
||||||
|
# keys Shift+F1 to Shift+F12 might not fit your needs
|
||||||
|
#
|
||||||
|
################# IMPORTANT NOTICE #############################
|
||||||
|
# the key bindings (Kcontrol -> look and feel -> keybindgs)
|
||||||
|
# overrule the settings in this file. The key bindings might be
|
||||||
|
# changed by the user WITHOUT notification of the maintainer of
|
||||||
|
# the keytab file. Konsole will not work as expected by
|
||||||
|
# the maintainer of the keytab file.
|
||||||
|
################################################################
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
keyboard "DEC VT420 Terminal"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This configuration table allows to customize the
|
||||||
|
# meaning of the keys.
|
||||||
|
#
|
||||||
|
# The syntax is that each entry has the form :
|
||||||
|
#
|
||||||
|
# "key" Keyname { ("+"|"-") Modename } ":" (String|Operation)
|
||||||
|
#
|
||||||
|
# Keynames are those defined in <qnamespace.h> with the
|
||||||
|
# "Qt::Key_" removed. (We'd better insert the list here)
|
||||||
|
#
|
||||||
|
# Mode names are :
|
||||||
|
#
|
||||||
|
# - Shift
|
||||||
|
# - Alt
|
||||||
|
# - Control
|
||||||
|
#
|
||||||
|
# The VT100 emulation has two modes that can affect the
|
||||||
|
# sequences emitted by certain keys. These modes are
|
||||||
|
# under control of the client program.
|
||||||
|
#
|
||||||
|
# - Newline : effects Return and Enter key.
|
||||||
|
# - Application : effects Up and Down key.
|
||||||
|
#
|
||||||
|
# - Ansi : effects Up and Down key (This is for VT52, really).
|
||||||
|
#
|
||||||
|
# Operations are
|
||||||
|
#
|
||||||
|
# - scrollUpLine
|
||||||
|
# - scrollUpPage
|
||||||
|
# - scrollDownLine
|
||||||
|
# - scrollDownPage
|
||||||
|
#
|
||||||
|
# - emitSelection
|
||||||
|
#
|
||||||
|
# If the key is not found here, the text of the
|
||||||
|
# key event as provided by QT is emitted, possibly
|
||||||
|
# preceeded by ESC if the Alt key is pressed.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
|
||||||
|
key Escape : "\E"
|
||||||
|
key Tab : "\t"
|
||||||
|
key Backtab: "\E[Z"
|
||||||
|
|
||||||
|
# VT100 can add an extra \n after return.
|
||||||
|
# The NewLine mode is set by an escape sequence.
|
||||||
|
|
||||||
|
key Return-NewLine : "\r"
|
||||||
|
key Return+NewLine : "\r\n"
|
||||||
|
|
||||||
|
# Some desperately try to save the ^H.
|
||||||
|
# may be not everyone wants this
|
||||||
|
|
||||||
|
key Backspace : "\x08" # Control H
|
||||||
|
key Delete : "\x7f"
|
||||||
|
|
||||||
|
# These codes are for the VT420pc
|
||||||
|
# The Ansi mode (i.e. VT100 mode) is set by
|
||||||
|
# an escape sequence
|
||||||
|
|
||||||
|
key Up -Shift-Ansi : "\EA"
|
||||||
|
key Down -Shift-Ansi : "\EB"
|
||||||
|
key Right-Shift-Ansi : "\EC"
|
||||||
|
key Left -Shift-Ansi : "\ED"
|
||||||
|
|
||||||
|
# VT100 emits a mode bit together
|
||||||
|
# with the arrow keys.The AppCuKeys
|
||||||
|
# mode is set by an escape sequence.
|
||||||
|
|
||||||
|
key Up -Shift+Ansi+AppCuKeys : "\EOA"
|
||||||
|
key Down -Shift+Ansi+AppCuKeys : "\EOB"
|
||||||
|
key Right-Shift+Ansi+AppCuKeys : "\EOC"
|
||||||
|
key Left -Shift+Ansi+AppCuKeys : "\EOD"
|
||||||
|
|
||||||
|
key Up -Shift+Ansi-AppCuKeys : "\E[A"
|
||||||
|
key Down -Shift+Ansi-AppCuKeys : "\E[B"
|
||||||
|
key Right-Shift+Ansi-AppCuKeys : "\E[C"
|
||||||
|
key Left -Shift+Ansi-AppCuKeys : "\E[D"
|
||||||
|
|
||||||
|
# function keys
|
||||||
|
|
||||||
|
key F1 -Shift : "\E[11~"
|
||||||
|
key F2 -Shift : "\E[12~"
|
||||||
|
key F3 -Shift : "\E[13~"
|
||||||
|
key F4 -Shift : "\E[14~"
|
||||||
|
key F5 -Shift : "\E[15~"
|
||||||
|
key F6 -Shift : "\E[17~"
|
||||||
|
key F7 -Shift : "\E[18~"
|
||||||
|
key F8 -Shift : "\E[19~"
|
||||||
|
key F9 -Shift : "\E[20~"
|
||||||
|
key F10-Shift : "\E[21~"
|
||||||
|
key F11-Shift : "\E[23~"
|
||||||
|
key F12-Shift : "\E[24~"
|
||||||
|
#
|
||||||
|
# Shift F1-F12
|
||||||
|
#
|
||||||
|
key F1 +Shift : "\E[11;2~"
|
||||||
|
key F2 +Shift : "\E[12;2~"
|
||||||
|
key F3 +Shift : "\E[13;2~"
|
||||||
|
key F4 +Shift : "\E[14;2~"
|
||||||
|
key F5 +Shift : "\E[15;2~"
|
||||||
|
key F6 +Shift : "\E[17;2~"
|
||||||
|
key F7 +Shift : "\E[18;2~"
|
||||||
|
key F8 +Shift : "\E[19;2~"
|
||||||
|
key F9 +Shift : "\E[20;2~"
|
||||||
|
key F10+Shift : "\E[21;2~"
|
||||||
|
key F11+Shift : "\E[23;2~"
|
||||||
|
key F12+Shift : "\E[24;2~"
|
||||||
|
|
||||||
|
key Home : "\E[H"
|
||||||
|
key End : "\E[F"
|
||||||
|
|
||||||
|
key Prior -Shift : "\E[5~"
|
||||||
|
key Next -Shift : "\E[6~"
|
||||||
|
key Insert-Shift : "\E[2~"
|
||||||
|
|
||||||
|
# Keypad-Enter. See comment on Return above.
|
||||||
|
|
||||||
|
key Enter+NewLine : "\r\n"
|
||||||
|
key Enter-NewLine : "\r"
|
||||||
|
|
||||||
|
key Space +Control : "\x00"
|
||||||
|
|
||||||
|
# some of keys are used by konsole.
|
||||||
|
|
||||||
|
key Up +Shift : scrollLineUp
|
||||||
|
key Prior +Shift : scrollPageUp
|
||||||
|
key Down +Shift : scrollLineDown
|
||||||
|
key Next +Shift : scrollPageDown
|
||||||
|
|
||||||
|
key ScrollLock : scrollLock
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
# keypad characters as offered by Qt
|
||||||
|
# cannot be recognized as such.
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
|
||||||
|
# Following other strings as emitted by konsole.
|
@ -0,0 +1,226 @@
|
|||||||
|
/* $XFree86: xc/programs/xterm/wcwidth.character,v 1.3 2001/07/29 22:08:16 tsi Exp $ */
|
||||||
|
/*
|
||||||
|
* This is an implementation of wcwidth() and wcswidth() as defined in
|
||||||
|
* "The Single UNIX Specification, Version 2, The Open Group, 1997"
|
||||||
|
* <http://www.UNIX-systems.org/online.html>
|
||||||
|
*
|
||||||
|
* Markus Kuhn -- 2001-01-12 -- public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "konsole_wcwidth.h"
|
||||||
|
|
||||||
|
struct interval {
|
||||||
|
unsigned short first;
|
||||||
|
unsigned short last;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* auxiliary function for binary search in interval table */
|
||||||
|
static int bisearch(quint16 ucs, const struct interval * table, int max)
|
||||||
|
{
|
||||||
|
int min = 0;
|
||||||
|
int mid;
|
||||||
|
|
||||||
|
if (ucs < table[0].first || ucs > table[max].last) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (max >= min) {
|
||||||
|
mid = (min + max) / 2;
|
||||||
|
if (ucs > table[mid].last) {
|
||||||
|
min = mid + 1;
|
||||||
|
} else if (ucs < table[mid].first) {
|
||||||
|
max = mid - 1;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The following functions define the column width of an ISO 10646
|
||||||
|
* character as follows:
|
||||||
|
*
|
||||||
|
* - The null character (U+0000) has a column width of 0.
|
||||||
|
*
|
||||||
|
* - Other C0/C1 control characters and DEL will lead to a return
|
||||||
|
* value of -1.
|
||||||
|
*
|
||||||
|
* - Non-spacing and enclosing combining characters (general
|
||||||
|
* category code Mn or Me in the Unicode database) have a
|
||||||
|
* column width of 0.
|
||||||
|
*
|
||||||
|
* - Other format characters (general category code Cf in the Unicode
|
||||||
|
* database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
|
||||||
|
*
|
||||||
|
* - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
|
||||||
|
* have a column width of 0.
|
||||||
|
*
|
||||||
|
* - Spacing characters in the East Asian Wide (W) or East Asian
|
||||||
|
* FullWidth (F) category as defined in Unicode Technical
|
||||||
|
* Report #11 have a column width of 2.
|
||||||
|
*
|
||||||
|
* - All remaining characters (including all printable
|
||||||
|
* ISO 8859-1 and WGL4 characters, Unicode control characters,
|
||||||
|
* etc.) have a column width of 1.
|
||||||
|
*
|
||||||
|
* This implementation assumes that quint16 characters are encoded
|
||||||
|
* in ISO 10646.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int konsole_wcwidth(quint16 ucs)
|
||||||
|
{
|
||||||
|
/* sorted list of non-overlapping intervals of non-spacing characters */
|
||||||
|
static const struct interval combining[] = {
|
||||||
|
{ 0x0300, 0x034E }, { 0x0360, 0x0362 }, { 0x0483, 0x0486 },
|
||||||
|
{ 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
|
||||||
|
{ 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
|
||||||
|
{ 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
|
||||||
|
{ 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
|
||||||
|
{ 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
|
||||||
|
{ 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C },
|
||||||
|
{ 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 },
|
||||||
|
{ 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
|
||||||
|
{ 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
|
||||||
|
{ 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
|
||||||
|
{ 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 },
|
||||||
|
{ 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 },
|
||||||
|
{ 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 },
|
||||||
|
{ 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 },
|
||||||
|
{ 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 },
|
||||||
|
{ 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 },
|
||||||
|
{ 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 },
|
||||||
|
{ 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
|
||||||
|
{ 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA },
|
||||||
|
{ 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 },
|
||||||
|
{ 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 },
|
||||||
|
{ 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD },
|
||||||
|
{ 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 },
|
||||||
|
{ 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 },
|
||||||
|
{ 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC },
|
||||||
|
{ 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 },
|
||||||
|
{ 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 },
|
||||||
|
{ 0x1160, 0x11FF }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 },
|
||||||
|
{ 0x17C9, 0x17D3 }, { 0x180B, 0x180E }, { 0x18A9, 0x18A9 },
|
||||||
|
{ 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x206A, 0x206F },
|
||||||
|
{ 0x20D0, 0x20E3 }, { 0x302A, 0x302F }, { 0x3099, 0x309A },
|
||||||
|
{ 0xFB1E, 0xFB1E }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF },
|
||||||
|
{ 0xFFF9, 0xFFFB }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* test for 8-bit control characters */
|
||||||
|
if (ucs == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* binary search in table of non-spacing characters */
|
||||||
|
if (bisearch(ucs, combining,
|
||||||
|
sizeof(combining) / sizeof(struct interval) - 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we arrive here, ucs is not a combining or C0/C1 control character */
|
||||||
|
|
||||||
|
return 1 +
|
||||||
|
(ucs >= 0x1100 &&
|
||||||
|
(ucs <= 0x115f || /* Hangul Jamo init. consonants */
|
||||||
|
(ucs >= 0x2e80 && ucs <= 0xa4cf && (ucs & ~0x0011) != 0x300a &&
|
||||||
|
ucs != 0x303f) || /* CJK ... Yi */
|
||||||
|
(ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
|
||||||
|
(ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
|
||||||
|
(ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
|
||||||
|
(ucs >= 0xff00 && ucs <= 0xff5f) || /* Fullwidth Forms */
|
||||||
|
(ucs >= 0xffe0 && ucs <= 0xffe6) /* do not compare UINT16 with 0x20000 ||
|
||||||
|
(ucs >= 0x20000 && ucs <= 0x2ffff) */));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
* The following function is the same as konsole_wcwidth(), except that
|
||||||
|
* spacing characters in the East Asian Ambiguous (A) category as
|
||||||
|
* defined in Unicode Technical Report #11 have a column width of 2.
|
||||||
|
* This experimental variant might be useful for users of CJK legacy
|
||||||
|
* encodings who want to migrate to UCS. It is not otherwise
|
||||||
|
* recommended for general use.
|
||||||
|
*/
|
||||||
|
int konsole_wcwidth_cjk(quint16 ucs)
|
||||||
|
{
|
||||||
|
/* sorted list of non-overlapping intervals of East Asian Ambiguous
|
||||||
|
* characters */
|
||||||
|
static const struct interval ambiguous[] = {
|
||||||
|
{ 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
|
||||||
|
{ 0x00AA, 0x00AA }, { 0x00AD, 0x00AD }, { 0x00B0, 0x00B4 },
|
||||||
|
{ 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
|
||||||
|
{ 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
|
||||||
|
{ 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
|
||||||
|
{ 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
|
||||||
|
{ 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
|
||||||
|
{ 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
|
||||||
|
{ 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
|
||||||
|
{ 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
|
||||||
|
{ 0x0148, 0x014A }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
|
||||||
|
{ 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
|
||||||
|
{ 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
|
||||||
|
{ 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
|
||||||
|
{ 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
|
||||||
|
{ 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB }, { 0x02CD, 0x02CD },
|
||||||
|
{ 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB }, { 0x02DD, 0x02DD },
|
||||||
|
{ 0x0391, 0x03A1 }, { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 },
|
||||||
|
{ 0x03C3, 0x03C9 }, { 0x0401, 0x0401 }, { 0x0410, 0x044F },
|
||||||
|
{ 0x0451, 0x0451 }, { 0x2010, 0x2010 }, { 0x2013, 0x2016 },
|
||||||
|
{ 0x2018, 0x2019 }, { 0x201C, 0x201D }, { 0x2020, 0x2021 },
|
||||||
|
{ 0x2025, 0x2027 }, { 0x2030, 0x2030 }, { 0x2032, 0x2033 },
|
||||||
|
{ 0x2035, 0x2035 }, { 0x203B, 0x203B }, { 0x2074, 0x2074 },
|
||||||
|
{ 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
|
||||||
|
{ 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
|
||||||
|
{ 0x2113, 0x2113 }, { 0x2121, 0x2122 }, { 0x2126, 0x2126 },
|
||||||
|
{ 0x212B, 0x212B }, { 0x2154, 0x2155 }, { 0x215B, 0x215B },
|
||||||
|
{ 0x215E, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
|
||||||
|
{ 0x2190, 0x2199 }, { 0x21D2, 0x21D2 }, { 0x21D4, 0x21D4 },
|
||||||
|
{ 0x2200, 0x2200 }, { 0x2202, 0x2203 }, { 0x2207, 0x2208 },
|
||||||
|
{ 0x220B, 0x220B }, { 0x220F, 0x220F }, { 0x2211, 0x2211 },
|
||||||
|
{ 0x2215, 0x2215 }, { 0x221A, 0x221A }, { 0x221D, 0x2220 },
|
||||||
|
{ 0x2223, 0x2223 }, { 0x2225, 0x2225 }, { 0x2227, 0x222C },
|
||||||
|
{ 0x222E, 0x222E }, { 0x2234, 0x2237 }, { 0x223C, 0x223D },
|
||||||
|
{ 0x2248, 0x2248 }, { 0x224C, 0x224C }, { 0x2252, 0x2252 },
|
||||||
|
{ 0x2260, 0x2261 }, { 0x2264, 0x2267 }, { 0x226A, 0x226B },
|
||||||
|
{ 0x226E, 0x226F }, { 0x2282, 0x2283 }, { 0x2286, 0x2287 },
|
||||||
|
{ 0x2295, 0x2295 }, { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 },
|
||||||
|
{ 0x22BF, 0x22BF }, { 0x2312, 0x2312 }, { 0x2460, 0x24BF },
|
||||||
|
{ 0x24D0, 0x24E9 }, { 0x2500, 0x254B }, { 0x2550, 0x2574 },
|
||||||
|
{ 0x2580, 0x258F }, { 0x2592, 0x2595 }, { 0x25A0, 0x25A1 },
|
||||||
|
{ 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 }, { 0x25B6, 0x25B7 },
|
||||||
|
{ 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 }, { 0x25C6, 0x25C8 },
|
||||||
|
{ 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 }, { 0x25E2, 0x25E5 },
|
||||||
|
{ 0x25EF, 0x25EF }, { 0x2605, 0x2606 }, { 0x2609, 0x2609 },
|
||||||
|
{ 0x260E, 0x260F }, { 0x261C, 0x261C }, { 0x261E, 0x261E },
|
||||||
|
{ 0x2640, 0x2640 }, { 0x2642, 0x2642 }, { 0x2660, 0x2661 },
|
||||||
|
{ 0x2663, 0x2665 }, { 0x2667, 0x266A }, { 0x266C, 0x266D },
|
||||||
|
{ 0x266F, 0x266F }, { 0x300A, 0x300B }, { 0x301A, 0x301B },
|
||||||
|
{ 0xE000, 0xF8FF }, { 0xFFFD, 0xFFFD }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* binary search in table of non-spacing characters */
|
||||||
|
if (bisearch(ucs, ambiguous,
|
||||||
|
sizeof(ambiguous) / sizeof(struct interval) - 1)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return konsole_wcwidth(ucs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// single byte char: +1, multi byte char: +2
|
||||||
|
int string_width( const QString & txt )
|
||||||
|
{
|
||||||
|
int w = 0;
|
||||||
|
for ( int i = 0; i < txt.length(); ++i ) {
|
||||||
|
w += konsole_wcwidth( txt[ i ].unicode() );
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/* $XFree86: xc/programs/xterm/wcwidth.h,v 1.2 2001/06/18 19:09:27 dickey Exp $ */
|
||||||
|
|
||||||
|
/* Markus Kuhn -- 2001-01-12 -- public domain */
|
||||||
|
/* Adaptions for KDE by Waldo Bastian <bastian@kde.org> */
|
||||||
|
/*
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _KONSOLE_WCWIDTH_H_
|
||||||
|
#define _KONSOLE_WCWIDTH_H_
|
||||||
|
|
||||||
|
// Qt
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
int konsole_wcwidth(quint16 ucs);
|
||||||
|
#if 0
|
||||||
|
int konsole_wcwidth_cjk(Q_UINT16 ucs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int string_width( const QString & txt );
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,412 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of QTerminal - http://gitorious.org/qterminal
|
||||||
|
*
|
||||||
|
* This file was un-linked from KDE and modified
|
||||||
|
* by Maxim Bourmistrov <maxim@unixconn.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is part of the KDE libraries
|
||||||
|
|
||||||
|
Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kprocess.h"
|
||||||
|
|
||||||
|
#include <qfile.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
# include <windows.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
# include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef Q_OS_WIN
|
||||||
|
# define STD_OUTPUT_HANDLE 1
|
||||||
|
# define STD_ERROR_HANDLE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void KProcessPrivate::writeAll(const QByteArray &buf, int fd)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
HANDLE h = GetStdHandle(fd);
|
||||||
|
if (h) {
|
||||||
|
DWORD wr;
|
||||||
|
WriteFile(h, buf.data(), buf.size(), &wr, 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fwrite(buf.data(), 1, buf.size(), (FILE*)fd);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
int off = 0;
|
||||||
|
do {
|
||||||
|
int ret = ::write(fd, buf.data() + off, buf.size() - off);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (errno != EINTR)
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
off += ret;
|
||||||
|
}
|
||||||
|
} while (off < buf.size());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcessPrivate::forwardStd(KProcess::ProcessChannel good, int fd)
|
||||||
|
{
|
||||||
|
Q_Q(KProcess);
|
||||||
|
|
||||||
|
QProcess::ProcessChannel oc = q->readChannel();
|
||||||
|
q->setReadChannel(good);
|
||||||
|
writeAll(q->readAll(), fd);
|
||||||
|
q->setReadChannel(oc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcessPrivate::_k_forwardStdout()
|
||||||
|
{
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
forwardStd(KProcess::StandardOutput, STD_OUTPUT_HANDLE);
|
||||||
|
#else
|
||||||
|
forwardStd(KProcess::StandardOutput, (int)stdout);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcessPrivate::_k_forwardStderr()
|
||||||
|
{
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
forwardStd(KProcess::StandardError, STD_ERROR_HANDLE);
|
||||||
|
#else
|
||||||
|
forwardStd(KProcess::StandardError, (int)stderr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// public member functions //
|
||||||
|
/////////////////////////////
|
||||||
|
|
||||||
|
KProcess::KProcess(QObject *parent) :
|
||||||
|
QProcess(parent),
|
||||||
|
d_ptr(new KProcessPrivate)
|
||||||
|
{
|
||||||
|
d_ptr->q_ptr = this;
|
||||||
|
setOutputChannelMode(ForwardedChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
KProcess::KProcess(KProcessPrivate *d, QObject *parent) :
|
||||||
|
QProcess(parent),
|
||||||
|
d_ptr(d)
|
||||||
|
{
|
||||||
|
d_ptr->q_ptr = this;
|
||||||
|
setOutputChannelMode(ForwardedChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
KProcess::~KProcess()
|
||||||
|
{
|
||||||
|
delete d_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::setOutputChannelMode(OutputChannelMode mode)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
d->outputChannelMode = mode;
|
||||||
|
disconnect(this, SIGNAL(readyReadStandardOutput()));
|
||||||
|
disconnect(this, SIGNAL(readyReadStandardError()));
|
||||||
|
switch (mode) {
|
||||||
|
case OnlyStdoutChannel:
|
||||||
|
connect(this, SIGNAL(readyReadStandardError()), SLOT(_k_forwardStderr()));
|
||||||
|
break;
|
||||||
|
case OnlyStderrChannel:
|
||||||
|
connect(this, SIGNAL(readyReadStandardOutput()), SLOT(_k_forwardStdout()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QProcess::setProcessChannelMode((ProcessChannelMode)mode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QProcess::setProcessChannelMode(QProcess::SeparateChannels);
|
||||||
|
}
|
||||||
|
|
||||||
|
KProcess::OutputChannelMode KProcess::outputChannelMode() const
|
||||||
|
{
|
||||||
|
Q_D(const KProcess);
|
||||||
|
|
||||||
|
return d->outputChannelMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::setNextOpenMode(QIODevice::OpenMode mode)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
d->openMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DUMMYENV "_KPROCESS_DUMMY_="
|
||||||
|
|
||||||
|
void KProcess::clearEnvironment()
|
||||||
|
{
|
||||||
|
setEnvironment(QStringList() << QString::fromLatin1(DUMMYENV));
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::setEnv(const QString &name, const QString &value, bool overwrite)
|
||||||
|
{
|
||||||
|
QStringList env = environment();
|
||||||
|
if (env.isEmpty()) {
|
||||||
|
env = systemEnvironment();
|
||||||
|
env.removeAll(QString::fromLatin1(DUMMYENV));
|
||||||
|
}
|
||||||
|
QString fname(name);
|
||||||
|
fname.append(QLatin1Char('='));
|
||||||
|
for (QStringList::Iterator it = env.begin(); it != env.end(); ++it)
|
||||||
|
if ((*it).startsWith(fname)) {
|
||||||
|
if (overwrite) {
|
||||||
|
*it = fname.append(value);
|
||||||
|
setEnvironment(env);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
env.append(fname.append(value));
|
||||||
|
setEnvironment(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::unsetEnv(const QString &name)
|
||||||
|
{
|
||||||
|
QStringList env = environment();
|
||||||
|
if (env.isEmpty()) {
|
||||||
|
env = systemEnvironment();
|
||||||
|
env.removeAll(QString::fromLatin1(DUMMYENV));
|
||||||
|
}
|
||||||
|
QString fname(name);
|
||||||
|
fname.append(QLatin1Char('='));
|
||||||
|
for (QStringList::Iterator it = env.begin(); it != env.end(); ++it)
|
||||||
|
if ((*it).startsWith(fname)) {
|
||||||
|
env.erase(it);
|
||||||
|
if (env.isEmpty())
|
||||||
|
env.append(QString::fromLatin1(DUMMYENV));
|
||||||
|
setEnvironment(env);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::setProgram(const QString &exe, const QStringList &args)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
d->prog = exe;
|
||||||
|
d->args = args;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
setNativeArguments(QString());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::setProgram(const QStringList &argv)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
Q_ASSERT( !argv.isEmpty() );
|
||||||
|
d->args = argv;
|
||||||
|
d->prog = d->args.takeFirst();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
setNativeArguments(QString());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
KProcess &KProcess::operator<<(const QString &arg)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
if (d->prog.isEmpty())
|
||||||
|
d->prog = arg;
|
||||||
|
else
|
||||||
|
d->args << arg;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
KProcess &KProcess::operator<<(const QStringList &args)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
if (d->prog.isEmpty())
|
||||||
|
setProgram(args);
|
||||||
|
else
|
||||||
|
d->args << args;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::clearProgram()
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
d->prog.clear();
|
||||||
|
d->args.clear();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
setNativeArguments(QString());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void KProcess::setShellCommand(const QString &cmd)
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
KShell::Errors err;
|
||||||
|
d->args = KShell::splitArgs(
|
||||||
|
cmd, KShell::AbortOnMeta | KShell::TildeExpand, &err);
|
||||||
|
if (err == KShell::NoError && !d->args.isEmpty()) {
|
||||||
|
d->prog = KStandardDirs::findExe(d->args[0]);
|
||||||
|
if (!d->prog.isEmpty()) {
|
||||||
|
d->args.removeFirst();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
setNativeArguments(QString());
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d->args.clear();
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
// #ifdef NON_FREE // ... as they ship non-POSIX /bin/sh
|
||||||
|
# if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) && !defined(__GNU__)
|
||||||
|
// If /bin/sh is a symlink, we can be pretty sure that it points to a
|
||||||
|
// POSIX shell - the original bourne shell is about the only non-POSIX
|
||||||
|
// shell still in use and it is always installed natively as /bin/sh.
|
||||||
|
d->prog = QFile::symLinkTarget(QString::fromLatin1("/bin/sh"));
|
||||||
|
if (d->prog.isEmpty()) {
|
||||||
|
// Try some known POSIX shells.
|
||||||
|
d->prog = KStandardDirs::findExe(QString::fromLatin1("ksh"));
|
||||||
|
if (d->prog.isEmpty()) {
|
||||||
|
d->prog = KStandardDirs::findExe(QString::fromLatin1("ash"));
|
||||||
|
if (d->prog.isEmpty()) {
|
||||||
|
d->prog = KStandardDirs::findExe(QString::fromLatin1("bash"));
|
||||||
|
if (d->prog.isEmpty()) {
|
||||||
|
d->prog = KStandardDirs::findExe(QString::fromLatin1("zsh"));
|
||||||
|
if (d->prog.isEmpty())
|
||||||
|
// We're pretty much screwed, to be honest ...
|
||||||
|
d->prog = QString::fromLatin1("/bin/sh");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
d->prog = QString::fromLatin1("/bin/sh");
|
||||||
|
# endif
|
||||||
|
|
||||||
|
d->args << QString::fromLatin1("-c") << cmd;
|
||||||
|
#else // Q_OS_UNIX
|
||||||
|
// KMacroExpander::expandMacrosShellQuote(), KShell::quoteArg() and
|
||||||
|
// KShell::joinArgs() may generate these for security reasons.
|
||||||
|
setEnv(PERCENT_VARIABLE, QLatin1String("%"));
|
||||||
|
|
||||||
|
#ifndef _WIN32_WCE
|
||||||
|
WCHAR sysdir[MAX_PATH + 1];
|
||||||
|
UINT size = GetSystemDirectoryW(sysdir, MAX_PATH + 1);
|
||||||
|
d->prog = QString::fromUtf16((const ushort *) sysdir, size);
|
||||||
|
d->prog += QLatin1String("\\cmd.exe");
|
||||||
|
setNativeArguments(QLatin1String("/V:OFF /S /C \"") + cmd + QLatin1Char('"'));
|
||||||
|
#else
|
||||||
|
d->prog = QLatin1String("\\windows\\cmd.exe");
|
||||||
|
setNativeArguments(QLatin1String("/S /C \"") + cmd + QLatin1Char('"'));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
QStringList KProcess::program() const
|
||||||
|
{
|
||||||
|
Q_D(const KProcess);
|
||||||
|
|
||||||
|
QStringList argv = d->args;
|
||||||
|
argv.prepend(d->prog);
|
||||||
|
return argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::start()
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
QProcess::start(d->prog, d->args, d->openMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KProcess::execute(int msecs)
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
if (!waitForFinished(msecs)) {
|
||||||
|
kill();
|
||||||
|
waitForFinished(-1);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return (exitStatus() == QProcess::NormalExit) ? exitCode() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
int KProcess::execute(const QString &exe, const QStringList &args, int msecs)
|
||||||
|
{
|
||||||
|
KProcess p;
|
||||||
|
p.setProgram(exe, args);
|
||||||
|
return p.execute(msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
int KProcess::execute(const QStringList &argv, int msecs)
|
||||||
|
{
|
||||||
|
KProcess p;
|
||||||
|
p.setProgram(argv);
|
||||||
|
return p.execute(msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KProcess::startDetached()
|
||||||
|
{
|
||||||
|
Q_D(KProcess);
|
||||||
|
|
||||||
|
qint64 pid;
|
||||||
|
if (!QProcess::startDetached(d->prog, d->args, workingDirectory(), &pid))
|
||||||
|
return 0;
|
||||||
|
return (int) pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
int KProcess::startDetached(const QString &exe, const QStringList &args)
|
||||||
|
{
|
||||||
|
qint64 pid;
|
||||||
|
if (!QProcess::startDetached(exe, args, QString(), &pid))
|
||||||
|
return 0;
|
||||||
|
return (int) pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
int KProcess::startDetached(const QStringList &argv)
|
||||||
|
{
|
||||||
|
QStringList args = argv;
|
||||||
|
QString prog = args.takeFirst();
|
||||||
|
return startDetached(prog, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KProcess::pid() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
return (int) QProcess::pid();
|
||||||
|
#else
|
||||||
|
return QProcess::pid() ? QProcess::pid()->dwProcessId : 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,372 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of QTerminal - http://gitorious.org/qterminal
|
||||||
|
*
|
||||||
|
* This file was un-linked from KDE and modified
|
||||||
|
* by Maxim Bourmistrov <maxim@unixconn.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file is part of the KDE libraries
|
||||||
|
|
||||||
|
Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KPROCESS_H
|
||||||
|
#define KPROCESS_H
|
||||||
|
|
||||||
|
//#include <kdecore_export.h>
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
class KProcessPrivate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class KProcess kprocess.h <KProcess>
|
||||||
|
*
|
||||||
|
* Child process invocation, monitoring and control.
|
||||||
|
*
|
||||||
|
* This class extends QProcess by some useful functionality, overrides
|
||||||
|
* some defaults with saner values and wraps parts of the API into a more
|
||||||
|
* accessible one.
|
||||||
|
* This is the preferred way of spawning child processes in KDE; don't
|
||||||
|
* use QProcess directly.
|
||||||
|
*
|
||||||
|
* @author Oswald Buddenhagen <ossi@kde.org>
|
||||||
|
**/
|
||||||
|
class KProcess : public QProcess
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PRIVATE(KProcess)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modes in which the output channels can be opened.
|
||||||
|
*/
|
||||||
|
enum OutputChannelMode {
|
||||||
|
SeparateChannels = QProcess::SeparateChannels,
|
||||||
|
/**< Standard output and standard error are handled by KProcess
|
||||||
|
as separate channels */
|
||||||
|
MergedChannels = QProcess::MergedChannels,
|
||||||
|
/**< Standard output and standard error are handled by KProcess
|
||||||
|
as one channel */
|
||||||
|
ForwardedChannels = QProcess::ForwardedChannels,
|
||||||
|
/**< Both standard output and standard error are forwarded
|
||||||
|
to the parent process' respective channel */
|
||||||
|
OnlyStdoutChannel,
|
||||||
|
/**< Only standard output is handled; standard error is forwarded */
|
||||||
|
OnlyStderrChannel /**< Only standard error is handled; standard output is forwarded */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
explicit KProcess(QObject *parent = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~KProcess();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set how to handle the output channels of the child process.
|
||||||
|
*
|
||||||
|
* The default is ForwardedChannels, which is unlike in QProcess.
|
||||||
|
* Do not request more than you actually handle, as this output is
|
||||||
|
* simply lost otherwise.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process.
|
||||||
|
*
|
||||||
|
* @param mode the output channel handling mode
|
||||||
|
*/
|
||||||
|
void setOutputChannelMode(OutputChannelMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query how the output channels of the child process are handled.
|
||||||
|
*
|
||||||
|
* @return the output channel handling mode
|
||||||
|
*/
|
||||||
|
OutputChannelMode outputChannelMode() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the QIODevice open mode the process will be opened in.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process, obviously.
|
||||||
|
*
|
||||||
|
* @param mode the open mode. Note that this mode is automatically
|
||||||
|
* "reduced" according to the channel modes and redirections.
|
||||||
|
* The default is QIODevice::ReadWrite.
|
||||||
|
*/
|
||||||
|
void setNextOpenMode(QIODevice::OpenMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the variable @p name to the process' environment.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process.
|
||||||
|
*
|
||||||
|
* @param name the name of the environment variable
|
||||||
|
* @param value the new value for the environment variable
|
||||||
|
* @param overwrite if @c false and the environment variable is already
|
||||||
|
* set, the old value will be preserved
|
||||||
|
*/
|
||||||
|
void setEnv(const QString &name, const QString &value, bool overwrite = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the variable @p name from the process' environment.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process.
|
||||||
|
*
|
||||||
|
* @param name the name of the environment variable
|
||||||
|
*/
|
||||||
|
void unsetEnv(const QString &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empties the process' environment.
|
||||||
|
*
|
||||||
|
* Note that LD_LIBRARY_PATH/DYLD_LIBRARY_PATH is automatically added
|
||||||
|
* on *NIX.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process.
|
||||||
|
*/
|
||||||
|
void clearEnvironment();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the program and the command line arguments.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process, obviously.
|
||||||
|
*
|
||||||
|
* @param exe the program to execute
|
||||||
|
* @param args the command line arguments for the program,
|
||||||
|
* one per list element
|
||||||
|
*/
|
||||||
|
void setProgram(const QString &exe, const QStringList &args = QStringList());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*
|
||||||
|
* @param argv the program to execute and the command line arguments
|
||||||
|
* for the program, one per list element
|
||||||
|
*/
|
||||||
|
void setProgram(const QStringList &argv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append an element to the command line argument list for this process.
|
||||||
|
*
|
||||||
|
* If no executable is set yet, it will be set instead.
|
||||||
|
*
|
||||||
|
* For example, doing an "ls -l /usr/local/bin" can be achieved by:
|
||||||
|
* \code
|
||||||
|
* KProcess p;
|
||||||
|
* p << "ls" << "-l" << "/usr/local/bin";
|
||||||
|
* ...
|
||||||
|
* \endcode
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process, obviously.
|
||||||
|
*
|
||||||
|
* @param arg the argument to add
|
||||||
|
* @return a reference to this KProcess
|
||||||
|
*/
|
||||||
|
KProcess &operator<<(const QString& arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*
|
||||||
|
* @param args the arguments to add
|
||||||
|
* @return a reference to this KProcess
|
||||||
|
*/
|
||||||
|
KProcess &operator<<(const QStringList& args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the program and command line argument list.
|
||||||
|
*/
|
||||||
|
void clearProgram();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a command to execute through a shell (a POSIX sh on *NIX
|
||||||
|
* and cmd.exe on Windows).
|
||||||
|
*
|
||||||
|
* Using this for anything but user-supplied commands is usually a bad
|
||||||
|
* idea, as the command's syntax depends on the platform.
|
||||||
|
* Redirections including pipes, etc. are better handled by the
|
||||||
|
* respective functions provided by QProcess.
|
||||||
|
*
|
||||||
|
* If KProcess determines that the command does not really need a
|
||||||
|
* shell, it will trasparently execute it without one for performance
|
||||||
|
* reasons.
|
||||||
|
*
|
||||||
|
* This function must be called before starting the process, obviously.
|
||||||
|
*
|
||||||
|
* @param cmd the command to execute through a shell.
|
||||||
|
* The caller must make sure that all filenames etc. are properly
|
||||||
|
* quoted when passed as argument. Failure to do so often results in
|
||||||
|
* serious security holes. See KShell::quoteArg().
|
||||||
|
*/
|
||||||
|
void setShellCommand(const QString &cmd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the currently set program and arguments.
|
||||||
|
*
|
||||||
|
* @return a list, the first element being the program, the remaining ones
|
||||||
|
* being command line arguments to the program.
|
||||||
|
*/
|
||||||
|
QStringList program() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the process.
|
||||||
|
*
|
||||||
|
* @see QProcess::start(const QString &, const QStringList &, OpenMode)
|
||||||
|
*/
|
||||||
|
void start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the process, wait for it to finish, and return the exit code.
|
||||||
|
*
|
||||||
|
* This method is roughly equivalent to the sequence:
|
||||||
|
* <code>
|
||||||
|
* start();
|
||||||
|
* waitForFinished(msecs);
|
||||||
|
* return exitCode();
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* Unlike the other execute() variants this method is not static,
|
||||||
|
* so the process can be parametrized properly and talked to.
|
||||||
|
*
|
||||||
|
* @param msecs time to wait for process to exit before killing it
|
||||||
|
* @return -2 if the process could not be started, -1 if it crashed,
|
||||||
|
* otherwise its exit code
|
||||||
|
*/
|
||||||
|
int execute(int msecs = -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*
|
||||||
|
* @param exe the program to execute
|
||||||
|
* @param args the command line arguments for the program,
|
||||||
|
* one per list element
|
||||||
|
* @param msecs time to wait for process to exit before killing it
|
||||||
|
* @return -2 if the process could not be started, -1 if it crashed,
|
||||||
|
* otherwise its exit code
|
||||||
|
*/
|
||||||
|
static int execute(const QString &exe, const QStringList &args = QStringList(), int msecs = -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*
|
||||||
|
* @param argv the program to execute and the command line arguments
|
||||||
|
* for the program, one per list element
|
||||||
|
* @param msecs time to wait for process to exit before killing it
|
||||||
|
* @return -2 if the process could not be started, -1 if it crashed,
|
||||||
|
* otherwise its exit code
|
||||||
|
*/
|
||||||
|
static int execute(const QStringList &argv, int msecs = -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the process and detach from it. See QProcess::startDetached()
|
||||||
|
* for details.
|
||||||
|
*
|
||||||
|
* Unlike the other startDetached() variants this method is not static,
|
||||||
|
* so the process can be parametrized properly.
|
||||||
|
* @note Currently, only the setProgram()/setShellCommand() and
|
||||||
|
* setWorkingDirectory() parametrizations are supported.
|
||||||
|
*
|
||||||
|
* The KProcess object may be re-used immediately after calling this
|
||||||
|
* function.
|
||||||
|
*
|
||||||
|
* @return the PID of the started process or 0 on error
|
||||||
|
*/
|
||||||
|
int startDetached();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*
|
||||||
|
* @param exe the program to start
|
||||||
|
* @param args the command line arguments for the program,
|
||||||
|
* one per list element
|
||||||
|
* @return the PID of the started process or 0 on error
|
||||||
|
*/
|
||||||
|
static int startDetached(const QString &exe, const QStringList &args = QStringList());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
*
|
||||||
|
* @param argv the program to start and the command line arguments
|
||||||
|
* for the program, one per list element
|
||||||
|
* @return the PID of the started process or 0 on error
|
||||||
|
*/
|
||||||
|
static int startDetached(const QStringList &argv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the process' ID as known to the system.
|
||||||
|
*
|
||||||
|
* Unlike with QProcess::pid(), this is a real PID also on Windows.
|
||||||
|
*
|
||||||
|
* This function can be called only while the process is running.
|
||||||
|
* It cannot be applied to detached processes.
|
||||||
|
*
|
||||||
|
* @return the process ID
|
||||||
|
*/
|
||||||
|
int pid() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
KProcess(KProcessPrivate *d, QObject *parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
KProcessPrivate * const d_ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// hide those
|
||||||
|
using QProcess::setReadChannelMode;
|
||||||
|
using QProcess::readChannelMode;
|
||||||
|
using QProcess::setProcessChannelMode;
|
||||||
|
using QProcess::processChannelMode;
|
||||||
|
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void _k_forwardStdout())
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void _k_forwardStderr())
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ----------- kprocess_p.h ---------------- */
|
||||||
|
class KProcessPrivate {
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC(KProcess)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
KProcessPrivate() :
|
||||||
|
openMode(QIODevice::ReadWrite)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void writeAll(const QByteArray &buf, int fd);
|
||||||
|
void forwardStd(KProcess::ProcessChannel good, int fd);
|
||||||
|
void _k_forwardStdout();
|
||||||
|
void _k_forwardStderr();
|
||||||
|
|
||||||
|
QString prog;
|
||||||
|
QStringList args;
|
||||||
|
KProcess::OutputChannelMode outputChannelMode;
|
||||||
|
QIODevice::OpenMode openMode;
|
||||||
|
|
||||||
|
KProcess *q_ptr;
|
||||||
|
};
|
||||||
|
/* ------------------------------------------- */
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,701 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
This file is part of the KDE libraries
|
||||||
|
Copyright (C) 2002 Waldo Bastian <bastian@kde.org>
|
||||||
|
Copyright (C) 2002-2003,2007 Oswald Buddenhagen <ossi@kde.org>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "kpty_p.h"
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||||
|
#define HAVE_LOGIN
|
||||||
|
#define HAVE_LIBUTIL_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __sgi
|
||||||
|
#define __svr4__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __osf__
|
||||||
|
#define _OSF_SOURCE
|
||||||
|
#include <float.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _AIX
|
||||||
|
#define _ALL_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// __USE_XOPEN isn't defined by default in ICC
|
||||||
|
// (needed for ptsname(), grantpt() and unlockpt())
|
||||||
|
#ifdef __INTEL_COMPILER
|
||||||
|
# ifndef __USE_XOPEN
|
||||||
|
# define __USE_XOPEN
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_PTY_H)
|
||||||
|
# include <pty.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUTIL_H
|
||||||
|
# include <libutil.h>
|
||||||
|
#elif defined(HAVE_UTIL_H)
|
||||||
|
# include <util.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UTEMPTER
|
||||||
|
extern "C" {
|
||||||
|
# include <utempter.h>
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# include <utmp.h>
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
# include <utmpx.h>
|
||||||
|
# endif
|
||||||
|
# if !defined(_PATH_UTMPX) && defined(_UTMPX_FILE)
|
||||||
|
# define _PATH_UTMPX _UTMPX_FILE
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_UPDWTMPX
|
||||||
|
# if !defined(_PATH_WTMPX) && defined(_WTMPX_FILE)
|
||||||
|
# define _PATH_WTMPX _WTMPX_FILE
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* for HP-UX (some versions) the extern C is needed, and for other
|
||||||
|
platforms it doesn't hurt */
|
||||||
|
extern "C" {
|
||||||
|
#include <termios.h>
|
||||||
|
#if defined(HAVE_TERMIO_H)
|
||||||
|
# include <termio.h> // struct winsize on some systems
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (_HPUX_SOURCE)
|
||||||
|
# define _TERMIOS_INCLUDED
|
||||||
|
# include <bsdtty.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STROPTS_H
|
||||||
|
# include <sys/stropts.h> // Defines I_PUSH
|
||||||
|
# define _NEW_TTY_CTRL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
|
||||||
|
# define _tcgetattr(fd, ttmode) ioctl(fd, TIOCGETA, (char *)ttmode)
|
||||||
|
#else
|
||||||
|
# if defined(_HPUX_SOURCE) || defined(__Lynx__) || defined (__CYGWIN__)
|
||||||
|
# define _tcgetattr(fd, ttmode) tcgetattr(fd, ttmode)
|
||||||
|
# else
|
||||||
|
# define _tcgetattr(fd, ttmode) ioctl(fd, TCGETS, (char *)ttmode)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__) || defined (__DragonFly__)
|
||||||
|
# define _tcsetattr(fd, ttmode) ioctl(fd, TIOCSETA, (char *)ttmode)
|
||||||
|
#else
|
||||||
|
# if defined(_HPUX_SOURCE) || defined(__CYGWIN__)
|
||||||
|
# define _tcsetattr(fd, ttmode) tcsetattr(fd, TCSANOW, ttmode)
|
||||||
|
# else
|
||||||
|
# define _tcsetattr(fd, ttmode) ioctl(fd, TCSETS, (char *)ttmode)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#include <kdebug.h>
|
||||||
|
//#include <kstandarddirs.h> // findExe
|
||||||
|
|
||||||
|
// not defined on HP-UX for example
|
||||||
|
#ifndef CTRL
|
||||||
|
# define CTRL(x) ((x) & 037)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TTY_GROUP "tty"
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// private functions //
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
// private data //
|
||||||
|
//////////////////
|
||||||
|
|
||||||
|
KPtyPrivate::KPtyPrivate(KPty* parent) :
|
||||||
|
masterFd(-1), slaveFd(-1), ownMaster(true), q_ptr(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KPtyPrivate::~KPtyPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPtyPrivate::chownpty(bool)
|
||||||
|
{
|
||||||
|
// return !QProcess::execute(KStandardDirs::findExe("kgrantpty"),
|
||||||
|
// QStringList() << (grant?"--grant":"--revoke") << QString::number(masterFd));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// public member functions //
|
||||||
|
/////////////////////////////
|
||||||
|
|
||||||
|
KPty::KPty() :
|
||||||
|
d_ptr(new KPtyPrivate(this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KPty::KPty(KPtyPrivate *d) :
|
||||||
|
d_ptr(d)
|
||||||
|
{
|
||||||
|
d_ptr->q_ptr = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
KPty::~KPty()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
delete d_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPty::open()
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
if (d->masterFd >= 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
d->ownMaster = true;
|
||||||
|
|
||||||
|
QByteArray ptyName;
|
||||||
|
|
||||||
|
// Find a master pty that we can open ////////////////////////////////
|
||||||
|
|
||||||
|
// Because not all the pty animals are created equal, they want to
|
||||||
|
// be opened by several different methods.
|
||||||
|
|
||||||
|
// We try, as we know them, one by one.
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENPTY
|
||||||
|
|
||||||
|
char ptsn[PATH_MAX];
|
||||||
|
if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0)) {
|
||||||
|
d->masterFd = -1;
|
||||||
|
d->slaveFd = -1;
|
||||||
|
qWarning(175) << "Can't open a pseudo teletype";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
d->ttyName = ptsn;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef HAVE__GETPTY // irix
|
||||||
|
|
||||||
|
char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
|
||||||
|
if (ptsn) {
|
||||||
|
d->ttyName = ptsn;
|
||||||
|
goto grantedpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)
|
||||||
|
|
||||||
|
#ifdef HAVE_POSIX_OPENPT
|
||||||
|
d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
|
||||||
|
#elif defined(HAVE_GETPT)
|
||||||
|
d->masterFd = ::getpt();
|
||||||
|
#elif defined(PTM_DEVICE)
|
||||||
|
d->masterFd = ::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
|
||||||
|
#else
|
||||||
|
# error No method to open a PTY master detected.
|
||||||
|
#endif
|
||||||
|
if (d->masterFd >= 0) {
|
||||||
|
#ifdef HAVE_PTSNAME
|
||||||
|
char *ptsn = ptsname(d->masterFd);
|
||||||
|
if (ptsn) {
|
||||||
|
d->ttyName = ptsn;
|
||||||
|
#else
|
||||||
|
int ptyno;
|
||||||
|
if (!ioctl(d->masterFd, TIOCGPTN, &ptyno)) {
|
||||||
|
d->ttyName = QByteArray("/dev/pts/") + QByteArray::number(ptyno);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GRANTPT
|
||||||
|
if (!grantpt(d->masterFd)) {
|
||||||
|
goto grantedpt;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
goto gotpty;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
::close(d->masterFd);
|
||||||
|
d->masterFd = -1;
|
||||||
|
}
|
||||||
|
#endif // HAVE_PTSNAME || TIOCGPTN
|
||||||
|
|
||||||
|
// Linux device names, FIXME: Trouble on other systems?
|
||||||
|
for (const char * s3 = "pqrstuvwxyzabcde"; *s3; s3++) {
|
||||||
|
for (const char * s4 = "0123456789abcdef"; *s4; s4++) {
|
||||||
|
ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toUtf8();
|
||||||
|
d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toUtf8();
|
||||||
|
|
||||||
|
d->masterFd = ::open(ptyName.data(), O_RDWR);
|
||||||
|
if (d->masterFd >= 0) {
|
||||||
|
#ifdef Q_OS_SOLARIS
|
||||||
|
/* Need to check the process group of the pty.
|
||||||
|
* If it exists, then the slave pty is in use,
|
||||||
|
* and we need to get another one.
|
||||||
|
*/
|
||||||
|
int pgrp_rtn;
|
||||||
|
if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
|
||||||
|
::close(d->masterFd);
|
||||||
|
d->masterFd = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif /* Q_OS_SOLARIS */
|
||||||
|
if (!access(d->ttyName.data(),R_OK|W_OK)) { // checks availability based on permission bits
|
||||||
|
if (!geteuid()) {
|
||||||
|
struct group * p = getgrnam(TTY_GROUP);
|
||||||
|
if (!p) {
|
||||||
|
p = getgrnam("wheel");
|
||||||
|
}
|
||||||
|
gid_t gid = p ? p->gr_gid : getgid ();
|
||||||
|
|
||||||
|
if (!chown(d->ttyName.data(), getuid(), gid)) {
|
||||||
|
chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto gotpty;
|
||||||
|
}
|
||||||
|
::close(d->masterFd);
|
||||||
|
d->masterFd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qWarning() << "Can't open a pseudo teletype";
|
||||||
|
return false;
|
||||||
|
|
||||||
|
gotpty:
|
||||||
|
struct stat st;
|
||||||
|
if (stat(d->ttyName.data(), &st)) {
|
||||||
|
return false; // this just cannot happen ... *cough* Yeah right, I just
|
||||||
|
// had it happen when pty #349 was allocated. I guess
|
||||||
|
// there was some sort of leak? I only had a few open.
|
||||||
|
}
|
||||||
|
if (((st.st_uid != getuid()) ||
|
||||||
|
(st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
|
||||||
|
!d->chownpty(true)) {
|
||||||
|
qWarning()
|
||||||
|
<< "chownpty failed for device " << ptyName << "::" << d->ttyName
|
||||||
|
<< "\nThis means the communication can be eavesdropped." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined (HAVE__GETPTY) || defined (HAVE_GRANTPT)
|
||||||
|
grantedpt:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_REVOKE
|
||||||
|
revoke(d->ttyName.data());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_UNLOCKPT
|
||||||
|
unlockpt(d->masterFd);
|
||||||
|
#elif defined(TIOCSPTLCK)
|
||||||
|
int flag = 0;
|
||||||
|
ioctl(d->masterFd, TIOCSPTLCK, &flag);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
|
||||||
|
if (d->slaveFd < 0) {
|
||||||
|
qWarning() << "Can't open slave pseudo teletype";
|
||||||
|
::close(d->masterFd);
|
||||||
|
d->masterFd = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined(__svr4__) || defined(__sgi__))
|
||||||
|
// Solaris
|
||||||
|
ioctl(d->slaveFd, I_PUSH, "ptem");
|
||||||
|
ioctl(d->slaveFd, I_PUSH, "ldterm");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_OPENPTY */
|
||||||
|
|
||||||
|
fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
|
||||||
|
fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPty::open(int fd)
|
||||||
|
{
|
||||||
|
#if !defined(HAVE_PTSNAME) && !defined(TIOCGPTN)
|
||||||
|
qWarning() << "Unsupported attempt to open pty with fd" << fd;
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
if (d->masterFd >= 0) {
|
||||||
|
qWarning() << "Attempting to open an already open pty";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->ownMaster = false;
|
||||||
|
|
||||||
|
# ifdef HAVE_PTSNAME
|
||||||
|
char *ptsn = ptsname(fd);
|
||||||
|
if (ptsn) {
|
||||||
|
d->ttyName = ptsn;
|
||||||
|
# else
|
||||||
|
int ptyno;
|
||||||
|
if (!ioctl(fd, TIOCGPTN, &ptyno)) {
|
||||||
|
char buf[32];
|
||||||
|
sprintf(buf, "/dev/pts/%d", ptyno);
|
||||||
|
d->ttyName = buf;
|
||||||
|
# endif
|
||||||
|
} else {
|
||||||
|
qWarning() << "Failed to determine pty slave device for fd" << fd;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->masterFd = fd;
|
||||||
|
if (!openSlave()) {
|
||||||
|
|
||||||
|
d->masterFd = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPty::closeSlave()
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
if (d->slaveFd < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
::close(d->slaveFd);
|
||||||
|
d->slaveFd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPty::openSlave()
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
if (d->slaveFd >= 0)
|
||||||
|
return true;
|
||||||
|
if (d->masterFd < 0) {
|
||||||
|
qDebug() << "Attempting to open pty slave while master is closed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//d->slaveFd = KDE_open(d->ttyName.data(), O_RDWR | O_NOCTTY);
|
||||||
|
d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
|
||||||
|
if (d->slaveFd < 0) {
|
||||||
|
qDebug() << "Can't open slave pseudo teletype";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPty::close()
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
if (d->masterFd < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeSlave();
|
||||||
|
// don't bother resetting unix98 pty, it will go away after closing master anyway.
|
||||||
|
if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) {
|
||||||
|
if (!geteuid()) {
|
||||||
|
struct stat st;
|
||||||
|
if (!stat(d->ttyName.data(), &st)) {
|
||||||
|
chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1);
|
||||||
|
chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fcntl(d->masterFd, F_SETFD, 0);
|
||||||
|
d->chownpty(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::close(d->masterFd);
|
||||||
|
d->masterFd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPty::setCTty()
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
// Setup job control //////////////////////////////////
|
||||||
|
|
||||||
|
// Become session leader, process group leader,
|
||||||
|
// and get rid of the old controlling terminal.
|
||||||
|
setsid();
|
||||||
|
|
||||||
|
// make our slave pty the new controlling terminal.
|
||||||
|
#ifdef TIOCSCTTY
|
||||||
|
ioctl(d->slaveFd, TIOCSCTTY, 0);
|
||||||
|
#else
|
||||||
|
// __svr4__ hack: the first tty opened after setsid() becomes controlling tty
|
||||||
|
::close(::open(d->ttyName, O_WRONLY, 0));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// make our new process group the foreground group on the pty
|
||||||
|
int pgrp = getpid();
|
||||||
|
#if defined(_POSIX_VERSION) || defined(__svr4__)
|
||||||
|
tcsetpgrp(d->slaveFd, pgrp);
|
||||||
|
#elif defined(TIOCSPGRP)
|
||||||
|
ioctl(d->slaveFd, TIOCSPGRP, (char *)&pgrp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPty::login(const char * user, const char * remotehost)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_UTEMPTER
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
addToUtmp(d->ttyName, remotehost, d->masterFd);
|
||||||
|
Q_UNUSED(user);
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
struct utmpx l_struct;
|
||||||
|
# else
|
||||||
|
struct utmp l_struct;
|
||||||
|
# endif
|
||||||
|
memset(&l_struct, 0, sizeof(l_struct));
|
||||||
|
// note: strncpy without terminators _is_ correct here. man 4 utmp
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remotehost) {
|
||||||
|
strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host));
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
|
||||||
|
l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host));
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifndef __GLIBC__
|
||||||
|
Q_D(KPty);
|
||||||
|
const char * str_ptr = d->ttyName.data();
|
||||||
|
if (!memcmp(str_ptr, "/dev/", 5)) {
|
||||||
|
str_ptr += 5;
|
||||||
|
}
|
||||||
|
strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_ID
|
||||||
|
strncpy(l_struct.ut_id,
|
||||||
|
str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id),
|
||||||
|
sizeof(l_struct.ut_id));
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
gettimeofday(&l_struct.ut_tv, 0);
|
||||||
|
# else
|
||||||
|
l_struct.ut_time = time(0);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef HAVE_LOGIN
|
||||||
|
# ifdef HAVE_LOGINX
|
||||||
|
::loginx(&l_struct);
|
||||||
|
# else
|
||||||
|
::login(&l_struct);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_TYPE
|
||||||
|
l_struct.ut_type = USER_PROCESS;
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_PID
|
||||||
|
l_struct.ut_pid = getpid();
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_SESSION
|
||||||
|
l_struct.ut_session = getsid(0);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
utmpxname(_PATH_UTMPX);
|
||||||
|
setutxent();
|
||||||
|
pututxline(&l_struct);
|
||||||
|
endutxent();
|
||||||
|
# ifdef HAVE_UPDWTMPX
|
||||||
|
updwtmpx(_PATH_WTMPX, &l_struct);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
utmpname(_PATH_UTMP);
|
||||||
|
setutent();
|
||||||
|
pututline(&l_struct);
|
||||||
|
endutent();
|
||||||
|
updwtmp(_PATH_WTMP, &l_struct);
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void KPty::logout()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_UTEMPTER
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
removeLineFromUtmp(d->ttyName, d->masterFd);
|
||||||
|
#else
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
const char *str_ptr = d->ttyName.data();
|
||||||
|
if (!memcmp(str_ptr, "/dev/", 5)) {
|
||||||
|
str_ptr += 5;
|
||||||
|
}
|
||||||
|
# ifdef __GLIBC__
|
||||||
|
else {
|
||||||
|
const char * sl_ptr = strrchr(str_ptr, '/');
|
||||||
|
if (sl_ptr) {
|
||||||
|
str_ptr = sl_ptr + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_LOGIN
|
||||||
|
# ifdef HAVE_LOGINX
|
||||||
|
::logoutx(str_ptr, 0, DEAD_PROCESS);
|
||||||
|
# else
|
||||||
|
::logout(str_ptr);
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
struct utmpx l_struct, *ut;
|
||||||
|
# else
|
||||||
|
struct utmp l_struct, *ut;
|
||||||
|
# endif
|
||||||
|
memset(&l_struct, 0, sizeof(l_struct));
|
||||||
|
|
||||||
|
strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line));
|
||||||
|
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
utmpxname(_PATH_UTMPX);
|
||||||
|
setutxent();
|
||||||
|
if ((ut = getutxline(&l_struct))) {
|
||||||
|
# else
|
||||||
|
utmpname(_PATH_UTMP);
|
||||||
|
setutent();
|
||||||
|
if ((ut = getutline(&l_struct))) {
|
||||||
|
# endif
|
||||||
|
memset(ut->ut_name, 0, sizeof(*ut->ut_name));
|
||||||
|
memset(ut->ut_host, 0, sizeof(*ut->ut_host));
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
|
||||||
|
ut->ut_syslen = 0;
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_TYPE
|
||||||
|
ut->ut_type = DEAD_PROCESS;
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_UTMPX
|
||||||
|
gettimeofday(&ut->ut_tv, 0);
|
||||||
|
pututxline(ut);
|
||||||
|
}
|
||||||
|
endutxent();
|
||||||
|
# else
|
||||||
|
ut->ut_time = time(0);
|
||||||
|
pututline(ut);
|
||||||
|
}
|
||||||
|
endutent();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Supposedly, tc[gs]etattr do not work with the master on Solaris.
|
||||||
|
// Please verify.
|
||||||
|
|
||||||
|
bool KPty::tcGetAttr(struct ::termios * ttmode) const
|
||||||
|
{
|
||||||
|
Q_D(const KPty);
|
||||||
|
|
||||||
|
return _tcgetattr(d->masterFd, ttmode) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPty::tcSetAttr(struct ::termios * ttmode)
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
return _tcsetattr(d->masterFd, ttmode) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPty::setWinSize(int lines, int columns)
|
||||||
|
{
|
||||||
|
Q_D(KPty);
|
||||||
|
|
||||||
|
struct winsize winSize;
|
||||||
|
memset(&winSize, 0, sizeof(winSize));
|
||||||
|
winSize.ws_row = (unsigned short)lines;
|
||||||
|
winSize.ws_col = (unsigned short)columns;
|
||||||
|
return ioctl(d->masterFd, TIOCSWINSZ, (char *)&winSize) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KPty::setEcho(bool echo)
|
||||||
|
{
|
||||||
|
struct ::termios ttmode;
|
||||||
|
if (!tcGetAttr(&ttmode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!echo) {
|
||||||
|
ttmode.c_lflag &= ~ECHO;
|
||||||
|
} else {
|
||||||
|
ttmode.c_lflag |= ECHO;
|
||||||
|
}
|
||||||
|
return tcSetAttr(&ttmode);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * KPty::ttyName() const
|
||||||
|
{
|
||||||
|
Q_D(const KPty);
|
||||||
|
|
||||||
|
return d->ttyName.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
int KPty::masterFd() const
|
||||||
|
{
|
||||||
|
Q_D(const KPty);
|
||||||
|
|
||||||
|
return d->masterFd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int KPty::slaveFd() const
|
||||||
|
{
|
||||||
|
Q_D(const KPty);
|
||||||
|
|
||||||
|
return d->slaveFd;
|
||||||
|
}
|
@ -0,0 +1,191 @@
|
|||||||
|
/* This file is part of the KDE libraries
|
||||||
|
|
||||||
|
Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef kpty_h
|
||||||
|
#define kpty_h
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
struct KPtyPrivate;
|
||||||
|
struct termios;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides primitives for opening & closing a pseudo TTY pair, assigning the
|
||||||
|
* controlling TTY, utmp registration and setting various terminal attributes.
|
||||||
|
*/
|
||||||
|
class KPty {
|
||||||
|
Q_DECLARE_PRIVATE(KPty)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
KPty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor:
|
||||||
|
*
|
||||||
|
* If the pty is still open, it will be closed. Note, however, that
|
||||||
|
* an utmp registration is @em not undone.
|
||||||
|
*/
|
||||||
|
~KPty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a pty master/slave pair.
|
||||||
|
*
|
||||||
|
* @return true if a pty pair was successfully opened
|
||||||
|
*/
|
||||||
|
bool open();
|
||||||
|
|
||||||
|
bool open(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the pty master/slave pair.
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the pty slave descriptor.
|
||||||
|
*
|
||||||
|
* When creating the pty, KPty also opens the slave and keeps it open.
|
||||||
|
* Consequently the master will never receive an EOF notification.
|
||||||
|
* Usually this is the desired behavior, as a closed pty slave can be
|
||||||
|
* reopened any time - unlike a pipe or socket. However, in some cases
|
||||||
|
* pipe-alike behavior might be desired.
|
||||||
|
*
|
||||||
|
* After this function was called, slaveFd() and setCTty() cannot be
|
||||||
|
* used.
|
||||||
|
*/
|
||||||
|
void closeSlave();
|
||||||
|
bool openSlave();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new session and process group and makes this pty the
|
||||||
|
* controlling tty.
|
||||||
|
*/
|
||||||
|
void setCTty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an utmp entry for the tty.
|
||||||
|
* This function must be called after calling setCTty and
|
||||||
|
* making this pty the stdin.
|
||||||
|
* @param user the user to be logged on
|
||||||
|
* @param remotehost the host from which the login is coming. This is
|
||||||
|
* @em not the local host. For remote logins it should be the hostname
|
||||||
|
* of the client. For local logins from inside an X session it should
|
||||||
|
* be the name of the X display. Otherwise it should be empty.
|
||||||
|
*/
|
||||||
|
void login(const char * user = 0, const char * remotehost = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the utmp entry for this tty.
|
||||||
|
*/
|
||||||
|
void logout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around tcgetattr(3).
|
||||||
|
*
|
||||||
|
* This function can be used only while the PTY is open.
|
||||||
|
* You will need an #include <termios.h> to do anything useful
|
||||||
|
* with it.
|
||||||
|
*
|
||||||
|
* @param ttmode a pointer to a termios structure.
|
||||||
|
* Note: when declaring ttmode, @c struct @c ::termios must be used -
|
||||||
|
* without the '::' some version of HP-UX thinks, this declares
|
||||||
|
* the struct in your class, in your method.
|
||||||
|
* @return @c true on success, false otherwise
|
||||||
|
*/
|
||||||
|
bool tcGetAttr(struct ::termios * ttmode) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper around tcsetattr(3) with mode TCSANOW.
|
||||||
|
*
|
||||||
|
* This function can be used only while the PTY is open.
|
||||||
|
*
|
||||||
|
* @param ttmode a pointer to a termios structure.
|
||||||
|
* @return @c true on success, false otherwise. Note that success means
|
||||||
|
* that @em at @em least @em one attribute could be set.
|
||||||
|
*/
|
||||||
|
bool tcSetAttr(struct ::termios * ttmode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the logical (screen) size of the pty.
|
||||||
|
* The default is 24 lines by 80 columns.
|
||||||
|
*
|
||||||
|
* This function can be used only while the PTY is open.
|
||||||
|
*
|
||||||
|
* @param lines the number of rows
|
||||||
|
* @param columns the number of columns
|
||||||
|
* @return @c true on success, false otherwise
|
||||||
|
*/
|
||||||
|
bool setWinSize(int lines, int columns);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the pty should echo input.
|
||||||
|
*
|
||||||
|
* Echo is on by default.
|
||||||
|
* If the output of automatically fed (non-interactive) PTY clients
|
||||||
|
* needs to be parsed, disabling echo often makes it much simpler.
|
||||||
|
*
|
||||||
|
* This function can be used only while the PTY is open.
|
||||||
|
*
|
||||||
|
* @param echo true if input should be echoed.
|
||||||
|
* @return @c true on success, false otherwise
|
||||||
|
*/
|
||||||
|
bool setEcho(bool echo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of the slave pty device.
|
||||||
|
*
|
||||||
|
* This function should be called only while the pty is open.
|
||||||
|
*/
|
||||||
|
const char * ttyName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the file descriptor of the master pty
|
||||||
|
*
|
||||||
|
* This function should be called only while the pty is open.
|
||||||
|
*/
|
||||||
|
int masterFd() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the file descriptor of the slave pty
|
||||||
|
*
|
||||||
|
* This function should be called only while the pty slave is open.
|
||||||
|
*/
|
||||||
|
int slaveFd() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
KPty(KPtyPrivate * d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
KPtyPrivate * const d_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
/* This file is part of the KDE libraries
|
||||||
|
|
||||||
|
Copyright (C) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
|
||||||
|
|
||||||
|
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public License
|
||||||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef kpty_p_h
|
||||||
|
#define kpty_p_h
|
||||||
|
|
||||||
|
#include "kpty.h"
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
struct KPtyPrivate {
|
||||||
|
|
||||||
|
Q_DECLARE_PUBLIC(KPty)
|
||||||
|
|
||||||
|
KPtyPrivate(KPty* parent);
|
||||||
|
virtual ~KPtyPrivate();
|
||||||
|
|
||||||
|
#ifndef HAVE_OPENPTY
|
||||||
|
bool chownpty(bool grant);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int masterFd;
|
||||||
|
int slaveFd;
|
||||||
|
bool ownMaster:1;
|
||||||
|
|
||||||
|
QByteArray ttyName;
|
||||||
|
|
||||||
|
KPty *q_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue