diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..599ac3e175e1e6f4a5ff217a9b451552c75ee109 --- /dev/null +++ b/.clang-format @@ -0,0 +1,166 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeConceptDeclarations: true +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +StatementAttributeLikeMacros: + - Q_EMIT +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: '.*' + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentRequires: false +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyIndentedWhitespace: 0 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortJavaStaticImport: Before +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +BitFieldColonSpacing: Both +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE + - NS_SWIFT_NAME + - CF_SWIFT_NAME +... + diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000000000000000000000000000000000..d2205b45d247818f1f5d621135959633967f3464 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,18 @@ +Checks: > + readability-identifier-naming, + clang-analyzer-deadcode.DeadStores, + unused-using-decls, + modernize-*, + bugprone-*, + performance-*, + readability-*, + cppcoreguidelines-avoid-magic-numbers, + cppcoreguidelines-narrowing-conversions, + misc-unused-parameters, + -performance-avoid-endl, + -readability-identifier-length, + -bugprone-unchecked-optional-access, + -bugprone-easily-swappable-parameters +WarningsAsErrors: "*" +HeaderFilterRegex: "" +FormatStyle: none diff --git a/.clangd b/.clangd new file mode 100644 index 0000000000000000000000000000000000000000..da15566648b76d3e1eccd69e090d59c4e5503689 --- /dev/null +++ b/.clangd @@ -0,0 +1,4 @@ +If: + PathMatch: ./src/* +CompileFlags: + CompilationDatabase: ./build/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..544b2b2edbe6293be94a5aec478d5dbd11145daf --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/ +.cache/ +.vscode/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..29b262765b34454f4063d85c8061343e28b3a3d2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "deps/libyui"] + path = deps/libyui + url = https://github.com/libyui/libyui.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f63f6448f282ef15e3563e1b4cb62b679d1a2e3c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,156 @@ +cmake_minimum_required(VERSION 3.17) +project(controlpanel) + +set(CMAKE_EXPORT_COMPILE_COMMANDS on) +set(CMAKE_CXX_STANDARD 20) + +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG") + +# use project specific cmake modules +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) + +# assert usage of libfmt +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) + message(FATAL_ERROR "GCC version must be at least 10.0") + endif() + message(STATUS "Using GCC version ${CMAKE_CXX_COMPILER_VERSION}") +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0) + message(FATAL_ERROR "Clang version must be at least 12.0") + endif() + message(STATUS "Using Clang version ${CMAKE_CXX_COMPILER_VERSION}") +else() + message(FATAL_ERROR "Unsupported compiler: ${CMAKE_CXX_COMPILER_ID}") +endif() + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build (Debug or Release)" FORCE) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Release") + message("Building in Release mode") +else() + message("Building in Debug mode") + option(ADDRESS_SANITIZER "Enable AddressSanitizer" ON) + option(THREAD_SANITIZER "Enable ThreadSanitizer" OFF) + + if(THREAD_SANITIZER) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread,undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls") + message(STATUS "ThreadSanitizer is enabled.") + elseif(ADDRESS_SANITIZER) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address,undefined -O0 -fno-omit-frame-pointer -fno-optimize-sibling-calls") + message(STATUS "AddressSanitizer is enabled.") + endif() +endif() + +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) +endif() + +find_program(CLANG_TIDY_EXE NAMES clang-tidy) +if(CLANG_TIDY_EXE) + message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXE}") + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE}") +else() + message(STATUS "clang-tidy not found.") +endif() + +set(MAIN_SOURCES + ${CMAKE_SOURCE_DIR}/src/controlpanel.cc +) + +set(FRONT_SOURCES + ${CMAKE_SOURCE_DIR}/src/frontend/ui_base.cc + ${CMAKE_SOURCE_DIR}/src/frontend/main_menu.cc + + ${CMAKE_SOURCE_DIR}/src/frontend/firewall/firewall_ui.cc + + ${CMAKE_SOURCE_DIR}/src/frontend/package_manager/package_ui.cc +) + +set(BACK_SOURCES + ${CMAKE_SOURCE_DIR}/src/backend/config_backend_base.cc + ${CMAKE_SOURCE_DIR}/src/backend/config_manager.cc + + ${CMAKE_SOURCE_DIR}/src/backend/firewall/firewall_backend.cc + ${CMAKE_SOURCE_DIR}/src/backend/firewall/rule_request.cc + + ${CMAKE_SOURCE_DIR}/src/backend/package_manager/package_manager_backend.cc +) + +set(TOOL_SOURCES + ${CMAKE_SOURCE_DIR}/src/tools/sys.cc + ${CMAKE_SOURCE_DIR}/src/tools/nettools.cc + ${CMAKE_SOURCE_DIR}/src/tools/uitools.cc + ${CMAKE_SOURCE_DIR}/src/tools/widget_manager.cc +) + +set(NON_MAIN_SOURCES + ${TOOL_SOURCES} + ${FRONT_SOURCES} + ${BACK_SOURCES} +) + +set(SOURCES + ${MAIN_SOURCES} + ${NON_MAIN_SOURCES} +) + +find_program(CLANG_FORMAT_EXE NAMES clang-format) +if(CLANG_FORMAT_EXE) + message(STATUS "Found clang-format: ${CLANG_FORMAT_EXE}") + add_custom_target( + clang_format + COMMAND ${CLANG_FORMAT_EXE} -i ${SOURCES} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Running clang-format on source files" + ) +else() + message(STATUS "clang-format not found.") +endif() + +include_directories(include) +include_directories(/usr/include/yui) + +#libyui +find_library(YUI_LIB yui REQUIRED) +find_path(YUI_INCLUDE_DIR yui REQUIRED) + +# libiptc +find_library(IPTC_LIB ip4tc ip6tc REQUIRED) +find_path(IPTC_INCLUDE_DIR libiptc/libiptc.h REQUIRED) +include_directories(${IPTC_INCLUDE_DIR}) + +#libdnf +find_path(LIBDNF_INCLUDE_DIR NAMES libdnf/libdnf.h) +find_library(LIBDNF_LIBRARY NAMES dnf) +include_directories(${LIBDNF_INCLUDE_DIRS}) + +# glib, required for libdnf +find_package(GLIB REQUIRED) +include_directories(${GLIB_INCLUDE_DIRS}) + + +find_package(fmt) + +# if new lib to be linked, add it to the ALL_LIBS variable +set(ALL_LIBS ${YUI_LIB} + ${IPTC_LIB} + fmt::fmt + ${LIBDNF_LIBRARY} +) + +add_executable(${PROJECT_NAME} ${SOURCES}) +target_link_libraries(${PROJECT_NAME} ${ALL_LIBS}) + +# Testing +option(BUILD_TESTS "Build tests" ON) + +if (BUILD_TESTS) + enable_testing() + add_subdirectory(test) +endif() diff --git a/README.en.md b/README.en.md index e09c1ac33c53a75947bfe141c23a33400c41e95d..7e915f2938507c0b20755ea2251aa027fb57e376 100644 --- a/README.en.md +++ b/README.en.md @@ -1,36 +1,38 @@ -# system-config-users-docs +# Control Panel -#### Description -Documentation for administering users and groups +WIP for OpenEuler. -#### Software Architecture -Software architecture description +## Build -#### Installation +Install dependencies: -1. xxxx -2. xxxx -3. xxxx +```bash +cd deps +./build-all +sudo ./build-all install +``` -#### Instructions +Build Control Panel: -1. xxxx -2. xxxx -3. xxxx +```bash +$ mkdir -p build && cd build -#### Contribution +$ cmake -DCMAKE_BUILD_TYPE=Debug .. +$ cmake --build . --parallel -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request +$ ./controlpanel +``` +## Test -#### Gitee Feature +We use gtest for testing. You can test all cases by: -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +```bash +ctest +``` + +## Code Conduct + +- use fmt for logging +- use smart pointer as possible +- use gtest for testing diff --git a/README.md b/README.md index a9a629c9d6858000430acd315ee6fb33b8b2cb03..0f666ef6124535ac7077d60cfb029e968d2eb40c 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,41 @@ -# system-config-users-docs +# 控制面板 -#### 介绍 -Documentation for administering users and groups +WIP, 为 OpenEuler 社区项目. -#### 软件架构 -软件架构说明 +## Build +构建并安装依赖: -#### 安装教程 +```bash +cd deps +./build-all +sudo ./build-all install +``` -1. xxxx -2. xxxx -3. xxxx +构建 control panel: -#### 使用说明 +```bash +$ mkdir -p build && cd build -1. xxxx -2. xxxx -3. xxxx +$ cmake -DCMAKE_BUILD_TYPE=Debug .. +$ cmake --build . --parallel -#### 参与贡献 +$ ./controlpanel +``` -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +## Test +项目使用 gtest 进行测试. 你可以通过以下命令测试所有用例: -#### 码云特技 +```bash +ctest +``` -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 -5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +## 代码风格 + +- 使用 fmt 进行日志输出 +- 尽可能使用智能指针 +- 使用 gtest 进行测试 +- 使用 clang-format 格式化代码 +- 使用 clang-tidy 检查代码 +- 使用异常机制处理错误 diff --git a/cmake/modules/FindGLIB.cmake b/cmake/modules/FindGLIB.cmake new file mode 100644 index 0000000000000000000000000000000000000000..abe3a886c22430dadde0b685f3b134e062801eac --- /dev/null +++ b/cmake/modules/FindGLIB.cmake @@ -0,0 +1,123 @@ +# - Try to find Glib and its components (gio, gobject etc) +# Once done, this will define +# +# GLIB_FOUND - system has Glib +# GLIB_INCLUDE_DIRS - the Glib include directories +# GLIB_LIBRARIES - link these to use Glib +# +# Optionally, the COMPONENTS keyword can be passed to find_package() +# and Glib components can be looked for. Currently, the following +# components can be used, and they define the following variables if +# found: +# +# gio: GLIB_GIO_LIBRARIES +# gobject: GLIB_GOBJECT_LIBRARIES +# gmodule: GLIB_GMODULE_LIBRARIES +# gthread: GLIB_GTHREAD_LIBRARIES +# +# Note that the respective _INCLUDE_DIR variables are not set, since +# all headers are in the same directory as GLIB_INCLUDE_DIRS. +# +# Copyright (C) 2012 Raphael Kubo da Costa +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS +# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +find_package(PkgConfig) +pkg_check_modules(PC_GLIB QUIET glib-2.0) + +find_library(GLIB_LIBRARIES + NAMES glib-2.0 + HINTS ${PC_GLIB_LIBDIR} + ${PC_GLIB_LIBRARY_DIRS} +) + +# Files in glib's main include path may include glibconfig.h, which, +# for some odd reason, is normally in $LIBDIR/glib-2.0/include. +get_filename_component(_GLIB_LIBRARY_DIR ${GLIB_LIBRARIES} PATH) +find_path(GLIBCONFIG_INCLUDE_DIR + NAMES glibconfig.h + HINTS ${PC_LIBDIR} ${PC_LIBRARY_DIRS} ${_GLIB_LIBRARY_DIR} + ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} + PATH_SUFFIXES glib-2.0/include +) + +find_path(GLIB_INCLUDE_DIR + NAMES glib.h + HINTS ${PC_GLIB_INCLUDEDIR} + ${PC_GLIB_INCLUDE_DIRS} + PATH_SUFFIXES glib-2.0 +) + +set(GLIB_INCLUDE_DIRS ${GLIB_INCLUDE_DIR} ${GLIBCONFIG_INCLUDE_DIR}) + +# Version detection +file(READ "${GLIBCONFIG_INCLUDE_DIR}/glibconfig.h" GLIBCONFIG_H_CONTENTS) +string(REGEX MATCH "#define GLIB_MAJOR_VERSION ([0-9]+)" _dummy "${GLIBCONFIG_H_CONTENTS}") +set(GLIB_VERSION_MAJOR "${CMAKE_MATCH_1}") +string(REGEX MATCH "#define GLIB_MINOR_VERSION ([0-9]+)" _dummy "${GLIBCONFIG_H_CONTENTS}") +set(GLIB_VERSION_MINOR "${CMAKE_MATCH_1}") +string(REGEX MATCH "#define GLIB_MICRO_VERSION ([0-9]+)" _dummy "${GLIBCONFIG_H_CONTENTS}") +set(GLIB_VERSION_MICRO "${CMAKE_MATCH_1}") +set(GLIB_VERSION "${GLIB_VERSION_MAJOR}.${GLIB_VERSION_MINOR}.${GLIB_VERSION_MICRO}") + +# Additional Glib components. We only look for libraries, as not all of them +# have corresponding headers and all headers are installed alongside the main +# glib ones. +SET(GLIB_FIND_COMPONENTS gobject; gio; gio-unix;) +foreach (_component ${GLIB_FIND_COMPONENTS}) + if (${_component} STREQUAL "gio") + find_library(GLIB_GIO_LIBRARIES NAMES gio-2.0 HINTS ${_GLIB_LIBRARY_DIR}) + set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GIO_LIBRARIES) + elseif (${_component} STREQUAL "gobject") + find_library(GLIB_GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${_GLIB_LIBRARY_DIR}) + set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GOBJECT_LIBRARIES) + elseif (${_component} STREQUAL "gmodule") + find_library(GLIB_GMODULE_LIBRARIES NAMES gmodule-2.0 HINTS ${_GLIB_LIBRARY_DIR}) + set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GMODULE_LIBRARIES) + elseif (${_component} STREQUAL "gthread") + find_library(GLIB_GTHREAD_LIBRARIES NAMES gthread-2.0 HINTS ${_GLIB_LIBRARY_DIR}) + set(ADDITIONAL_REQUIRED_VARS ${ADDITIONAL_REQUIRED_VARS} GLIB_GTHREAD_LIBRARIES) + elseif (${_component} STREQUAL "gio-unix") + # gio-unix is compiled as part of the gio library, but the include paths + # are separate from the shared glib ones. Since this is currently only used + # by WebKitGTK+ we don't go to extraordinary measures beyond pkg-config. + pkg_check_modules(GIO_UNIX QUIET gio-unix-2.0) + include_directories(${GIO_UNIX_INCLUDE_DIRS}) + endif () +endforeach () + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLIB REQUIRED_VARS GLIB_INCLUDE_DIRS GLIB_LIBRARIES ${ADDITIONAL_REQUIRED_VARS} + VERSION_VAR GLIB_VERSION) + +mark_as_advanced( + GLIBCONFIG_INCLUDE_DIR + GLIB_GIO_LIBRARIES + GLIB_GIO_UNIX_LIBRARIES + GLIB_GMODULE_LIBRARIES + GLIB_GOBJECT_LIBRARIES + GLIB_GTHREAD_LIBRARIES + GLIB_INCLUDE_DIR + GLIB_INCLUDE_DIRS + GLIB_LIBRARIES +) + diff --git a/deps/build_deps.sh b/deps/build_deps.sh new file mode 100644 index 0000000000000000000000000000000000000000..1babcc3c600cfcbf53d90edb1c48f3441b9c9b94 --- /dev/null +++ b/deps/build_deps.sh @@ -0,0 +1,5 @@ +#/bin/bash + +cd libyui +./build_all +sudo ./build_all install diff --git a/deps/libyui/.github/workflows/ci.yml b/deps/libyui/.github/workflows/ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..f6f5452d397bb7a9c7c45228391f90873822c6a6 --- /dev/null +++ b/deps/libyui/.github/workflows/ci.yml @@ -0,0 +1,43 @@ + +# See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions + +name: CI + +on: [push, pull_request] + +jobs: + Package: + runs-on: ubuntu-latest + container: + image: registry.opensuse.org/devel/libraries/libyui/containers/libyui-devel:latest + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + + # just for easier debugging... + - name: Inspect Installed Packages + run: rpm -qa | sort + + - name: Fix directory owner (Git workaround) + run: chown -c "$UID" . + + - name: Packages Build And Install + ## uncomment this to enable cmake verbose output + # env: + # VERBOSE: "1" + run: scripts/ci-tasks + + NonRoot: + runs-on: ubuntu-latest + container: + image: registry.opensuse.org/devel/libraries/libyui/containers/libyui-devel:latest + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + + - name: Non-root installation + run: scripts/ci-non-root diff --git a/deps/libyui/.github/workflows/publish-api-doc.yml b/deps/libyui/.github/workflows/publish-api-doc.yml new file mode 100644 index 0000000000000000000000000000000000000000..e1174f30769c384dbf6e090f3e7ddda9f23dd752 --- /dev/null +++ b/deps/libyui/.github/workflows/publish-api-doc.yml @@ -0,0 +1,61 @@ + +# This generates Doxygen autodocs for the C++ API (for the libyui base lib) +# and pushes them to the "gh-pages" branch which publishes them +# to the project's GitHub pages at https://libyui.github.io/libyui/api-doc/ +# +# See also +# +# https://gist.github.com/shundhammer/ed359db0d9329d4db551528256060d2a +# +# GitHub actions syntax: +# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions + +name: publish-api-doc + +# Trigger this when a pull request is merged (which implies pushing to master). +on: + push: + branches: + - master + +jobs: + api-doc: + runs-on: ubuntu-latest + container: + image: registry.opensuse.org/devel/libraries/libyui/containers/libyui-devel:latest + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + + - name: Fix file permissions + run: chown -R -c "$UID" . + + - name: Create clean gh-pages branch + run: git checkout -b gh-pages + + - name: Generate autodocs for libyui base lib + run: make -C libyui -f Makefile.repo doc + + - name: Move generated autodocs to target directory + run: mv libyui/build/doc/html api-doc + + - name: Add generated autodocs to Git repo in the gh-pages branch + run: | + git config --global user.email "libyui-github-bot@suse.com" + git config --global user.name "$GITHUB_WORKFLOW GitHub action" + git add api-doc + git commit -am "Generated API doc" + + - name: Publish autodocs as GitHub pages + run: git push -f origin gh-pages:gh-pages + + - name: Result URLs + run: | + REPO_OWNER=$(echo $GITHUB_REPOSITORY | cut -d '/' -f 1) + REPO_NAME=$(echo $GITHUB_REPOSITORY | cut -d '/' -f 2) + echo "Formatted API docs: https://$REPO_OWNER.github.io/$REPO_NAME/api-doc" + echo "" + echo "GitHub pages branch: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/tree/gh-pages" + diff --git a/deps/libyui/.gitignore b/deps/libyui/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ed659120f08a2a61528bda30a61c53a76233d549 --- /dev/null +++ b/deps/libyui/.gitignore @@ -0,0 +1,5 @@ +package/*.tar.* + +*~ +*.bak +*.auto diff --git a/deps/libyui/COPYING.gpl-3 b/deps/libyui/COPYING.gpl-3 new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/deps/libyui/COPYING.gpl-3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/deps/libyui/COPYING.lgpl-2.1 b/deps/libyui/COPYING.lgpl-2.1 new file mode 100644 index 0000000000000000000000000000000000000000..4362b49151d7b34ef83b3067a8f9c9f877d72a0e --- /dev/null +++ b/deps/libyui/COPYING.lgpl-2.1 @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 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. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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. + + + Copyright (C) + + This library 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.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; 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. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/deps/libyui/COPYING.lgpl-3 b/deps/libyui/COPYING.lgpl-3 new file mode 100644 index 0000000000000000000000000000000000000000..65c5ca88a67c30becee01c5a8816d964b03862f9 --- /dev/null +++ b/deps/libyui/COPYING.lgpl-3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser 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 +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/deps/libyui/README.md b/deps/libyui/README.md new file mode 100644 index 0000000000000000000000000000000000000000..07d0b631cb45ebb18efa0c200ab063998a50116e --- /dev/null +++ b/deps/libyui/README.md @@ -0,0 +1,388 @@ +# LibYUI - Widget Abstraction Library + +[![Workflow Status](https://github.com/libyui/libyui/workflows/CI/badge.svg?branch=master)](https://github.com/libyui/libyui/actions?query=branch%3Amaster) +[![Jenkins Status](https://ci.opensuse.org/buildStatus/icon?job=libyui-master)](https://ci.opensuse.org/view/libyui/job/libyui-master/) + + +Libyui is a widget abstraction library providing graphical (Qt) and +text-based (NCurses) front-ends. + +There is also a Gtk front-end with (limited) community support. + +Originally, libyui was developed for [YaST](https://yast.github.io/), but it +can be also used in independent projects. + + +## End User's Perspective: Selecting the UI plug-in + +By default, libyui tries to load any of the available UI plug-ins in this order: + +- Qt: + - if $DISPLAY is set + - NCurses is user-selected and stdout is *not* a TTY + +- Gtk: + - if $DISPLAY is set and Qt is not available, + - a GTK-based desktop environment is detected from the XDG_CURRENT_DESKTOP + environment variable + - any of the above pre-conditions are met and NCurses is user-selected, but + stdout is *not* a TTY + +- NCurses: + - if $DISPLAY is *not* set and stdout is a TTY + - Qt and Gtk are not available and stdout is a TTY + + +This default behaviour can be overridden by either: + +- unsetting the DISPLAY environment variable to force NCurses: + + DISPLAY="" myprogram + +- setting the environment variable YUI_PREFERED_BACKEND to one of + - `gtk` + - `ncurses` + - `qt` + +- specifing one of the switches on the command line of the program: + - `--gtk` + - `--ncurses` + - `--qt` + + This overrides the environment variable. + +If the user-selected UI plug-in is not installed on the system, an installed +UI plug-in will be chosen by the above criteria. + + +# Developer's and Packager's Perspective + +## Components and Subprojects + +This source repository contains the officially supported components as +subprojects: + +- libyui: This is the base library that defines the API. + +- libyui-qt: The Qt UI front-end +- libyui-qt-pkg: The package selector extension based on libzypp for the Qt UI +- libyui-qt-graph: A Qt UI extension for displaying Graphviz files + +- libyui-ncurses: The NCurses (text-based) front-end +- libyui-ncurses-pkg: The package selector extension based on libzypp for the + NCurses UI + +- libyui-rest-api: A REST API for introspection and widgets remote control from + a QA environment +- libyui-qt-rest-api: The Qt UI extension for the REST API +- libyui-ncurses-rest-api: The NCurses UI extension for the REST API + +- libyui-bindings: SWIG bindings for Python, Perl, Ruby and Mono + + _Notice that YaST does not use this, it uses yast-ycp-ui-bindings based on + YCPValue container classes._ + +There are also community-maintained components in separate repositories like + +- libyui-gtk: The Gtk UI front-end +- libyui-mga: Extensions for Mageia Linux + + +# Building + +Each subproject is self-sufficient (except for the shared VERSION.cmake file in +the toplevel directory) and can be built separately. They all use CMake, and +most operations are available from a very simple `Makefile.repo` file in the +subprojects directory. Of course you can also simply invoke _cmake_ manually. + + +## Building Manually in a Subproject + +Using the Qt UI as an example: + + cd libyui-qt + make -f Makefile.repo + cd build + make + sudo make install + +or + + cd libyui-qt + make -f Makefile.repo build + sudo make -C build install + +Clean up with + + rm -rf build + +or + + make -f Makefile.repo clean + +Do all of this for the needed subprojects in order. + +For YaST: + +- libyui +- libyui-qt +- libyui-qt-pkg +- libyui-qt-graph +- libyui-ncurses +- libyui-ncurses-pkg + +For non-YaST projects you may want to omit the -pkg and -graph parts, but build +the bindings: + +- libyui +- libyui-qt +- libyui-ncurses +- libyui-bindings + + +## Building all Subprojects at Once + +Use the `build-all` script in the project toplevel directory; it will build +each needed subproject in the correct sequence. + +Call it with `-n` (`--dry-run`) to see what it _would_ do: + + ./build-all -n + + *** Dry run - not executing any make commands *** + + make -C libyui -f Makefile.repo build + make -C libyui-qt -f Makefile.repo build + make -C libyui-qt-graph -f Makefile.repo build + make -C libyui-qt-pkg -f Makefile.repo build + make -C libyui-ncurses -f Makefile.repo build + make -C libyui-ncurses-pkg -f Makefile.repo build + + +For non-YaST projects, use `-s -b` (`--small --bindings`) for a small build +with the subprojects that are typically needed: + + ./build-all -n -s -b + + *** Dry run - not executing any make commands *** + + make -C libyui -f Makefile.repo build + make -C libyui-qt -f Makefile.repo build + make -C libyui-ncurses -f Makefile.repo build + make -C libyui-bindings -f Makefile.repo build + + +or `-a` (`--all`) to build all subprojects: + + ./build-all -n -a + + *** Dry run - not executing any make commands *** + + make -C libyui -f Makefile.repo build + make -C libyui-qt -f Makefile.repo build + make -C libyui-qt-graph -f Makefile.repo build + make -C libyui-qt-pkg -f Makefile.repo build + make -C libyui-ncurses -f Makefile.repo build + make -C libyui-ncurses-pkg -f Makefile.repo build + make -C libyui-rest-api -f Makefile.repo build + make -C libyui-qt-rest-api -f Makefile.repo build + make -C libyui-ncurses-rest-api -f Makefile.repo build + make -C libyui-bindings -f Makefile.repo build + + +or explicitly select subprojects to build with or without like +`-p` (`--no-pkg`) or `-g` (`--no-graph`) or `-r` (`--rest-api`). +See `./build-all -h` for an up-to-date complete list. + + +### Daily Development Work: Keeping an Existing Build + +When working on libyui, it is common to change or add a class on the abstract +libyui level, then extend the concrete implementation in the Qt and NCurses +UIs; you don't want to rebuild everything from scratch after every little +change. + +If you use `build-all build`, it will do just that: It will remove each +`build/` subdirectory in each subproject, recreate it, invoke `cmake`, then +`make`. + +If you simply call it without any make target, however, it will check in each +subproject if there is an existing `build/` subdirectory, and if there is, just +call `make`. If there is no `build/` subdirectory, it will call `make -f +Makefile.repo build` instead. Notice that this handles each subproject +individually, so you can have a mixture of existing and non-existing `build/` +subdirectories. + + ./build-all + +This builds everything from scratch. + +Now continue editing files in subprojects and then + + ./build-all + +This now just invokes `make` in each subproject, keeping the object +files for unchanged sources. + +### make install + +Of course you need root permissions to install any file to the system: + + ./build-all + sudo ./build-all install + + +### Keeping Changes Locally in the Source Tree + +The CMake environments in the subprojects are set up to prefer header files and +built libraries from sibling subprojects over those from the system; so you can +work for a long time in the source tree without a need for `sudo make install`. + + +# Version Numbers + +All packages in this source tree have the same version numer; that's why the +subprojects share the toplevel `VERSION.cmake` file. + +The general idea is to enable transaction-like changes on the libyui base +packages to avoid long delays in the distribution build cycle and broken builds: + +Some parts may have become incompatible, yet the higher-level parts require the +base lib parts to be published as a prerequisite for building. In the past, +this resulted in staging projects not building; manual interaction was often +needed to break depencency cycles. + +The version numbers are also in all the .spec files in the `package/` +subdirectory, so they need to be kept consistent among each other and with the +`VERSION.cmake` file. + +For a simple version number increment, use + + rake version:bump + +that does the required changes consistently. + + +This requires some more packages to be installed: + +- rake (part of the ruby base package on SUSE distributions) +- the packaging_rake_tasks ruby gem +- the libyui-rake ruby gem + +At the time of this writing, those packages were named + +- ruby2.7 +- ruby2.7-rubygem-libyui-rake +- ruby2.7-rubygem-packaging_rake_tasks + +I.e. the package name of the gems contains the ruby version. +Use `zypper search` to find the current complete package name. + + +## Binary Compatibility and SO Version + +Whenever there is an ABI change, the SO version needs to be bumped to the next +higher number, also in the toplevel `VERSION.cmake` and in all .spec files in +the `package/` subdirectory. + +Use + + rake so_version:bump + +(same package requirements as above) + + +### Binary Compatibility + +The abstract libyui class uses the PIMPL idiom for API classes such as the +widgets: Each of the widget classes only has one single data member, the `priv` +pointer that holds a pointer to a private class holding all the real data +(e.g. YPushButtonPrivate). Adding data members to that private class is +perfectly safe and does not change the ABI (Application Binary Interface). + +However, beware of any of the following (incomplete list): + +- Data members are added to YUI or any similar class that is inherited in UI + plug-ins + +- Virtual functions are added or removed in API classes (or, again, in general + in classes like YUI that are inherited in UI plug-ins) + +- The order of virtual functions is changed (!) in any such class + +- The inheritance hierarchy between API classes changes + +- Enum values are added or removed + +Exceptions: + +- You can add a new virtual function at the end of a class. + +- You can add a new enum value at the end of the enum. + + +If there is any doubt, better bump the SO version once too many rather than +once not enough. Making this easy and painless was one rationale behind the +changed libyui build environment and repo structure in early 2021, so please +use it. + + +## Building with Prefix + +To install to another directory than `/usr`, set CMAKE_INSTALL_PREFIX; +either for each `cmake` call individually with `-D` or in the environment: + + mkdir build + cd build + cmake -DCMAKE_INSTALL_PREFIX=/usr/local .. + make && make install + +or + + CMAKE_INSTALL_PREFIX=/usr/local build-all -s + + +# Building RPMs + +For reproducible builds it is best to use the +[libyui-rake](https://github.com/libyui/libyui-rake) +Ruby gem like the [Jenkins CI](https://ci.opensuse.org/view/libyui/) jobs do. + +It can be installed from [rubygems.org](https://rubygems.org/gems/libyui-rake/) +using this command (Ruby needs to be installed in the system): + +``` +gem install libyui-rake +``` + +Then to build the package run: + +``` +rake osc:build +``` + + +# Further Reading + +## API Documentation + +- [C++ API documentation](https://libyui.github.io/libyui/api-doc/index.html) +- [Widgets documentation](https://doc.opensuse.org/projects/YaST/openSUSE11.3/tdg/Book-UIReference.html) +- [UI layout and events](https://doc.opensuse.org/projects/YaST/openSUSE11.3/tdg/Book-YCPUIlayout.html) + + +## Tips and Tricks + +- Interactive libyui dialog introspection with [YDialogSpy](https://en.opensuse.org/openSUSE:YaST_development_Misc_YDialogSpy) +- [Magic key combinations](https://en.opensuse.org/SDB:YaST_tricks) + + +## More info + +Please visit the documentation at the +[doc folder](https://github.com/libyui/libyui/tree/master/libyui/doc) +for more information about +[how to branch](https://github.com/libyui/libyui/tree/master/libyui/doc/branching.md) +libyui and about +[auto-tagging](https://github.com/libyui/libyui/tree/master/libyui/doc/auto-tagging.md) +new versions. diff --git a/deps/libyui/Rakefile b/deps/libyui/Rakefile new file mode 100644 index 0000000000000000000000000000000000000000..d425ab8946d80d683ae7ff062b638ec15a8ce2fc --- /dev/null +++ b/deps/libyui/Rakefile @@ -0,0 +1,31 @@ +#-- +# Copyright (c) 2015-2021 SUSE LLC +# +# make continuous integration using rubygem-libyui-rake. +# +# MIT license +#++ +# +# Common tasks for libyui: +# +# rake version:bump +# rake so_version:bump + +require "libyui/rake" + +Libyui::Tasks.configuration do |conf| + include Libyui::Tasks::Helpers + + conf.skip_license_check << /_multibuild/ + conf.skip_license_check << /^scripts\// + conf.skip_license_check << /^build-all$/ + conf.skip_license_check << /^Dockerfile$/ + conf.skip_license_check << /legacy-buildtools\/.*/ + conf.skip_license_check << /Makefile\.repo$/ + conf.skip_license_check << /CMakeLists\.txt$/ + conf.skip_license_check << /src\/.*\.h\.in$/ + conf.skip_license_check << /src\/icons\/.*\.svg$/ + conf.skip_license_check << /\/pkgconfig\/.*\.pc\.in$/ + conf.skip_license_check << /^libyui-bindings\/.*/ + conf.skip_license_check << /^libyui-qt\/src\/lang_fonts/ +end diff --git a/deps/libyui/VERSION.cmake b/deps/libyui/VERSION.cmake new file mode 100644 index 0000000000000000000000000000000000000000..34ca66515ff7c96b93706000feb4ebb99ef10c19 --- /dev/null +++ b/deps/libyui/VERSION.cmake @@ -0,0 +1,9 @@ +SET( VERSION_MAJOR "4") +SET( VERSION_MINOR "6" ) +SET( VERSION_PATCH "2" ) +SET( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" ) + +SET( SONAME_MAJOR "16" ) +SET( SONAME_MINOR "0" ) +SET( SONAME_PATCH "0" ) +SET( SONAME "${SONAME_MAJOR}.${SONAME_MINOR}.${SONAME_PATCH}" ) diff --git a/deps/libyui/build-all b/deps/libyui/build-all new file mode 100755 index 0000000000000000000000000000000000000000..1002f05e5512d4d672c4f0e3fe87198908348945 --- /dev/null +++ b/deps/libyui/build-all @@ -0,0 +1,235 @@ +#!/bin/bash +# +# Script to build all (or most) libyui subprojects in the correct order. +# +# This script is intentionally kept in the project toplevel directory +# so it is easy to discover. +# +# Author: Stefan Hundhammer +# License: GPL V2 + +script_name=$(basename $0) +keep_going=0 +error_count=0 +dry_run=0 +verbose=0 + +# subprojects that will or will not be built +with_qt=1 +with_ncurses=1 +with_pkg=1 +with_graph=1 +with_rest_api=0 +with_bindings=0 + + +# Show usage information and exit. +function usage() +{ + cat < +# + +set( csharp_mono_valid 1 ) +if( DEFINED CSHARP_MONO_FOUND ) + # The Mono compiler has already been found + # It may have been reset by the user, verify it is correct + if( NOT DEFINED CSHARP_MONO_COMPILER_${CSHARP_MONO_VERSION} ) + set( csharp_mono_version_user ${CSHARP_MONO_VERSION} ) + set( csharp_mono_valid 0 ) + set( CSHARP_MONO_FOUND 0 ) + set( CSHARP_MONO_VERSION "CSHARP_MONO_VERSION-NOTVALID" CACHE STRING "C# Mono compiler version, choices: ${CSHARP_MONO_VERSIONS}" FORCE ) + message( FATAL_ERROR "The C# Mono version '${csharp_mono_version_user}' is not valid. Please enter one of the following: ${CSHARP_MONO_VERSIONS}" ) + endif( NOT DEFINED CSHARP_MONO_COMPILER_${CSHARP_MONO_VERSION} ) +endif( DEFINED CSHARP_MONO_FOUND ) + +unset( CSHARP_MONO_VERSIONS CACHE ) # Clear versions +if( WIN32 ) + # Search for Mono on Win32 systems + # See http://mono-project.com/OldReleases and http://www.go-mono.com/mono-downloads/download.html + set( csharp_mono_bin_dirs ) + set( csharp_mono_search_hints + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.11.2;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.9;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.8;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.7;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.6;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.5;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.4;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.3;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.2;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10.1;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.10;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.8;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.6.7;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.6.4;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.6.3;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.6.1;SdkInstallRoot]/bin" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono\\2.6;SdkInstallRoot]/bin" + ) + foreach( csharp_mono_search_hint ${csharp_mono_search_hints} ) + get_filename_component( csharp_mono_bin_dir "${csharp_mono_search_hint}" ABSOLUTE ) + if ( EXISTS "${csharp_mono_bin_dir}" ) + set( csharp_mono_bin_dirs ${csharp_mono_bin_dirs} ${csharp_mono_bin_dir} ) + endif ( EXISTS "${csharp_mono_bin_dir}" ) + endforeach( csharp_mono_search_hint ) + # TODO: Use HKLM_LOCAL_MACHINE\Software\Novell\Mono\DefaultCLR to specify default version + # get_filename_component( test "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Novell\\Mono;DefaultCLR]" NAME ) + + foreach ( csharp_mono_bin_dir ${csharp_mono_bin_dirs} ) + string( REPLACE "\\" "/" csharp_mono_bin_dir ${csharp_mono_bin_dir} ) + if (EXISTS "${csharp_mono_bin_dir}/dmcs.bat") + set( csharp_mono_executable "${csharp_mono_bin_dir}/dmcs.bat") + elseif (EXISTS "${csharp_mono_bin_dir}/gmcs.bat") + set( csharp_mono_executable "${csharp_mono_bin_dir}/gmcs.bat") + elseif (EXISTS "${csharp_mono_bin_dir}/mcs.bat") + set( csharp_mono_executable "${csharp_mono_bin_dir}/mcs.bat") + endif (EXISTS "${csharp_mono_bin_dir}/dmcs.bat") + + if( csharp_mono_valid ) + # Extract version number (eg. 2.10.2) + string(REGEX MATCH "([0-9]*)([.])([0-9]*)([.]*)([0-9]*)" csharp_mono_version_temp ${csharp_mono_bin_dir}) + set( CSHARP_MONO_VERSION ${csharp_mono_version_temp} CACHE STRING "C# Mono compiler version" ) + mark_as_advanced( CSHARP_MONO_VERSION ) + + # Add variable holding executable + set( CSHARP_MONO_COMPILER_${csharp_mono_version_temp} ${csharp_mono_executable} CACHE STRING "C# Mono compiler ${csharp_mono_version_temp}" FORCE ) + mark_as_advanced( CSHARP_MONO_COMPILER_${csharp_mono_version_temp} ) + + # Set interpreter + if (EXISTS "${csharp_mono_bin_dir}/mono.exe") + set( CSHARP_MONO_INTERPRETER_${csharp_mono_version_temp} "${csharp_mono_bin_dir}/mono.exe" CACHE STRING "C# Mono interpreter ${csharp_mono_version_temp}" FORCE ) + mark_as_advanced( CSHARP_MONO_INTERPRETER_${csharp_mono_version_temp} ) + endif (EXISTS "${csharp_mono_bin_dir}/mono.exe") + endif( csharp_mono_valid ) + + # Create a list of supported compiler versions + if( NOT DEFINED CSHARP_MONO_VERSIONS ) + set( CSHARP_MONO_VERSIONS "${csharp_mono_version_temp}" CACHE STRING "Available C# Mono compiler versions" FORCE ) + else( NOT DEFINED CSHARP_MONO_VERSIONS ) + set( CSHARP_MONO_VERSIONS "${CSHARP_MONO_VERSIONS}, ${csharp_mono_version_temp}" CACHE STRING "Available C# Mono versions" FORCE ) + endif( NOT DEFINED CSHARP_MONO_VERSIONS ) + mark_as_advanced( CSHARP_MONO_VERSIONS ) + + # We found at least one Mono compiler version + set( CSHARP_MONO_FOUND 1 CACHE INTERNAL "Boolean indicating if C# Mono was found" ) + endforeach( csharp_mono_bin_dir ) + +else( UNIX ) + # Search for Mono on non-Win32 systems + set( chsarp_mono_names "mcs" "mcs.exe" "dmcs" "dmcs.exe" "smcs" "smcs.exe" "gmcs" "gmcs.exe" ) + set( + csharp_mono_paths + "/usr/bin/" + "/usr/local/bin/" + "/usr/lib/mono/2.0" + "/opt/novell/mono/bin" + ) + find_program( + csharp_mono_compiler # variable is added to the cache, we removed it below + NAMES ${chsarp_mono_names} + PATHS ${csharp_mono_paths} + ) + + if( EXISTS ${csharp_mono_compiler} ) + # Determine version + find_program( + csharp_mono_interpreter # variable is added to the cache, we removed it below + NAMES mono + PATHS ${csharp_mono_paths} + ) + if ( EXISTS ${csharp_mono_interpreter} ) + execute_process( + COMMAND ${csharp_mono_interpreter} -V + OUTPUT_VARIABLE csharp_mono_version_string + ) + string( REGEX MATCH "([0-9]*)([.])([0-9]*)([.]*)([0-9]*)" csharp_mono_version_temp ${csharp_mono_version_string} ) + set( CSHARP_MONO_INTERPRETER_${CSHARP_MONO_VERSION} ${csharp_mono_interpreter} CACHE STRING "C# Mono interpreter ${csharp_mono_version_temp}" FORCE ) + mark_as_advanced( CSHARP_MONO_INTERPRETER_${CSHARP_MONO_VERSION} ) + endif ( EXISTS ${csharp_mono_interpreter} ) + unset( csharp_mono_interpreter CACHE ) + + # We found Mono compiler + set( CSHARP_MONO_VERSION ${csharp_mono_version_temp} CACHE STRING "C# Mono compiler version" ) + mark_as_advanced( CSHARP_MONO_VERSION ) + set( CSHARP_MONO_COMPILER_${CSHARP_MONO_VERSION} ${csharp_mono_compiler} CACHE STRING "C# Mono compiler ${CSHARP_MONO_VERSION}" FORCE ) + mark_as_advanced( CSHARP_MONO_COMPILER_${CSHARP_MONO_VERSION} ) + set( CSHARP_MONO_VERSIONS ${CSHARP_MONO_VERSION} CACHE STRING "Available C# Mono compiler versions" FORCE ) + mark_as_advanced( CSHARP_MONO_VERSIONS ) + set( CSHARP_MONO_FOUND 1 CACHE INTERNAL "Boolean indicating if C# Mono was found" ) + endif( EXISTS ${csharp_mono_compiler} ) + + # Remove temp variable from cache + unset( csharp_mono_compiler CACHE ) + +endif( WIN32 ) + +if( CSHARP_MONO_FOUND ) + # Report the found versions + message( STATUS "Found the following C# Mono versions: ${CSHARP_MONO_VERSIONS}" ) +endif( CSHARP_MONO_FOUND ) + +# Set USE_FILE +get_filename_component( current_list_path ${CMAKE_CURRENT_LIST_FILE} PATH ) +set( Mono_USE_FILE ${current_list_path}/UseMono.cmake ) \ No newline at end of file diff --git a/deps/libyui/libyui-bindings/swig/CMakeLists.txt b/deps/libyui/libyui-bindings/swig/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b21350611b593eaedf14d08ecb7c51e0a58306f5 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/CMakeLists.txt @@ -0,0 +1,44 @@ +# +# Generic setting for all generated bindings +# +SET( SWIG_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/yui.i" ) + +OPTION (WITH_MONO "Build CSharp/Mono bindings" ON) +OPTION (WITH_PYTHON "Build Python bindings" ON) +OPTION (WITH_PERL "Build Perl bindings" ON) +OPTION (WITH_RUBY "Build Ruby bindings" ON) + + +IF (WITH_RUBY) + FIND_PACKAGE(Ruby) + IF (RUBY_LIBRARY AND RUBY_INCLUDE_PATH) + ADD_SUBDIRECTORY(ruby) + ENDIF(RUBY_LIBRARY AND RUBY_INCLUDE_PATH) +ENDIF (WITH_RUBY) + +IF (WITH_PYTHON) + FIND_PACKAGE(PythonLibs) + IF (PYTHON_LIBRARY) + ADD_SUBDIRECTORY(python) + ENDIF(PYTHON_LIBRARY) +ENDIF (WITH_PYTHON) + +IF (WITH_PERL) + # doesn't work yet :-( + # CMake problem, FindPerlLibs.cmake is in a _really_ bad, bad state :-(( + # see e.g. http://www.vtk.org/Bug/print_bug_page.php?bug_id=3665 + FIND_PACKAGE(PerlLibs) + #FindPerl.cmake included by FindPerlLibs.cmake + #FIND_PACKAGE(Perl) + IF (PERL_EXECUTABLE) + MESSAGE(STATUS "Perl executable: ${PERL_EXECUTABLE}") + ADD_SUBDIRECTORY(perl) + ENDIF (PERL_EXECUTABLE) +ENDIF (WITH_PERL) + +IF (WITH_MONO) + FIND_PACKAGE(Mono) + IF (CSHARP_MONO_FOUND) + ADD_SUBDIRECTORY(mono) + ENDIF (CSHARP_MONO_FOUND) +ENDIF (WITH_MONO) diff --git a/deps/libyui/libyui-bindings/swig/mono/CMakeLists.txt b/deps/libyui/libyui-bindings/swig/mono/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a2a05c92945b806e072e0cdaef3283e1b3471a2d --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/mono/CMakeLists.txt @@ -0,0 +1,93 @@ +# +# cmake description for libyui CSharp bindings +# +# !!Attn!!: This creates two files +# 1. yui.so +# 2. yui.dll +# and the .dll file gets imported. See bindings/csharp/tests. +# + +IF (NOT MONO_LIBRARIES) + SET (MONO_LIBRARIES "/usr/lib/mono") +ENDIF (NOT MONO_LIBRARIES) + +# SWIG_OUPUT is per-target +SET( SWIG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/yui_csharp.cxx" ) + + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + + +# Symlink ../../../libyui/src to build/src/include/yui +# so the headers there can be included as +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR} ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui/src ${LOCAL_INCLUDE_DIR}/yui SYMBOLIC ) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src) + file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src ${LOCAL_INCLUDE_DIR}/yui/mga SYMBOLIC ) +endif() + + +ADD_CUSTOM_COMMAND ( + OUTPUT ${SWIG_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E echo_append "Creating wrapper code for CSharp ..." + COMMAND ${SWIG_EXECUTABLE} -c++ -csharp -features autodoc ${SWIG_FLAGS} -o ${SWIG_OUTPUT} -I${LOCAL_INCLUDE_DIR} ${LIBYUI_INCLUDE_CFLAGS} ${SWIG_INPUT} + COMMAND ${CMAKE_COMMAND} -E echo "Done." + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../*.i +) + + +SET(yui_csharp_SRCS ${SWIG_OUTPUT} ) + +set( TARGETLIB yui_csharp ) +ADD_LIBRARY( ${TARGETLIB} SHARED ${yui_csharp_SRCS} ) +# name it 'yui' ==> i.e. yui.so +# and don't prefix with 'lib' +SET_TARGET_PROPERTIES( ${TARGETLIB} PROPERTIES PREFIX "" OUTPUT_NAME "yui") + +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) + +if ( WITH_MGA) + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/build/src) + # Find yui and yui-mga during a combined build + target_link_directories( ${TARGETLIB} + BEFORE PUBLIC ../../../libyui/build/src + BEFORE PUBLIC ../../../libyui-mga/build/src + ) + else() + # Using yui and yui-mga from system + target_link_directories( ${TARGETLIB} + PUBLIC ${YUI_LIBRARY_DIRS} + PUBLIC ${YUIMGA_LIBRARY_DIRS} + ) + endif() +else() + # Find yui during a combined build + target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../../libyui/build/src ) +endif() + +TARGET_LINK_LIBRARIES( ${TARGETLIB} ${LIBYUI_LIBRARY} ) + +# +# WORKAROUND: replace DllImport("yui" with DllImport("/abs_path/yui.so" +# +ADD_CUSTOM_COMMAND( + TARGET ${TARGETLIB} + POST_BUILD + COMMAND sed -i -e 's|DllImport\(\"yui\"|DllImport\(\"${MONO_LIBRARIES}/yui/yui.so\"|g' "${CMAKE_CURRENT_BINARY_DIR}/yuiPINVOKE.cs" ) + + +ADD_CUSTOM_COMMAND( + TARGET ${TARGETLIB} POST_BUILD + COMMAND "${CSHARP_MONO_COMPILER_${CSHARP_MONO_VERSION}}" /t:library *.cs /out:yui.dll + COMMENT "Creating yui.dll" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +) + +INSTALL(TARGETS ${TARGETLIB} LIBRARY DESTINATION "${MONO_LIBRARIES}/yui") + +INSTALL( + FILES ${CMAKE_CURRENT_BINARY_DIR}/yui.dll + DESTINATION "${MONO_LIBRARIES}/yui" + COMPONENT csharp +) diff --git a/deps/libyui/libyui-bindings/swig/perl/CMakeLists.txt b/deps/libyui/libyui-bindings/swig/perl/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..575ea67aa3d7ddc2431c2a62917b1b70376ba990 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/perl/CMakeLists.txt @@ -0,0 +1,89 @@ +# +# cmake description for libyui Perl bindings +# +# !!Attn!!: This creates two files +# 1. _yui.so +# 2. yui.pm +# and the .pm file gets loaded. See bindings/perl/tests. +# + +# SWIG_OUPUT is per-target +SET( SWIG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/yui_perl.cxx" ) + +EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -e "use Config; print \$Config{ccflags}" OUTPUT_VARIABLE PERL_CCFLAGS) +EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -e "use Config; print \$Config{archlib}.\"/CORE\"" OUTPUT_VARIABLE PERL_CORE_DIR) +EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -e "use Config; print \$Config{installvendorarch}" OUTPUT_VARIABLE PERL_VENDOR_ARCH) +EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -e "use Config; print \$Config{installvendorlib}" OUTPUT_VARIABLE PERL_VENDOR_LIB) +EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -e "use Config; print \$Config{ccdlflags}; print \",-lpthread\"" OUTPUT_VARIABLE PERL_LINK_FLAGS) + +STRING(REGEX REPLACE "^/usr/" "${CMAKE_INSTALL_PREFIX}/" PERL_VENDOR_ARCH "${PERL_VENDOR_ARCH}") +STRING(REGEX REPLACE "^/usr/" "${CMAKE_INSTALL_PREFIX}/" PERL_VENDOR_LIB "${PERL_VENDOR_LIB}") + +MESSAGE(STATUS "Perl executable: ${PERL_EXECUTABLE}") +MESSAGE(STATUS "Perl core dir: ${PERL_CORE_DIR}") +MESSAGE(STATUS "Perl vendor arch dir: ${PERL_VENDOR_ARCH}") +MESSAGE(STATUS "Perl vendor lib dir: ${PERL_VENDOR_LIB}") + +ADD_DEFINITIONS( ${PERL_CCFLAGS} -Wno-unused -Wno-error ) +LINK_DIRECTORIES( ${PERL_CORE_DIR} ) + +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif(COMMAND cmake_policy) + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + + +# Symlink ../../../libyui/src to build/src/include/yui +# so the headers there can be included as +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR} ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui/src ${LOCAL_INCLUDE_DIR}/yui SYMBOLIC ) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src) + file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src ${LOCAL_INCLUDE_DIR}/yui/mga SYMBOLIC ) +endif() + + +ADD_CUSTOM_COMMAND ( + OUTPUT ${SWIG_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E echo_append "Creating wrapper code for Perl ..." + COMMAND ${SWIG_EXECUTABLE} -c++ -perl -shadow -features autodoc ${SWIG_FLAGS} -o ${SWIG_OUTPUT} -I${LOCAL_INCLUDE_DIR} ${LIBYUI_INCLUDE_CFLAGS} ${SWIG_INPUT} + COMMAND ${CMAKE_COMMAND} -E echo "Done." + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../*.i +) + +SET(yui_perl_SRCS ${SWIG_OUTPUT} ) + +set( TARGETLIB yui_perl ) +ADD_LIBRARY( ${TARGETLIB} SHARED ${yui_perl_SRCS} ) +# name it 'yui.so' +# and don't prefix with 'lib' +SET_TARGET_PROPERTIES( ${TARGETLIB} PROPERTIES PREFIX "" OUTPUT_NAME "yui") + +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) +INCLUDE_DIRECTORIES( ${PERL_CORE_DIR} ${LIBYUI_INCLUDE_DIR}) + +if ( WITH_MGA) + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/build/src) + # Find yui and yui-mga during a combined build + target_link_directories( ${TARGETLIB} + BEFORE PUBLIC ../../../libyui/build/src + BEFORE PUBLIC ../../../libyui-mga/build/src + ) + else() + # Using yui and yui-mga from system + target_link_directories( ${TARGETLIB} + PUBLIC ${YUI_LIBRARY_DIRS} + PUBLIC ${YUIMGA_LIBRARY_DIRS} + ) + endif() +else() + # Find yui during a combined build + target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../../libyui/build/src ) +endif() + +TARGET_LINK_LIBRARIES( ${TARGETLIB} pthread ${LIBYUI_LIBRARY} ${PERL_LIBRARY}) + +INSTALL(TARGETS ${TARGETLIB} LIBRARY DESTINATION ${PERL_VENDOR_ARCH} ) + +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/yui.pm DESTINATION ${PERL_VENDOR_LIB} ) diff --git a/deps/libyui/libyui-bindings/swig/perl/examples/hello_world.pl b/deps/libyui/libyui-bindings/swig/perl/examples/hello_world.pl new file mode 100644 index 0000000000000000000000000000000000000000..d069e81e43144c811ac1373003e17d9c8618511f --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/perl/examples/hello_world.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl +# +# Trivial libyui example +# +use lib '../../../build/swig/perl'; + +use yui; + +my $factory = yui::YUI::widgetFactory; +my $dialog = $factory->createPopupDialog; + +my $vbox = $factory->createVBox( $dialog ); +$factory->createLabel( $vbox, "Hello, World!" ); +$factory->createPushButton( $vbox, "&OK" ); +my $event = $dialog->waitForEvent(); +$dialog->destroy(); diff --git a/deps/libyui/libyui-bindings/swig/perl/examples/loading.pl b/deps/libyui/libyui-bindings/swig/perl/examples/loading.pl new file mode 100644 index 0000000000000000000000000000000000000000..58956ceb4db065386c0f5c22e3caa43b41c24728 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/perl/examples/loading.pl @@ -0,0 +1,6 @@ +#!/usr/bin/perl + +use lib '../../../build/swig/perl'; + +use yui; + diff --git a/deps/libyui/libyui-bindings/swig/perl/examples/selection_box1.pl b/deps/libyui/libyui-bindings/swig/perl/examples/selection_box1.pl new file mode 100644 index 0000000000000000000000000000000000000000..d6b4450593d89896173347673869b6816639db5c --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/perl/examples/selection_box1.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# +# More advanced libyui example +# + +use lib '../../../build/swig/perl'; + +use yui; + +# yui::YUILog::setLogFileName( "/tmp/libyui-examples.log" ); +# yui::YUILog::enableDebugLogging(); + +my $factory = yui::YUI::widgetFactory; +my $dialog = $factory->createPopupDialog; + +my $vbox = $factory->createVBox( $dialog ); + +my $selBox = $factory->createSelectionBox( $vbox, "&Menu" ); + +$selBox->addItem( "Pizza Margherita" ); +$selBox->addItem( "Pizza Capricciosa" ); +$selBox->addItem( "Pizza Funghi" ); +$selBox->addItem( "Pizza Prosciutto" ); +$selBox->addItem( "Pizza Quattro Stagioni" ); +$selBox->addItem( "Calzone" ); + +my $hbox = $factory->createHBox( $vbox ); +$valueField = $factory->createOutputField( $hbox, "" ); +$valueField->setStretchable( $yui::YD_HORIZ, 1 ); # // allow stretching over entire dialog width + +$valueButton = $factory->createPushButton( $hbox, "&Value" ); +$factory->createVSpacing( $vbox, 0.3 ); + +$rightAlignment = $factory->createRight( $vbox ); +$closeButton = $factory->createPushButton( $rightAlignment, "&Close" ); + +# +# Event loop +# +while (1) { + $event = $dialog->waitForEvent(); + if( not event ) { + next + } + if ($event->eventType() == $yui::YEvent::CancelEvent) { # window manager "close window" button + last; + } + $valueField->setValue( "???" ); + if ($event->widget() == $closeButton) { + last; + } + + if ( ($event->widget() == $valueButton) or ($event->widget() == $selBox )) { # selBox will only send events with setNotify() + $item = $selBox->selectedItem(); + if ($item) { + $valueField->setValue( $item->label() ); + } + else { + $valueField->setValue( "" ); + } + } +} diff --git a/deps/libyui/libyui-bindings/swig/perl/examples/twitter.pl b/deps/libyui/libyui-bindings/swig/perl/examples/twitter.pl new file mode 100644 index 0000000000000000000000000000000000000000..82ed2956a3ed5914c07442fa6cd83f74fc4b9555 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/perl/examples/twitter.pl @@ -0,0 +1,116 @@ +#!/usr/bin/perl + +use lib '../../../build/swig/perl'; +use yui; +use Data::Dumper; +use Net::Twitter; + +my $nt; +my $factory = yui::YUI::widgetFactory; + +sub login { + my $username = shift; + my $password = shift; + + $nt = Net::Twitter::Lite->new( + username => $username, + password => $password, + ); +} + +sub post { + my $newdialog = $factory->createPopupDialog; + + my $min = $factory->createMinWidth($newdialog, 45); + my $vvbox = $factory->createVBox( $min ); + my $textbox = $factory->createMultiLineEdit($vvbox, "What's up?"); + + my $hbox = $factory->createHBox( $vvbox ); + + my $left = $factory->createLeft( $hbox ); + my $statuslabel = $factory->createLabel($left, "Ready ..."); + my $right = $factory->createRight( $hbox ); + my $update = $factory->createPushButton( $right, "Post Update..." ); + my $cruft = $factory->createVSpacing($vvbox, 1); + my $cancel = $factory->createPushButton( $vvbox, "Quit" ); + + while ( 1 ) { + $event = $newdialog->waitForEvent(); + + if ( not event) { + next + } + + # break the loop, quit + + if ($event->widget() == $cancel ) { + last; + } + + # post an update + + if ($event->widget() == $update ) { + my $text = $textbox->value(); + eval { $nt->update($text) }; + + if ( $@ ) { + $statuslabel->setValue( "Update failed!" ); + } + else { + $statuslabel->setValue( "Update OK :)"); + $textbox->setValue(""); + } + next; + } + } + # clean up + $newdialog->destroy(); +} + +my $dialog = $factory->createPopupDialog; + +#################################################### +# # +# dialog # +# vbox # +# label # +# input field # +# passwd field # +# spacing # +# hbox # +# pushbutton # +# pushbutton # +# # +#################################################### + +my $vbox = $factory->createVBox( $dialog ); +my $label = $factory->createLabel( $vbox, "Login to your Twitter account"); +my $username = $factory->createInputField($vbox, "User"); +$username->setStretchable( $yui::YD_HORIZ, 1 ); +my $pass = $factory->createPasswordField($vbox,"Password"); +$pass->setStretchable( $yui::YD_HORIZ, 1 ); + +my $fillup = $factory->createVSpacing($vbox, 1); +my $buttonbox = $factory->createHBox( $vbox ); +my $cancel = $factory->createPushButton( $buttonbox, "Cancel" ); +my $login = $factory->createPushButton( $buttonbox, "Login" ); + +while ( 1 ) { + $event = $dialog->waitForEvent(); + if ( not event ) { + next + } + + if ($event->widget() == $cancel ) { + $dialog->destroy(); + last; + } + + if ($event->widget() == $login ) { + login( $username->value(), $pass->value() ); + $dialog->destroy(); + post; + last; + } +} + diff --git a/deps/libyui/libyui-bindings/swig/python/CMakeLists.txt b/deps/libyui/libyui-bindings/swig/python/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8d5f90bc91a4467c78f020b7291e7a587cef6b40 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/CMakeLists.txt @@ -0,0 +1,83 @@ +# +# cmake description for libyui Python bindings +# +# !!Attn!!: This creates two files +# 1. yui.so +# 2. yui.py +# and the .py file gets imported. See bindings/python/tests. +# + +# SWIG_OUPUT is per-target +SET( SWIG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/yui_python.cxx" ) + + +FIND_PACKAGE(PythonInterp) +EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -c "import sys; sys.stdout.write(sys.path[2])" OUTPUT_VARIABLE PYTHON_LIB_DIR) + +IF (NOT PYTHON_SITEDIR) + SET (PYTHON_SITEDIR ${PYTHON_LIB_DIR}/site-packages) + STRING(REGEX REPLACE "^/usr/" "${CMAKE_INSTALL_PREFIX}/" PYTHON_SITEDIR "${PYTHON_SITEDIR}") +ENDIF (NOT PYTHON_SITEDIR) + +MESSAGE(STATUS "Python executable: ${PYTHON_EXECUTABLE}") +MESSAGE(STATUS "Python include dir: ${PYTHON_INCLUDE_PATH}") +MESSAGE(STATUS "Python lib dir: ${PYTHON_LIB_DIR}") +MESSAGE(STATUS "Python site dir: ${PYTHON_SITEDIR}") + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + + +# Symlink ../../../libyui/src to build/src/include/yui +# so the headers there can be included as +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR} ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui/src ${LOCAL_INCLUDE_DIR}/yui SYMBOLIC ) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src) + file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src ${LOCAL_INCLUDE_DIR}/yui/mga SYMBOLIC ) +endif() + + +ADD_CUSTOM_COMMAND ( + OUTPUT ${SWIG_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E echo_append "Creating wrapper code for Python ..." + COMMAND ${SWIG_EXECUTABLE} -c++ -python -shadow -features autodoc ${SWIG_FLAGS} -o ${SWIG_OUTPUT} -I${LOCAL_INCLUDE_DIR} ${LIBYUI_INCLUDE_CFLAGS} ${SWIG_INPUT} + COMMAND ${CMAKE_COMMAND} -E echo "Done." + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../*.i +) + +SET(yui_python_SRCS ${SWIG_OUTPUT} ) + +set( TARGETLIB yui_python ) +ADD_LIBRARY( ${TARGETLIB} SHARED ${yui_python_SRCS} ) +# name it '_yui.so' +# and don't prefix with 'lib' +SET_TARGET_PROPERTIES( ${TARGETLIB} PROPERTIES PREFIX "" OUTPUT_NAME "_yui") + +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) +INCLUDE_DIRECTORIES( ${PYTHON_INCLUDE_PATH} ${LIBYUI_INCLUDE_DIR} ) + +if ( WITH_MGA) + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/build/src) + # Find yui and yui-mga during a combined build + target_link_directories( ${TARGETLIB} + BEFORE PUBLIC ../../../libyui/build/src + BEFORE PUBLIC ../../../libyui-mga/build/src + ) + else() + # Using yui and yui-mga from system + target_link_directories( ${TARGETLIB} + PUBLIC ${YUI_LIBRARY_DIRS} + PUBLIC ${YUIMGA_LIBRARY_DIRS} + ) + endif() +else() + # Find yui during a combined build + target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../../libyui/build/src ) +endif() + +TARGET_LINK_LIBRARIES( ${TARGETLIB} ${LIBYUI_LIBRARY} ) +TARGET_LINK_LIBRARIES( ${TARGETLIB} ${PYTHON_LIBRARIES} ) + +INSTALL(TARGETS ${TARGETLIB} LIBRARY DESTINATION ${PYTHON_SITEDIR}) + +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/yui.py DESTINATION ${PYTHON_SITEDIR} ) diff --git a/deps/libyui/libyui-bindings/swig/python/examples/YTable_n_YItemCollection.py b/deps/libyui/libyui-bindings/swig/python/examples/YTable_n_YItemCollection.py new file mode 100644 index 0000000000000000000000000000000000000000..2a013f1f9b4541c74e8d880718bceee8a747ebfd --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/YTable_n_YItemCollection.py @@ -0,0 +1,57 @@ +# +# Example that shows how to fill a table using YItemCollection +# +# Copyright information +# +# Author: Angelo Naselli +# +# License +# +# 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, see . + +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui + +factory = yui.YUI.widgetFactory() +dialog = factory.createMainDialog() + +VBox = factory.createVBox(dialog) + +yTableHeader = yui.YTableHeader() +yTableHeader.addColumn("package") +yTableHeader.addColumn("version") +yTableHeader.addColumn("release") +yTableHeader.addColumn("arch") + +myTableMinSize = factory.createMinSize(VBox, 50, 12) +myTable = factory.createTable(myTableMinSize, yTableHeader) + +myOK = factory.createPushButton(VBox, "OK") + +# NOTE YItemCollection have problems +# because YItem is not disown() so it must +# be done explicitally by using this.own property +ic = yui.YItemCollection() +for pkg in range(1,10): + name = "name-{0}".format(pkg) + item = yui.YTableItem(name , "1.0", "1", "i585") + item.this.own(False) # comment this to have a crash + ic.push_back(item) + +myTable.addItems(ic) + +event1 = dialog.waitForEvent() + +dialog.destroy() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/displayinfo.py b/deps/libyui/libyui-bindings/swig/python/examples/displayinfo.py new file mode 100644 index 0000000000000000000000000000000000000000..fe9a46d1f205d4208c8b577b1f2d177e8d060836 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/displayinfo.py @@ -0,0 +1,38 @@ +# +# map disp = UI::GetDisplayInfo(); +# is a YCP-only function defined in ycp-ui-bindings/src/YCP_UI.cc +# + +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui + +appl = yui.YUI.application() +print "Width ", appl.displayWidth() +print "Height ", appl.displayHeight() +print "Depth ", appl.displayDepth() +print "Colors ", appl.displayColors() +print "DefaultWidth ", appl.defaultWidth() +print "DefaultHeight ", appl.defaultHeight() +print "TextMode ", appl.isTextMode() +print "HasImageSupport ", appl.hasImageSupport() +print "HasIconSupport ", appl.hasIconSupport() +print "HasAnimationSupport ", appl.hasAnimationSupport() +print "HasFullUtf8Support ", appl.hasFullUtf8Support() +print "RichTextSupportsTable ", appl.richTextSupportsTable() +print "LeftHandedMouse ", appl.leftHandedMouse() +log = yui.YUILog.instance() +print "y2debug ", log.debugLoggingEnabled() + +optional = yui.YUI.optionalWidgetFactory() + +print "Has wizard ", optional.hasWizard() + +#factory = yui.YUI.widgetFactory() +#dialog = factory.createPopupDialog() + +#vbox = factory.createVBox( dialog ) +#factory.createLabel( vbox, "Hello, World!" ) +#factory.createPushButton( vbox, "&OK" ) +#event = dialog.waitForEvent() +#dialog.destroy() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/hello_world.py b/deps/libyui/libyui-bindings/swig/python/examples/hello_world.py new file mode 100644 index 0000000000000000000000000000000000000000..e84024e5e59dcd26a6a7cb76231c0bbc93def911 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/hello_world.py @@ -0,0 +1,16 @@ +# +# Trivial libyui example +# + +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui + +factory = yui.YUI.widgetFactory() +dialog = factory.createPopupDialog() + +vbox = factory.createVBox( dialog ) +factory.createLabel( vbox, "Hello, World!" ) +factory.createPushButton( vbox, "&OK" ) +event = dialog.waitForEvent() +dialog.destroy() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/loading.py b/deps/libyui/libyui-bindings/swig/python/examples/loading.py new file mode 100644 index 0000000000000000000000000000000000000000..cf803bd4c192326589665036a2976bf67ced2c85 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/loading.py @@ -0,0 +1,3 @@ +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui diff --git a/deps/libyui/libyui-bindings/swig/python/examples/menu.py b/deps/libyui/libyui-bindings/swig/python/examples/menu.py new file mode 100644 index 0000000000000000000000000000000000000000..ef467f4e05d4d08a376baeec80d61667de284565 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/menu.py @@ -0,0 +1,19 @@ +# +# Trivial libyui example +# + +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui + +factory = yui.YUI.widgetFactory() +dialog = factory.createMainDialog() +hbox = factory.createHBox(dialog) +menu1 = factory.createMenuButton(hbox, "File") +print "menu1", menu1 +item1 = yui.YMenuItem("open") +print "item1", item1 +menu1.addItem(item1) +menu1.rebuildMenuTree() +event = dialog.waitForEvent() # push button +dialog.destroy() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/menubar.py b/deps/libyui/libyui-bindings/swig/python/examples/menubar.py new file mode 100644 index 0000000000000000000000000000000000000000..65c5a02a8c037c5cdd161b74c0c971290a76f7bd --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/menubar.py @@ -0,0 +1,117 @@ +# vim: set et ts=4 sw=4: +#coding:utf-8 +############################################################################# +# +# menubar.py - Show a dialog with YMenuBar implementation +# +# License: GPLv2+ +# Author: Angelo Naselli +############################################################################# + +########### +# imports # +########### +import sys +sys.path.insert(0,'../../../build/swig/python') +import os + +import yui + +log = yui.YUILog.instance() +log.setLogFileName("/tmp/menubar.log") +log.enableDebugLogging( True ) +appl = yui.YUI.application() +appl.setApplicationTitle("Show YMenuBar example") + +################# +# class mainGui # +################# + +class mainGui(): + """ + Main class + """ + + def __init__(self): + self.factory = yui.YUI.widgetFactory() + self.dialog = self.factory.createPopupDialog() + minSize = self.factory.createMinSize(self.dialog, 50, 20 ) + mainvbox = self.factory.createVBox(minSize) + self.menubar = self.factory.createMenuBar(mainvbox) + + #Items must be "disowned" + fileMenu = self.menubar.addMenu("&File") + fileMenu.this.own(False) + tmi = yui.YMenuItem(fileMenu, "&New") + tmi.this.own(False) + item = yui.YMenuItem( tmi, "New &1" , "document-new") + item.this.own(False) + item = yui.YMenuItem( tmi, "New &2" , "contact-new") + item.this.own(False) + item = fileMenu.addSeparator() + item.this.own(False) + item = yui.YMenuItem(fileMenu, "&Open", "document-open.png") + item.this.own(False) + item = fileMenu.addSeparator() + item.this.own(False) + item = yui.YMenuItem(fileMenu, "&Save", "document-save.png") + item.this.own(False) + item = yui.YMenuItem(fileMenu, "&Save as", "document-save-as") + item.this.own(False) + item = fileMenu.addSeparator() + item.this.own(False) + self.quitMenu = yui.YMenuItem(fileMenu, "&Quit", "application-exit") + self.quitMenu.this.own(False) + + editmenu = self.menubar.addMenu("&Edit") + self.editMenu = { + 'menu' : editmenu, + 'undo' : editmenu.addItem("&Undo", "edit-undo.png"), + 'redo' : editmenu.addItem("&Redo", "edit-redo.png"), + 'sep0' : editmenu.addSeparator(), + 'cut' : editmenu.addItem("Cu&t", "edit-cut.png"), + 'copy' : editmenu.addItem("&Copy", "edit-copy.png"), + 'paste' : yui.YMenuItem(editmenu, "&Paste", "edit-paste.png"), + } + #Items must be "disowned" + for k in self.editMenu.keys(): + self.editMenu[k].this.own(False) + + self.menubar.resolveShortcutConflicts() + self.menubar.rebuildMenuTree() + + HBox = self.factory.createHBox(mainvbox) + self.closebutton = self.factory.createPushButton(self.factory.createRight(HBox), "&Close") + + + def handleevent(self): + """ + Event-handler for the 'widgets' demo + """ + while True: + event = self.dialog.waitForEvent() + eventType = event.eventType() + if eventType == yui.YEvent.CancelEvent: + break + elif (eventType == yui.YEvent.MenuEvent) : + item = event.item() + if (item) : + if item == self.quitMenu : + break + elif (eventType == yui.YEvent.WidgetEvent) : + # widget selected + widget = event.widget() + if (widget == self.closebutton) : + break + + self.dialog.destroy() + +if __name__ == "__main__": + main_gui = mainGui() + main_gui.handleevent() + + yui.YDialog.deleteAllDialogs() + # next line seems to be a workaround to prevent the qt-app from crashing + # see https://github.com/libyui/libyui-qt/issues/41 + yui.YUILoader.deleteUI() + diff --git a/deps/libyui/libyui-bindings/swig/python/examples/mga-dialogs.py b/deps/libyui/libyui-bindings/swig/python/examples/mga-dialogs.py new file mode 100644 index 0000000000000000000000000000000000000000..285590cc53b55fd6d043de13d892c78731fcb002 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/mga-dialogs.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# vim: set et ts=4 sw=4: +#coding:utf-8 +############################################################################# +# +# mga-dialogs.py - Show mga msg dialog and about dialog. +# +# License: GPLv3 +# Author: Angelo Naselli +############################################################################# + +########### +# imports # +########### +import sys +sys.path.insert(0,'../../../build/swig/python') +import os + +import yui + +log = yui.YUILog.instance() +log.setLogFileName("/tmp/debug.log") +log.enableDebugLogging( True ) +appl = yui.YUI.application() +appl.setApplicationTitle("Show dialogs example") + +################# +# class mainGui # +################# +class Info(object): + def __init__(self,title,richtext,text): + self.title=title + self.richtext=richtext + self.text=text + +class mainGui(): + """ + Main class + """ + + def __init__(self): + self.factory = yui.YUI.widgetFactory() + self.dialog = self.factory.createPopupDialog() + mainvbox = self.factory.createVBox(self.dialog) + frame = self.factory.createFrame(mainvbox,"Test frame") + HBox = self.factory.createHBox(frame) + self.aboutbutton = self.factory.createPushButton(HBox,"&About") + self.closebutton = self.factory.createPushButton(self.factory.createRight(HBox), "&Close") + + + def ask_YesOrNo(self, info): + yui.YUI.widgetFactory + mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory(yui.YExternalWidgets.externalWidgetFactory("mga")) + dlg = mgafactory.createDialogBox(yui.YMGAMessageBox.B_TWO) + dlg.setTitle(info.title) + dlg.setText(info.text, info.richtext) + dlg.setButtonLabel("Yes", yui.YMGAMessageBox.B_ONE) + dlg.setButtonLabel("No", yui.YMGAMessageBox.B_TWO) + dlg.setMinSize(50, 5); + return dlg.show() == yui.YMGAMessageBox.B_ONE + + def aboutDialog(self): + yui.YUI.widgetFactory; + mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory(yui.YExternalWidgets.externalWidgetFactory("mga")) + dlg = mgafactory.createAboutDialog("About dialog title example", "1.0.0", "GPLv3", + "Angelo Naselli", "This beautiful test example shows how it is easy to play with libyui bindings", "") + dlg.show(); + + + def handleevent(self): + """ + Event-handler for the 'widgets' demo + """ + while True: + event = self.dialog.waitForEvent() + if event.eventType() == yui.YEvent.CancelEvent: + self.dialog.destroy() + break + if event.widget() == self.closebutton: + info = Info("Quit confirmation", 1, "Are you sure you want to quit?") + if self.ask_YesOrNo(info): + self.dialog.destroy() + break + if event.widget() == self.aboutbutton: + self.aboutDialog() + +if __name__ == "__main__": + main_gui = mainGui() + main_gui.handleevent() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/replacepoint.py b/deps/libyui/libyui-bindings/swig/python/examples/replacepoint.py new file mode 100644 index 0000000000000000000000000000000000000000..288b33aa34f3f6e66c18617061094aad9a8258bb --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/replacepoint.py @@ -0,0 +1,28 @@ +# coding=UTF-8 +# +# Replacepoint, allows you to replace part of the widget tree +# +# Example by Jan-Simon Möller +# + +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui + +factory = yui.YUI.widgetFactory() +dialog = factory.createMainDialog() +replacepoint = factory.createReplacePoint(dialog) +hbox = factory.createHBox(replacepoint) +b1 = factory.createPushButton(hbox, "1") +b2 = factory.createPushButton(hbox, "2") +b3 = factory.createPushButton(hbox, "3") +event = dialog.waitForEvent() # push button +replacepoint.deleteChildren() +vbox = factory.createVBox(replacepoint) +b1 = factory.createPushButton(vbox, "1") +b2 = factory.createPushButton(vbox, "2") +b3 = factory.createPushButton(vbox, "3") +dialog.recalcLayout() +replacepoint.showChild() +event = dialog.waitForEvent() # tada! +dialog.destroy() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/selection_box1.py b/deps/libyui/libyui-bindings/swig/python/examples/selection_box1.py new file mode 100644 index 0000000000000000000000000000000000000000..a8dcd673dbe8f78339a4cde09b03b09cf90bc5a1 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/selection_box1.py @@ -0,0 +1,57 @@ +# +# More advanced libyui example +# + +import sys +sys.path.insert(0, '../../../build/swig/python') +import yui + +factory = yui.YUI.widgetFactory(); + +yui.YUILog.setLogFileName( "/tmp/libyui-examples.log" ) +yui.YUILog.enableDebugLogging() + +dialog = factory.createPopupDialog() +vbox = factory.createVBox( dialog ) +selBox = factory.createSelectionBox( vbox, "&Menu" ) + +selBox.addItem( "Pizza Margherita" ) +selBox.addItem( "Pizza Capricciosa" ) +selBox.addItem( "Pizza Funghi" ) +selBox.addItem( "Pizza Prosciutto" ) +selBox.addItem( "Pizza Quattro Stagioni" ) +selBox.addItem( "Calzone" ) + +hbox = factory.createHBox( vbox ) +valueField = factory.createOutputField( hbox, "" ) +valueField.setStretchable( yui.YD_HORIZ, True ) # // allow stretching over entire dialog width + +valueButton = factory.createPushButton( hbox, "&Value" ) +factory.createVSpacing( vbox, 0.3 ) + +rightAlignment = factory.createRight( vbox ) +closeButton = factory.createPushButton( rightAlignment, "&Close" ) + +# +# Event loop +# + +while True: + event = dialog.waitForEvent() + if not event: + print "Empty" + next + if event.eventType() == yui.YEvent.CancelEvent: # window manager "close window" button + break + valueField.setValue( "???" ) + if event.widget() == closeButton: + break + + if ( event.widget() == valueButton or event.widget() == selBox ): # selBox will only send events with setNotify() + item = selBox.selectedItem() + if item: + valueField.setValue( item.label() ) + else: + valueField.setValue( "" ) + +dialog.destroy() diff --git a/deps/libyui/libyui-bindings/swig/python/examples/table.py b/deps/libyui/libyui-bindings/swig/python/examples/table.py new file mode 100644 index 0000000000000000000000000000000000000000..aa14f9185d74ef3d44a242ae73a19c0842183d30 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/table.py @@ -0,0 +1,57 @@ +# +# Table example +# taken from https://bugzilla.novell.com/show_bug.cgi?id=449842#c10 +# + +# ensure we're using the latest build, if called from our build environment +import sys +sys.path.insert(0,'../../../build/swig/python') + +import yui + +# enable logging for debug +log = yui.YUILog.instance() +log.setLogFileName("debug.log") +log.enableDebugLogging( True ) + +factory = yui.YUI.widgetFactory() +dialog = factory.createMainDialog() + +VBox = factory.createVBox(dialog) + +yTableHeader = yui.YTableHeader() +yTableHeader.addColumn("aaaaa") +yTableHeader.addColumn("bbbbb") +yTableHeader.addColumn("ccccc") +yTableHeader.addColumn("ddddd") + +myTableMinSize = factory.createMinSize(VBox, 50, 12) +myTable = factory.createTable(myTableMinSize, yTableHeader) + +myOK = factory.createPushButton(VBox, "OK") + +# note YItemCollection seems unavailable ! +myItem = yui.YTableItem("X", "foo", "1.2.1", "qwertz") +myTable.addItem(myItem) +myItem2 = yui.YTableItem("", "bar", "1.3.1", "asdasdasd") +myTable.addItem(myItem2) + +event1 = dialog.waitForEvent() +print 1 +myTable.deleteAllItems() +print 2 #crashes now. +del myItem +del myItem2 +print 3 # if not "del" before, crashes here. +myItem = yui.YTableItem("X3", "foo3", "1.2.13", "qwertz3") +print 4 +myTable.addItem(myItem) +print 5 +myItem2 = yui.YTableItem("4", "bar4", "1.3.14", "asdasdasd4") +print 6 +myTable.addItem(myItem2) + +# should already have crashed +event2 = dialog.waitForEvent() +dialog.destroy() + diff --git a/deps/libyui/libyui-bindings/swig/python/examples/tabwidget.py b/deps/libyui/libyui-bindings/swig/python/examples/tabwidget.py new file mode 100644 index 0000000000000000000000000000000000000000..85daa9686771ff8033cb330afb493fb30a492d88 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/tabwidget.py @@ -0,0 +1,51 @@ + +#!/usr/bin/python +# +# tabwidget.py +# Minimalistic example for tab widget +# (http://forgeftp.novell.com//yast/doc/SL11.0/tdg/DumbTab_widget.html) + +import sys +sys.path.insert(0,'../../../build/swig/python') +import yui + + +#if ( ! UI::HasSpecialWidget(`DumbTab ) ) +# UI::OpenDialog( +# `VBox( +# `Label("Error: This UI doesn't support the DumbTab widget!"), +# `PushButton(`opt(`default), "&OK") +# ) +# ); +# UI::UserInput(); +# UI::CloseDialog(); +# +# return; +# } + + +factory = yui.YUI.widgetFactory() +optional = yui.YUI.optionalWidgetFactory() +dialog = factory.createPopupDialog() + +vbox = factory.createVBox( dialog ) +if optional.hasDumbTab(): + dumptab = optional.createDumbTab( vbox ) + dumptab.addItem( yui.YItem("Page 1") ) + dumptab.addItem( yui.YItem("Page 2") ) + dumptab.addItem( yui.YItem("Page 3") ) +else: + factory.createLabel(vbox, "Error: This UI doesn't support the DumbTab widget!") + +factory.createPushButton( vbox, "&Close" ) +event = dialog.waitForEvent() +dialog.destroy() + +# `VBox( +# `DumbTab( +# [ "Page 1", "Page 2", "Page 3" ], +# `RichText(`id(`contents), "Contents" ) +# ), +# `Right(`PushButton(`id(`close), "&Close" ) ) +# ) +# ); diff --git a/deps/libyui/libyui-bindings/swig/python/examples/utf8.py b/deps/libyui/libyui-bindings/swig/python/examples/utf8.py new file mode 100644 index 0000000000000000000000000000000000000000..7322d1180ca1f39c4cfd6324090612ea9a0d43fc --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/utf8.py @@ -0,0 +1,38 @@ +#coding:utf-8 +# +# Trivial libyui example +# + +text = "Hello,Wörld!" + +import sys +sys.path.insert(0,'../../../build/swig/python') + +# see http://svn.opensuse.org/svn/yast/trunk/ncurses/src/YNCursesUI.cc +# approx line 67 +# this call is usually done by YaSTs 'WFM' +import locale +locale.setlocale(locale.LC_ALL, "") + +import yui + +log = yui.YUILog.instance() +log.setLogFileName("debug.log") +log.enableDebugLogging( True ) + +appl = yui.YUI.application() +appl.setLanguage( "de", "UTF-8" ) +#appl.setConsoleFont(magic, font, screenMap, unicodeMap, language) +# see /usr/share/YaST2/data/consolefonts.ycp +appl.setConsoleFont("(K", "lat9w-16.psfu", "trivial", "", "en_US.UTF-8") +factory = yui.YUI.widgetFactory() + +print "Lang: ", appl.language() +dialog = factory.createPopupDialog() + +vbox = factory.createVBox( dialog ) +factory.createLabel( vbox, text ) +factory.createPushButton( vbox, "&OK" ) +event = dialog.waitForEvent() +dialog.destroy() +# BEISPIEL 1 geht im graphischen gut, aber nicht auf der konsole ... diff --git a/deps/libyui/libyui-bindings/swig/python/examples/widgets.py b/deps/libyui/libyui-bindings/swig/python/examples/widgets.py new file mode 100644 index 0000000000000000000000000000000000000000..e045cdc5d53cda464938edc0526b51f12ee677c2 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/python/examples/widgets.py @@ -0,0 +1,233 @@ +#coding:utf-8 +############################################################################# +# +# widgets.py - Demonstration of widgets available in python-libyui +# +# License: GPLv2 +# Author: Jan-Simon Möller, dl9pf@gmx.de +############################################################################# + +# ensure we're using the latest build, if called from our build environment +import sys +sys.path.insert(0,'../../../build/swig/python') + +########### +# imports # +########### +import yui +import locale + + +#################################### +# LOCALE (important for TERMINAL!) # +#################################### +# set the locale to de/utf-8 +locale.setlocale(locale.LC_ALL, "") +log = yui.YUILog.instance() +log.setLogFileName("debug.log") +log.enableDebugLogging( True ) +appl = yui.YUI.application() +appl.setLanguage( "de", "UTF-8" ) +#appl.setConsoleFont(magic, font, screenMap, unicodeMap, language) +# see /usr/share/YaST2/data/consolefonts.ycp +appl.setConsoleFont("(K", "lat9w-16.psfu", "trivial", "", "en_US.UTF-8") + + +################# +# class widgets # +################# +class WIDGETS(object): + """ + Main class for the 'widgets' demo + """ + + def __init__(self, myavwidgets): + """ + Init/Constructor for the 'widgets' demo + """ + self.factory = yui.YUI.widgetFactory() + self.dialog = self.factory.createMainDialog() + self.avwidgets = myavwidgets.copy() + # create the main gui + # +---+-----------+ + # | s | display | + # | e +-----------+ + # | l |description| + # | b +-----------+ + # | x | code | + # +---+-----------+ + self.mainhbox = self.factory.createHBox(self.dialog) + self.mainvbox = self.factory.createVBox(self.mainhbox) + self.mainvbox.setWeight(0,20) + self.selbox = self.factory.createSelectionBox(self.mainvbox, "Widgets") + self.selbox.setNotify() + self.closebutton = self.factory.createPushButton(self.mainvbox, "&Close") + self.boxright = self.factory.createVBox(self.mainhbox) + self.boxright.setWeight(0,80) + self.framedisplay = self.factory.createFrame(self.boxright, "View") + self.framedisplay.setWeight(1,33) + self.framedisplay.setStretchable(0,True) + self.framedisplayminsize = self.factory.createMinSize(self.framedisplay, 5, 5) + self.display = self.factory.createReplacePoint(self.framedisplayminsize) # here we change the widget + self.displaychild_ = {} + self.framedescription = self.factory.createFrame(self.boxright, "Description") + self.framedescription.setWeight(1,33) + self.framedescription.setStretchable(0,True) + self.description = self.factory.createReplacePoint(self.framedescription) # here we change the widget + self.descriptionchild_ = {} + self.framecode = self.factory.createFrame(self.boxright, "Code") + self.framecode.setWeight(1,33) + self.framecode.setStretchable(0,True) + self.code = self.factory.createReplacePoint(self.framecode) # here we change the widget + self.codechild_ = {} + self.updateselbox() # import available widgets into display + self.updatedisplay() + self.updatedescription() + self.updatecode() + + def updateselbox(self): + for i in self.avwidgets.keys(): + self.selbox.addItem(i) + + def updatedisplay(self): + self.display.deleteChildren() # remove old widgets + selected = self.selbox.selectedItem().label() + #self.displaychild_[selected] = self.factory.createPushButton(self.display, "&OK") #self.avwidgets[selected][0] + #print type(self.displaychild_[selected]) + widgettodisplay = "self.displaychild_[selected] = self.factory."+self.avwidgets[selected][0] + exec widgettodisplay + if self.avwidgets[selected][1]: + widgettodisplay1 = "self.displaychild_[selected]"+self.avwidgets[selected][1] + exec widgettodisplay1 + if self.avwidgets[selected][2]: + widgettodisplay2 = "self.displaychild_[selected]"+self.avwidgets[selected][2] + exec widgettodisplay2 + self.dialog.recalcLayout() + self.display.showChild() + + def updatedescription(self): + self.description.deleteChildren() + selected = self.selbox.selectedItem().label() + text = self.avwidgets[selected][3] + self.descriptionchild_[selected] = self.factory.createRichText(self.description, str(text)) + #exec widgettodescribe + self.dialog.recalcLayout() + self.description.showChild() + + def updatecode(self): + self.code.deleteChildren() + selected = self.selbox.selectedItem().label() + text = self.avwidgets[selected][4] + print text + self.codechild_[selected] = self.factory.createRichText(self.code, str(text)) + self.dialog.recalcLayout() + self.code.showChild() + + + def handleevent(self): + """ + Event-handler for the 'widgets' demo + """ + while True: + event = self.dialog.waitForEvent() + if event.eventType() == yui.YEvent.CancelEvent: + self.dialog.destroy() + break + if event.widget() == self.closebutton: + self.dialog.destroy() + break + if event.widget() == self.selbox: + self.dialog.startMultipleChanges() + self.updatedisplay() + self.updatedescription() + self.updatecode() + self.dialog.doneMultipleChanges() + +if __name__ == "__main__": + avwidgets = {} + avwidgets["PushButton"]=['createPushButton(self.display, "&OK")', + None, + None, + """This Widget is a Button with a name and a configurable shortcut""", + """Code:
myPushButton = factory.createPushButton(parentWidget, Name)
e.g. myPushButton = f.createPushButton(myHBox, "&OK")"""] + avwidgets["ComboBox"] =['createComboBox(self.display, "Combobox")', + '.addItem("Item1")' , + '.addItem("Item2")' , + """This Widget is a Combobox with 1 or more items.""", + """Code:
+ myComboBox = factory.createComboBox(parentWidget, "Name")
+ myComboBox.addItem("Item")
+ + Event:
+ if event.widget() == myComboBox:
+ dosomething() """] + avwidgets["InputField"]=['createInputField(self.display, "Inputfield")', + '.setValue("Input nonsense here")', + None, + """This Widget is an InputField for User-Input""", + """Code:
+ myInputField = factory.createInputField(parentWidget, "Name")
+ myInputField.setValue("Insert valid input here")
+ myInputField.setValidChars("abcdefghijklmnopqrstuvwxyz")
+ Event:
+ if event.widget() = myInputField:
+ value = myInputField.value() + """] + avwidgets["CheckBox"] =['createCheckBox(self.display, "Checkbox")', + '.setChecked(True)', + None, + """This Widget is a Checkbox""", + """Code:
+ myCheckBox = fatory.createCheckbox(parentWidget, "Name")
+ myCheckbox.setEnabled(True)
+ Event:
+ if event.widget() == myCheckbox:
+ if myCheckbox.isChecked():
+ print "Box is checked" + """] + avwidgets["Frame"] =['createFrame(self.display, "Frame")', + ".setStretchable(0,True)", + ".setStretchable(1,True)", + """This Widget is a Frame. It can hold other widgets (vbox,hbox,single widget).""", + """Code:
+ myFrame = factory.createFrame(parentWidget, "Name")
+ """] + avwidgets["Label"] =['createLabel(self.display, "Label")', + None, + None, + """This Widget is a Label""", + """Code:
+ myLabel = factory.createLabel(parentWidget, "LabelText")
+ """] + avwidgets["LogView"] =['createLogView(self.display, "LogView", 10, 10)', + '.appendLines("Logtext1 ")', + '.appendLines("Logtext2 ")', + """This Widget is a Log-window.""", + """Code:
+ myLogView = factory.createLogView(parentWidget, "Name", nrLinesShown, nrLinesCached)
+ myLogView.appendLines("Logtext1") + """] # can't use \n in Logtext1 ... need to check + avwidgets["ProgressBar"]=['createProgressBar(self.display, "ProgressBar", 100)', + '.setValue(10)', + None, + """This Widget is a ProgressBar.""", + """Code:
+ myProgressBar = factory.createProgressBar(parentWidget, "Name", maxpercentvalue)
+ e.g.:
+ myProgressBar = factory.createProgressBar(dialog, "Progress", 100")
+ myProgressBar.setValue(33) + """] + avwidgets["SelectionBox"]=['createSelectionBox(self.display, "Selection")', + '.addItem("SELBOX_item1")', + '.addItem("SELBOX_item2")', + """This Widget is a SelectionBox""", + """Code:
+ mySelectionBox = factory.createSelectionBox(parentWidget, "Name")
+ mySelectionBox.addItem("Item1")
+ Event:
+ if event.widget() = mySelectionBox:
+ selected = mySelectionBox.selectedItem() + """] + MY_MAIN_GUI = WIDGETS(avwidgets) + MY_MAIN_GUI.handleevent() + diff --git a/deps/libyui/libyui-bindings/swig/ruby/CMakeLists.txt b/deps/libyui/libyui-bindings/swig/ruby/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e18a2e86b7b1f7be3a0bc4036a8fb6065736320e --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/CMakeLists.txt @@ -0,0 +1,132 @@ +# +# CMakeLists.txt for libyui/swig/ruby +# + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") + +EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['vendorarchdir']" OUTPUT_VARIABLE RUBY_VENDOR_ARCH_DIR) +STRING(REGEX REPLACE "^/usr/" "${CMAKE_INSTALL_PREFIX}/" RUBY_VENDOR_ARCH_DIR "${RUBY_VENDOR_ARCH_DIR}") + +# 3.18.0: "Rename variables to match case of module name" +if( + (("${CMAKE_MAJOR_VERSION}" GREATER_EQUAL 3) AND ("${CMAKE_MINOR_VERSION}" GREATER_EQUAL 18)) OR + ("${CMAKE_MAJOR_VERSION}" GREATER_EQUAL 4) + ) + SET(RUBY_VENDORLIB_DIR "${Ruby_VENDORLIB_DIR}") +endif() + +MESSAGE(STATUS "Ruby executable: ${RUBY_EXECUTABLE}") +MESSAGE(STATUS "Ruby vendor arch dir: ${RUBY_VENDOR_ARCH_DIR}") +MESSAGE(STATUS "Ruby vendor lib dir: ${RUBY_VENDORLIB_DIR}") +MESSAGE(STATUS "Ruby include path: ${RUBY_INCLUDE_PATH}") + +SET( SWIG_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/yui_ruby.cxx" ) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yui/version.rb.in ${CMAKE_CURRENT_BINARY_DIR}/yui/version.rb) + + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + +# Symlink ../../../libyui/src to build/src/include/yui +# so the headers there can be included as +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR} ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui/src ${LOCAL_INCLUDE_DIR}/yui SYMBOLIC ) +if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src) + file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/src ${LOCAL_INCLUDE_DIR}/yui/mga SYMBOLIC ) +endif() + +ADD_CUSTOM_COMMAND ( + OUTPUT ${SWIG_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E echo_append "Creating wrapper code for ruby..." + COMMAND ${SWIG_EXECUTABLE} -c++ -ruby -autorename ${SWIG_FLAGS} -o ${SWIG_OUTPUT} -I${LOCAL_INCLUDE_DIR} ${LIBYUI_INCLUDE_CFLAGS} ${SWIG_INPUT} + COMMAND ${CMAKE_COMMAND} -E echo "Done." + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../*.i +) + +set( TARGETLIB yui_ruby ) +ADD_LIBRARY( ${TARGETLIB} SHARED ${SWIG_OUTPUT} ) + +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) + +INCLUDE_DIRECTORIES( ${RUBY_INCLUDE_PATH} ${LIBYUI_INCLUDE_DIR} ) + +SET_TARGET_PROPERTIES( ${TARGETLIB} PROPERTIES PREFIX "" OUTPUT_NAME "_yui") + +if ( WITH_MGA) + if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../../libyui-mga/build/src) + # Find yui and yui-mga during a combined build + target_link_directories( ${TARGETLIB} + BEFORE PUBLIC ../../../libyui/build/src + BEFORE PUBLIC ../../../libyui-mga/build/src + ) + else() + # Using yui and yui-mga from system + target_link_directories( ${TARGETLIB} + PUBLIC ${YUI_LIBRARY_DIRS} + PUBLIC ${YUIMGA_LIBRARY_DIRS} + ) + endif() +else() + # Find yui during a combined build + target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../../libyui/build/src ) +endif() + +TARGET_LINK_LIBRARIES( ${TARGETLIB} ${LIBYUI_LIBRARY} ) +TARGET_LINK_LIBRARIES( ${TARGETLIB} ${RUBY_LIBRARY} ) + +INSTALL(TARGETS ${TARGETLIB} LIBRARY DESTINATION ${RUBY_VENDOR_ARCH_DIR}) + +IF( BUILD_RUBY_GEM ) +# +# Ruby GEM +# + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/yui.gemspec.in ${CMAKE_CURRENT_BINARY_DIR}/yui.gemspec) + +SET(GEM_NAME "yui-${VERSION}.gem") +ADD_CUSTOM_TARGET(ruby_gem ALL DEPENDS ${GEM_NAME}) +ADD_DEPENDENCIES(ruby_gem ${SWIG_OUTPUT}) + +ADD_CUSTOM_COMMAND ( + OUTPUT ${GEM_NAME} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND "gem" "build" "${CMAKE_CURRENT_BINARY_DIR}/yui.gemspec" + DEPENDS "ext" + DEPENDS ${rdoc_dir} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/yui.gemspec +) + +# +# Prep GEM files +# gemspec needs _relative_ pathes +# so create ext and lib here and copy files +# +ADD_CUSTOM_COMMAND ( + OUTPUT "ext" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND "rm" "-rf" "lib" + COMMAND "rm" "-rf" "ext" + COMMAND "mkdir" "-p" "ext/yui" + COMMAND "cp" "${CMAKE_CURRENT_BINARY_DIR}/yui_ruby.cxx" "ext/yui" + COMMAND "cp" "${CMAKE_CURRENT_SOURCE_DIR}/extconf.rb" "ext/yui" + + COMMAND "mkdir" "-p" "lib/yui" + COMMAND "cp" "${CMAKE_CURRENT_SOURCE_DIR}/yui.rb" "lib" + COMMAND "cp" "${CMAKE_CURRENT_SOURCE_DIR}/yui/*.rb" "lib/yui" + COMMAND "cp" "${CMAKE_CURRENT_BINARY_DIR}/yui/*.rb" "lib/yui" + + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/extconf.rb + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/yui.rb + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/yui/*.rb + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/yui/*.rb.in + DEPENDS ${SWIG_OUTPUT} +) +ELSE( BUILD_RUBY_GEM ) +# install ruby files to vendor dir +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/yui.rb DESTINATION ${RUBY_VENDORLIB_DIR} ) +FILE(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/yui/*.rb") +INSTALL(FILES ${files} DESTINATION ${RUBY_VENDORLIB_DIR}/yui) +FILE(GLOB files_built "${CMAKE_CURRENT_BINARY_DIR}/yui/*.rb") +INSTALL(FILES ${files_built} DESTINATION ${RUBY_VENDORLIB_DIR}/yui) +ENDIF( BUILD_RUBY_GEM ) diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/_loadpath.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/_loadpath.rb new file mode 100644 index 0000000000000000000000000000000000000000..bf13810e2626a134a8acd858ab5b894646b40961 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/_loadpath.rb @@ -0,0 +1,16 @@ +DIR = File.dirname(__FILE__) + +$: << DIR + +if ENV["LIBYUI_GEM"] # set LIBYUI_GEM to test gem-based libyui-bindings + require 'rubygems' +else + # Autotools binary + $:.unshift File.expand_path(File.join(DIR,"../.libs")) + + # cmake binary + $:.unshift File.expand_path(File.join(DIR,"../../../build/swig/ruby")) + + # cmake local for openwsman.rb + $:.unshift File.expand_path(File.join(DIR,"..")) +end diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/combo_box1.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/combo_box1.rb new file mode 100644 index 0000000000000000000000000000000000000000..5e7dd4527d84355407b20765701fcd10042a436a --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/combo_box1.rb @@ -0,0 +1,101 @@ +# +# Combo box example +# +require File.join(File.dirname(__FILE__),'_loadpath') + +require 'yui' + + editable = ARGV.size > 0 + + Yui::YUILog::set_log_file_name "/tmp/libyui-examples.log" + Yui::YUILog::enable_debug_logging + + factory = Yui::YUI::widget_factory + dialog = factory.create_popup_dialog + vbox = factory.create_vbox dialog + + comboBox = factory.create_combo_box( vbox, "&Menu", editable ) + + comboBox.add_item( Yui::YItem.new( "Pizza Margherita" ) ) + comboBox.add_item( Yui::YItem.new( "Pizza Capricciosa" ) ) + comboBox.add_item( Yui::YItem.new( "Pizza Funghi" ) ) + comboBox.add_item( Yui::YItem.new( "Pizza Prosciutto" ) ) + comboBox.add_item( Yui::YItem.new( "Pizza Quattro Stagioni" ) ) + comboBox.add_item( Yui::YItem.new( "Calzone" ) ) + + + hbox = factory.create_hbox( vbox ) + valueField = factory.create_output_field( hbox, "" ) + valueField.set_stretchable( Yui::YD_HORIZ, true ) # allow stretching over entire dialog width + + valueButton = factory.create_push_button( hbox, "&Value" ) + + factory.create_vspacing( vbox, 0.3 ) + + rightAlignment = factory.create_right( vbox ) + closeButton = factory.create_push_button( rightAlignment, "&Close" ) + + + # + # Event loop + # + + loop do + event = dialog.wait_for_event + + if ( event ) + break if ( event.event_type == Yui::YEvent::CancelEvent ) # window manager "close window" button + + valueField.set_value( "???" ) + + # leave event loop + break if ( event.widget == closeButton ) + + if ( event.widget == valueButton || event.widget == comboBox ) # comboBox will only send events with setNotify() + # Get the current value of the ComboBox and display it in valueField. + # + # In normal applications, it should be clear whether or not a + # ComboBox is editable, so the following if()...else should + # not be necessary, only either the "if" branch or the "else" branch. + + if ( comboBox.editable ) + # An editable ComboBox can have a selectedItem(), but the user can + # also enter any other text. YComboBox::value() will return that text or, + # if the user chose an item from the list, that item's + # label. + # + # YComboBox::set_value() OTOH will automatically select a list item + # if an item with that label exists. + # + # Semantically, an editable ComboBox is an InputField with some + # frequently used values in a drop-down list. This means that it + # makes a lot more sense to use strings and YComboBox::value() / + # YComboBox::set_value() consistently for such a ComboBox, not + # YComboBox::selected_item() / YComboBox::select_item(). + + valueField.set_value( comboBox.value ) + else # not editable + # For non-editable ComboBox widgets, using items is preferred: + # YComboBox::selected_item() / YComboBox::select_item(). + # + # While it is possible to use YComboBox::value() and + # YComboBox::set_value(), this is not the idea behind it. + + item = comboBox.selected_item + + if ( item ) + valueField.set_value( item.label ) + else + valueField.set_value( "" ) + end + end + end + end + end + + + # + # Clean up + # + + dialog.destroy diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/hello_world.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/hello_world.rb new file mode 100644 index 0000000000000000000000000000000000000000..ab9a649469337b32e9f55581185afd5dcb16016a --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/hello_world.rb @@ -0,0 +1,21 @@ +# encoding: utf-8 + +# +# Trivial libyui example +# + +require File.join(File.dirname(__FILE__),'_loadpath') + +require 'test/unit' + +class LoadTest < Test::Unit::TestCase + def test_hello_world + require 'yui' + factory = Yui::YUI::widget_factory + dialog = factory.create_popup_dialog + vbox = factory.create_vbox dialog + factory.create_label vbox, "Hello, Wörld!" + factory.create_push_button vbox, "&OK" + dialog.destroy + end +end diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/loading.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/loading.rb new file mode 100644 index 0000000000000000000000000000000000000000..cb59eddaa999b8cd29e6ac520c70948d3812574b --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/loading.rb @@ -0,0 +1,15 @@ +# +# Test loading of the bindings +# + +require File.join(File.dirname(__FILE__),'_loadpath') + +# test loading of extension +require 'test/unit' + +class LoadTest < Test::Unit::TestCase + def test_loading + require 'yui' + assert true + end +end diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box1.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box1.rb new file mode 100644 index 0000000000000000000000000000000000000000..4f5edf487191e267570a4accce21c0a151faaf9a --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box1.rb @@ -0,0 +1,67 @@ +# +# Trivial libyui example +# + +require File.join(File.dirname(__FILE__),'_loadpath') + +require 'test/unit' + +class LoadTest < Test::Unit::TestCase + def test_selection_box1 + require 'yui' + + Yui::YUILog::set_log_file_name "/tmp/libyui-examples.log" + Yui::YUILog::enable_debug_logging + + dialog = Yui::YUI::widget_factory.create_popup_dialog + vbox = Yui::YUI::widget_factory.create_vbox dialog + selBox = Yui::YUI::widget_factory.create_selection_box vbox, "&Menu" + +# items = [] #Yui::YItemCollection.new + selBox.add_item( Yui::YItem.new( "Pizza Margherita" ) ) + selBox.add_item( Yui::YItem.new( "Pizza Capricciosa" ) ) + selBox.add_item( Yui::YItem.new( "Pizza Funghi" ) ) + selBox.add_item( Yui::YItem.new( "Pizza Prosciutto" ) ) + selBox.add_item( Yui::YItem.new( "Pizza Quattro Stagioni" ) ) + selBox.add_item( Yui::YItem.new( "Calzone" ) ) + #selBox.add_items items # This is more efficient than repeatedly calling selBox.add_item + + hbox = Yui::YUI::widget_factory.create_hbox vbox + valueField = Yui::YUI::widget_factory.create_output_field hbox, "" + valueField.set_stretchable Yui::YD_HORIZ, true # // allow stretching over entire dialog width + + valueButton = Yui::YUI::widget_factory.create_push_button hbox, "&Value" + + Yui::YUI::widget_factory.create_vspacing vbox, 0.3 + + rightAlignment = Yui::YUI::widget_factory.create_right vbox + closeButton = Yui::YUI::widget_factory.create_push_button rightAlignment, "&Close" + + # + # Event loop + # + + loop do + event = dialog.wait_for_event + next unless event + + break if event.event_type == Yui::YEvent::CancelEvent # window manager "close window" button + + valueField.set_value "???" + break if event.widget == closeButton + + if ( event.widget == valueButton || + event.widget == selBox ) # selBox will only send events with setNotify() + item = selBox.selected_item + if item + valueField.set_value item.label + else + valueField.set_value "" + end + end + end + end +end + + + diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box2.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box2.rb new file mode 100644 index 0000000000000000000000000000000000000000..6c24115b4b2f7ad0885075da12876a7ea2924564 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box2.rb @@ -0,0 +1,159 @@ +# +# Selection box example +# +require File.join(File.dirname(__FILE__),'_loadpath') + +require 'yui' + +def pizzaItems + items = Array.new + items << Yui::YItem.new( "Pizza Margherita" ) + items << Yui::YItem.new( "Pizza Capricciosa" ) + items << Yui::YItem.new( "Pizza Funghi" ) + items << Yui::YItem.new( "Pizza Prosciutto" ) + items << Yui::YItem.new( "Pizza Quattro Stagioni" ) + items << Yui::YItem.new( "Calzone" ) + + items +end + + +def pastaItems + items = Array.new + items << Yui::YItem.new( "Spaghetti Napoli" ) + items << Yui::YItem.new( "Spaghetti Bolognese" ) + items << Yui::YItem.new( "Fusili Emiliana" ) + items << Yui::YItem.new( "Penne Calabrese" ) + items << Yui::YItem.new( "Penne Al Forno" ) + items << Yui::YItem.new( "Lasagne" ) + + items +end + + + Yui::YUILog::set_log_file_name "/tmp/libyui-examples.log" + Yui::YUILog::enable_debug_logging + + factory = Yui::YUI::widget_factory + dialog = factory.create_popup_dialog + vbox = factory.create_vbox dialog + + # Specify larger size for the SelectionBox: It can scroll, so its size + # depends on other widgets in the layout. + minSize = factory.create_min_size( vbox, 40, 8 ) # minWidth, minHeight + + + # The SelectionBox. This is what this example all about. + # The other widgets are just here to allow some experimenting. + + selBox = factory.create_selection_box( minSize, "&Menu" ) + pizzaItems.each { |i| selBox.add_item( i ) } + + + # Buttons to allow changing the SelectionBox items + + buttonBox = factory.create_hbox( vbox ) + pastaButton = factory.create_push_button( buttonBox, "&Pasta" ) + pizzaButton = factory.create_push_button( buttonBox, "Pi&zza" ) + clearButton = factory.create_push_button( buttonBox, "C&lear" ) + deselectButton = factory.create_push_button( buttonBox, "&Deselect" ) + + factory.create_vspacing( vbox, 0.5 ) + + + # Check boxes to allow toogling "notify" and "immediate" for the SelectionBox + + leftAlignment = factory.create_left( vbox ) + notifyCheckBox = factory.create_check_box( leftAlignment, "&Notify Mode" ) + notifyCheckBox.set_notify + + leftAlignment = factory.create_left( vbox ) + immediateCheckBox = factory.create_check_box( leftAlignment, "&Immediate Mode" ) + immediateCheckBox.set_notify + + factory.create_vspacing( vbox, 0.3 ) + + + # OutputField + button to allow monitoring the SelectionBox value + # (and when it changes, i.e. when events are sent) + + hbox = factory.create_hbox( vbox ) + valueField = factory.create_output_field( hbox, "???" ) + valueField.set_stretchable( Yui::YD_HORIZ, true ) # allow stretching over entire dialog width + + valueButton = factory.create_push_button( hbox, "&Value" ) + + factory.create_vspacing( vbox, 0.7 ) + + + # "Close" button + + rightAlignment = factory.create_right( vbox ) + closeButton = factory.create_push_button( rightAlignment, "&Close" ) + + + # + # Event loop + # + + loop do + event = dialog.wait_for_event + + if ( event ) + break if ( event.event_type() == Yui::YEvent::CancelEvent ) # window manager "close window" button + + valueField.set_value( "???" ) + + if ( event.widget == closeButton ) + break + elsif ( event.widget == pastaButton ) + selBox.delete_all_items + pastaItems.each { |i| selBox.add_item( i ) } + elsif ( event.widget == pizzaButton ) + selBox.delete_all_items + pizzaItems.each { |i| selBox.add_item( i ) } + elsif ( event.widget == clearButton ) + selBox.delete_all_items + elsif ( event.widget == deselectButton ) + selBox.deselect_all_items + elsif ( event.widget == notifyCheckBox ) + notify = notifyCheckBox.is_checked + + if ( ! notify ) + # immediateMode implicitly includes notify, so set + # immediateMode off if the user wants to set notify off + + selBox.set_immediate_mode( false ) + immediateCheckBox.set_checked( false ) + end + + selBox.set_notify( notify ) + elsif ( event.widget == immediateCheckBox ) + immediate = immediateCheckBox.is_checked + selBox.set_immediate_mode( immediate ) + + # immediateMode implicitly includes notify; + # reflect this in the notify check box + + if ( immediate ) + notifyCheckBox.set_checked( true ) + end + elsif ( event.widget == selBox || event.widget == valueButton ) + item = selBox.selected_item + + if ( item ) + valueField.set_value( item.label ) + else + valueField.set_value( "" ) + end + end + end + end + + + # + # Clean up + # + + dialog.destroy + diff --git a/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box3.rb b/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box3.rb new file mode 100755 index 0000000000000000000000000000000000000000..054a6c0f75986768984a375b2439b4561bb33444 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/examples/selection_box3.rb @@ -0,0 +1,95 @@ +#!/usr/bin/ruby +require File.join(File.dirname(__FILE__),'_loadpath') +require 'yui' + +# reopen the class to add a convenience method +module Yui + class YSelectionBox + def <<(item_string) + add_item Yui::YItem.new(item_string) + end + end +end + +class SimpleFactory + def initialize(parent_widget = nil) + @parent_widget = parent_widget + end + + # YSelectionBox should really yield self, + # but it is dumb and yields a useless SimpleFactory instead, + # so let's forward it + def <<(*args) + @parent_widget.<<(*args) + end + + METHODS = ["popup_dialog", "selection_box", "hbox", "vbox", "output_field", + "push_button", "vspacing", "left", "right"] + + def method_missing(name, *args, &block) + super(name, *args, &block) unless METHODS.include? name.to_s + + create_args = [] + create_args << @parent_widget unless @parent_widget.nil? + create_args += args + widget = Yui::YUI::widget_factory.send "create_#{name}", *create_args + unless block.nil? + child_factory = self.class.new(widget) + block.call child_factory + end + widget + end +end + +def example + value_field = value_button = close_button = sel_box = nil + + ui = SimpleFactory.new + dialog = ui.popup_dialog do |w| + w.vbox do |w| + sel_box = w.selection_box "&Menu" do |s| + s << "Pizza Margherita" + s << "Pizza Capricciosa" + s << "Pizza Funghi" + s << "Pizza Prosciutto" + s << "Pizza Quattro Stagioni" + s << "Calzone" + end + w.hbox do |w| + value_field = w.output_field "" + # allow stretching over entire dialog width + value_field.set_stretchable Yui::YD_HORIZ, true + value_button = w.push_button "&Value" + end + w.vspacing 0.3 + w.right do |w| + close_button = w.push_button "&Close" + end + end + end + + loop do + event = dialog.wait_for_event + next unless event + + # window manager "close window" button + break if event.event_type == Yui::YEvent::CancelEvent + + value_field.set_value "???" + break if event.widget == close_button + + if ( event.widget == value_button || + event.widget == sel_box ) # sel_box will only send events with setNotify() + item = sel_box.selected_item + if item + value_field.set_value item.label + else + value_field.set_value "" + end + end + end + dialog.destroy + +end + +example diff --git a/deps/libyui/libyui-bindings/swig/ruby/extconf.rb b/deps/libyui/libyui-bindings/swig/ruby/extconf.rb new file mode 100644 index 0000000000000000000000000000000000000000..556ef9c23310e8c43f259562d6681ac0765b3fd6 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/extconf.rb @@ -0,0 +1,19 @@ +# +# extconf.rb for yui Gem +# + +require 'mkmf' +# $CFLAGS = "#{$CFLAGS} -Werror" + +RbConfig::CONFIG['CC'] = "g++" +RbConfig::CONFIG['CPP'] = "g++ -E" + +have_library('stdc++') + +unless have_library('yui', 'YUI::widgetFactory', 'yui/YUI.h') + STDERR.puts "Cannot find libyui" + STDERR.puts "Is libyui-devel installed ?" +end +find_header 'YUI.h', '/usr/include/yui' + +create_makefile('_yui') diff --git a/deps/libyui/libyui-bindings/swig/ruby/yui.gemspec.in b/deps/libyui/libyui-bindings/swig/ruby/yui.gemspec.in new file mode 100644 index 0000000000000000000000000000000000000000..ec564a1eb765d9e3d19f5ee39e46eb03ce24c5fc --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/yui.gemspec.in @@ -0,0 +1,39 @@ +# -*- encoding: utf-8 -*- +if RUBY_VERSION =~ /1.9/ + Encoding.default_external = Encoding::UTF_8 + Encoding.default_internal = Encoding::UTF_8 +end + +Gem::Specification.new do |s| + s.name = "yui" + s.version = "@VERSION@" + s.platform = Gem::Platform::RUBY + s.authors = ["Klaus Kämpf"] + s.email = ["kkaempf@suse.de"] + s.homepage = "http://www.github.com/libyui/libyui-bindings" + s.summary = "Ruby client bindings for libyui" + s.description = "The yui gem provides a Ruby API to drive graphical +(Qt, Gtk) or text-mode (ncurses) UIs with libyui" + + s.required_rubygems_version = ">= 1.3.6" + s.add_development_dependency("rake-compiler", [">= 0"]) + s.add_development_dependency("mocha", [">= 0.9"]) + s.add_development_dependency("yard", [">= 0.5"]) + s.extensions << "ext/yui/extconf.rb" + + s.files = Dir.glob("lib/*.rb") + + Dir.glob("lib/**/*.rb") + + Dir.glob("ext/*.{h,cxx}") + + Dir.glob("ext/**/*.{h,cxx}") + +# s.require_path = '' + + s.post_install_message = <<-POST_INSTALL_MESSAGE + ____ +/@ ~-. +\/ __ .- | remember to have fun! + // // @ + + POST_INSTALL_MESSAGE +end + diff --git a/deps/libyui/libyui-bindings/swig/ruby/yui.rb b/deps/libyui/libyui-bindings/swig/ruby/yui.rb new file mode 100644 index 0000000000000000000000000000000000000000..e5b0943370ee44c2e6d30565167eb39b55b70b29 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/yui.rb @@ -0,0 +1,4 @@ +# This is yui.rb +# + +require 'yui/yui' diff --git a/deps/libyui/libyui-bindings/swig/ruby/yui/version.rb.in b/deps/libyui/libyui-bindings/swig/ruby/yui/version.rb.in new file mode 100644 index 0000000000000000000000000000000000000000..45885a3b4f06ec452512c3aca7ac98ba9e2e86e1 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/yui/version.rb.in @@ -0,0 +1,10 @@ +# yui/version.rb + +module Yui + require 'rbconfig' + YUI_RUBY_VERSION = "@RUBY_VERSION_MAJOR@.@RUBY_VERSION_MINOR@" + SYSTEM_RUBY_VERSION = "#{RbConfig::CONFIG['MAJOR']}.#{RbConfig::CONFIG['MINOR']}" + if SYSTEM_RUBY_VERSION != YUI_RUBY_VERSION + STDERR.puts "** Warning: Ruby version mismatch: Yui Ruby #{YUI_RUBY_VERSION}, Runtime Ruby #{SYSTEM_RUBY_VERSION}" + end +end diff --git a/deps/libyui/libyui-bindings/swig/ruby/yui/yui.rb b/deps/libyui/libyui-bindings/swig/ruby/yui/yui.rb new file mode 100644 index 0000000000000000000000000000000000000000..41413e0dc69c33206fba67bed0f3f5654d916690 --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/ruby/yui/yui.rb @@ -0,0 +1,11 @@ +# This is yui/yui +# do NOT require this file, but do a simple +# require 'yui' +# instead +# + +require 'yui/version' + +# this loads the binary .so file +require '_yui' + diff --git a/deps/libyui/libyui-bindings/swig/yui.i b/deps/libyui/libyui-bindings/swig/yui.i new file mode 100644 index 0000000000000000000000000000000000000000..74735271728c06edb35632be959a1eb795ebb64f --- /dev/null +++ b/deps/libyui/libyui-bindings/swig/yui.i @@ -0,0 +1,392 @@ +%module yui + +#if defined(SWIGPERL5) +%{ + #undef NORMAL + #undef readdir + #undef Fflush + #undef Mkdir + #undef strerror +%} +#endif + +%{ +/* Includes the header in the wrapper code */ +#include +#include +#include + +#if defined(SWIGRUBY) + +extern "C" { +/* Init_ for the %module, defined by Swig */ +SWIGEXPORT void Init_yui(void); + +/* Init_ for the .so lib, called by Ruby */ +SWIGEXPORT void Init__yui(void) { + Init_yui(); + } +} +#endif + +#define YUILogComponent "bindings" +#include "yui/YUILog.h" + +#include "yui/YUI.h" +#include "yui/YWidgetFactory.h" +#include "yui/YExternalWidgets.h" +#include "yui/YExternalWidgetFactory.h" +#include "yui/YOptionalWidgetFactory.h" +#include "yui/YDialog.h" +#include "yui/YLayoutBox.h" +#include "yui/YEvent.h" + +#include "yui/YSelectionBox.h" +#include "yui/YLabel.h" +#include "yui/YPushButton.h" +#include "yui/YAlignment.h" +#include "yui/YApplication.h" +#include "yui/YBarGraph.h" +#include "yui/YBuiltinCaller.h" +#include "yui/YBusyIndicator.h" +#include "yui/YCheckBox.h" +#include "yui/YCheckBoxFrame.h" +#include "yui/YComboBox.h" +#include "yui/YCommandLine.h" +#include "yui/YDateField.h" +#include "yui/YDownloadProgress.h" +#include "yui/YDumbTab.h" +#include "yui/YEmpty.h" +#include "yui/YFrame.h" +#include "yui/YImage.h" +#include "yui/YInputField.h" +#include "yui/YItem.h" +#include "yui/YItemSelector.h" +#include "yui/YLogView.h" +#include "yui/YMacro.h" +#include "yui/YMacroPlayer.h" +#include "yui/YMacroRecorder.h" +#include "yui/YMenuWidget.h" +#include "yui/YMenuBar.h" +#include "yui/YMenuButton.h" +#include "yui/YMenuItem.h" +#include "yui/YMultiLineEdit.h" +#include "yui/YMultiProgressMeter.h" +#include "yui/YMultiSelectionBox.h" +#include "yui/YPackageSelector.h" +#include "yui/YPackageSelectorPlugin.h" +#include "yui/YProgressBar.h" +#include "yui/YPartitionSplitter.h" +#include "yui/YRadioButtonGroup.h" +#include "yui/YRadioButton.h" +#include "yui/YReplacePoint.h" +#include "yui/YRichText.h" +#include "yui/YShortcut.h" +#include "yui/YShortcutManager.h" +#include "yui/YSimpleInputField.h" +#include "yui/YSlider.h" +#include "yui/YSpacing.h" +#include "yui/YStringTree.h" +#include "yui/YSquash.h" +#include "yui/YTable.h" +#include "yui/YTableItem.h" +#include "yui/YTableHeader.h" +#include "yui/YTimezoneSelector.h" +#include "yui/YTimeField.h" +#include "yui/YTransText.h" +#include "yui/YTree.h" +#include "yui/YTreeItem.h" +#include "yui/YWidgetID.h" +#include "yui/YWizard.h" + +#include "yui/YUILoader.h" + +#if defined(WITH_MGA) +#include "yui/mga/YMGA_CBTable.h" +#include "yui/mga/YMGAMsgBox.h" +#include "yui/mga/YMGAAboutDialog.h" +#include "yui/mga/YMGAWidgetExtensionFactory.h" +#endif + +using namespace std; + +extern void *start_ui_thread( void *ui_int ); + +#if 0 +template < typename T > +class intrusive_ptr { + public: + T *operator->(); +}; +#endif + +%} + +%define DEFINE_PTR_TYPE(name) +%enddef + +#if !defined(SWIGCSHARP) +%rename("+") "operator+"; +%rename("<<") "operator<<"; +%rename("!=") "operator!="; +%rename("!") "operator!"; +%rename("==") "operator=="; + +%include "exception.i" +%include "std_string.i" +%include "std_list.i" +%include "std_vector.i" + +#endif + +#if defined(SWIGPERL5) || defined(SWIGCSHARP) +/* %include "std/std_set.i" # doesn't compile ?! */ +#else +%include "std_set.i" +#endif + +%include "stl.i" + +class Exception; +%include yui/YUI.h + +%define YUILogComponent "bindings" +%enddef + +#if defined(SWIGPYTHON) +%ignore None; /* is a reserved word in Python */ +#endif + +/* + * See https://bugzilla.novell.com/show_bug.cgi?id=427372#c16 + * + * YMenuButton.h: virtual void addItem( YItem * item_disown ); + * YSelectionWidget.h: virtual void addItem( YItem * item_disown ); + * YSimpleEventHandler.h: void sendEvent( YEvent * event_disown ); + * YTableItem.h: void addCell( YTableCell * cell_disown ); + * YWidget.h: void setId( YWidgetID * newId_disown ); + * YWidgetFactory.h: virtual YTable *createTable( YWidget *parent, YTableHeader * header_disown, bool multiSelection = false ): + virtual YReplacePoint *createReplacePoint( YWidget *parent_disown ) = 0; + + * + */ + +%apply SWIGTYPE *DISOWN { YItem *item_disown }; +%apply SWIGTYPE *DISOWN { YEvent *event_disown }; +%apply SWIGTYPE *DISOWN { YTableCell *cell_disown }; +%apply SWIGTYPE *DISOWN { YWidgetID *newId_disown }; +%apply SWIGTYPE *DISOWN { YTableHeader *header_disown }; +%apply SWIGTYPE *DISOWN { YTableHeader *header_disown }; +%apply SWIGTYPE *DISOWN { YWidget *parent_disown }; + +%include yui/YUILog.h +%include yui/YUIPlugin.h + +%include yui/YTypes.h +%include yui/YWidget.h +%include yui/YSingleChildContainerWidget.h +%include yui/YSelectionWidget.h +%include yui/YSimpleInputField.h +%include yui/YItem.h +%include yui/YTreeItem.h +%include yui/YStringTree.h + +%include yui/YWidgetFactory.h + +%include yui/YDialog.h + +%include yui/YAlignment.h +%include yui/YApplication.h +%include yui/YBarGraph.h +%include yui/YBothDim.h +%include yui/YBuiltinCaller.h +%include yui/YBusyIndicator.h +%include yui/YCheckBoxFrame.h +%include yui/YCheckBox.h +%include yui/YChildrenManager.h +%include yui/YColor.h +%include yui/YComboBox.h +%include yui/YCommandLine.h +%include yui/YDateField.h +%include yui/YDownloadProgress.h +%include yui/YDumbTab.h +%include yui/YEmpty.h +%include yui/YEvent.h +%include yui/YFrame.h +%include yui/YImage.h +%include yui/YInputField.h +%include yui/YIntField.h +%include yui/YItemSelector.h +%include yui/YLabel.h +%include yui/YLayoutBox.h +%include yui/YLogView.h +%include yui/YMacro.h +%include yui/YMacroPlayer.h +%include yui/YMacroRecorder.h +%include yui/YMenuWidget.h +%include yui/YMenuBar.h +%include yui/YMenuButton.h +%include yui/YMenuItem.h +%include yui/YMultiLineEdit.h +%include yui/YMultiProgressMeter.h +%include yui/YMultiSelectionBox.h +%include yui/YWizard.h +%include yui/YOptionalWidgetFactory.h +%include yui/YPackageSelector.h +%include yui/YPackageSelectorPlugin.h +%include yui/YPartitionSplitter.h +%include yui/YProgressBar.h +%include yui/YProperty.h +%include yui/YPushButton.h +%include yui/YRadioButtonGroup.h +%include yui/YRadioButton.h +%include yui/YReplacePoint.h +%include yui/YRichText.h +%include yui/YSelectionBox.h +%include yui/YSettings.h +%include yui/YShortcut.h +%include yui/YShortcutManager.h +%include yui/YSimpleEventHandler.h +%include yui/YSlider.h +%include yui/YSpacing.h +%include yui/YSquash.h +%include yui/YTable.h +%include yui/YTableHeader.h +%include yui/YTableItem.h +%include yui/YTimeField.h +%include yui/YTimezoneSelector.h +%include yui/YTransText.h +%include yui/YTree.h +%include yui/YUIException.h +%include yui/YUI.h +%include yui/YUILoader.h +%include yui/YUILog.h +%include yui/YUISymbols.h +%include yui/YWidgetID.h +%include yui/YExternalWidgetFactory.h +%include yui/YExternalWidgets.h + +#if defined(WITH_MGA) +%include yui/mga/YMGA_CBTable.h +%include yui/mga/YMGAAboutDialog.h +%include yui/mga/YMGAMsgBox.h +%include yui/mga/YMGAWidgetExtensionFactory.h +#endif + +#if defined(SWIGRUBY) +%extend YEvent { + VALUE mywidget() { return INT2FIX( (long)$self->widget() ); } +} +#endif + +%extend YItem { +#if defined(SWIGPERL5) + int __eq__( YItem *i ) + { return ($self == i); } + int __ne__( YItem *i ) + { return ($self != i); } +#endif +#if defined(SWIGPYTHON) + int __eq__( YItem *i ) + { return ($self == i); } + int __ne__( YItem *i ) + { return ($self != i); } +#endif +#if defined(SWIGRUBY) + %rename( "==" ) equals( YItem *i ); + %typemap(out) int equals + "$result = ($1 != 0) ? Qtrue : Qfalse;"; +#endif + int equals( YItem *i ) { return ($self == i); } +} + +namespace std { + %template(YItemCollection) vector; +} + +using namespace std; +typedef std::vector YItemCollection; + +%extend YWidget { +#if defined(SWIGPERL5) + int __eq__( YWidget *w ) + { return ($self == w); } + int __ne__( YWidget *w ) + { return ($self != w); } +#endif +#if defined(SWIGPYTHON) + int __eq__( YWidget *w ) + { return ($self == w); } + int __ne__( YWidget *w ) + { return ($self != w); } +#endif +#if defined(SWIGRUBY) + %rename( "==" ) equals( YWidget *w ); + %typemap(out) int equals + "$result = ($1 != 0) ? Qtrue : Qfalse;"; +#endif + int equals( YWidget *w ) { return ($self == w); } +} + +%inline %{ + +/* C++-style cast */ +YWidgetEvent* toYWidgetEvent(YEvent *event) { + return dynamic_cast(event); +} + +YKeyEvent* toYKeyEvent(YEvent *event) { + return dynamic_cast(event); +} + +YMenuEvent* toYMenuEvent(YEvent *event) { + return dynamic_cast(event); +} + +YCancelEvent* toYCancelEvent(YEvent *event) { + return dynamic_cast(event); +} + +YDebugEvent* toYDebugEvent(YEvent *event) { + return dynamic_cast(event); +} +YTimeoutEvent* toYTimeoutEvent(YEvent *event) { + return dynamic_cast(event); +} + +YTreeItem* toYTreeItem(YItem *item) { + return dynamic_cast(item); +} + +YTableItem* toYTableItem(YItem *item) { + return dynamic_cast(item); +} + +YItem* toYItem(YItemIterator iter) { + return *iter; +} + +YTableCell* toYTableCell(YTableCellIterator iter) { + return *iter; +} + +/* C++ Iterators*/ +YItemIterator incrYItemIterator( YItemIterator currentIterator) { + return ++currentIterator; +} + +YItemIterator beginYItemCollection( YItemCollection *coll) { + return coll->begin(); +} + +YItemIterator endYItemCollection( YItemCollection *coll) { + return coll->end(); +} + +YTableCellIterator incrYTableCellIterator(YTableCellIterator currentIterator) { + return ++currentIterator; +} + + +%} + diff --git a/deps/libyui/libyui-ncurses-pkg/.gitignore b/deps/libyui/libyui-ncurses-pkg/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b7797e40d60d62bb787649f204d9203cb86a725c --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/.gitignore @@ -0,0 +1,19 @@ + +*.o +*.so +*.so.* + +CMakeCache.txt +CMakeFiles +CMakeDoxyfile.in +Doxyfile +Doxygen.warnings +Makefile + +build*/ +package/*.tar.* + +*~ +*.bak +*.auto + diff --git a/deps/libyui/libyui-ncurses-pkg/CMakeLists.txt b/deps/libyui/libyui-ncurses-pkg/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e556f8b166a7c51f875dec2ce47b2413c4694b9d --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/CMakeLists.txt @@ -0,0 +1,78 @@ +# CMakeLists.txt for libyui-ncurses-pkg +# +# Usage: +# +# mkdir build +# cd build +# cmake .. +# +# make +# sudo make install +# +# Restart with a clean build environment: +# rm -rf build +# +# Show the complete compiler commands with all arguments: +# make VERBOSE=1 + +cmake_minimum_required( VERSION 3.10 ) +project( libyui-ncurses-pkg ) + +# Options usage: +# +# cmake -DBUILD_DOC=on -DBUILD_EXAMPLES=off .. + +option( BUILD_SRC "Build in src/ subdirectory" on ) +option( BUILD_DOC "Build class documentation" off ) +option( WERROR "Treat all compiler warnings as errors" on ) + + +#---------------------------------------------------------------------- + + +# We use /usr as the default CMAKE_INSTALL_PREFIX, but it can be set on the +# cmake command line with +# +# cmake -DCMAKE_INSTALL_PREFIX=/my/install/prefix .. +# +# or in the environment with +# +# CMAKE_INSTALL_PREFIX=/usr/local cmake .. + +if ( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) + if ( DEFINED ENV{CMAKE_INSTALL_PREFIX} ) + set( CIP $ENV{CMAKE_INSTALL_PREFIX} ) + else() + set( CIP /usr ) + endif() + set( CMAKE_INSTALL_PREFIX "${CIP}" CACHE PATH "Install path prefix" FORCE) +endif() + +message( "-- CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}" ) + + +set( CMAKE_INSTALL_MESSAGE LAZY ) # Suppress "up-to-date" messages during "make install" + + +# Initialize compiler flags for all targets in all subdirectories +add_compile_options( "-Wall" ) +add_compile_options( "-Os" ) # Optimize for size (overrides CMake's -O3 in RELEASE builds) + +if ( WERROR ) + add_compile_options( "-Werror" ) +endif() + +# libzypp uses the C++17 standard +set(CMAKE_CXX_STANDARD 17) + +# +# Descend into subdirectories +# + +if ( BUILD_SRC ) + add_subdirectory( src ) +endif() + +if ( BUILD_DOC ) + add_subdirectory( doc ) +endif() diff --git a/deps/libyui/libyui-ncurses-pkg/Makefile.repo b/deps/libyui/libyui-ncurses-pkg/Makefile.repo new file mode 100644 index 0000000000000000000000000000000000000000..4b7ae0e70438df6fd6f579fc01fb24da1ccaa907 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/Makefile.repo @@ -0,0 +1,64 @@ +# +# Makefile.repo for libyui-ncurses-pkg +# + +# Local Variables: +# mode: Makefile +# End: + + +all: clean configure build-hint + +build-hint: + @echo "" + @echo "To build:" + @echo "" + @echo " cd build" + @echo " make" + @echo "" + +configure: + mkdir build; \ + cd build; \ + cmake .. + +build: clean configure + cd build; \ + make -j $$(nproc) + +# This needs root privileges, of course +install: configure + cd build; \ + make -j $$(nproc) && make install + +clean: + rm -rf build + +package: + rake package + +doc: + test -d build || mkdir build + cd build; \ + cmake -DBUILD_DOC=on .. ; \ + make doc + +version-bump: + rake version:bump + +so-version-bump: + rake so_version:bump + +# Just some aliases +bump-version: version-bump + +bump-so-version: so-version-bump + + +# Enforce rebuilding some targets unconditionally, even if a file or directory +# with that name exists; otherwise the timestamp of that file or directory +# would be checked. +# +# We need this because we have a subdirectory doc/, a subdirectory package/ +# and possibly a subdirectory build/ here. +.PHONY: doc package build diff --git a/deps/libyui/libyui-ncurses-pkg/doc/CMakeLists.txt b/deps/libyui/libyui-ncurses-pkg/doc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..45bc32b56ad52e008fcda2c8a0b58726ba0687df --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/doc/CMakeLists.txt @@ -0,0 +1,24 @@ +# CMakeLists.txt for libyui*/doc + +include( ../../VERSION.cmake ) + +find_package( Doxygen REQUIRED dot ) + + +# +# Doxygen-generated autodocs +# + +if ( DOXYGEN_FOUND ) + + set( DOXYGEN_GENERATE_TREEVIEW yes ) # Enable views tree HTML frame + set( DOXYGEN_QUIET yes ) # Less verbose output + set( DOXYGEN_WARN_LOGFILE doxygen-warnings.log ) + # See build/CMakeDoxyfile.in for more supported variables + + doxygen_add_docs( doc ../src ) + +else() + message( WARNING "Missing doxygen package" ) +endif() + diff --git a/deps/libyui/libyui-ncurses-pkg/src/.gitignore b/deps/libyui/libyui-ncurses-pkg/src/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d861370731f1d003429265a7037eaa86cdc46ea8 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/.gitignore @@ -0,0 +1,17 @@ +Makefile +Makefile.in +ncurses +widgetlist +core +bak +*.swp +*.o +*.lo +*.loT +*.la +.deps +.libs +*.kdoc +SETUPENV.sh +gsrc +obsolete diff --git a/deps/libyui/libyui-ncurses-pkg/src/CMakeLists.txt b/deps/libyui/libyui-ncurses-pkg/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..530015c8e889a71269c8a7d6fb2676ef3175c6cc --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/CMakeLists.txt @@ -0,0 +1,184 @@ +# CMakeLists.txt for libyui-ncurses/src + +include( ../../VERSION.cmake ) +include( GNUInstallDirs ) # set CMAKE_INSTALL_INCLUDEDIR, ..._LIBDIR + + +# Check if the libs we link against are available. +# They are all part of package ncurses-devel. + +find_library( TINFO_LIB NAMES tinfo REQUIRED ) +# We don't use libncursesw or libpanelw here. Check with ldd -u . + +set( NCURSES_LIBS ${PANELW_LIB} ${TINFO_LIB} ) + +# find_library( zypp ) is pointless because there is a libzypp on every SUSE + + +# +# libyui plugin specific +# + +set( TARGETLIB libyui-ncurses-pkg ) +set( TARGETLIB_BASE yui-ncurses-pkg ) + +set( HEADERS_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/yui/ncurses-pkg ) +set( PLUGIN_DIR ${CMAKE_INSTALL_LIBDIR}/yui ) # /usr/lib64/yui + +# if DESTDIR is set, CMAKE_INSTALL_INCLUDEDIR already contains it +# during "make install" (but not for other make targets!): +# +# sudo make install DESTDIR=/work/foo +# or +# DESTDIR=/work/foo sudo make install +# +# -> the include files are installed to /work/foo/usr/include/... +# We need that for RPM builds to install everything to $RPM_BUILD_ROOT. + + +set( SOURCES + NCPackageSelector.cc + NCPackageSelectorPluginImpl.cc + NCPackageSelectorStart.cc + + NCPkgFilterClassification.cc + NCPkgFilterInstSummary.cc + NCPkgFilterLocale.cc + NCPkgFilterMain.cc + NCPkgFilterPattern.cc + NCPkgFilterRepo.cc + NCPkgFilterSearch.cc + NCPkgFilterService.cc + NCPkgMenuAction.cc + NCPkgMenuConfig.cc + NCPkgMenuDeps.cc + NCPkgMenuExtras.cc + NCPkgMenuFilter.cc + NCPkgMenuHelp.cc + NCPkgMenuView.cc + NCPkgPackageDetails.cc + NCPkgPatchSearch.cc + NCPkgPopupDeps.cc + NCPkgPopupDescr.cc + NCPkgPopupDiskspace.cc + NCPkgPopupTable.cc + NCPkgSearchSettings.cc + NCPkgSelMapper.cc + NCPkgStatusStrategy.cc + NCPkgStrings.cc + NCPkgTable.cc + ) + + +set( HEADERS + NCPackageSelector.h + NCPackageSelectorPluginImpl.h + NCPackageSelectorStart.h + + NCPkgFilterClassification.h + NCPkgFilterInstSummary.h + NCPkgFilterLocale.h + NCPkgFilterMain.h + NCPkgFilterPattern.h + NCPkgFilterRepo.h + NCPkgFilterSearch.h + NCPkgFilterService.h + NCPkgMenuAction.h + NCPkgMenuConfig.h + NCPkgMenuDeps.h + NCPkgMenuExtras.h + NCPkgMenuFilter.h + NCPkgMenuHelp.h + NCPkgMenuView.h + NCPkgPackageDetails.h + NCPkgPatchSearch.h + NCPkgPopupDeps.h + NCPkgPopupDescr.h + NCPkgPopupDiskspace.h + NCPkgPopupTable.h + NCPkgSearchSettings.h + NCPkgSelMapper.h + NCPkgStatusStrategy.h + NCPkgStrings.h + NCPkgTable.h + NCZypp.h + ) + + +# Add shared lib to be built +add_library( ${TARGETLIB} SHARED ${SOURCES} ${HEADERS} ) + +# +# Include directories and compile options +# + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + +# Create an include dir with some symlinks to include headers from sibling projects: +# build/src/include/yui/ncurses -> ../../libyui-ncurses/src +# build/src/include/yui/yui -> ../../libyui/src +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR}/yui ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../libyui/src ${LOCAL_INCLUDE_DIR}/yui/yui SYMBOLIC ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../libyui-ncurses/src ${LOCAL_INCLUDE_DIR}/yui/ncurses SYMBOLIC ) + +# from build/src/include/yui/ncurses -> ../../libyui-ncurses/src +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) + +# from build/src/include/yui/yui -> ../../libyui/src +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR}/yui ) + + +# Workaround for boost::bind() complaining about deprecated _1 placeholder +# deep in the libzypp headers +target_compile_definitions( ${TARGETLIB} PUBLIC BOOST_BIND_GLOBAL_PLACEHOLDERS=1 ) + +# Allow operator<<() to output internal values of NCurses WINDOW etc. +target_compile_definitions( ${TARGETLIB} PUBLIC NCURSES_INTERNALS=1 ) + +# Add more compile options to this target in addition to those +# added in the toplevel CMakeLists.txt and target_compile_definitions(). +# +# Notice that CMake will automatically add -fPIC etc. where needed, +# like for this shared lib. +### target_compile_options( ${TARGETLIB} PUBLIC "-Dfoo" ) + +# Show the complete compiler commands with all arguments: +# make VERBOSE=1 + +# Add more compile options to an individual source file: +### set_source_files_properties( YUI.cc PROPERTIES COMPILE_OPTIONS "-Dfoo" ) + + +# +# Linking +# + +# Find yui during a combined build +target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../libyui/build/src ) + + +# Libraries that are needed to build this shared lib +# +# If in doubt what is really needed, check with "ldd -u" which libs are unused. +target_link_libraries( ${TARGETLIB} + yui + zypp + ${NCURSES_LIBS} + ) + + +# https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#target-properties +set_target_properties( ${TARGETLIB} PROPERTIES + VERSION ${SONAME} # From ../../VERSION.cmake + SOVERSION ${SONAME_MAJOR} # From ../../VERSION.cmake + OUTPUT_NAME ${TARGETLIB_BASE} + ) + + +# +# Install +# + +# Install the headers first so the message about the lib does not scroll away +install( FILES ${HEADERS} DESTINATION ${HEADERS_INSTALL_DIR} ) +install( TARGETS ${TARGETLIB} LIBRARY DESTINATION ${PLUGIN_DIR} ) diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelector.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelector.cc new file mode 100644 index 0000000000000000000000000000000000000000..b23275d406234b9382f4748e757aaebb822969f8 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelector.cc @@ -0,0 +1,1958 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPackageSelector.cc + Author: Gabriele Strattner + +*/ + + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "NCPkgFilterPattern.h" +#include "NCPkgFilterLocale.h" +#include "NCPkgFilterRepo.h" +#include "NCPkgFilterService.h" +#include "NCPkgFilterClassification.h" +#include "NCPkgPopupDeps.h" +#include "NCPkgPopupDiskspace.h" +#include "NCPkgMenuDeps.h" +#include "NCPkgMenuView.h" +#include "NCPkgMenuExtras.h" +#include "NCPkgMenuConfig.h" +#include "NCPkgMenuHelp.h" +#include "NCPkgMenuAction.h" +#include "NCPkgPopupDescr.h" +#include "NCZypp.h" // tryCastToZyppPkg(), tryCastToZyppPat.h>) + +#include "NCPackageSelector.h" + + +#define PATH_TO_YAST_SYSCONFIG "/etc/sysconfig/yast2" + +#define OPTION_RECOMMENDED "PKGMGR_RECOMMENDED" +#define OPTION_REEVALUATE "PKGMGR_REEVALUATE_RECOMMENDED" +#define OPTION_VERIFY "PKGMGR_VERIFY_SYSTEM" +#define OPTION_AUTO_CHECK "PKGMGR_AUTO_CHECK" +#define OPTION_EXIT "PKGMGR_ACTION_AT_EXIT" + +typedef zypp::Patch::Contents ZyppPatchContents; +typedef zypp::Patch::Contents::Selectable_iterator ZyppPatchContentsIterator; + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// Constructor +// +NCPackageSelector::NCPackageSelector( long modeFlags ) + : depsPopup( 0 ) + , patternPopup( 0 ) + , languagePopup( 0 ) + , repoPopup( 0 ) + , servicePopup( 0 ) + , diskspacePopup( 0 ) + , searchPopup( 0 ) + , inst_summary( 0 ) + , pkgClass( 0 ) + , autoCheck( true ) + , verifySystem( false ) + , installRecommended( false ) + , pkgList( 0 ) + , depsMenu( 0 ) + , viewMenu( 0 ) + , configMenu( 0 ) + , extrasMenu( 0 ) + , helpMenu( 0 ) + , filterMain( 0 ) + , actionMenu( 0 ) + , filterMenu( 0 ) + , updatelistItem( 0 ) + , packageLabel( 0 ) + , diskspaceLabel( 0 ) + , patternLabel( 0 ) + , infoText( 0 ) + , filter_desc( 0 ) + , searchField( 0 ) + , searchSet( 0 ) + , replacePoint( 0 ) + , replPoint( 0 ) + , replPoint2( 0 ) + , versionsList( 0 ) + , patchPkgs( 0 ) + , patchPkgsVersions( 0 ) + , okButton( 0 ) + , cancelButton( 0 ) + , visibleInfo( 0 ) +{ + setFlags( modeFlags ); + readSysconfig(); + saveState(); + diskspacePopup = new NCPkgDiskspace( testMode ); + + setInstallRecommended( isInstallRecommended() ); + setAutoCheck( isAutoCheck() ); + setVerifySystem( isVerifySystem() ); +} + + +/////////////////////////////////////////////////////////////////// +// +// Destructor +// +NCPackageSelector::~NCPackageSelector() +{ + // Don't call delete for the popups in destructor but call + // YDialog::deleteTopmostDialog() instead at the end of + // NCPackageSelectorPlugin::runPkgSelection +} + + +void NCPackageSelector::setFlags( long modeFlags ) +{ + youMode = ( modeFlags & YPkg_OnlineUpdateMode ) ? true : false; + updateMode = ( modeFlags & YPkg_UpdateMode ) ? true : false; + repoMgrEnabled = ( modeFlags & YPkg_RepoMgr ) ? true : false; + testMode = ( modeFlags & YPkg_TestMode ) ? true : false; + repoMode = ( modeFlags & YPkg_RepoMode ) ? true : false; + summaryMode = ( modeFlags & YPkg_SummaryMode ) ? true : false; + onlineSearchEnabled = ( modeFlags & YPkg_OnlineSearch ) ? true : false; +} + + +void NCPackageSelector::readSysconfig() +{ + sysconfig = zypp::base::sysconfig::read( PATH_TO_YAST_SYSCONFIG ); + std::map ::const_iterator it = sysconfig.find( OPTION_EXIT ); + + if (it != sysconfig.end()) + { + actionAtExit = it->second; + yuiMilestone() << "Read sysconfig's action at pkg mgr exit value: " << actionAtExit << endl; + } + else + { + actionAtExit = ""; + yuiMilestone() << "Could not read " << OPTION_EXIT << "variable from sysconfig, disabling the menu" << endl; + } +} + + +void NCPackageSelector::writeSysconfig() +{ + + if ( !actionAtExit.empty() ) + { + try + { + zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG, + OPTION_EXIT, + actionAtExit, + "Set behaviour when package installation has finished."); + } + catch( const std::exception &e ) + { + yuiError() << "Writing " << OPTION_EXIT << " failed" << endl; + } + } + + try + { + zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG, + OPTION_AUTO_CHECK, + (autoCheck?"yes":"no"), + "Automatic dependency checking" ); + } + catch( const std::exception &e ) + { + yuiError() << "Writing " << OPTION_AUTO_CHECK << " failed" << endl; + } + + try + { + zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG, + OPTION_VERIFY, + (verifySystem?"yes":"no"), + "System verification mode" ); + } + catch( const std::exception &e ) + { + yuiError() << "Writing " << OPTION_VERIFY << " failed" << endl; + } + + try + { + zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG, + OPTION_RECOMMENDED, + (installRecommended?"yes":"no"), + "Install recommended packages" ); + } + catch( const std::exception &e ) + { + yuiError() << "Writing " << OPTION_RECOMMENDED << " failed" << endl; + } +} + + +bool NCPackageSelector::checkNow( bool *ok ) +{ + bool ret = false; + + depsPopup = new NCPkgPopupDeps( wpos( 3, 4 ), this ); + ret = depsPopup->showDependencies( NCPkgPopupDeps::S_Solve, ok ); + YDialog::deleteTopmostDialog(); + return ret; +} + + +bool NCPackageSelector::systemVerification( bool *ok ) +{ + bool ret = false; + + depsPopup = new NCPkgPopupDeps( wpos( 3, 4 ), this ); + ret = depsPopup->showDependencies( NCPkgPopupDeps::S_Verify, ok ); + YDialog::deleteTopmostDialog(); + return ret; +} + + +bool NCPackageSelector::doInstallRecommended( bool *ok ) +{ + zypp::getZYpp()->resolver()->setIgnoreAlreadyRecommended( false ); + zypp::getZYpp()->resolver()->resolvePool(); + *ok = true; + bool ret = true; + return ret; +} + + +// +// 'Clean dependencies on remove' option' is NOT saved and cannot be set in /etc/sysconfig/yast2. +// The package selector starts with setting from /etc/zypp/zypp.conf (default is false). +// +bool NCPackageSelector::isCleanDepsOnRemove() +{ + return zypp::getZYpp()->resolver()->cleandepsOnRemove(); +} + + +void NCPackageSelector::setCleanDepsOnRemove( bool on ) +{ + zypp::getZYpp()->resolver()->setCleandepsOnRemove( on ); + zypp::getZYpp()->resolver()->resolvePool(); + updatePackageList(); +} + + +// +// 'Install recommended packages' option can be set and is saved +// in /etc/sysconfig/yast2 +// +bool NCPackageSelector::isInstallRecommended() +{ + std::map ::const_iterator it = sysconfig.find( OPTION_RECOMMENDED ); + + if ( it != sysconfig.end() ) + { + yuiMilestone() << OPTION_RECOMMENDED << ": " << it->second << endl; + if ( it->second == "yes" ) + installRecommended = true; + else if ( it->second == "no") + installRecommended = false; + else + installRecommended = !(zypp::getZYpp()->resolver()->onlyRequires()); // reverse value + } + else + { + installRecommended = !(zypp::getZYpp()->resolver()->onlyRequires()); // reverse value + } + yuiMilestone() << "installRecommended: " << (installRecommended?"yes":"no") << endl; + + return installRecommended; +} + + +void NCPackageSelector::setInstallRecommended( bool on ) +{ + installRecommended = on; + zypp::getZYpp()->resolver()->setOnlyRequires( !on ); // reverse value here ! + // solve after changing the solver settings + zypp::getZYpp()->resolver()->resolvePool(); + updatePackageList(); +} + + +bool NCPackageSelector::isAutoCheck() +{ + // automatic dependency check is on by default (check on every click) + + std::map ::const_iterator it = sysconfig.find( OPTION_AUTO_CHECK); + + if ( it != sysconfig.end() ) + { + yuiMilestone() << OPTION_AUTO_CHECK << ": " << it->second << endl; + if ( it->second == "no" ) + autoCheck = false; + } + yuiMilestone() << "autoCheck " << (autoCheck?"yes":"no") << endl; + + return autoCheck; +} + + +bool NCPackageSelector::isVerifySystem() +{ + std::map ::const_iterator it = sysconfig.find( OPTION_VERIFY ); + + if ( it != sysconfig.end() ) + { + yuiMilestone() << OPTION_VERIFY << ": " << it->second << endl; + if ( it->second == "yes" ) + verifySystem = true; + else if ( it->second == "no") + verifySystem = false; + else + verifySystem = zypp::getZYpp()->resolver()->systemVerification(); + } + else + { + verifySystem = zypp::getZYpp()->resolver()->systemVerification(); + } + yuiMilestone() << "verifySystem: " << (verifySystem?"yes":"no") << endl; + + return verifySystem; +} + + +void NCPackageSelector::setVerifySystem( bool on ) +{ + verifySystem = on; + zypp::getZYpp()->resolver()->setSystemVerification( on ); + // solve after changing the solver settings + zypp::getZYpp()->resolver()->resolvePool(); + updatePackageList(); +} + + +// +// 'Allow vendor change' option is NOT saved and cannot be set in /etc/sysconfig/yast2. +// The package selector starts with setting from /etc/zypp/zypp.conf (default is false). +// +bool NCPackageSelector::isAllowVendorChange() +{ + zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver(); + bool change = resolver->allowVendorChange(); + yuiMilestone() << "Vendor change allowed: " << (change?"true":"false") << endl; + return change; +} + + +void NCPackageSelector::setAllowVendorChange( bool on ) +{ + zypp::getZYpp()->resolver()->setAllowVendorChange( on ); + zypp::getZYpp()->resolver()->dupSetAllowVendorChange( on ); // bsc#1170521 + zypp::getZYpp()->resolver()->resolvePool(); + updatePackageList(); +} + + +void NCPackageSelector::saveState() +{ + ZyppPool p = zyppPool(); + + p.saveState(); + p.saveState(); + + p.saveState(); + + p.saveState(); + // p.saveState(); +} + + +void NCPackageSelector::restoreState() +{ + ZyppPool p = zyppPool(); + + p.restoreState(); + p.restoreState(); + + p.restoreState(); + + p.restoreState(); + // p.restoreState(); +} + + +bool NCPackageSelector::diffState() +{ + ZyppPool p = zyppPool(); + + bool diff = false; + + std::ostream & log = yuiMilestone(); + log << "diffState" << endl; + diff = diff || p.diffState(); + log << diff << endl; + diff = diff || p.diffState(); + log << diff << endl; + + diff = diff || p.diffState(); + log << diff << endl; + + diff = diff || p.diffState(); + log << diff << endl; + // diff = diff || p.diffState(); + log << diff << endl; + return diff; +} + + +/////////////////////////////////////////////////////////////////// +// +// handleEvent +// +// Handle event, calls corresponding handler-function +// +bool NCPackageSelector::handleEvent ( const NCursesEvent& event ) +{ + bool retVal = false; + + if ( event == NCursesEvent::handled ) + return false; + + // yuiMilestone() << "widget event: " << event << endl; + // Call the appropriate handler + if ( event == NCursesEvent::button ) + { + if ( event.widget == okButton ) + { + retVal = OkButtonHandler( event ); + } + else if ( event.widget == cancelButton ) + { + retVal = CancelHandler( event ); + } + else if ( event.widget == filterMain ) + { + retVal = filterMain->handleEvent(); + } + else if ( event.widget == searchField ) + { + if ( event.reason == YEvent::Activated ) + { + retVal = searchPopup->showSearchResultPackages(); + } + else // no action, reason was YEvent::SelectionChanged + { + retVal = true; + } + } + } + else if ( event == NCursesEvent::menu ) + { + if ( event.widget == actionMenu ) + // change package/patch status + retVal = actionMenu->handleEvent( event ); + else if ( event.widget == viewMenu ) + // show package/patch information + retVal = viewMenu->handleEvent( event ); + else if ( event.widget == depsMenu ) + retVal = depsMenu->handleEvent( event ); + else if ( event.widget == extrasMenu ) + retVal = extrasMenu->handleEvent( event ); + else if ( event.widget == configMenu ) + retVal = configMenu->handleEvent( event ); + else if ( event.widget == helpMenu ) + retVal = helpMenu->handleEvent( event ); + else if ( event.widget == filterMenu ) + retVal = filterMenu->handleEvent( event ); + else if ( event.selection->label().substr(0, 4) == "pkg:" ) + // handle hyper links + retVal = LinkHandler( event.selection->label() ); + + } + + return retVal; +} + + +/////////////////////////////////////////////////////////////////// +// +// fillPatchSearchList +// +// Fills the patch list with search results +// +bool NCPackageSelector::fillPatchSearchList( const std::string & expr, bool checkName, bool checkSum ) +{ + NCPkgTable * packageList = PackageList(); + + if ( !packageList ) + { + return false; + } + + // clear the patch list + packageList->itemsCleared(); + + zypp::PoolQuery q; + q.addString( expr ); + q.addKind( zypp::ResKind::patch ); + q.addAttribute( zypp::sat::SolvAttr::keywords ); + if ( checkName ) + { + q.addAttribute( zypp::sat::SolvAttr::name ); + } + if ( checkSum ) + { + q.addAttribute( zypp::sat::SolvAttr::summary ); + } + + for ( zypp::PoolQuery::Selectable_iterator it = q.selectableBegin(); + it != q.selectableEnd(); it++) + { + yuiMilestone() << (*it)->name() << endl; + ZyppPatch patchPtr = tryCastToZyppPatch( (*it)->theObj() ); + packageList->createPatchEntry ( patchPtr, *it); + } + + // show the patch list with search result + packageList->drawList(); + + // set filter label to 'Search' + if ( packageLabel ) + { + packageLabel->setLabel( NCPkgStrings::SearchResults() ); + } + + return true; +} + + +/////////////////////////////////////////////////////////////////// +// +// fillPatchList +// +// Fills the package table with the list of YOU patches +// +bool NCPackageSelector::fillPatchList( NCPkgMenuFilter::PatchFilter filter ) +{ + NCPkgTable * packageList = PackageList(); + + if ( !packageList ) + { + yuiError() << "No valid NCPkgTable widget" << endl; + return false; + } + + // clear list of patches + packageList->itemsCleared(); + + // get the patch list and sort it + std::list patchList( zyppPatchesBegin(), zyppPatchesEnd() ); + patchList.sort( sortByName ); + std::list::iterator listIt = patchList.begin(); + + while ( listIt != patchList.end() ) + { + ZyppPatch patchPtr = tryCastToZyppPatch( ( *listIt)->theObj() ); + + if ( patchPtr ) + { + checkPatch( patchPtr, *listIt, filter ); + } + ++listIt; + } + + if ( filter == NCPkgMenuFilter::F_All + && packageList->getNumLines() == 0 ) + { + packageList->createInfoEntry( NCPkgStrings::NoPatches() ); + } + + // show the patches + packageList->drawList(); + + // show the selected filter label + if ( packageLabel ) + { + switch ( filter ) + { + case NCPkgMenuFilter::F_Needed: + // show common label "Needed Patches" + packageLabel->setLabel( NCPkgStrings::YOUPatches() ); + break; + + case NCPkgMenuFilter::F_Unneeded: + packageLabel->setLabel( NCPkgStrings::InstPatches() ); + break; + + default: + packageLabel->setLabel( NCPkgStrings::Patches() ); + break; + } + } + + return true; +} + + +/////////////////////////////////////////////////////////////////// +// +// fillUpdateList +// +// +bool NCPackageSelector::fillUpdateList() +{ + NCPkgTable * packageList = PackageList(); + + if ( !packageList ) + { + yuiError() << "Widget is not a valid NCPkgTable widget" << endl; + return false; + } + + // clear the package table + packageList->itemsCleared(); + + std::list problemList = zypp::getZYpp()->resolver()->problematicUpdateItems(); + + for ( std::list::const_iterator it = problemList.begin(); + it != problemList.end(); + ++it ) + { + ZyppPkg pkg = tryCastToZyppPkg( (*it).resolvable() ); + + if ( pkg ) + { + ZyppSel slb = selMapper.findZyppSel( pkg ); + + if ( slb ) + { + yuiMilestone() << "Problematic package: " << pkg->name().c_str() << " " << + pkg->edition().asString().c_str() << endl; + packageList->createListEntry( pkg, slb ); + } + } + + } + + // show the list + packageList->drawList(); + + // show the selected filter label + if ( packageLabel ) + { + packageLabel->setLabel( NCPkgStrings::UpdateProblem() ); + } + + return true; +} + + +/////////////////////////////////////////////////////////////////// +// +// fillPatchPackages +// +// +bool NCPackageSelector::fillPatchPackages ( NCPkgTable * pkgTable, ZyppObj objPtr ) +{ + if ( !pkgTable || !objPtr ) + return false; + + pkgTable->itemsCleared(); + + std::set patchSelectables; + ZyppPatch patchPtr = tryCastToZyppPatch( objPtr ); + + if ( !patchPtr ) + return false; + + ZyppPatchContents patchContents( patchPtr->contents() ); + + yuiMilestone() << "Filtering for patch: " << patchPtr->name().c_str() << " number of atoms: " + << patchContents.size() << endl; + + for ( ZyppPatchContentsIterator it = patchContents.selectableBegin(); + it != patchContents.selectableEnd(); + ++it ) + { + ZyppPkg pkg = tryCastToZyppPkg( (*it)->theObj() ); + + if ( pkg ) + { + yuiMilestone() << "Patch package found: " << (*it)->name().c_str() << endl; + ZyppSel sel = selMapper.findZyppSel( pkg ); + + if ( sel ) + { + if ( inContainer( patchSelectables, sel ) ) + { + yuiMilestone() << "Suppressing duplicate selectable: " << (*it)->name().c_str() << "-" << + pkg->edition().asString().c_str() << " " << + pkg->arch().asString().c_str() << endl; + } + else + { + patchSelectables.insert( sel ); + yuiDebug() << (*it)->name().c_str() << ": Version: " << pkg->edition().asString() << endl; + + pkgTable->createListEntry( pkg, sel ); + } + } + } + else // No ZyppPkg - some other kind of object + { + yuiDebug() << "Found unknown atom of kind %s: %s" << + (*it)->kind().asString().c_str() << + (*it)->name().c_str() << endl; + + } + } + + // show the list + pkgTable->drawList(); + + return true; +} + + +// patches + + +/////////////////////////////////////////////////////////////////// +// +// checkPatch +// +// +bool NCPackageSelector::checkPatch( ZyppPatch patchPtr, + ZyppSel selectable, + NCPkgMenuFilter::PatchFilter filter ) + +{ + NCPkgTable * packageList = PackageList(); + bool displayPatch = false; + + if ( !packageList ) + { + yuiError() << "Widget is not a valid NCPkgTable widget" << endl; + return false; + } + if ( !patchPtr || !selectable || !selectable->hasCandidateObj() ) + { + yuiError() << "Patch data not valid" << endl; + return false; + } + yuiDebug() << "Filter: " << filter << endl; + + if ( filter == NCPkgMenuFilter::F_All ) + { + displayPatch = true; + } + // only show patches relevant for the system, means any of the patch packages is installed + else if ( selectable->candidateObj().isRelevant() ) + { + switch ( filter ) + { + case NCPkgMenuFilter::F_Unneeded: // unneeded means satisfied (installed) + { + if ( selectable->candidateObj().isSatisfied() && + !selectable->candidateObj().status().isToBeInstalled() ) + { + displayPatch = true; + } + break; + } + case NCPkgMenuFilter::F_Needed: // needed means not satisfied... + { + if ( !selectable->candidateObj().isSatisfied() || + // or already satified because the patch is preselected + selectable->candidateObj().status().isToBeInstalled() ) + displayPatch = true; + break; + } + case NCPkgMenuFilter::F_Security: + { + if ( patchPtr->category() == "security" ) + displayPatch = true; + break; + } + case NCPkgMenuFilter::F_Recommended: + { + if ( patchPtr->category() == "recommended" ) + displayPatch = true; + break; + } + case NCPkgMenuFilter::F_Optional: + { + if ( patchPtr->category() == "optional" ) + displayPatch = true; + break; + } + default: + yuiWarning() << "Unknown patch filter" << endl; + } + } + if ( displayPatch ) + packageList->createPatchEntry( patchPtr, selectable ); + + return displayPatch; +} + + +/////////////////////////////////////////////////////////////////// +// +// deleteReplacePoint +// +// Gets ( and returns ) the current size of the widget at the replace +// point and deletes it. +// +wrect NCPackageSelector::deleteReplacePoint() +{ + // delete current child of the ReplacePoint + YWidget * replaceChild = replacePoint->firstChild(); + wrect oldSize; + + if ( replaceChild ) + { + oldSize = dynamic_cast(replaceChild)->wGetSize(); + + delete replaceChild; + // reset all info widgets + infoText = 0; // NCPkgPackageDetails ( NCRichText ) + versionsList = 0; // NCPkgTable - type: T_Availables + patchPkgs = 0; // NCPkgTable - type: T_PatchPkgs + patchPkgsVersions = 0; // NCPkgTable - type: T_Availables + } + + return oldSize; +} + + +/////////////////////////////////////////////////////////////////// +// +// showInformation +// +// Creates an NCPkgPackageDetails (a RichtText widget) which is +// used to show the required information (called from NCPkgMenuView) +// +// +void NCPackageSelector::showInformation() +{ + wrect oldSize = deleteReplacePoint(); + + // show the rich text widget + infoText = new NCPkgPackageDetails( replacePoint, " ", this); + + if ( infoText ) + { + infoText->setSize( oldSize.Sze.W, oldSize.Sze.H ); + infoText->Redraw(); + } +} + + +/////////////////////////////////////////////////////////////////// +// +// showVersionsList +// +// Creates an NCPkgTable (type T_Availables) which is used to show +// the list of package versions (called from NCPkgMenuView) +// +// +void NCPackageSelector::showVersionsList() +{ + wrect oldSize = deleteReplacePoint(); + NCPkgTable * packageList = PackageList(); + + // show a package table with all available package versions + YTableHeader * tableHeader = new YTableHeader(); + versionsList = new NCPkgTable( replacePoint, tableHeader ); + // YDialog::currentDialog()->setInitialSize(); -> doesn't work + // call versionsList->setSize() and versionsList->Redraw() instead + + if ( versionsList && packageList ) + { + // set the connection to the NCPackageSelector !!!! + versionsList->setPackager( this ); + // fill default header, set correct header in NCPkgTable::fillAvailableList() + versionsList->fillHeader(); + versionsList->setSize( oldSize.Sze.W, oldSize.Sze.H ); + + versionsList->fillAvailableList( packageList->getSelPointer( packageList->getCurrentItem() ) ); + versionsList->Redraw(); + + packageList->setKeyboardFocus(); + } +} + + +/////////////////////////////////////////////////////////////////// +// +// showPatchPackages +// +// Creates an NCPkgTable (type T_PatchPkgs) which is used to show +// the list of all packages belonging to a patch (called from NCPkgMenuView) +// +// +void NCPackageSelector::showPatchPackages() +{ + wrect oldSize = deleteReplacePoint(); + NCPkgTable * packageList = PackageList(); + + // show a package table with packages belonging to a patch + YTableHeader * tableHeader = new YTableHeader(); + patchPkgs = new NCPkgTable( replacePoint, tableHeader ); + + if ( patchPkgs && packageList ) + { + // set the connection to the NCPackageSelector !!!! + patchPkgs->setPackager( this ); + // set status strategy - don't set extra strategy, use 'normal' package strategy + NCPkgStatusStrategy * strategy = new PackageStatStrategy(); + patchPkgs->setTableType( NCPkgTable::T_PatchPkgs, strategy ); + patchPkgs->fillHeader(); + patchPkgs->setSize( oldSize.Sze.W, oldSize.Sze.H ); + + fillPatchPackages( patchPkgs, packageList->getDataPointer( packageList->getCurrentItem() ) ); + patchPkgs->Redraw(); + + packageList->setKeyboardFocus(); + } +} + + +/////////////////////////////////////////////////////////////////// +// +// showPatchPkgVersions +// +// Creates an NCPkgTable (type T_Availables) which is used to show +// a list of all versions of all packages belonging to a patch +// (called from NCPkgMenuView) +// +// +void NCPackageSelector::showPatchPkgVersions() +{ + // only available if patch packages are currently shown + if ( patchPkgs ) + { + // get selected line and show availables for this package + ZyppSel sel = patchPkgs->getSelPointer( patchPkgs->getCurrentItem() ); + + // show the availables + NCPkgPopupTable * availablePopup = + new NCPkgPopupTable( wpos( 3, 8), this, + // headline of package versions popup + _("Package Versions"), + // text above of list of all package versions + _("List of all available package versions:"), + "", // no additional text line + false ); // no 'Cancel' button + NCursesEvent input = availablePopup->showAvailablesPopup( sel ); + + YDialog::deleteTopmostDialog(); + + patchPkgs->setKeyboardFocus(); + } +} + +void NCPackageSelector::clearInfoArea() +{ + if ( infoText ) + infoText->setText(""); + if ( versionsList ) + versionsList->itemsCleared(); + + packageLabel->setText("....................................."); +} + + +void NCPackageSelector::replaceFilter( FilterMode mode ) +{ + // If one of those checks result in an exception, this method might have + // been called in youMode where it creates a completely different layout + // with packager->createYouLayout() instead of packager->createPkgLayout(), + // and it will not create the widgets that are used here. + + YUI_CHECK_PTR( replPoint ); + YUI_CHECK_PTR( patternLabel ); + + patternLabel->setLabel( " " ); + + YWidget * replaceChild = replPoint->firstChild(); + wrect oldSize; + + if ( replaceChild ) + { + oldSize = dynamic_cast(replaceChild)->wGetSize(); + + delete replaceChild; + + patternPopup = 0; + languagePopup = 0; + repoPopup = 0; + servicePopup = 0; + searchPopup = 0; + pkgClass = 0; + } + + // replace the description area already here, so the next selected + // filter can update it right away (#377857) + replaceFilterDescr( mode == Search ); + + switch (mode) + { + case Patterns: + { + YTableHeader *hhh = new YTableHeader(); + patternPopup = new NCPkgFilterPattern( replPoint, hhh, this ); + patternPopup->setSize( oldSize.Sze.W, oldSize.Sze.H ); + patternPopup->Redraw(); + patternPopup->showPatternPackages(); + patternPopup->setKeyboardFocus(); + break; + } + case Languages: + { + YTableHeader *hhh = new YTableHeader(); + languagePopup = new NCPkgLocaleTable( replPoint, hhh, this ); + languagePopup->setSize( oldSize.Sze.W, oldSize.Sze.H ); + languagePopup->Redraw(); + languagePopup->showLocalePackages(); + languagePopup->setKeyboardFocus(); + break; + } + case Repositories: + { + YTableHeader *hhh = new YTableHeader(); + repoPopup = new NCPkgRepoTable( replPoint, hhh, this ); + repoPopup->setSize( oldSize.Sze.W, oldSize.Sze.H ); + repoPopup->Redraw(); + repoPopup->showRepoPackages(); + repoPopup->setKeyboardFocus(); + break; + } + case Services: + { + YTableHeader *hhh = new YTableHeader(); + servicePopup = new NCPkgServiceTable( replPoint, hhh, this ); + servicePopup->setSize( oldSize.Sze.W, oldSize.Sze.H ); + servicePopup->Redraw(); + servicePopup->showServicePackages(); + servicePopup->setKeyboardFocus(); + break; + } + case Search: + { + searchPopup = new NCPkgFilterSearch( replPoint, YD_VERT, this ); + searchPopup->createLayout( replPoint ); + searchPopup->setSize( oldSize.Sze.W, oldSize.Sze.H ); + searchPopup->Redraw(); + + searchField = searchPopup->getSearchField(); + + if ( searchField ) + { + searchField->setKeyboardFocus(); + searchField->setNotify(true); + } + break; + } + case Summary: + { + inst_summary = new NCPkgFilterInstSummary( replPoint, _( "&Packages with Status" ), this ); + inst_summary->setSize( oldSize.Sze.W, oldSize.Sze.H ); + inst_summary->Redraw(); + inst_summary->setKeyboardFocus(); + pkgList->fillSummaryList(NCPkgTable::L_Changes); + break; + } + case PkgClassification: + { + pkgClass = new NCPkgFilterClassification( replPoint, this ); + pkgClass->setSize( oldSize.Sze.W, oldSize.Sze.H ); + pkgClass->Redraw(); + pkgClass->setKeyboardFocus(); + break; + } + + default: + yuiError() << "zatim nic" << endl; + break; + } + + if (mode == Search) + { + pkgList->itemsCleared(); + clearInfoArea(); + } + else + { + pkgList->scrollToFirstItem(); + pkgList->showInformation(); + } +} + + +void NCPackageSelector::replaceFilterDescr( bool b ) +{ + YUI_CHECK_PTR( replPoint2 ); + + YWidget * replaceChild = replPoint2->firstChild(); + wrect oldSize; + + if ( replaceChild ) + { + oldSize = dynamic_cast(replaceChild)->wGetSize(); + + delete replaceChild; + filter_desc = 0; + searchSet = 0; + } + + if (b) + { + searchSet = new NCPkgSearchSettings( replPoint2, NCPkgStrings::SearchIn() ); + searchSet->setSize( oldSize.Sze.W, oldSize.Sze.H ); + searchSet->Redraw(); + } + else + { + filter_desc = new NCRichText( replPoint2, ""); + filter_desc->setSize( oldSize.Sze.W, oldSize.Sze.H ); + filter_desc->Redraw(); + } + +} + + +/////////////////////////////////////////////////////////////////// +// +// LinkHandler +// +// Handles hyperlinks in package description. +// +bool NCPackageSelector::LinkHandler ( std::string link ) +{ + bool found = false; + // e.g. link is pkg://hp-officeJet + std::string pkgName = link.substr(6); + + ZyppPoolIterator + b = zyppPkgBegin(), + e = zyppPkgEnd(), + i; + for (i = b; i != e; ++i) + { + ZyppPkg pkgPtr = tryCastToZyppPkg ((*i)->theObj()); + if ( pkgPtr && pkgPtr->name() == pkgName ) + { + yuiMilestone() << "Package " << pkgName << " found" << endl; + // open popup with package info + NCPkgPopupDescr * popupDescr = new NCPkgPopupDescr( wpos(1, 1), this ); + popupDescr->showInfoPopup( pkgPtr, *i ); + + YDialog::deleteTopmostDialog(); + + found = true; + } + } + + if ( !found ) + { + yuiError() << "Package " << pkgName << " NOT found" << endl; + // open error popup + } + + return found; +} + + +/////////////////////////////////////////////////////////////////// +// +// CancelHandler +// +// Cancel button handler. +// +bool NCPackageSelector::CancelHandler( const NCursesEvent& event ) +{ + bool changes = diffState(); + + if (changes) + { + // show a popup and ask the user + NCPopupInfo * cancelMsg = new NCPopupInfo( wpos( (NCurses::lines()-8)/2, (NCurses::cols()-45)/2 ), + NCPkgStrings::NotifyLabel(), + NCPkgStrings::CancelText(), + NCPkgStrings::YesLabel(), + NCPkgStrings::NoLabel() + ); + cancelMsg->setPreferredSize( 45, 8 ); + cancelMsg->focusCancelButton(); + NCursesEvent input = cancelMsg->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + + if ( input == NCursesEvent::cancel ) + { + // don't leave the package installation dialog + return true; + } + } + + restoreState(); + + yuiMilestone() << "Cancel button pressed - leaving package selection" << endl; + const_cast(event).result = "cancel"; + + // return false, which means stop the event loop (see runPkgSelection) + return false; +} + + +/////////////////////////////////////////////////////////////////// +// +// OkButtonHandler +// +// OK button handler. +// +bool NCPackageSelector::OkButtonHandler( const NCursesEvent& event ) +{ + bool closeDialog = true; + bool confirmedAllLicenses = false; + + // check/show dependencies also if youMode == true + do + { + // show the dependency popup + if ( showPackageDependencies( true ) ) + { + // don't leave the package installation if the user has clicked on Cancel + // in dependency popup because maybe he wants to change his choices + closeDialog = false; + } + + confirmedAllLicenses = showPendingLicenseAgreements(); + + } while ( !confirmedAllLicenses && closeDialog ); + + if ( !youMode ) // don't show automatic changes if YOU mode + { + // show the automatic changes list + NCPkgPopupTable * autoChangePopup = + new NCPkgPopupTable( wpos( 3, 8), this, + // headline - packages with automatic status change + _("Automatic Changes"), + // text part1 of popup with automatic changes (it's a label; text continous) + _( "In addition to your manual selections, the following" ), + // text part2 of popup with automatic changes + _( "packages have been changed to resolve dependencies:" ) + ); + NCursesEvent input = autoChangePopup->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + + if ( input == NCursesEvent::cancel ) + { + // user clicked on Cancel + closeDialog = false; + } + } + + if ( diskspacePopup ) + { + std::string message = ""; + message = diskspacePopup->checkDiskSpace(); + if ( message != "" ) + { + // open the popup e.g. with the text "/usr needs 50 MB more disk space" + NCPopupInfo * spaceMsg = new NCPopupInfo( wpos( (NCurses::lines()-10)/2, (NCurses::cols()-50)/2 ), + NCPkgStrings::ErrorLabel(), + NCPkgStrings::DiskSpaceError() + "
" + message + + _( "You can choose to install anyway, but you risk getting a corrupted system." ), + _( "&Continue anyway" ), + NCPkgStrings::CancelLabel() ); + + spaceMsg->setPreferredSize( 50, 10 ); + spaceMsg->focusOkButton(); + NCursesEvent input = spaceMsg->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + + if ( input == NCursesEvent::cancel ) + { + // disk space error warning returned :cancel + closeDialog = false; + } + } + } + + if ( closeDialog ) + { + // clear the saved states + // could free some memory? + // clearSaveState(); + + writeSysconfig(); + const_cast(event).result = "accept"; + yuiMilestone() << "OK button pressed - leaving package selection, starting installation" << endl; + + // return false, leave the package selection + return false; + } + else + { + NCPkgTable * packageList = PackageList(); + if ( packageList ) + { + packageList->updateTable(); + packageList->setKeyboardFocus(); + } + // don't leave the dialog + return true; + } +} + + +bool NCPackageSelector::showPendingLicenseAgreements() +{ + bool allConfirmed = true; + + if ( youMode ) + allConfirmed = showPendingLicenseAgreements( zyppPatchesBegin(), zyppPatchesEnd() ); + + allConfirmed = showPendingLicenseAgreements( zyppPkgBegin(), zyppPkgEnd() ) && allConfirmed; + + return allConfirmed; +} + + +bool NCPackageSelector::showPendingLicenseAgreements( ZyppPoolIterator begin, ZyppPoolIterator end ) +{ + yuiMilestone() << "Showing all pending license agreements" << endl; + + bool allConfirmed = true; + + for ( ZyppPoolIterator it = begin; it != end; ++it ) + { + ZyppSel sel = (*it); + + switch ( sel->status() ) + { + case S_Install: + case S_AutoInstall: + case S_Update: + case S_AutoUpdate: + + if ( sel->candidateObj() ) + { + std::string licenseText = sel->candidateObj()->licenseToConfirm(); + + if ( ! licenseText.empty() ) + { + yuiMilestone() << "Package/Patch " << sel->name().c_str() << + "has a license" << endl; + + if ( ! sel->hasLicenceConfirmed() ) + { + allConfirmed = showLicenseAgreement( sel, licenseText ) && allConfirmed; + } + else + { + yuiMilestone() << "License for " << sel->name().c_str() << + " is already confirmed" << endl; + } + } + } + break; + + default: + break; + } + } + + return allConfirmed; +} + + +bool NCPackageSelector::showLicenseAgreement( ZyppSel & slbPtr , std::string licenseText ) +{ + if ( !slbPtr ) + return false; + + bool license_confirmed = true; + bool ok = true; + std::string pkgName = slbPtr->name(); + + license_confirmed = showLicensePopup( pkgName, licenseText ); + + if ( !license_confirmed ) + { + // make sure the package won't be installed + switch ( slbPtr->status() ) + { + case S_Install: + case S_AutoInstall: + slbPtr->setStatus( S_Taboo ); + break; + + case S_Update: + case S_AutoUpdate: + slbPtr->setStatus( S_Protected ); + break; + + default: + break; + } + + ok = false; + } + else + { + yuiMilestone() << "User confirmed license agreement for " << pkgName << endl; + slbPtr->setLicenceConfirmed (true); + ok = true; + } + + return ok; +} + + +/////////////////////////////////////////////////////////////////// +// +// showDependencies +// +// Checks and shows the dependencies +// +bool NCPackageSelector::showPackageDependencies( bool doit ) +{ + bool ok = false; + bool cancel = false; + + if ( doit || autoCheck ) + { + yuiMilestone() << "Checking dependencies" << endl; + cancel = checkNow( & ok ); + } + + return cancel; +} + + +void NCPackageSelector::showSelectionDependencies() +{ + showPackageDependencies (true); +} + + +bool NCPackageSelector::showLicensePopup( std::string pkgName, std::string license ) +{ + std::string html_text = ""; + const std::string htmlIdent(DOCTYPETAG); + bool confirmed = false; + + if ( license.find( htmlIdent ) != std::string::npos ) + { + html_text = license; // HTML text + } + else + { + html_text = "
" + license + "
"; // add
 to preserve newlines and spaces
+    }
+
+    NCPopupInfo * info = new NCPopupInfo ( wpos( NCurses::lines()/10, NCurses::cols()/10),
+					   // headline of a popup showing the package license
+					   _( "End User License Agreement" ),
+					   "" + pkgName + "

" + + html_text, + NCPkgStrings::AcceptLabel(), + NCPkgStrings::CancelLabel() ); + + info->setPreferredSize( (NCurses::cols() * 80)/100, (NCurses::lines()*80)/100); + info->focusOkButton(); + confirmed = info->showInfoPopup() != NCursesEvent::cancel; + + YDialog::deleteTopmostDialog(); + + return confirmed; +} + +/////////////////////////////////////////////////////////////////// +// +// updatePackageList +// +void NCPackageSelector::updatePackageList() +{ + NCPkgTable * packageList = PackageList(); + + if ( packageList ) + { + packageList->updateTable(); + } +} + +/////////////////////////////////////////////////////////////////// +// +// showDiskSpace() +// +void NCPackageSelector::showDiskSpace() +{ + + + // check whether required diskspace enters the warning range + if ( diskspacePopup ) + { + diskspacePopup->checkDiskSpaceRange(); + // show pkg_diff, i.e. total difference of disk space (can be negative in installed system + // if packages are deleted) + if ( diskspaceLabel ) + { + diskspaceLabel->setText( diskspacePopup->calculateDiff().asString() ); + } + } +} + + +/////////////////////////////////////////////////////////////////// +// +// showDownloadSize() +// +// total download size of YOU patches +// +void NCPackageSelector::showDownloadSize() +{ + std::set selectablesToInstall; + + for ( ZyppPoolIterator patches_it = zyppPatchesBegin(); + patches_it != zyppPatchesEnd(); + ++patches_it ) + { + ZyppPatch patch = tryCastToZyppPatch( (*patches_it)->theObj() ); + + if ( patch ) + { + ZyppPatchContents patchContents( patch->contents() ); + + for ( ZyppPatchContentsIterator contents_it = patchContents.selectableBegin(); + contents_it != patchContents.selectableEnd(); + ++contents_it ) + { + ZyppPkg pkg = tryCastToZyppPkg( (*contents_it)->theObj() ); + ZyppSel sel; + + if ( pkg ) + sel = selMapper.findZyppSel( pkg ); + + + if ( sel ) + { + switch ( sel->status() ) + { + case S_Install: + case S_AutoInstall: + case S_Update: + case S_AutoUpdate: + // Insert the patch contents selectables into a set, + // don't immediately sum up their sizes: The same + // package could be in more than one patch, but of + // course it will be downloaded only once. + + selectablesToInstall.insert( sel ); + break; + + case S_Del: + case S_AutoDel: + case S_NoInst: + case S_KeepInstalled: + case S_Taboo: + case S_Protected: + break; + + // intentionally omitting 'default' branch so the compiler can + // catch unhandled enum states + } + + } + } + } + } + + FSize totalSize = 0; + + for ( std::set::iterator it = selectablesToInstall.begin(); + it != selectablesToInstall.end(); + ++it ) + { + if ( (*it)->candidateObj() ) + totalSize += zypp::ByteCount::SizeType((*it)->candidateObj()->installSize()); + } + + // show the download size + if ( diskspaceLabel ) + { + diskspaceLabel->setText( totalSize.asString() ); + } +} + + +/////////////////////////////////////////////////////////////////// +// +// PackageList() +// +NCPkgTable * NCPackageSelector::PackageList() +{ + return pkgList; +} + +// +// Create layout for Online Update +// +// FIXME: This should not use a status flag and then create completely +// different widgets; instead, this youMode should be moved to a completely +// different subclass that doesn't even have the member variables that are not +// created here. This should be: +// +// NCPackageSelectorBase +// NCPackageSelector (in pkgMode) +// NCPatchSelector (in youMode) +// +// No widget pointers that are not common to both subclasses should be in the +// base class. +// +void NCPackageSelector::createYouLayout( YWidget * selector ) +{ + // the vertical split is the (only) child of the dialog + YLayoutBox * split = YUI::widgetFactory()->createVBox( selector ); + + YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( split ); + + YAlignment * left1 = YUI::widgetFactory()->createLeft( hSplit ); + filterMenu = new NCPkgMenuFilter( left1, NCPkgStrings::Filter(), this ); + + YAlignment * left2 = YUI::widgetFactory()->createLeft( hSplit ); + actionMenu = new NCPkgMenuAction( left2, NCPkgStrings::Actions(), this ); + + YAlignment * left3 = YUI::widgetFactory()->createLeft( hSplit ); + viewMenu = new NCPkgMenuView( left3, NCPkgStrings::View(), this); + + YAlignment * left4 = YUI::widgetFactory()->createLeft( hSplit ); + depsMenu = new NCPkgMenuDeps( left4, NCPkgStrings::Deps(), this); + + // add the package table + YTableHeader * tableHeader = new YTableHeader(); + + pkgList = new NCPkgTable( split, tableHeader ); + YUI_CHECK_NEW( pkgList ); + + // set table type 'T_Patches' + NCPkgStatusStrategy * strategy; + strategy = new PatchStatStrategy(); + pkgList->setTableType( NCPkgTable::T_Patches, strategy ); + pkgList->fillHeader(); + + // set the pointer to the packager object + pkgList->setPackager( this ); + + // set sort strategy + std::vector pkgHeader = pkgList->getHeader(); + pkgList->setSortStrategy( new NCPkgTableSort( pkgHeader ) ); + + // HBox for Filter and Disk Space (both in additional HBoxes ) + YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( split ); + + YLayoutBox * hSplit3 = YUI::widgetFactory()->createHBox( hSplit2 ); + // label text - keep it short + new NCLabel( hSplit3, _( "Filter: " ) ); + packageLabel = YUI::widgetFactory()->createLabel ( hSplit3, "....................................." ); + + new NCSpacing( hSplit2, YD_HORIZ, true, 0.5 ); + + YLayoutBox * hSplit4 = YUI::widgetFactory()->createHBox( hSplit2 ); + // label text - keep it short (use abbreviation if necessary) + new NCLabel( hSplit4, _( "Total Download Size: " ) ); + // create label with spaces to have enough space available for download size + diskspaceLabel = YUI::widgetFactory()->createLabel ( hSplit4, " " ); + + YLayoutBox * vSplit = YUI::widgetFactory()->createVBox( split ); + replacePoint = YUI::widgetFactory()->createReplacePoint( vSplit ); + + infoText = new NCPkgPackageDetails( replacePoint, " ", this ); + YUI_CHECK_NEW( infoText ); + + YLayoutBox * bottom_bar = YUI::widgetFactory()->createHBox( vSplit ); + YAlignment *ll = YUI::widgetFactory()->createLeft( bottom_bar ); + + helpMenu = new NCPkgMenuHelp (ll, _( "&Help" ), this); + + YAlignment *r = YUI::widgetFactory()->createRight( bottom_bar ); + YLayoutBox * hSplit5 = YUI::widgetFactory()->createHBox( r ); + + // add the Cancel button + cancelButton = new NCPushButton( hSplit5, _( "&Cancel" ) ); + YUI_CHECK_NEW( cancelButton ); + cancelButton->setFunctionKey( 9 ); + + // add the OK button + okButton = new NCPushButton( hSplit5, _( "&Accept" ) ); + YUI_CHECK_NEW( okButton ); + okButton->setFunctionKey( 10 ); + +} + +// +// Create layout for Package Selector +// +void NCPackageSelector::createPkgLayout( YWidget * selector, NCPkgTable::NCPkgTableType type ) +{ + // the vertical split is the (only) child of the dialog + YLayoutBox * vsplit = YUI::widgetFactory()->createVBox( selector ); + YLayoutBox * menu_bar = YUI::widgetFactory()->createHBox( vsplit ); + YLayoutBox * panels = YUI::widgetFactory()->createVBox( vsplit ); + YLayoutBox * bottom_bar = YUI::widgetFactory()->createHBox( vsplit ); + + YAlignment * left1 = YUI::widgetFactory()->createLeft( menu_bar ); + + YLayoutBox * menu_buttons = YUI::widgetFactory()->createHBox( left1); + depsMenu = new NCPkgMenuDeps( menu_buttons, NCPkgStrings::Deps(), this); + viewMenu = new NCPkgMenuView( menu_buttons, NCPkgStrings::View(), this); + + // Add only if requested by Opt(:repoMgr) flag - #381956 + if (isRepoMgrEnabled()) + configMenu = new NCPkgMenuConfig( menu_buttons, _( "C&onfiguration" ), this); + + extrasMenu = new NCPkgMenuExtras( menu_buttons, NCPkgStrings::Extras(), this); + + YLayoutBox * hbox_top = YUI::widgetFactory()->createHBox( panels ); + YLayoutBox * hbox_bottom = YUI::widgetFactory()->createHBox( panels ); + + YLayoutBox * vbox_left = YUI::widgetFactory()->createVBox( hbox_top ); + vbox_left->setWeight(YD_HORIZ, 1); + YFrame * fr = YUI::widgetFactory()->createFrame (vbox_left, ""); + YLayoutBox * vv = YUI::widgetFactory()->createVBox( fr ); + YAlignment *l = YUI::widgetFactory()->createLeft( vv ); + filterMain = new NCPkgFilterMain (l, NCPkgStrings::Filter(), this ); + + replPoint = YUI::widgetFactory()->createReplacePoint( vv ); + + // Initial filter view + + // Search view is now default (#404694) + searchPopup = new NCPkgFilterSearch( replPoint, YD_VERT, this ); + searchPopup->createLayout( replPoint ); + + searchField = searchPopup->getSearchField(); + if ( searchField ) + { + searchField->setKeyboardFocus(); + searchField->setNotify( true ); + } + + YAlignment *l1 = YUI::widgetFactory()->createLeft( vbox_left ); + patternLabel = new NCLabel( l1, " " ); + + // add the package table + YTableHeader * tableHeader = new YTableHeader(); + + YLayoutBox * v = YUI::widgetFactory()->createVBox( hbox_top ); + v->setWeight(YD_HORIZ, 2); + pkgList = new NCPkgTable( v, tableHeader ); + YUI_CHECK_NEW( pkgList ); + + NCPkgStatusStrategy * strategy; + // set table type and status strategy (either 'normal' package list or update list) + switch ( type ) + { + case NCPkgTable::T_Packages: + strategy = new PackageStatStrategy(); + pkgList->setTableType( NCPkgTable::T_Packages, strategy ); + case NCPkgTable::T_Update: + strategy = new UpdateStatStrategy(); + pkgList->setTableType( NCPkgTable::T_Update, strategy ); + default: + strategy = new PackageStatStrategy(); + pkgList->setTableType( NCPkgTable::T_Packages, strategy ); + } + // set the pointer to the packager object + pkgList->setPackager( this ); + pkgList->fillHeader(); + + // set sort strategy + std::vector pkgHeader = pkgList->getHeader(); + pkgList->setSortStrategy( new NCPkgTableSort( pkgHeader ) ); + + // label text + actions menu + YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( v ); + new NCLabel( hSplit2, NCPkgStrings::PackageName() ); + packageLabel = YUI::widgetFactory()->createLabel ( hSplit2, "......................" ); + new NCSpacing( hSplit2, YD_HORIZ, true, 0.5 ); + actionMenu = new NCPkgMenuAction ( hSplit2, NCPkgStrings::Actions(), this ); + + // Search parameters resp. filter description + replPoint2 = YUI::widgetFactory()->createReplacePoint( hbox_bottom ); + replPoint2->setWeight(YD_HORIZ, 1); + searchSet = new NCPkgSearchSettings( replPoint2, NCPkgStrings::SearchIn() ); + + // Package description resp. package version table + YLayoutBox * vSplit = YUI::widgetFactory()->createVBox( hbox_bottom ); + vSplit->setWeight(YD_HORIZ, 2); + replacePoint = YUI::widgetFactory()->createReplacePoint( vSplit ); + infoText = new NCPkgPackageDetails( replacePoint, " ", this ); + YUI_CHECK_NEW( infoText ); + + // Bottom button bar + YAlignment *ll = YUI::widgetFactory()->createLeft( bottom_bar ); + helpMenu = new NCPkgMenuHelp (ll, _( "&Help" ), this); + YUI_CHECK_NEW( helpMenu ); + + // right-alignment for OK-Cancel + YAlignment *right = YUI::widgetFactory()->createRight( bottom_bar ); + YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( right ); + + // add the Cancel button + cancelButton = new NCPushButton( hSplit, _( "&Cancel" ) ); + YUI_CHECK_NEW( cancelButton ); + cancelButton->setFunctionKey( 9 ); + + // add the OK button + okButton = new NCPushButton( hSplit, _( "&Accept" ) ); + YUI_CHECK_NEW( okButton ); + okButton->setFunctionKey( 10 ); + +} + +// +// Fill package list with packages of default RPM group/update list or installable patches +// +bool NCPackageSelector::fillDefaultList() +{ + if ( !pkgList ) + return false; + + yuiMilestone() << "Filling package list: " << (NCWidget *) pkgList << endl; + + switch ( pkgList->getTableType() ) + { + case NCPkgTable::T_Patches: + { + fillPatchList( NCPkgMenuFilter::F_Needed ); // default: needed patches + + // set the visible info to long description + pkgList->setVisibleInfo(NCPkgTable::I_PatchDescr); + // show the patch description of the current item + pkgList->showInformation(); + pkgList->setKeyboardFocus(); + break; + } + case NCPkgTable::T_Update: + { + if ( ! zypp::getZYpp()->resolver()->problematicUpdateItems().empty() ) + { + fillUpdateList(); + // set the visible info to technical information + pkgList->setVisibleInfo(NCPkgTable::I_Technical); + // show the package information of the current item + pkgList->showInformation(); + break; + } + } + case NCPkgTable::T_Packages: + { + // Search view is the default (#404694) + pkgList->setVisibleInfo(NCPkgTable::I_Technical); + searchField->setKeyboardFocus(); + break; + } + default: + break; + } + + // if started with :repoMode or :summaryMode replace filter accordingly + if ( repoMode ) + { + replaceFilter ( NCPackageSelector::Repositories ); + if ( filterMain) + filterMain->setReposSelected(); + } + else if ( summaryMode ) + { + replaceFilter ( NCPackageSelector::Summary ); + if ( filterMain ) + filterMain->setSummarySelected(); + } + else if ( !youMode && anyRetractedPkgInstalled() ) + { + yuiMilestone() << "Switching to pkg classification filter view" << endl; + replaceFilter( NCPackageSelector::PkgClassification ); + filterMain->setPkgClassSelected(); + + yuiMilestone() << "Showing retracted installed packages" << endl; + pkgClass->showRetractedInstalled(); + } + + return true; +} + + +bool NCPackageSelector::anyRetractedPkgInstalled() +{ + yuiMilestone() << "Checking for retracted installed packages..." << endl; + + for ( ZyppPoolIterator it = zyppPkgBegin(); it != zyppPkgEnd(); ++it ) + { + if ( (*it)->hasRetractedInstalled() ) + { + yuiMilestone() << "Found a retracted installed package." << endl; + return true; + } + } + + yuiMilestone() << "No retracted packages installed." << endl; + + return false; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelector.h b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..b176981f850a3b47c6eddc9dc59ca8791649a06d --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelector.h @@ -0,0 +1,516 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPackageSelector.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPackageSelector_h +#define NCPackageSelector_h + +#include +#include +#include +#include // for STL std::pair + +#include +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include +#include + +#include "NCPkgFilterInstSummary.h" +#include "NCPkgFilterMain.h" +#include "NCPkgFilterSearch.h" +#include "NCPkgMenuFilter.h" +#include "NCPkgPackageDetails.h" +#include "NCPkgPopupDeps.h" +#include "NCPkgSearchSettings.h" +#include "NCPkgSelMapper.h" +#include "NCPkgStrings.h" +#include "NCPkgTable.h" + +class LangCode; +class NCMenuButton; +class NCPkgDiskspace; +class NCPkgFilterClassification; +class NCPkgFilterInstSummary; +class NCPkgFilterMain; +class NCPkgFilterPattern; +class NCPkgFilterSearch; +class NCPkgLocaleTable; +class NCPkgMenuAction; +class NCPkgMenuConfig; +class NCPkgMenuDeps; +class NCPkgMenuExtras; +class NCPkgMenuHelp; +class NCPkgMenuView; +class NCPkgPackageDetails; +class NCPkgPopupDeps; +class NCPkgPopupFile; +class NCPkgRepoTable; +class NCPkgSearchSettings; +class NCPkgServiceTable; +class NCPushButton; +class YNCursesUI; +class YReplacePoint; + +inline bool ic_compare ( char c1, char c2 ) +{ + return ( toupper( c1 ) == toupper( c2 ) ); +} + +#define DOCTYPETAG "" // Special doctype for preformatted HTML + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPackageSelector +// +// DESCRIPTION : Specialized high-level widget for package selection +// +//------------------------------------------------------------------------------ +// +// FIXME: This should be split up into a base class and two subclasses, one for +// pkgMode and one for youMode. They should not share any member variables or +// methods that can't be used in both modes. In particular, they should not +// share any widget pointers where the corresponding widgets are not created in +// both modes. +// +// NCPackageSelectorBase (containing only common members and methods) +// NCPackageSelector (for pkgMode) +// NCPatchSelector (for youMode) +// +class NCPackageSelector +{ + + friend std::ostream & operator<<( std::ostream & STREAM, const NCPackageSelector & OBJ ); + + NCPackageSelector & operator=( const NCPackageSelector & ); + NCPackageSelector ( const NCPackageSelector & ); + +private: + + // typedef for the pointer to handler member function + typedef bool (NCPackageSelector::* tHandlerFctPtr) ( const NCursesEvent& event ); + + // typedef for the internal map: key=nameId, value=handler-fct-ptr + typedef std::map tHandlerMap; + + tHandlerMap eventHandlerMap; // event handler map + + NCPkgPopupDeps * depsPopup; // the package dependeny popup + + NCPkgFilterPattern * patternPopup; // the pattern popup + NCPkgLocaleTable * languagePopup; // language popup + NCPkgRepoTable * repoPopup; + NCPkgServiceTable * servicePopup; + + NCPkgDiskspace * diskspacePopup; // the popup showing the disk usage + + NCPkgFilterSearch * searchPopup; // the package search popup + NCPkgFilterInstSummary *inst_summary; + + NCPkgFilterClassification * pkgClass; // classification of packages + + bool youMode; // YOU + bool updateMode; // Update + bool testMode; // testing + bool repoMgrEnabled; // Manage repositories (add menu button "Configuration") + bool repoMode; // Start with "Repositories" filter view + bool summaryMode; // Start with "Summary" filter view + bool onlineSearchEnabled; // Add a "Search Online" option in the "Extras" menu + + std::map sysconfig; // sysconfig values + + bool autoCheck; // dependency check on every 'click' + bool verifySystem; // system verification mode + bool installRecommended; // option install recommended packages + + std::string actionAtExit; + + // the package table + NCPkgTable * pkgList; + + NCPkgMenuDeps *depsMenu; + NCPkgMenuView *viewMenu; + NCPkgMenuConfig *configMenu; + NCPkgMenuExtras *extrasMenu; + NCPkgMenuHelp *helpMenu; + NCPkgFilterMain *filterMain; + NCPkgMenuAction *actionMenu; + NCPkgMenuFilter *filterMenu; + // FIXME - add update list to NCPkgFilterMain + YMenuItem * updatelistItem; + + // labels + YLabel * packageLabel; + YLabel * diskspaceLabel; + YLabel *patternLabel; + + // information about packages + NCPkgPackageDetails * infoText; // short/longdecsription, filelist + NCRichText * filter_desc; + NCInputField *searchField; + NCPkgSearchSettings *searchSet; + YReplacePoint * replacePoint; // replace point for info text + YReplacePoint * replPoint; + YReplacePoint * replPoint2; + + NCPkgTable * versionsList; // list of available package versions + // information about patches + NCPkgTable * patchPkgs; // pakages belonging to a patch + NCPkgTable * patchPkgsVersions; // versions of packages above + + NCPushButton * okButton; + NCPushButton * cancelButton; + + YMenuItem * visibleInfo; // current visible package info (description, file list, ...) + + // Mapping from ZyppPkg to the corresponding ZyppSel. + NCPkgSelMapper selMapper; + + std::set verified_pkgs; + + +public: + + enum FilterMode + { + Patterns, + Languages, + Repositories, + Services, + Search, + Summary, + PkgClassification + }; + + /** + * The package selector class handles the events and holds the + * data needed for the package selection. + * @param ui The NCurses UI + * @param opt The widget options + */ + NCPackageSelector( long modeFlags ); + + /** + * Destructor + */ + virtual ~NCPackageSelector(); + + void setFlags( long modeFlags); + + void readSysconfig(); + void writeSysconfig(); + + /** + * Create layout for the PackageSelector + * @param parent Parent is PackageSelectorStart + * @param type The package table type + * @return void + */ + void createPkgLayout( YWidget * parent, NCPkgTable::NCPkgTableType type ); + + /** + * Create layout for the Online Update + * @param parent Parent is PackageSelectorStart + * @return void + */ + void createYouLayout( YWidget * parent ); + + /** + * Return 'true' if any package is installed in a retracted version. + **/ + bool anyRetractedPkgInstalled(); + + // returns the package table widget + NCPkgTable * PackageList(); + NCPkgPopupDeps *DepsPopup() { return depsPopup; } + NCPkgDiskspace *diskSpacePopup() { return diskspacePopup; } + YLabel *PackageLabel() { return packageLabel; } + YLabel *PatternLabel() { return patternLabel; } + + NCPkgPackageDetails *InfoText() { return infoText; } + void setInfoText ( NCPkgPackageDetails *itext ) { infoText = itext;} + + NCPkgTable *VersionsList() { return versionsList; } + void setVersionsList ( NCPkgTable *table ) { versionsList = table; } + + NCPkgTable * PatchPkgs() { return patchPkgs; } + NCPkgTable * PatchPkgsVersions() { return patchPkgsVersions; } + + YReplacePoint *ReplacePoint() { return replacePoint; } + NCRichText *FilterDescription() { return filter_desc; } + NCPkgSearchSettings *SearchSettings() { return searchSet; } + + bool checkNow( bool *ok ); + bool systemVerification( bool *ok ); + bool doInstallRecommended( bool *ok ); + + + /** + * Fills the package table with YOU patches matching the filter + * @param filter + * @return bool + */ + bool fillPatchList( NCPkgMenuFilter::PatchFilter filter ); + + /** + * Fills the package table with packages with update problems + * @return bool + */ + bool fillUpdateList(); + + + /** + * Fills the list of packages belonging to the youPatch + * @param pkgTable The table widget + * @param youPatch Show all packages belonging to the patch + * @return bool + */ + bool fillPatchPackages ( NCPkgTable * pkgTable, ZyppObj youPatch ); + + /** + * Fills the package table with packages matching the search expression + * @param expr The search expression + * @param ignoreCase Ignore case (true or false) + * @param checkName Search in package name (true or false) + * @param checkSummary Check the summary (true or false) + * @param checkProvides Check in Provides (true or false) + * @param checkRequires Check in Requires (true or false) + * @return bool + */ + bool fillPatchSearchList( const std::string & expr, bool checkName, bool checkSum ); + + /** + * Fills the default package table + */ + bool fillDefaultList(); + + bool isYouMode() { return youMode; } + + bool isUpdateMode() { return updateMode; } + + bool isRepoMgrEnabled() { return repoMgrEnabled; } + + bool isTestMode() { return testMode; } + + bool isOnlineSearchEnabled() { return onlineSearchEnabled; } + + // + // Action at exit (means "summary", "restart" or "close") is written to + // /etc/sysconfig/yast2 and gets evaluated by the YaST packager workflow. + // + std::string ActionAtExit() { return actionAtExit; } + void setActionAtExit( std::string action ) { actionAtExit = action; } + + // + // The solver options 'cleanup dependencies on remove' and + // 'is allow vendor change' can only be set in /etc/zypp/zypp.conf. + // + bool isCleanDepsOnRemove(); + void setCleanDepsOnRemove( bool on ); + + bool isAllowVendorChange(); + void setAllowVendorChange( bool on ); + + // + // The solver options 'Install recommended packages' and + // 'verify system' can be changed in UI and are written to /etc/sysconfig/yast2. + // + bool isInstallRecommended(); + void setInstallRecommended( bool on ); + bool InstallRecommended() { return installRecommended; } + + bool isVerifySystem(); + void setVerifySystem( bool on ); + bool VerifySystem() { return verifySystem; } + // + // The 'automatic dependency check' setting is also saved in /etc/sysconfig/yast2 + // + bool isAutoCheck(); + void setAutoCheck( bool check) { autoCheck = check; } + bool AutoCheck() { return autoCheck; } + + /** + * Handle the given event. For the given event (the widget-id + * is contained in the event) the corresponding handler is executed. + * @param event The NCurses event + * @return bool + */ + bool handleEvent( const NCursesEvent& event ); + + /** + * Creates an NCPkgTable widget and shows all versions + * of all packages belonging to a patch + * @return void + */ + void showPatchPkgVersions(); + + /** + * Creates an NCPkgTable widget and shows all packages + * belonging to a patch + * @return void + */ + void showPatchPackages(); + + /** + * Creates an NCPkgTable widget and shows all verions + * a the selected package + * @return void + */ + void showVersionsList(); + + /** + * Creates an NCRichText widget for package (patch) + * information + * @return void + */ + void showInformation(); + + void clearInfoArea(); + + wrect deleteReplacePoint(); + + void replaceFilter ( FilterMode mode); + void replaceFilterDescr ( bool b ); + /** + * Handler function for "OK button pressed" + * @param event The Ncurses event + * @return bool + */ + bool OkButtonHandler ( const NCursesEvent& event ); + + /** + * Handler function for "Cancel button pressed" + * @param event The Ncurses event + * @return bool + */ + bool CancelHandler ( const NCursesEvent& event ); + + /** + * Handles hyperlinks in package description + * @param link The link + * @return bool + */ + bool LinkHandler ( std::string link ); + + /** + * Checks and shows the dependencies + * @param doit true: do the check, false: only check if auto check is on + */ + bool showPackageDependencies ( bool doit ); + + /** + * Checks and shows the selectiondependencies + */ + void showSelectionDependencies(); + + /** + * Updates the status in list of packages + */ + void updatePackageList(); + + /** + * Check if 'patch' matches the selected filter. + * Returns true if there is a match, false otherwise or if 'patch' is 0. + * @return bool + **/ + bool checkPatch( ZyppPatch patch, + ZyppSel selectable, + NCPkgMenuFilter::PatchFilter filter ); + + /** + * Shows 'End User License Agreement' popup with license text + * @param pkgName the package name + * @param license the license text + * @return bool license confirmed? + */ + bool showLicensePopup( std::string pkgName, std::string license ); + + /** + * Calls the package mananager (updateDu()) and shows the required disk space + */ + void showDiskSpace(); + + /** + * Shows the total download size + */ + void showDownloadSize(); + + /** + * Check for changes + */ + void saveState(); + void restoreState(); + bool diffState(); + + /** + * Check for license + */ + bool showPendingLicenseAgreements(); + bool showPendingLicenseAgreements( ZyppPoolIterator begin, ZyppPoolIterator end ); + + /** + * Show popup with license. + * @return bool + */ + bool showLicenseAgreement( ZyppSel & slbPtr , std::string licenseText ); + + /** + * Get list of packages already selected for automatic changes + * (usually via 'verify system' call) + * @return std::set + */ + std::set getVerifiedPkgs() + { + return verified_pkgs; + } + + /** + * Insert package name into the list of already selected for automatic changes + * @param pkgname Package name + */ + void insertVerifiedPkg( std::string pkgname ) + { + verified_pkgs.insert( pkgname); + } + + /** + * Empty the std::set of packages selected for automatic changes + * @return void + */ + void clearVerifiedPkgs() + { + if ( !verified_pkgs.empty() ) + { + yuiMilestone() << "Discarding auto-dependency changes" << std::endl; + verified_pkgs.clear(); + } + } + +}; + + +#endif // NCPackageSelector_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorPluginImpl.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorPluginImpl.cc new file mode 100644 index 0000000000000000000000000000000000000000..cd7fe7c118b1577291bbd453907a6709756abc0c --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorPluginImpl.cc @@ -0,0 +1,195 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPackageSelectorPluginImpl.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include "NCPackageSelectorPluginImpl.h" +#include "NCPackageSelectorStart.h" + + +using std::endl; + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPackageSelectorPluginStub::createPackageSelector +// METHOD TYPE : YWidget +// +// DESCRIPTION : Create NCPackageSelectorStart which reads the layout +// term of the package selection dialog, creates the widget +// tree and creates the NCPackageSelector. +// +NCPackageSelectorPluginImpl PSP; + +YPackageSelector * +NCPackageSelectorPluginImpl::createPackageSelector( YWidget * parent, + long modeFlags ) +{ + YWidget * w = 0; + + try + { + w = new NCPackageSelectorStart ( parent, modeFlags, YD_HORIZ ); + } + catch (const std::exception & e) + { + yuiError() << "Caught a std::exception: " << e.what() << endl; + } + catch (...) + { + yuiError() << "Caught an unspecified exception" << endl; + } + + yuiMilestone() << "Package selector created: " << w << endl; + + return (YPackageSelector *)(w); +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPackageSelectorPluign::createPkgSpecial +// METHOD TYPE : YWidget +// +// DESCRIPTION : creates special widgets used for the package selection +// dialog (which do not have a corresponding widget in qt-ui) +// +YWidget * +NCPackageSelectorPluginImpl::createPkgSpecial( YWidget *parent, const std::string &subwidget ) +{ + YWidget * w = 0; + YTableHeader * tableHeader = new YTableHeader(); + + if ( subwidget == "pkgTable" ) + { + yuiDebug() << "Creating a NCPkgTable" << endl; + try + { + // yuiError() << "Tady taky nic neni " << endl; + w = new NCPkgTable( parent, tableHeader ); + } + catch (const std::exception & e) + { + yuiError() << "Caught a std::exception: " << e.what() << endl; + } + catch (...) + { + yuiError() << "Caught an unspecified exception" << endl; + } + } + else + { + yuiError() << "PkgSpecial( " << subwidget << " ) not found - take default Label" << endl; + w = new NCLabel( parent, subwidget, false, false ); + } + + return w; +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPackageSelectorPLugin::runPkgSelection +// METHOD TYPE : YEvent * +// +// DESCRIPTION : Implementation of UI builtin RunPkgSelection() which +// has to be called after OpenDialog( PackageSelector() ). +// +YEvent * +NCPackageSelectorPluginImpl::runPkgSelection( YDialog * dialog, + YWidget * selector ) +{ + NCPackageSelectorStart * ncSelector = 0; + + yuiMilestone() << "Calling runPkgSelection()" << endl; + + if ( !dialog ) + { + yuiError() << "ERROR package selection: No dialog existing." << endl; + return 0; + } + if ( !selector ) + { + yuiError() << "ERROR package selection: No package selector existing." << endl; + return 0; + } + + ncSelector = dynamic_cast( selector ); + + bool result = true; + + // start event loop + NCursesEvent event = NCursesEvent::cancel; + NCDialog * ncd = static_cast( dialog ); + + if ( ncSelector && ncd ) + { + try + { + ncSelector->showDefaultList(); + ncd->setStatusLine(); // show function keys + yuiMilestone() << "NCDialog: " << ncd << endl; + do + { + event = ncd->userInput(); + result = ncSelector->handleEvent( event ); + // reset to function keys of the main dialog + ncd->setStatusLine(); + // yuiMilestone() << "Result of handleEvent: " << (result?"true":"false") << endl; + } + while ( event != NCursesEvent::cancel && result == true ); + } + catch (const std::exception & e) + { + yuiError() << "Caught a std::exception: " << e.what() << endl; + } + catch (...) + { + yuiError() << "Caught an unspecified exception" << endl; + } + } + else + { + yuiError() << "No NCPackageSelectorStart existing" << endl; + } + + if ( event.result != "" ) + { + // Before returning some value to the YCP client, + // we must delete (==close) any leftover dialogs, + // Wizard will not do it for us (#354712) + while( YDialog::topmostDialog() != dialog ) + YDialog::deleteTopmostDialog(); + + yuiMilestone() << "Return value: " << event.result << endl; + return new YMenuEvent( event.result ); + } + else + return new YCancelEvent(); +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorPluginImpl.h b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorPluginImpl.h new file mode 100644 index 0000000000000000000000000000000000000000..ea2f7cf42d59e523167d6e1964327634e5923223 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorPluginImpl.h @@ -0,0 +1,44 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPackageSelectorPluginImpl.h + Author: Hedgehog Painter + +*/ + + +#ifndef NCPackageSelectorPluginImpl_h +#define NCPackageSelectorPluginImpl_h + +#include + + +class NCPackageSelectorPluginImpl : public NCPackageSelectorPluginIf +{ + + public: + + virtual ~NCPackageSelectorPluginImpl() {}; + + virtual YPackageSelector * createPackageSelector( YWidget * parent, long modeFlags); + + virtual YEvent *runPkgSelection (YDialog *currentDialog, YWidget *packageSelector ); + + virtual YWidget *createPkgSpecial (YWidget *parent, const std::string &subwidget ); + +}; +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorStart.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorStart.cc new file mode 100644 index 0000000000000000000000000000000000000000..62a0c5998dd3013786afbc5f1b9baad3b1f381cc --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorStart.cc @@ -0,0 +1,166 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPackageSelectorStart.cc + Author: Gabriele Strattner + +*/ + +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include +#include +#include +#include +#include + +#include "NCPackageSelectorStart.h" +#include "NCPkgStrings.h" +#include "NCPkgTable.h" + + +using std::endl; + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPackageSelectorStart::NCPackageSelectorStart +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPackageSelectorStart::NCPackageSelectorStart( YWidget * parent, + long modeFlags, + YUIDimension dimension ) + : NCLayoutBox( parent, dimension ) + , packager( 0 ) +{ + // set the textdomain + setTextdomain( "ncurses-pkg" ); + + // NEW NEW + packager = new NCPackageSelector( modeFlags ); + + NCPkgTable::NCPkgTableType type; + + if ( packager ) + { + if ( packager->isYouMode() ) + { + packager->createYouLayout( this ); + type = NCPkgTable::T_Patches; + } + else + { + if ( packager->isUpdateMode() ) + type = NCPkgTable::T_Update; + else + type = NCPkgTable::T_Packages; + packager->createPkgLayout( this, type ); + } + } + + yuiDebug() << endl; + wstate = NC::WSdumb; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPackageSelectorStart::~NCPackageSelectorStart +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPackageSelectorStart::~NCPackageSelectorStart() +{ + if ( packager ) + { + delete packager; + } +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPackageSelectorStart::setSize +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPackageSelectorStart::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); + YLayoutBox::setSize( newwidth, newheight ); +} + + +/////////////////////////////////////////////////////////////////// +// +// METHOD NAME : NCPackageSelectorStart::showDefaultList +// METHOD TYPE : void +// +// DESCRIPTION : fill up the package table with default data +// +// +void NCPackageSelectorStart::showDefaultList() +{ + // fill the package table with packages belonging to the default filter + + if ( packager ) + { + // always do an initial dependency solving - BEFORE filling the default list + packager->showPackageDependencies( true ); + + // fill package list with packages belonging to default RPM group + packager->fillDefaultList(); + + if ( packager->isYouMode() ) + { + // show download size + packager->showDownloadSize(); + } + else + { + // show the required diskspace + packager->showDiskSpace(); + } + } +} + +/////////////////////////////////////////////////////////////////// +// +// METHOD NAME : NCPackageSelectorStart::handleEvent +// METHOD TYPE : bool +// +// DESCRIPTION : passes the event to the handleEvent method +// of the member variable PackageSelector packager +// +bool NCPackageSelectorStart::handleEvent ( const NCursesEvent & event ) +{ + if ( !packager ) + return false; + + return packager->handleEvent( event ); +} + + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorStart.h b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorStart.h new file mode 100644 index 0000000000000000000000000000000000000000..2a3047d7b7dc8dca7efaf72dbd871b9f89fe0450 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPackageSelectorStart.h @@ -0,0 +1,109 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + File: NCPackageSelectorStart.h + + Author: Gabriele Strattner + +*/ + + +#ifndef NCPackageSelectorStart_h +#define NCPackageSelectorStart_h + +#include + +#include +#include + +#include +#include +#include + +#include "NCPackageSelector.h" + + +class NCPkgTable; +class NCPackageSelector; +class NCPushButton; + +/** + * @short the package selector widget + */ +class NCPackageSelectorStart : public NCLayoutBox +{ + + friend std::ostream & operator<<( std::ostream & STREAM, const NCPackageSelectorStart & OBJ ); + + NCPackageSelectorStart & operator=( const NCPackageSelectorStart & ); + NCPackageSelectorStart ( const NCPackageSelectorStart & ); + + private: + + NCPackageSelector *packager; // packager object contains the data and handles events + + protected: + + virtual const char * location() const + { + return primary() == YD_HORIZ ? "NC(H)PackageSelectorStart" : "NC(V)PackageSelectorStart"; + } + + public: + + /** + * Constructor + * creates the widget tree of the package selector + */ + NCPackageSelectorStart( YWidget * parent, + long modeFlags, + YUIDimension dimension ); + + /** + * Destructor + */ + virtual ~NCPackageSelectorStart(); + + virtual int preferredWidth() { return NCLayoutBox::preferredWidth(); } + virtual int preferredHeight() { return NCLayoutBox::preferredHeight(); } + + /** + * Set the new size of the widget. + * + * Reimplemented from YWidget. + **/ + virtual void setSize( int newWidth, int newHeight ); + + /** + * Fills the package table with packages belonging to the + * default filter (the filter which is selected when entering the + * package selection). + **/ + void showDefaultList(); + + /** + * Pass the event to the handleEvent method of the member variable + * NCPackageSelector packager. + * @param event The NCursesEvent + * @return bool + */ + bool handleEvent( const NCursesEvent& event ); + +}; + +/////////////////////////////////////////////////////////////////// + +#endif // NCPackageSelectorStart_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterClassification.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterClassification.cc new file mode 100644 index 0000000000000000000000000000000000000000..84362905ac5344dd3f1555c28ea54630e74e2bc1 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterClassification.cc @@ -0,0 +1,288 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterRepo.cc + Author: Gabriele Mohr + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCZypp.h" +#include "NCPkgFilterClassification.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterClassification::NCPkgFilterClassification +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// + +NCPkgFilterClassification::NCPkgFilterClassification( YWidget *parent, NCPackageSelector *pkg ) + :NCSelectionBox( parent, "" ) + , packager( pkg ) +{ + // fill selection box + suggested = new YItem( _("Suggested Packages") ); + addItem( suggested ); + + recommended = new YItem( _("Recommended Packages") ); + addItem( recommended ); + + orphaned = new YItem( _("Orphaned Packages") ); + addItem( orphaned ); + + unneeded = new YItem( _("Unneeded Packages" ) ); + addItem( unneeded ); + + multiversion = new YItem( _("Multiversion Packages" ) ); + addItem( multiversion ); + + retracted = new YItem( _("Retracted Packages" ) ); + addItem( retracted ); + + retractedInstalled = new YItem( _("Retracted Installed Packages" ) ); + addItem( retractedInstalled ); + + all = new YItem( _("All Packages" ) ); + addItem( all ); + + showPackages(); + showDescription(); +} + + +bool NCPkgFilterClassification::showPackages() +{ + NCPkgTable * packageList = packager->PackageList(); + YItem * pkgClass = currentPkgClass(); + yuiMilestone() << "Showing pkg class: " << pkgClass->label() << endl; + + if ( !pkgClass ) + return false; + + if ( !packageList ) + { + yuiError() << "No valid NCPkgTable widget" << endl; + return false; + } + + // clear the package table + packageList->itemsCleared(); + + for ( ZyppPoolIterator it = zyppPkgBegin(); + it != zyppPkgEnd(); + ++it ) + { + ZyppSel selectable = *it; + bool match = false; + + // If there is an installed obj, check this first. The bits are set for the installed + // obj only and the installed obj is not contained in the pick list if there in an + // identical candidate available from a repo. + if ( selectable->installedObj() ) + { + match = check( selectable, tryCastToZyppPkg( selectable->installedObj() ), pkgClass ); + } + // otherwise display the candidate object (the "best" version) + else if ( selectable->hasCandidateObj() ) + { + match = check( selectable, tryCastToZyppPkg( selectable->candidateObj() ), pkgClass ); + } + + // And then check the pick list which contain all availables and all objects for multi + // version packages and the installed obj if there isn't same version in a repo. + if ( !match ) + { + zypp::ui::Selectable::picklist_iterator it = selectable->picklistBegin(); + while ( it != selectable->picklistEnd() && !match ) + { + check( selectable, tryCastToZyppPkg( *it ), pkgClass ); + ++it; + } + } + } + + // show the package list + packageList->scrollToFirstItem(); + packageList->drawList(); + packageList->showInformation(); + + int pkgCount = packageList->getNumLines(); + + if ( pkgCount == 0 ) + packager->clearInfoArea(); + + yuiMilestone() << "Filling package list \"" << pkgClass->label() << "\"" << endl; + + return true; +} + + +void NCPkgFilterClassification::showRetractedInstalled() +{ + selectItem( retractedInstalled, true ); + showPackages(); + showDescription(); +} + + +bool NCPkgFilterClassification::check( ZyppSel selectable, ZyppPkg pkg, YItem * pkgClass ) +{ + NCPkgTable * packageList = packager->PackageList(); + + // log solver bits, e.g. I__s_ou(668)libcogl11-1.12.0-1.2.i586(@System) + yuiDebug() << zypp::PoolItem( pkg ) << endl; + + if ( !packageList || !selectable || !pkg ) + { + yuiError() << "No valid data" << endl; + return false; + } + + bool match = false; + + if ( pkgClass == all ) match = true; + else if ( pkgClass == recommended ) match = zypp::PoolItem( pkg ).status().isRecommended(); + else if ( pkgClass == suggested ) match = zypp::PoolItem( pkg ).status().isSuggested(); + else if ( pkgClass == orphaned ) match = zypp::PoolItem( pkg ).status().isOrphaned(); + else if ( pkgClass == unneeded ) match = zypp::PoolItem( pkg ).status().isUnneeded(); + else if ( pkgClass == multiversion ) match = selectable->multiversionInstall(); + else if ( pkgClass == retracted ) match = selectable->hasRetracted(); + else if ( pkgClass == retractedInstalled ) match = selectable->hasRetractedInstalled(); + + if ( match ) + packageList->createListEntry( pkg, selectable ); + + return match; +} + + +void NCPkgFilterClassification::showDescription() +{ + std::string description; + YItem * pkgClass = currentPkgClass(); + + if ( pkgClass == recommended ) + { + description = _("This is a list of useful packages. They will be additionally installed if recommended by a newly installed package."); + } + else if ( pkgClass == suggested ) + { + description = _("It's suggested to install these packages because they fit to already installed packages. The decision to install it is by the user."); + } + else if ( pkgClass == orphaned ) + { + description = _("The solver has detected that these packages are without a repository, i.e. updates aren't possible."); + } + else if ( pkgClass == unneeded ) + { + description = _("These packages might be unneeded because former dependencies don't apply any longer."); + } + else if ( pkgClass == multiversion ) + { + description = _("These packages might be installed in several versions in parallel."); + } + else if ( pkgClass == retracted ) + { + description = _("These packages have versions that are retracted. Using those versions is strongly discouraged."); + } + else if ( pkgClass == retractedInstalled ) + { + description = _("These packages have a retracted version installed. Consider up- or downgrading them to a different version."); + } + else if ( pkgClass == all ) + { + description = _("All packages known by the package manager, no filtering applied."); + } + + packager->FilterDescription()->setText ( description ); +} + + +YItem * NCPkgFilterClassification::currentPkgClass() const +{ + int index = getCurrentItem(); + + return itemAt( index ); +} + + +void NCPkgFilterClassification::setCurrentPkgClass( YItem * item ) +{ + int index = itemIndex( item ); + + if ( index >= 0 ) + setCurrentItem( index ); +} + + +int NCPkgFilterClassification::itemIndex( YItem * item ) const +{ + for ( int i=0; i < itemsCount(); ++i ) + { + if ( itemAt( i ) == item ) + return i; + } + + return -1; +} + + +NCursesEvent NCPkgFilterClassification::wHandleInput( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + handleInput( ch ); + + switch ( ch ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + ret = NCursesEvent::handled; + showPackages(); + showDescription(); + break; + + default: + ret = NCSelectionBox::wHandleInput( ch ); + break; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterClassification.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterClassification.h new file mode 100644 index 0000000000000000000000000000000000000000..e9c2d110dc1ffe0d98ff086bbd19a98553e2116f --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterClassification.h @@ -0,0 +1,93 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterClassification.h + Author: Gabriele Mohr + +*/ + + +#ifndef NCPkgFilterClassification_h +#define NCPkgFilterClassification_h + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "NCZypp.h" + + +class NCTable; +class NCPackageSelector; + +class NCPkgFilterClassification: public NCSelectionBox +{ +public: + + /** + * A helper class to hold repository data in a neat table + * widget + * @param parent A parent widget + * @param opt Widget options + */ + + NCPkgFilterClassification( YWidget *parent, NCPackageSelector *pkg); + + virtual ~NCPkgFilterClassification() {}; + + void showRetractedInstalled(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +protected: + + YItem * currentPkgClass() const; + void setCurrentPkgClass( YItem * item ); + int itemIndex( YItem * item ) const; + + bool showPackages(); + void showDescription(); + + bool check(ZyppSel selectable, ZyppPkg pkg, YItem * group ); + + + // Data members + + NCPackageSelector *packager; + + YItem *recommended; + YItem *suggested; + YItem *orphaned; + YItem *unneeded; + YItem *multiversion; + YItem *retracted; + YItem *retractedInstalled; + YItem *all; + +private: + + NCPkgFilterClassification & operator=( const NCPkgFilterClassification & ); + NCPkgFilterClassification ( const NCPkgFilterClassification & ); + +}; +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterInstSummary.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterInstSummary.cc new file mode 100644 index 0000000000000000000000000000000000000000..ba3b67ae9ad0c59aa9fb89aaeefaae3ec531e43e --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterInstSummary.cc @@ -0,0 +1,164 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterInstSummary.cc + Author: Hedgehog Painter + +*/ + + +#include "NCPkgFilterInstSummary.h" + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgFilterInstSummary::NCPkgFilterInstSummary ( YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMultiSelectionBox ( parent, label) + , pkg( pkger ) +{ + // setNotify(true); + createLayout(); +} + +NCPkgFilterInstSummary::~NCPkgFilterInstSummary() +{ + +} + +void NCPkgFilterInstSummary::createLayout() +{ + del = new YItem ( _( "Delete" ), true); + items.push_back (del); + inst = new YItem ( _( "Install" ), true); + items.push_back (inst); + update = new YItem ( _( "Update" ), true); + items.push_back (update); + taboo = new YItem ( _( "Taboo" ), true); + items.push_back (taboo); + protect = new YItem ( _( "Protected" ), true); + items.push_back (protect); + keep = new YItem ( _( "Keep" )); + items.push_back (keep); + dontinstall = new YItem ( _( "Do not install" )); + items.push_back (dontinstall); + + addItems( items ); +} + +bool NCPkgFilterInstSummary::check( ZyppObj opkg, ZyppSel slb ) +{ + if (!slb) + return false; + + bool show = false; + + switch ( slb->status() ) + { + // group these two together, due to lack of space + case S_Del: + case S_AutoDel: show = del->selected(); break; + case S_Install: + case S_AutoInstall: show = inst->selected(); break; + case S_KeepInstalled: show = keep->selected(); break; + case S_NoInst: show = dontinstall->selected(); break; + case S_Protected: show = protect->selected(); break; + case S_Taboo: show = taboo->selected(); break; + case S_Update: + case S_AutoUpdate: show = update->selected(); break; + } + + if ( show ) + { + ZyppPkg pkg = tryCastToZyppPkg (opkg); + + if ( !pkg ) + return false; + } + + return show; +} + +bool NCPkgFilterInstSummary::showInstSummaryPackages() +{ + + NCPkgTable * packageList = pkg->PackageList(); + + if ( !packageList ) + { + yuiError() << "No valid NCPkgTable widget" << endl; + return false; + } + + // clear the package table + packageList->itemsCleared(); + + + for_( listIt, zyppPkgBegin(), zyppPkgEnd() ) + { + ZyppSel selectable = *listIt; + ZyppObj obj = selectable->candidateObj(); + + if (!obj) + { + // If there is neither an installed nor a candidate package, check + // any other instance. + ( selectable->installedObj() ) ? (obj = selectable->installedObj()) + : ( obj = selectable->theObj() ); + } + + if ( check( obj, selectable ) ) + { + ZyppPkg pkg = tryCastToZyppPkg (obj); + packageList->createListEntry( pkg, selectable); + } + + } + + // show the package list + packageList->scrollToFirstItem(); + packageList->drawList(); + packageList->showInformation(); + + yuiMilestone() << "Fill package list" << endl; + + return true; + +} + +NCursesEvent NCPkgFilterInstSummary::wHandleInput( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + + // treat this like any other MultiSelBox input ... + NCMultiSelectionBox::wHandleInput( ch ); + switch ( ch ) + { + // special case for toggling item status + case KEY_SPACE: + case KEY_RETURN: + showInstSummaryPackages(); + } + + //... but do not return to the main loop + ret = NCursesEvent::handled; + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterInstSummary.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterInstSummary.h new file mode 100644 index 0000000000000000000000000000000000000000..5060a4d9fd654d3fd3584715f1c78aef315d0e20 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterInstSummary.h @@ -0,0 +1,67 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterMain.h + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgFilterInstSummary_h +#define NCPkgFilterInstSummary_h + +#include + +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCPkgTable.h" +#include "NCZypp.h" + + +class NCPkgFilterInstSummary : public NCMultiSelectionBox +{ + NCPkgFilterInstSummary & operator=( const NCPkgFilterInstSummary & ); + NCPkgFilterInstSummary ( const NCPkgFilterInstSummary & ); + + bool check (ZyppObj opkg, ZyppSel slb); + NCPackageSelector *pkg; + +public: + + YItemCollection items; + YItem *del; + YItem *inst; + YItem *update; + YItem *taboo; + YItem *protect; + YItem *keep; + YItem *dontinstall; + + + NCPkgFilterInstSummary (YWidget *parent, std::string label, NCPackageSelector *pkg); + virtual ~NCPkgFilterInstSummary(); + + void createLayout(); + bool showInstSummaryPackages(); + NCursesEvent wHandleInput( wint_t ch ); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterLocale.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterLocale.cc new file mode 100644 index 0000000000000000000000000000000000000000..01a9e9adddc87813934764d2c4c928b6d45c5d61 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterLocale.cc @@ -0,0 +1,236 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + File: NCPkgFilterLocale.cc + Author: Bubli + +*/ + + +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgFilterLocale.h" + +using std::endl; + + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgLocaleTag::NCPkgLocaleTag ( zypp::sat::LocaleSupport loc, std::string status ) + : YTableCell( status ) + , locale ( loc ) +{ + +} + + +NCPkgLocaleTable::NCPkgLocaleTable( YWidget *parent, YTableHeader *tableHeader, NCPackageSelector *pkg ) + :NCTable( parent, tableHeader ) + , packager(pkg) +{ + fillHeader(); + fillLocaleList(); +} + + +void NCPkgLocaleTable::fillHeader() +{ + std::vector header; + + header.reserve(4); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::LangCode() ); + header.push_back( NCPkgStrings::LangName() ); + + setHeader( header); +} + + +void NCPkgLocaleTable::addLine ( zypp::sat::LocaleSupport l, const std::vector & cols, std::string status ) +{ + // use default ctor, add cell in the next step + YTableItem *tabItem = new YTableItem(); + + // place tag (with repo reference) to the 0th column + tabItem->addCell( new NCPkgLocaleTag ( l, status ) ); + + // and append the rest (name, URL and stuff) + for ( const std::string& s: cols ) + tabItem->addCell(s); + + // this is NCTable::addItem( tabItem ); + // it actually appends the line to the table + addItem( tabItem ); + +} + + +std::string NCPkgLocaleTable::status( zypp::Locale lang ) +{ + ZyppStatus status; + + if ( zypp::getZYpp()->pool().isRequestedLocale( lang ) ) + status = S_Install; + else + status = S_NoInst; + + // convert ZyppStatus to std::string + switch ( status ) + { + case S_NoInst: + return " "; + case S_Install: + return " i "; + default: + return "####"; + } +} + + +void NCPkgLocaleTable::fillLocaleList() +{ + std::vector oneLine; + + const zypp::LocaleSet available_locales( zypp::ResPool::instance().getAvailableLocales() ); + for_( it, available_locales.begin(), available_locales.end() ) + { + oneLine.clear(); + zypp::sat::LocaleSupport myLocale( *it ); + oneLine.push_back( myLocale.locale().code() ); + oneLine.push_back( myLocale.locale().name() ); + addLine( myLocale, oneLine, status(*it) ); + } + + sortItems( 1 ); +} + + +NCPkgLocaleTag* NCPkgLocaleTable::getTag (const int & index ) +{ + NCTableLine *line = myPad()->ModifyLine( index ); + if ( !line ) + { + return 0; + } + + YTableItem *it = dynamic_cast (line->origItem() ); + + YTableCell *tcell = it->cell(0); + NCPkgLocaleTag *tag = static_cast( tcell ); + + return tag; +} + + +zypp::sat::LocaleSupport NCPkgLocaleTable::getLocale( int index ) +{ + NCPkgLocaleTag *t = getTag( index ); + + return t->getLocale(); +} + + +void NCPkgLocaleTable::showLocalePackages() +{ + int index = getCurrentItem(); + zypp::sat::LocaleSupport myLocale = getLocale( index ); + + NCPkgTable * packageList = packager->PackageList(); + packageList->itemsCleared(); + + yuiMilestone() << "Packages supporting locale '" << myLocale.locale() << "':" << endl; + for_( it, myLocale.selectableBegin(), myLocale.selectableEnd() ) + { + ZyppPkg zyppPkg = tryCastToZyppPkg( (*it)->theObj() ); + packageList->createListEntry( zyppPkg, *it ); + } + + std::ostringstream s; + // Translators: %s is a locale code, e.g. en_GB + s << boost::format( _( "Translations, dictionaries and other language-related files for %s locale" )) % myLocale.locale().code(); + packager->FilterDescription()->setText( s.str() ); + + packageList->scrollToFirstItem(); + packageList->drawList(); + packageList->showInformation(); +} + + +void NCPkgLocaleTable::cycleStatus() +{ + int index = getCurrentItem(); + zypp::sat::LocaleSupport myLocale = getLocale( index ); + NCPkgLocaleTag * t = getTag ( index ); + NCTableLine *line = myPad()->ModifyLine( index ); + + if ( !t || !line ) + return; + + yuiMilestone() << "Toggle status of: " << myLocale.locale().code() << endl; + + if ( zypp::getZYpp()->pool().isRequestedLocale( myLocale.locale() ) ) + { + zypp::getZYpp()->pool().eraseRequestedLocale( myLocale.locale() ); + } + else + { + zypp::getZYpp()->pool().addRequestedLocale( myLocale.locale() ); + } + packager->showPackageDependencies( true ); + + NCTableCol * cell = line->GetCol( 0 ); + cell->SetLabel( NCstring( status( myLocale.locale() ) ) ); +} + + +NCursesEvent NCPkgLocaleTable::wHandleInput( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + handleInput( ch ); + + switch ( ch ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + ret = NCursesEvent::handled; + showLocalePackages(); + break; + + case KEY_SPACE: + case KEY_RETURN: + ret = NCursesEvent::handled; + cycleStatus(); + showLocalePackages(); + break; + + default: + ret = NCTable::wHandleInput( ch ); + break; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterLocale.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterLocale.h new file mode 100644 index 0000000000000000000000000000000000000000..6857abf09866a5bb5e45d8babc8d0ff9046eddd8 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterLocale.h @@ -0,0 +1,78 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterLocale.h + Author: Bubli + +*/ + + +#ifndef NCPkgFilterLocale_h +#define NCPkgFilterLocale_h + +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCZypp.h" + + +class NCPkgLocaleTag : public YTableCell +{ + +private: + + zypp::sat::LocaleSupport locale; + +public: + + NCPkgLocaleTag ( zypp::sat::LocaleSupport locale, std::string status ); + + ~NCPkgLocaleTag() {}; + + zypp::sat::LocaleSupport getLocale() const { return locale; } + +}; + +class NCPkgLocaleTable : public NCTable +{ +private: + + NCPkgLocaleTable & operator=( const NCPkgLocaleTable & ); + NCPkgLocaleTable ( const NCPkgLocaleTable & ); + + NCPackageSelector *packager; +public: + + NCPkgLocaleTable ( YWidget *parent, YTableHeader *tableHeader, NCPackageSelector *pkg); + + virtual ~NCPkgLocaleTable() {}; + + void fillHeader(); + void addLine ( zypp::sat::LocaleSupport, const std::vector & cols, std::string status ); + void fillLocaleList(); + void showLocalePackages(); + + NCPkgLocaleTag* getTag (const int & index ); + zypp::sat::LocaleSupport getLocale( int index ); + std::string status( zypp::Locale lang ); + void cycleStatus(); + NCursesEvent wHandleInput( wint_t ch ); +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterMain.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterMain.cc new file mode 100644 index 0000000000000000000000000000000000000000..a276e1cb9e5d1e629f7fc4bbbd82630c455e62ee --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterMain.cc @@ -0,0 +1,103 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterMain.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgFilterMain.h" +#include "NCPkgFilterService.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgFilterMain::NCPkgFilterMain (YWidget *parent, std::string label, NCPackageSelector *pkger ) + :NCComboBox(parent, label, false) + , pkg (pkger) +{ + createLayout(); + setNotify( true ); +} + +NCPkgFilterMain::~NCPkgFilterMain() +{ + +} + +void NCPkgFilterMain::createLayout() +{ + patterns = new YItem( _( "Patterns" ) ); + items.push_back( patterns ); + + languages = new YItem( _( "Languages" ) ); + items.push_back( languages ); + + repositories = new YItem( _( "Repositories" ) ); + items.push_back( repositories ); + + if (NCPkgServiceTable::any_service()) + { + services = new YItem( _( "Services" ) ); + items.push_back( services ); + } + + search = new YItem( _( "Search" ) ); + search->setSelected(); + items.push_back( search ); + + inst_summary = new YItem( _( "Installation Summary" ) ); + items.push_back( inst_summary ); + + pkg_class = new YItem( _( "Package Classification" ) ); + items.push_back( pkg_class ); + + addItems( items ); + +} + +bool NCPkgFilterMain::handleEvent() +{ + + YItem *currentItem = selectedItem(); + + if ( currentItem == patterns ) + pkg->replaceFilter ( NCPackageSelector::Patterns ); + else if ( currentItem == languages ) + pkg->replaceFilter ( NCPackageSelector::Languages ); + else if ( currentItem == repositories ) + pkg->replaceFilter ( NCPackageSelector::Repositories ); + else if ( currentItem == services ) + pkg->replaceFilter ( NCPackageSelector::Services ); + else if ( currentItem == search ) + pkg->replaceFilter ( NCPackageSelector::Search ); + else if ( currentItem == inst_summary ) + pkg->replaceFilter ( NCPackageSelector::Summary ); + else if ( currentItem == pkg_class ) + pkg->replaceFilter ( NCPackageSelector::PkgClassification ); + else + yuiError() << "zatim nic" << endl; + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterMain.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterMain.h new file mode 100644 index 0000000000000000000000000000000000000000..b4c541bb403d417884c1386183ab312adf4f4a87 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterMain.h @@ -0,0 +1,69 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterMain.h + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgFilterMain_h +#define NCPkgFilterMain_h + +#include + +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCZypp.h" + +class NCPackageSelector; + + +class NCPkgFilterMain : public NCComboBox +{ + NCPkgFilterMain & operator=( const NCPkgFilterMain & ); + NCPkgFilterMain ( const NCPkgFilterMain & ); + +public: + + YItemCollection items; + NCPackageSelector *pkg; + + YItem *patterns; + YItem *languages; + YItem *repositories; + YItem *services; + YItem *search; + YItem *inst_summary; + YItem *pkg_class; + + NCPkgFilterMain (YWidget *parent, std::string label, NCPackageSelector *pkger ); + virtual ~NCPkgFilterMain(); + + void createLayout(); + + bool handleEvent(); + + void setSummarySelected() { selectItem(inst_summary); } + void setReposSelected() { selectItem(repositories); } + void setPkgClassSelected() { selectItem(pkg_class); } +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterPattern.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterPattern.cc new file mode 100644 index 0000000000000000000000000000000000000000..ad2a6cdef6972c748d6a94f94343bcc9a71f23c1 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterPattern.cc @@ -0,0 +1,353 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + File: NCPkgFilterPattern.cc + Author: Gabriele Strattner + +*/ + + +#include +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCPkgTable.h" +#include "NCPkgStatusStrategy.h" +#include "NCZypp.h" +#include "NCPkgFilterPattern.h" + + +#ifdef FIXME +#define LOCALE Y2PM::getPreferredLocale() +#else +#define LOCALE +#endif + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +struct paircmp +{ + bool operator() (std::pair p1, std::pair p2) const + { + if ( p1.second != p2.second ) + return p1.second < p2.second; + else + return ( p1.first < p2.first ); + } +}; +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterPattern::NCPkgFilterPattern +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgFilterPattern::NCPkgFilterPattern( YWidget *parent, YTableHeader *header, NCPackageSelector * pkg ) + : NCPkgTable( parent, header ) + , packager( pkg ) +{ + createLayout( parent ); + setNotify( true ); + fillPatternList(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterPattern::~NCPkgFilterPattern +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgFilterPattern::~NCPkgFilterPattern() +{ + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterPattern::createLayout +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgFilterPattern::createLayout( YWidget *parent ) +{ + + setPackager( packager ); + + // set status strategy + NCPkgStatusStrategy * strat = new SelectionStatStrategy(); + + setTableType( NCPkgTable::T_Selections, strat ); + + fillHeader(); + +} + +/////////////////////////////////////////////////////////////////// +// +// NCursesEvent & showSelectionPopup() +// +// +void NCPkgFilterPattern::showPatternPackages() +{ + int index = getCurrentItem(); + ZyppObj objPtr = getDataPointer( index ); + if ( objPtr ) + { + // show the package list + std::set packages; + ZyppPattern patPtr = tryCastToZyppPattern (objPtr); + + if (patPtr) + { + int total = 0; + int installed = 0; + + yuiMilestone() << "Show packages belonging to selected pattern: " << getCurrentLine() << endl; + NCPkgTable * packageList = packager->PackageList(); + + if ( !packageList ) + { + yuiError() << "Widget is not a valid NCPkgTable widget" << endl; + return; + } + packageList->itemsCleared(); + + zypp::Pattern::Contents related ( patPtr->contents() ); + for ( zypp::Pattern::Contents::Selectable_iterator it = related.selectableBegin(); + it != related.selectableEnd(); + ++it ) + { + ZyppPkg zyppPkg = tryCastToZyppPkg( (*it)->theObj() ); + if ( zyppPkg ) + { + packageList->createListEntry( zyppPkg, *it ); + if ( (*it)->installedSize() > 0 ) + { + ++installed; + } + ++total; + } + } + packager->FilterDescription()->setText ( showDescription( objPtr ) ); + + std::ostringstream s; + + s << boost::format( _( "%d of %d package installed", "%d of %d packages installed", total )) % installed % total; + + packager->PatternLabel()->setLabel ( s.str() ); + + packageList->scrollToFirstItem(); + packageList->drawList(); + packageList->showInformation(); + } + } +} + + +////////////////////////////////////////////////////////////////// +// +// getCurrentLine() +// +// returns the currently selected list item (may be "really" selected +// or not) +// +std::string NCPkgFilterPattern::getCurrentLine() +{ +// if ( !sel ) +// return ""; + + int index = getCurrentItem(); + ZyppObj selPtr = getDataPointer(index); + + return ( selPtr?selPtr->summary(LOCALE):"" ); +} +std::string NCPkgFilterPattern::showDescription( ZyppObj objPtr ) +{ + ZyppPattern patPtr = tryCastToZyppPattern (objPtr); + return patPtr->description(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopup::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCPkgFilterPattern::wHandleInput( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + + // call handleInput of NCPad + handleInput( ch ); + + switch ( ch ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + ret = NCursesEvent::handled; + break; + + default: + ret = NCPkgTable::wHandleInput( ch ); + break; + } + + showPatternPackages(); + + return ret; +} + +/////////////////////////////////////////////////////////////////// +// +// OrderFuncPattern +// +bool orderPattern( ZyppSel slb1, ZyppSel slb2 ) +{ + ZyppPattern ptr1 = tryCastToZyppPattern (slb1->theObj()); + ZyppPattern ptr2 = tryCastToZyppPattern (slb2->theObj()); + if ( !ptr1 || !ptr2 ) + return false; + else + { + if ( ptr1->order() != ptr2->order() ) + return ( ptr1->order() < ptr2->order() ); + else + return ( ptr1->name() < ptr2->name() ); + } +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterPattern::fillContainerList +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgFilterPattern::fillPatternList() +{ + + ZyppPoolIterator i, b, e; + std::map > patterns; + std::map >::iterator mapIt; + + for ( i = zyppPatternsBegin(); i != zyppPatternsEnd(); ++i ) + { + ZyppObj resPtr = (*i)->theObj(); + bool show; + + ZyppPattern patPtr = tryCastToZyppPattern (resPtr); + show = patPtr && patPtr->userVisible(); + + if (show) + { + std::string cat = patPtr->category(); + + // fallback category + if ( cat.empty()) + cat = "other"; + + // create "category_name" : list std::pair + std::map >::iterator item = patterns.find(cat); + if ( item == patterns.end()) + { + std::list slbList; + slbList.push_back( (*i) ); + yuiMilestone() << "New category added: " << cat << endl; + patterns.insert( make_pair (cat, slbList) ); + } + else + { + (*item).second.push_back( (*i)); + } + + yuiMilestone() << resPtr->kind() <<": " << resPtr->name() + << ", initial status: " << (*i)->status() << ", order: " << patPtr->order() << endl; + } + } + + std::set < std::pair , paircmp > pat_index; + std::set < std::pair , paircmp >::iterator indexIt; + + // for each category + for ( mapIt = patterns.begin(); mapIt != patterns.end(); ++mapIt ) + { + std::string name = (*mapIt).first; + // sort the patterns by their order # + (*mapIt).second.sort( orderPattern ); + std::list::iterator it = (*mapIt).second.begin(); + + ZyppPattern pat = tryCastToZyppPattern ((*it)->theObj()); + + if (pat) + { + yuiDebug() << "Lowest #: "<< pat->order() << endl; + // create "category name" : "order #" std::pair in index structure + pat_index.insert( make_pair( name, pat->order()) ); + + } + } + + std::list::iterator listIt; + std::vector pkgLine; + + // now retrieve patterns in defined order + for ( indexIt = pat_index.begin(); indexIt != pat_index.end(); ++indexIt) + { + std::string name = (*indexIt).first; + std::list slbList = patterns[name]; + + for ( listIt = slbList.begin(); listIt != slbList.end(); ++listIt ) + { + ZyppObj resPtr = (*listIt)->theObj(); + pkgLine.clear(); + + pkgLine.push_back( resPtr->summary(LOCALE) ); // the description + + addLine( (*listIt)->status(), // the status + pkgLine, + resPtr, // ZyppPattern + (*listIt) ); // ZyppSel + } + } + + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterPattern.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterPattern.h new file mode 100644 index 0000000000000000000000000000000000000000..ae6d9947703886b244b06097d25a01eab406fdc9 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterPattern.h @@ -0,0 +1,84 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterPattern.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgFilterPattern_h +#define NCPkgFilterPattern_h + +#include +#include +#include + +#include +#include + +#include "NCPackageSelector.h" + + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgFilterPattern +// +// DESCRIPTION : +// +class NCPkgFilterPattern : public NCPkgTable +{ + NCPkgFilterPattern & operator=( const NCPkgFilterPattern & ); + NCPkgFilterPattern ( const NCPkgFilterPattern & ); + +private: + + NCPackageSelector * packager; // connection to the PackageSelector, + +protected: + + std::string getCurrentLine(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCPkgFilterPattern( YWidget *parent, YTableHeader *header, NCPackageSelector * pkg ); + virtual ~NCPkgFilterPattern(); + + void createLayout( YWidget *parent ); + + /** + * Fills the std::list with the available selections (and the status info) + * @return bool + */ + bool fillPatternList(); + + std::string showDescription( ZyppObj objPtr ); + + /** + * Shows the popup with the add ons (package categories). + * @return NCursesEvent + */ + void showPatternPackages(); + +}; + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgFilterPattern_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterRepo.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterRepo.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c7286246b3a249cf82fbbf91173dedbf1bdcb6f --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterRepo.cc @@ -0,0 +1,345 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + File: NCPkgFilterRepo.cc + Author: Bubli + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include +#include + +#include "NCPackageSelector.h" +#include "NCZypp.h" +#include "NCPkgFilterRepo.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgRepoTag::NCPkgRepoTag +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// + +NCPkgRepoTag::NCPkgRepoTag ( ZyppRepo repoPtr) + : YTableCell(std::string(" ")) + , repo (repoPtr) +{ + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgRepoTable::NCPkgRepoTable +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// + +NCPkgRepoTable::NCPkgRepoTable( YWidget *parent, YTableHeader *tableHeader, NCPackageSelector *pkg ) + :NCTable( parent, tableHeader ) + , packager(pkg) +{ + fillHeader(); + fillRepoList(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgRepoTable::fillHeader +// METHOD TYPE : void +// +// DESCRIPTION : Fill header of repositories table (name + URL) +// + +void NCPkgRepoTable::fillHeader() +{ + std::vector header; + + header.reserve(2); + header.push_back( "" ); + header.push_back( NCPkgStrings::PkgName() ); + + setHeader( header); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgRepoTable::addLine +// METHOD TYPE : void +// +// DESCRIPTION : Add one line (with tag) to the repository table +// + +void NCPkgRepoTable::addLine ( ZyppRepo r, const std::vector & cols ) +{ + // use default ctor, add cell in the next step + YTableItem *tabItem = new YTableItem(); + + // place tag (with repo reference) to the 0th column + tabItem->addCell( new NCPkgRepoTag ( r ) ); + + // and append the rest (name, URL and stuff) + for ( const std::string& s: cols ) + tabItem->addCell(s); + + // this is NCTable::addItem( tabItem ); + // it actually appends the line to the table + addItem( tabItem ); + + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgRepoTable::getTag +// METHOD TYPE : NCPkgRepoTag * +// +// DESCRIPTION : Get tag of repository table line on current index, +// ( contains repository reference) +// + +NCPkgRepoTag* NCPkgRepoTable::getTag (const int & index ) +{ + NCTableLine *line = myPad()->ModifyLine( index ); + if ( !line ) + { + return 0; + } + + YTableItem *it = dynamic_cast (line->origItem() ); + + // get actual repo tag from 0th column of the table + YTableCell *tcell = it->cell(0); + NCPkgRepoTag *tag = static_cast( tcell ); + + return tag; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgRepoTable::getRepo +// METHOD TYPE : ZyppRepo +// +// DESCRIPTION : Get repository reference from selected line's tag +// + +ZyppRepo NCPkgRepoTable::getRepo( int index ) +{ + NCPkgRepoTag *t = getTag( index ); + + if ( !t ) + { + return ZyppRepo(); + } + else + { + return t->getRepo(); + } +} + +std::string NCPkgRepoTable::showDescription( ZyppRepo r) +{ + std::string ret = ""; + + if ( r.isSystemRepo()) + ret = _( "@System: local RPM database" ); + else + { + std::string label = _( "Repository URL:" ); + zypp::Url srcUrl; + if ( ! r.info().baseUrlsEmpty() ) + srcUrl = *(r).info().baseUrlsBegin(); + + ret = label + srcUrl.asString(); + } + return ret; +} + +///////////////////////////////////////////////////////////////////// +//// +//// +//// METHOD NAME : NCPkgFilterRepo::fillRepoList +//// METHOD TYPE : bool +//// +//// DESCRIPTION : Add items to the repository list (assoc. +//// product name, if any, and URL) +//// +// +bool NCPkgRepoTable::fillRepoList() +{ + yuiMilestone() << "Filling repository list" << endl; + + std::vector oneLine; + + // iterate through all repositories + for ( ZyppRepositoryIterator it = ZyppRepositoriesBegin(); + it != ZyppRepositoriesEnd(); + ++it) + { + oneLine.clear(); + + // let's find some product for this repository + // but not now :) bug #296782 + // ZyppProduct product = findProductForRepo( (*it) ); + // if ( product ) + //{ + // name = product->summary(); + //} + std::string name = (*it).info().name(); + + oneLine.push_back( name ); + addLine( (*it), oneLine); + } + + return true; +} + +bool NCPkgRepoTable::showRepoPackages() +{ + int index = getCurrentItem(); + ZyppRepo repo = getRepo( index ); + + yuiMilestone() << "Selected repository " << repo.info().alias().c_str() << endl; + yuiMilestone() << "Collecting packages in selected repository" << endl; + + NCPkgTable *pkgList = packager->PackageList(); + // clean the pkg table first + pkgList->itemsCleared(); + + zypp::PoolQuery q; + q.addRepo( repo.info().alias() ); + q.addKind( zypp::ResKind::package ); + + for ( zypp::PoolQuery::Selectable_iterator it = q.selectableBegin(); + it != q.selectableEnd(); it++) + { + ZyppPkg pkg = tryCastToZyppPkg( (*it)->theObj() ); + pkgList->createListEntry ( pkg, *it); + } + + packager->FilterDescription()->setText( showDescription( repo ) ); + + pkgList->scrollToFirstItem(); + pkgList->drawList(); + pkgList->showInformation(); + + return true; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterRepo::findProductForRepo +// METHOD TYPE : ZyppProduct +// +// DESCRIPTION : Find single zypp::Product for this repository +// (null product if multiple products found) +// + +ZyppProduct NCPkgRepoTable::findProductForRepo( ZyppRepo repo) +{ + + ZyppProduct product; + + zypp::ResPool::byKind_iterator beg = zypp::ResPool::instance().byKindBegin( zypp::ResKind::product); + zypp::ResPool::byKind_iterator end = zypp::ResPool::instance().byKindEnd( zypp::ResKind::product); + + while( beg != end && !product ) + { + // Single product - most common case + if ( beg->resolvable()->repoInfo().alias() == repo.info().alias() ) + product = zypp::asKind( beg->resolvable() ); + beg++; + } + + while ( beg != end ) + { + if ( beg->resolvable()->repoInfo().alias() == repo.info().alias() ) + { + // Aw, multiple product found, we don't want those + yuiWarning() << "Multiple products in repository " << + repo.info().alias().c_str() << endl; + ZyppProduct null; + return null; + } + + beg++; + } + + if ( !product ) + { + // bad luck, nothing found + yuiMilestone() << "No product in repository " << + repo.info().alias().c_str() << endl; + } + + return product; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterRepo::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : default boring handle-input +// + +NCursesEvent NCPkgRepoTable::wHandleInput( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + handleInput( ch ); + + switch ( ch ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + ret = NCursesEvent::handled; + showRepoPackages(); + break; + + default: + ret = NCTable::wHandleInput( ch ); + break; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterRepo.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterRepo.h new file mode 100644 index 0000000000000000000000000000000000000000..9be4108e0489ff19c4f353518835a15165bd2ffd --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterRepo.h @@ -0,0 +1,146 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterRepo.h + Author: Bubli + +*/ + + +#ifndef NCPkgFilterRepo_h +#define NCPkgFilterRepo_h + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "NCZypp.h" + + +class NCTable; +class NCPushButton; +class NCPackageSelector; + +class NCPkgRepoTag : public YTableCell +{ + +private: + + ZyppRepo repo; + +public: + /** + * A helper class to hold a reference to zypp::Repository + * for each repository table line + * (actually it's a dummy column of the table) + * @param repo zypp::Repository reference + */ + + NCPkgRepoTag ( ZyppRepo repo); + + // Nikdy, ale opravdu nikdy nenechavej v odvozene tride virtualni + // destruktor, kdyz ani v puvodni neni, Bublino! + ~NCPkgRepoTag() {}; + + /* + * Get repository reference from the line tag + * @return ZyppRepo + */ + + ZyppRepo getRepo() const { return repo; } + +}; + +class NCPkgRepoTable : public NCTable +{ +private: + + NCPkgRepoTable & operator=( const NCPkgRepoTable & ); + NCPkgRepoTable ( const NCPkgRepoTable & ); + + NCPackageSelector *packager; +public: + + /** + * A helper class to hold repository data in a neat table + * widget + * @param parent A parent widget + * @param opt Widget options + */ + + NCPkgRepoTable ( YWidget *parent, YTableHeader *tableHeader, NCPackageSelector *pkg); + + virtual ~NCPkgRepoTable() {}; + + /** + * Add one line (with tag) to the repositories table + * @param ZyppRepo Reference to zypp::Repository + * @param cols String std::vector with repository data (name + URL) + */ + virtual void addLine( ZyppRepo r, const std::vector & cols ); + + /* + * Fill header of repositories table (name + URL) + */ + void fillHeader(); + + /** + * Get tag of repository table line on current index, + * ( contains repository reference) + * @param index Index of selected table line + * @return NCPkgRepoTag* Tag of selected line + */ + NCPkgRepoTag * getTag ( const int & index ); + + /** + * Get repository reference from selected line's tag + * @param index Index of selected table line + * @return ZyppRepo Associated zypp::Repository reference + */ + ZyppRepo getRepo( int index ); + + std::string showDescription (ZyppRepo r); + + virtual NCursesEvent wHandleInput ( wint_t ch ); + + /** + * Find single zypp::Product for this repository + * (null product if multiple products found) + * @param repo zypp::Repository + * @return ZyppProduct + */ + + ZyppProduct findProductForRepo (ZyppRepo repo); + + /** + * Add items to the repository list (assoc. + * product name, if any, and URL) + * @return bool (always true;-) ) + */ + bool fillRepoList(); + + bool showRepoPackages(); + +}; +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterSearch.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterSearch.cc new file mode 100644 index 0000000000000000000000000000000000000000..7ba52388fc2829e3dd95064fc8b6c1c82af62a17 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterSearch.cc @@ -0,0 +1,310 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + File: NCPkgFilterSearch.cc + Author: Gabriele Strattner + +*/ + + +#include +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCPkgSearchSettings.h" +#include "NCPkgStrings.h" +#include "NCPkgFilterSearch.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterSearch::NCPkgFilterSearch +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgFilterSearch::NCPkgFilterSearch( YWidget *parent, YUIDimension dim, NCPackageSelector *pkger ) + : NCLayoutBox( parent, dim ) + , searchExpr( 0 ) + , ignoreCase( 0 ) + , packager( pkger ) +{ + // the layout is created in NCPackageSelector +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterSearch::~NCPkgFilterSearch +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgFilterSearch::~NCPkgFilterSearch() +{ +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterSearch::createLayout +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgFilterSearch::createLayout( YWidget *parent ) +{ + + NCFrame * frame0 = new NCFrame( this, "" ); + + // add the input field (a editable combo box) + NCLayoutBox * vSplit = new NCLayoutBox ( frame0, YD_VERT); + // new NCSpacing( vSplit, YD_VERT, true, 0.5 ); + + searchExpr = new NCInputField( vSplit, NCPkgStrings::SearchPhrase() ); + searchExpr->setStretchable( YD_HORIZ, true ); + + // new NCSpacing( vSplit, YD_VERT, false, 0.5 ); + + if ( !packager->isYouMode() ) + { + // add the checkBox ignore case + NCAlignment *left1 = new NCAlignment( vSplit, YAlignBegin, YAlignUnchanged ); + + ignoreCase = new NCCheckBox( left1, _( "&Ignore Case" ), true ); + new NCSpacing( vSplit, YD_VERT, true, 0.5 ); + + } + + NCAlignment *left2 = new NCAlignment( vSplit, YAlignBegin, YAlignUnchanged ); + searchMode = new NCComboBox (left2, _( "Search &Mode" ), false); + + searchMode->addItem( _( "Contains" ), false); + searchMode->addItem( _( "Begins with" ), false); + searchMode->addItem( _( "Exact Match" ), false); + searchMode->addItem( _( "Use Wildcards" ), false); + searchMode->addItem( _( "Use RegExp" ), false); + + new NCSpacing( vSplit, YD_VERT, true, 0.5 ); +} + + +/////////////////////////////////////////////////////////////////// +// +// DESCRIPTION : +// +std::string NCPkgFilterSearch::getSearchExpression() const +{ + std::string value; + + if ( searchExpr ) + { + // get the expression and store it in combo box list + // value = searchExpr->getValue(); + + value = searchExpr->value(); + // searchExpr->addItem( value, true ); + } + + return value; +} + +bool NCPkgFilterSearch::match( std::string s1, std::string s2, bool ignoreCase ) +{ + std::string::iterator pos; + + if ( ignoreCase ) + { + pos = search( s1.begin(), s1.end(), + s2.begin(), s2.end(), + ic_compare ); + } + else + { + pos = search( s1.begin(), s1.end(), + s2.begin(), s2.end() ); + } + + return ( pos != s1.end() ); +} + + +bool NCPkgFilterSearch::fillSearchList( std::string & expr, + bool ignoreCase ) +{ + NCPkgTable * packageList = packager->PackageList(); + + if ( !packageList ) + { + return false; + } + + // clear the package table + packageList->itemsCleared(); + + NCPkgSearchSettings *settings = packager->SearchSettings(); + zypp::PoolQuery q; + + switch ( searchMode->getCurrentItem() ) + { + case Contains: + q.setMatchSubstring(); + break; + case BeginsWith: + expr = '^' + expr; + q.setMatchRegex(); + break; + case ExactMatch: + q.setMatchExact(); + break; + case UseWildcard: + q.setMatchGlob(); + break; + case UseRegexp: + q.setMatchRegex(); + break; + } + + q.addString( expr ); + q.addKind( zypp::ResKind::package ); + + if ( !ignoreCase ) + q.setCaseSensitive(); + if ( settings->doCheckName() ) + q.addAttribute( zypp::sat::SolvAttr::name ); + if ( settings->doCheckSummary() ) + q.addAttribute( zypp::sat::SolvAttr::summary ); + if ( settings->doCheckKeywords() ) + q.addAttribute( zypp::sat::SolvAttr::keywords ); + if ( settings->doCheckDescr() ) + q.addAttribute( zypp::sat::SolvAttr::description ); + if ( settings->doCheckProvides() ) + q.addAttribute( zypp::sat::SolvAttr::provides ); + if ( settings->doCheckRequires() ) + // attribute SolvAttr::requires means "required by" + q.addAttribute( zypp::sat::SolvAttr::requires ); + + NCPopupInfo * info = new NCPopupInfo( wpos( (NCurses::lines()-4)/2, (NCurses::cols()-18)/2 ), + "", + _( "Searching..." ) + ); + info->setPreferredSize( 18, 4 ); + info->popup(); + + try + { + for ( zypp::PoolQuery::Selectable_iterator it = q.selectableBegin(); + it != q.selectableEnd(); it++) + { + ZyppPkg pkg = tryCastToZyppPkg( (*it)->theObj() ); + packageList->createListEntry ( pkg, *it); + } + } + catch (const std::exception & e) + { + NCPopupInfo * info = new NCPopupInfo ( wpos( NCurses::lines()/10, + NCurses::cols()/10), + NCPkgStrings::ErrorLabel(), + // Popup informs the user that the query std::string + // entered for package search isn't correct + _( "Query Error:" ) + ("
") + e.what(), + NCPkgStrings::OKLabel() ); + info->setPreferredSize( 50, 10 ); + info->showInfoPopup(); + YDialog::deleteTopmostDialog(); + yuiError() << "Caught a std::exception: " << e.what() << endl; + } + + info->popdown(); + YDialog::deleteTopmostDialog(); + + int found_pkgs = packageList->getNumLines(); + std::ostringstream s; + s << boost::format( _( "%d packages found" )) % found_pkgs; + packager->PatternLabel()->setText( s.str() ); + + // show the package list + packageList->drawList(); + + if ( found_pkgs > 0 ) + { + packageList->scrollToFirstItem(); + packageList->showInformation(); + packageList->setKeyboardFocus(); + } + else + packager->clearInfoArea(); + + return true; + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterSearch::postAgain +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgFilterSearch::showSearchResultPackages() +{ + std::string filter = getSearchExpression(); + + if ( !packager->isYouMode() ) + { + // fill the package list with packages matching the search expression + fillSearchList( filter, getCheckBoxValue( ignoreCase ) ); + } + + return true; +} + +bool NCPkgFilterSearch::getCheckBoxValue( NCCheckBox * checkBox ) +{ + YCheckBoxState value = YCheckBox_off; + + if ( checkBox ) + { + value = checkBox->value(); + + return ( value == YCheckBox_on ? true : false ); + } + + return false; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterSearch.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterSearch.h new file mode 100644 index 0000000000000000000000000000000000000000..6b36c7554e00f21f359a051e30dda45f8d3efb2e --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterSearch.h @@ -0,0 +1,98 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterSearch.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgFilterSearch_h +#define NCPkgFilterSearch_h + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +class NCPackageSelector; + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgFilterSearch +// +// DESCRIPTION : +// +class NCPkgFilterSearch : public NCLayoutBox +{ + NCPkgFilterSearch & operator=( const NCPkgFilterSearch & ); + NCPkgFilterSearch ( const NCPkgFilterSearch & ); + +private: + + enum SearchMode + { + Contains = 0, + BeginsWith, + ExactMatch, + UseWildcard, + UseRegexp + }; + + NCInputField * searchExpr; + NCCheckBox * ignoreCase; + NCComboBox * searchMode; + + NCPackageSelector * packager; // connection to the package selector + + bool getCheckBoxValue( NCCheckBox * checkBox ); + +protected: + + std::string getSearchExpression() const; + +public: + + NCPkgFilterSearch( YWidget *parent, YUIDimension dim, NCPackageSelector *pkger ); + virtual ~NCPkgFilterSearch(); + + void createLayout( YWidget *parent ); + + virtual bool showSearchResultPackages(); + + bool match ( std::string s1, std::string s2, bool ignoreCase ); + + bool fillSearchList( std::string & expr, bool ignoreCase ); + + NCInputField * getSearchField() { return searchExpr; } + +}; + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgFilterSearch_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterService.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterService.cc new file mode 100644 index 0000000000000000000000000000000000000000..ca5c5c4463d99d1c1ba03a37a4f1ba6ac526846b --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterService.cc @@ -0,0 +1,298 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2018-2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include +#include + +#include +#include + +#include "NCPackageSelector.h" +#include "NCZypp.h" +#include "NCPkgFilterService.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgServiceTag::NCPkgServiceTag +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// + +NCPkgServiceTag::NCPkgServiceTag ( ZyppService servicePtr) + : YTableCell(std::string(" ")) + , service (servicePtr) +{ + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgServiceTable::NCPkgServiceTable +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// + +NCPkgServiceTable::NCPkgServiceTable( YWidget *parent, YTableHeader *tableHeader, NCPackageSelector *pkg ) + :NCTable( parent, tableHeader ) + , packager(pkg) + , repo_manager(new zypp::RepoManager()) +{ + fillHeader(); + fillServiceList(); +} + +bool NCPkgServiceTable::any_service() +{ + bool ret = std::any_of(ZyppRepositoriesBegin(), ZyppRepositoriesEnd(), [](const zypp::Repository& repo) { + // if the repository does not belong to any service then the service name is empty + return !repo.info().service().empty(); + }); + + yuiMilestone() << "Found a libzypp service: " << ret << endl; + return ret; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgServiceTable::fillHeader +// METHOD TYPE : void +// +// DESCRIPTION : Fill header of servicesitories table (name + URL) +// + +void NCPkgServiceTable::fillHeader() +{ + std::vector header; + + header.reserve(2); + header.push_back( "" ); + header.push_back( NCPkgStrings::PkgName() ); + + setHeader( header); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgServiceTable::addLine +// METHOD TYPE : void +// +// DESCRIPTION : Add one line (with tag) to the service table +// + +void NCPkgServiceTable::addLine ( ZyppService svc, const std::vector & cols ) +{ + // use default ctor, add cell in the next step + YTableItem *tabItem = new YTableItem(); + + // place tag (with service reference) to the 0th column + tabItem->addCell( new NCPkgServiceTag( svc ) ); + + // and append the rest (name, URL and stuff) + for ( const std::string& s: cols ) + tabItem->addCell(s); + + // this is NCTable::addItem( tabItem ); + // it actually appends the line to the table + addItem( tabItem ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgServiceTable::getTag +// METHOD TYPE : NCPkgServiceTag * +// +// DESCRIPTION : Get tag of service table line on current index, +// (contains service reference) +// + +NCPkgServiceTag* NCPkgServiceTable::getTag (int index) +{ + NCTableLine *line = myPad()->ModifyLine( index ); + if ( !line ) + { + return nullptr; + } + + YTableItem *it = line->origItem(); + + // get actual service tag from 0th column of the table + YTableCell *tcell = it->cell(0); + NCPkgServiceTag *tag = static_cast( tcell ); + + return tag; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgServiceTable::getService +// METHOD TYPE : ZyppService +// +// DESCRIPTION : Get service reference from selected line's tag +// + +ZyppService NCPkgServiceTable::getService( int index ) +{ + NCPkgServiceTag *t = getTag( index ); + + return t ? t->getService() : ZyppService(); +} + +static std::string html_escape(const std::string& s) +{ + std::string escaped = boost::replace_all_copy(s, "&", "&"); + boost::replace_all(escaped, "<", "<"); + boost::replace_all(escaped, ">", ">"); + return escaped; +} + +std::string NCPkgServiceTable::getDescription(ZyppService svc) +{ + zypp::ServiceInfo si = repo_manager->getService(svc); + + std::string label = _( "Service URL:" ); + std::string ret = label + html_escape(si.url().asString()); + return ret; +} + +///////////////////////////////////////////////////////////////////// +//// +//// +//// METHOD NAME : NCPkgFilterService::fillServiceList +//// METHOD TYPE : bool +//// +//// DESCRIPTION : Add items to the service list (assoc. +//// product name, if any, and URL) +//// +// +bool NCPkgServiceTable::fillServiceList() +{ + yuiMilestone() << "Filling service list" << endl; + + std::set seen_services; + + std::for_each(ZyppRepositoriesBegin(), ZyppRepositoriesEnd(), [&](const zypp::Repository& repo) + { + const std::string &service_name(repo.info().service()); + if (!service_name.empty()) + { + if (seen_services.find(service_name) == seen_services.end()) + { + seen_services.insert(service_name); + + std::vector oneLine; + oneLine.push_back( service_name ); + addLine( service_name, oneLine); + } + } + }); + + return true; +} + +void NCPkgServiceTable::showServicePackages() +{ + int index = getCurrentItem(); + ZyppService service = getService( index ); + + yuiMilestone() << "Selected service " << service << endl; + yuiMilestone() << "Collecting packages in selected service" << endl; + + NCPkgTable *pkgList = packager->PackageList(); + // clean the pkg table first + pkgList->itemsCleared(); + + zypp::PoolQuery query; + query.addKind( zypp::ResKind::package ); + + std::for_each(ZyppRepositoriesBegin(), ZyppRepositoriesEnd(), [&](const zypp::Repository& repo) + { + if (service == repo.info().service()) + { + yuiMilestone() << "Adding repo filter: " << repo.info().alias() << endl; + query.addRepo( repo.info().alias() ); + } + }); + + for ( zypp::PoolQuery::Selectable_iterator it = query.selectableBegin(); + it != query.selectableEnd(); + it++) + { + ZyppPkg pkg = tryCastToZyppPkg( (*it)->theObj() ); + pkgList->createListEntry ( pkg, *it); + } + + packager->FilterDescription()->setText( getDescription( service ) ); + + pkgList->scrollToFirstItem(); + pkgList->drawList(); + pkgList->showInformation(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgFilterService::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : default boring handle-input +// + +NCursesEvent NCPkgServiceTable::wHandleInput( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + handleInput( ch ); + + switch ( ch ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + ret = NCursesEvent::handled; + showServicePackages(); + break; + + default: + ret = NCTable::wHandleInput( ch ); + break; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterService.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterService.h new file mode 100644 index 0000000000000000000000000000000000000000..5f4c253fef16efcf3f4cce1369fe4ed49ad5b663 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgFilterService.h @@ -0,0 +1,150 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2018-2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +#ifndef NCPkgFilterService_h +#define NCPkgFilterService_h + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "NCZypp.h" + + +class NCTable; +class NCPushButton; +class NCPackageSelector; + +// represent a service by its name +typedef std::string ZyppService; + +class NCPkgServiceTag : public YTableCell +{ + +private: + + ZyppService service; + +public: + /** + * A helper class to hold a reference to zypp::Service + * for each service table line + * (actually it's a dummy column of the table) + * @param service zypp::Service reference + */ + + NCPkgServiceTag( ZyppService service ); + + ~NCPkgServiceTag() {}; + + /* + * Get service reference from the line tag + * @return ZyppService + */ + + ZyppService getService() const { return service; } + +}; + +class NCPkgServiceTable : public NCTable +{ +private: + + NCPkgServiceTable & operator=( const NCPkgServiceTable & ); + NCPkgServiceTable ( const NCPkgServiceTable & ); + + NCPackageSelector *packager; + zypp::shared_ptr repo_manager; + +public: + + /** + * A helper class to hold service data in a neat table + * widget + * @param parent A parent widget + * @param tableHeader table header + * @param pkg the master object + */ + + NCPkgServiceTable ( YWidget *parent, YTableHeader *tableHeader, NCPackageSelector *pkg); + + virtual ~NCPkgServiceTable() {}; + + /** + * @return bool any service is present at all + */ + static bool any_service(); + + /** + * Add one line (with tag) to the services table + * @param ZyppService Reference to zypp::Service + * @param cols String std::vector with service data (name + URL) + */ + virtual void addLine( ZyppService r, const std::vector & cols ); + + /* + * Fill header of services table (name + URL) + */ + void fillHeader(); + + /** + * Get tag of service table line on current index, + * (contains service reference) + * @param index Index of selected table line + * @return NCPkgServiceTag* Tag of selected line + */ + NCPkgServiceTag * getTag ( int index ); + + /** + * Get service reference from selected line's tag + * @param index Index of selected table line + * @return ZyppService Associated zypp::Service reference + */ + ZyppService getService( int index ); + + /** + * @return HTML contents for the description pane + */ + std::string getDescription (ZyppService r); + + virtual NCursesEvent wHandleInput ( wint_t ch ); + + /** + * Add items to the service list (assoc. + * product name, if any, and URL) + * @return bool (always true;-) ) + */ + bool fillServiceList(); + + /** + * Make the Package List show the packages + * for the currently selected service + */ + void showServicePackages(); + +}; +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuAction.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuAction.cc new file mode 100644 index 0000000000000000000000000000000000000000..e876acfac974e67da42e5acb228be42161a0d447 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuAction.cc @@ -0,0 +1,166 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuAction.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgMenuAction.h" +#include "NCPackageSelector.h" + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgMenuAction::NCPkgMenuAction (YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMenuButton( parent, label) + , pkg( pkger ) +{ + createLayout(); +} + +NCPkgMenuAction::~NCPkgMenuAction() +{ + +} + +void NCPkgMenuAction::createLayout() +{ + if ( !pkg->isYouMode() ) + { + // Please note: add an appropriate number of whitespaces to get a well + // formated menu (the [ ]s should be in one column) and use unique hotkeys until end: + // begin: Actions menu, cycle the status of a package, e.g. change from installed to delete + toggleItem = new YMenuItem( _( "&Toggle [SPACE]" ) ); + installItem = new YMenuItem( _( "&Install [+]" ) ); + deleteItem = new YMenuItem( _( "&Delete [-]" ) ); + updateItem = new YMenuItem( _( "&Update [>]" ) ); + tabooItem = new YMenuItem( _( "Ta&boo [!]" ) ); + lockItem = new YMenuItem( _( "&Lock [*]" ) ); + // end: Actions menu, set status of all packages (title of a submenu) + allItem = new YMenuItem( _( "&All Listed Packages" ) ); + + items.push_back( toggleItem ); + items.push_back( installItem ); + items.push_back( deleteItem ); + items.push_back( updateItem ); + items.push_back( tabooItem ); + items.push_back( lockItem ); + items.push_back( allItem ); + + // begin: submenu items actions concerning all packages + installAllItem = new YMenuItem( allItem, _( "&Install All" ) ); + deleteAllItem = new YMenuItem( allItem, _( "&Delete All" ) ); + keepAllItem = new YMenuItem( allItem, _( "&Keep All" ) ); + updateAllItem = new YMenuItem( allItem, _( "U&pdate All Unconditionally" ) ); + // end: submenu items: actions concerning all packages + updateNewerItem = new YMenuItem( allItem, _( "&Update If Newer Version Available" ) ); + + addItems( items ); + } + else // YOU mode + { // Please note: add an appropriate number of whitespaces to get a well + // formated menu (the [ ]s should be in one column) and use unique hotkeys until end: + // begin: Online Update Actions menu + toggleItem = new YMenuItem( _( "&Toggle [SPACE]" ) ); + installItem = new YMenuItem( _( "&Install [+]" ) ); + deleteItem = new YMenuItem( _( "&Do Not Install [-]" ) ); + tabooItem = new YMenuItem( _( "&Lock or Taboo [!]" ) ); + // end: Update Actions menu + + // update and delete aren't supported for patches + + items.push_back( toggleItem ); + items.push_back( installItem ); + items.push_back( deleteItem ); + items.push_back( tabooItem ); + + addItems( items ); + } +} + +bool NCPkgMenuAction::handleEvent ( const NCursesEvent & event) +{ + NCPkgTable *pkgList = pkg->PackageList(); + if ( !pkgList || !event.selection) + return false; + + if ( pkgList->getNumLines() == 0) + return true; + + if (event.selection == toggleItem) + { + pkgList->cycleObjStatus(); + } + else if (event.selection == installItem) + { + pkgList->changeObjStatus( '+' ); + } + else if (event.selection == deleteItem ) + { + pkgList->changeObjStatus( '-' ); + } + else if (event.selection == updateItem ) + { + pkgList->changeObjStatus( '>' ); + } + else if (event.selection == tabooItem ) + { + pkgList->changeObjStatus( '!' ); + } + else if (event.selection == lockItem ) + { + pkgList->changeObjStatus( '*' ); + } + else if (event.selection == installAllItem ) + { + pkgList->changeListObjStatus( NCPkgTable::A_Install ); + } + else if (event.selection == deleteAllItem ) + { + pkgList->changeListObjStatus( NCPkgTable::A_Delete ); + } + else if (event.selection == keepAllItem ) + { + pkgList->changeListObjStatus( NCPkgTable::A_Keep ); + } + else if ( event.selection == updateNewerItem ) + { + pkgList->changeListObjStatus( NCPkgTable::A_UpdateNewer ); + } + else if (event.selection == updateAllItem ) + { + pkgList->changeListObjStatus( NCPkgTable::A_Update ); + } + else + { + yuiError() << "No action performed." << endl; + } + + if ( pkg->VersionsList() ) + pkg->VersionsList()->updateTable(); + + return true; + +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuAction.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuAction.h new file mode 100644 index 0000000000000000000000000000000000000000..cb0a4b462248700ce84243f1bcfe196177dbaa56 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuAction.h @@ -0,0 +1,72 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuAction.cc + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgMenuAction_h +#define NCPkgMenuAction_h + +#include + +#include +#include +#include +#include + +#include "NCZypp.h" + +class NCPackageSelector; + +class NCPkgMenuAction : public NCMenuButton +{ + NCPkgMenuAction & operator=( const NCPkgMenuAction & ); + NCPkgMenuAction ( const NCPkgMenuAction & ); + +public: + + NCPackageSelector *pkg; + + YItemCollection items; + + YMenuItem *toggleItem; + YMenuItem *installItem; + YMenuItem *deleteItem; + YMenuItem *updateItem; + YMenuItem *tabooItem; + YMenuItem *lockItem; + YMenuItem *allItem; + + YMenuItem *installAllItem; + YMenuItem *deleteAllItem; + YMenuItem *keepAllItem; + YMenuItem *updateAllItem; + YMenuItem *updateNewerItem; + + NCPkgMenuAction (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuAction(); + + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuConfig.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuConfig.cc new file mode 100644 index 0000000000000000000000000000000000000000..2cbe7cf7ff51f965f2065c051b35af073545db88 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuConfig.cc @@ -0,0 +1,137 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuConfig.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgMenuConfig.h" +#include "NCPackageSelector.h" + + +#define CHECK_BOX "[ ] " + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + + +NCPkgMenuConfig::NCPkgMenuConfig (YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMenuButton( parent, label) + , pkg( pkger ) +{ + createLayout(); +} + +NCPkgMenuConfig::~NCPkgMenuConfig() +{ + +} + +void NCPkgMenuConfig::setSelected( YMenuItem *item, bool selected) +{ + std::string oldLabel = item->label(); + + std::string newLabel = oldLabel.replace(1, 1, 1, selected ? 'x' : ' '); + + item->setLabel( newLabel); +} + +void NCPkgMenuConfig::createLayout() +{ + exitAction = pkg->ActionAtExit(); + + repoManager = new YMenuItem( _( "Launch &Repository Manager") ); + onlineUpdate = new YMenuItem( _( "Launch &Online Update Configuration" ) ); + actionOnExit = new YMenuItem( _( "&Action after Package Installation" ) ); + + items.push_back( repoManager ); + items.push_back( onlineUpdate ); + + if (! exitAction.empty()) + { + items.push_back( actionOnExit ); + + restart = new YMenuItem( actionOnExit, CHECK_BOX + _( "&Restart Package Manager" ) ); + close = new YMenuItem( actionOnExit, CHECK_BOX + _( "&Close Package Manager" ) ); + showSummary = new YMenuItem( actionOnExit, CHECK_BOX + _( "&Show Summary" ) ); + + idToItemPtr["restart"] = restart; + idToItemPtr["close"] = close; + idToItemPtr["summary"] = showSummary; + + setSelected( idToItemPtr[ exitAction ], true); + } + + addItems( items ); + +} + +bool NCPkgMenuConfig::handleEvent( const NCursesEvent & event) +{ + if (!event.selection) + return false; + + if ( event.selection == repoManager ) + { + // return :repo_mgr symbol to Ruby module (FaTE #302517) + const_cast(event).result = "repo_mgr"; + yuiMilestone() << "Launching repository manager " << endl; + + // and close the main loop + return false; + } + else if ( event.selection == onlineUpdate ) + { + // the same as above, return :online_update_config + const_cast(event).result = "online_update_configuration"; + yuiMilestone() << "Launching YOU configuration " << endl; + + return false; + } + else + { + std::string old = exitAction; + + if ( event.selection == restart ) + { + exitAction = "restart"; + } + else if ( event.selection == close ) + { + exitAction = "close"; + } + else if ( event.selection == showSummary ) + { + exitAction = "summary"; + } + + setSelected(idToItemPtr[old], false); + setSelected(idToItemPtr[exitAction], true); + pkg->setActionAtExit( exitAction ); + } + + return true; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuConfig.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..fe9f00febb1fb7461244ce967154d79ae0923e32 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuConfig.h @@ -0,0 +1,73 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuConfig.cc + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgMenuConfig_h +#define NCPkgMenuConfig_h + +#include + +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCPkgPopupDiskspace.h" + + +class NCPackageSelector; + + +class NCPkgMenuConfig : public NCMenuButton +{ + NCPkgMenuConfig & operator=( const NCPkgMenuConfig & ); + NCPkgMenuConfig ( const NCPkgMenuConfig & ); + +private: + std::map idToItemPtr; + std::string exitAction; + +public: + + YItemCollection items; + + YMenuItem *repoManager; + YMenuItem *onlineUpdate; + YMenuItem *actionOnExit; + + YMenuItem *restart; + YMenuItem *close; + YMenuItem *showSummary; + + NCPackageSelector *pkg; + + NCPkgMenuConfig (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuConfig(); + + void setSelected ( YMenuItem *item, bool selected); + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuDeps.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuDeps.cc new file mode 100644 index 0000000000000000000000000000000000000000..ba2b9671c55fe1d7b60f9e87522ff25482035992 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuDeps.cc @@ -0,0 +1,299 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuDeps.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgMenuDeps.h" +#include "NCPackageSelector.h" + + +#define CHECK_BOX "[ ] " +#define NO_CHECK_BOX " " + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgMenuDeps::NCPkgMenuDeps (YWidget *parent, std::string label, NCPackageSelector *pkger ) + : NCMenuButton( parent, label) + , pkg (pkger) +{ + createLayout(); +} + +NCPkgMenuDeps::~NCPkgMenuDeps() +{ + +} + +void NCPkgMenuDeps::setSelected( YMenuItem *item, bool selected) +{ + std::string oldLabel = item->label(); + char sel = 'x'; + + if ( item == cleanDepsOnRemove || item == allowVendorChange ) + sel = '+'; + + std::string newLabel = oldLabel.replace(1, 1, 1, selected ? sel : ' '); + + item->setLabel( newLabel); +} + +void NCPkgMenuDeps::createLayout() +{ + + autoCheckDeps = new YMenuItem( CHECK_BOX + _( "&Automatic Dependency Check" ) ); + items.push_back( autoCheckDeps ); + setSelected( autoCheckDeps, pkg->AutoCheck() ); + + checkNow = new YMenuItem( NO_CHECK_BOX + _( "&Check Dependencies Now" ) ); + items.push_back( checkNow ); + + verifySystemOpt = new YMenuItem( CHECK_BOX + _( "&System Verification Mode" ) ); + items.push_back( verifySystemOpt ); + setSelected( verifySystemOpt, pkg->VerifySystem() ); + + verifySystem = new YMenuItem( NO_CHECK_BOX + _( "&Verify System Now" ) ); + items.push_back( verifySystem ); + + installRecommendedOpt = new YMenuItem( CHECK_BOX + _( "Install &Recommended Packages" ) ); + items.push_back( installRecommendedOpt ); + setSelected( installRecommendedOpt, pkg->InstallRecommended() ); + + installRecommendedNow = new YMenuItem( NO_CHECK_BOX + _( "&Install Recommended Packages for Already Installed Packages Now" ) ); + items.push_back( installRecommendedNow ); + + cleanDepsOnRemove = new YMenuItem( CHECK_BOX + _( "Cleanup when &Deleting Packages (Temporary Change)" )); + items.push_back ( cleanDepsOnRemove ); + setSelected( cleanDepsOnRemove, pkg->isCleanDepsOnRemove() ); + + allowVendorChange = new YMenuItem( CHECK_BOX + _( "Allow &Vendor Change (Temporary Change)" ) ); + items.push_back ( allowVendorChange ); + setSelected( allowVendorChange, pkg->isAllowVendorChange() ); + + testCase = new YMenuItem( NO_CHECK_BOX + _( "&Generate Dependency Solver Testcase" ) ); + items.push_back( testCase ); + + addItems( items ); +} + +bool NCPkgMenuDeps::handleEvent( const NCursesEvent & event) +{ + if (!event.selection) + return false; + + if (event.selection == checkNow ) + return checkDependencies(); + else if (event.selection == autoCheckDeps) + return setAutoCheck(); + else if (event.selection == verifySystem) + return verify(); + else if (event.selection == verifySystemOpt ) + return setVerifySystem(); + else if (event.selection == cleanDepsOnRemove ) + return setCleanDepsOnRemove(); + else if (event.selection == installRecommendedOpt ) + return setInstallRecommended(); + else if (event.selection == installRecommendedNow ) + return doInstallRecommended(); + else if (event.selection == allowVendorChange ) + return setAllowVendorChange(); + else if (event.selection == testCase) + return generateTestcase(); + return true; +} + +static +void popupInfo(const wsze size, const std::string & text) +{ + wpos pos((NCurses::lines() - size.H) / 2, (NCurses::cols() - size.W) / 2); + NCPopupInfo * info = new NCPopupInfo( pos, + "", text, + NCPkgStrings::OKLabel() ); + info->setPreferredSize(size.W, size.H); + info->showInfoPopup(); + YDialog::deleteTopmostDialog(); +} + +bool NCPkgMenuDeps::checkDependencies() +{ + bool ok = false; + + if ( pkg->DepsPopup() ) + { + yuiMilestone() << "Checking dependencies" << endl; + pkg->checkNow ( &ok ); + } + + if ( ok ) + { + popupInfo(wsze(5, 35), _( "All package dependencies are OK." )); + } + + // update the package list and the disk space info + pkg->updatePackageList(); + pkg->showDiskSpace(); + + return true; +} + +bool NCPkgMenuDeps::doInstallRecommended() +{ + bool ok = false; + + yuiMilestone() << "Adding recommended packages" << endl; + + pkg->saveState(); + pkg->doInstallRecommended ( &ok ); + + // display the popup with automatic changes + NCPkgPopupTable * autoChangePopup = + new NCPkgPopupTable( wpos( 3, 8 ), pkg, + // headline of a popup with packages + _("Automatic Changes"), + // part 1 of a text explaining the list of packages which follow + _("Being recommended by already installed packages, the following"), + // part 2 of the text + _("packages have been automatically selected for installation:") + ); + + NCursesEvent input = autoChangePopup->showInfoPopup(); + if ( input == NCursesEvent::cancel ) + { + // user clicked on Cancel + pkg->restoreState(); + } + YDialog::deleteTopmostDialog(); // delete NCPopupInfo dialog + + // update the package list and the disk space info + pkg->updatePackageList(); + pkg->showDiskSpace(); + + return true; +} + + +bool NCPkgMenuDeps::generateTestcase() +{ + std::string testCaseDir = "/var/log/YaST2/solverTestcase"; + + yuiMilestone() << "Generating solver test case START" << endl; + bool success = zypp::getZYpp()->resolver()->createSolverTestcase( testCaseDir ); + yuiMilestone() << "Generating solver test case END" << endl; + + if ( success ) + { + popupInfo(wsze(8, 40), + _( "Dependency resolver test case written to " ) + "
" + + testCaseDir + ); + } + return success; + +} + +bool NCPkgMenuDeps::setAutoCheck() +{ + pkg->setAutoCheck( !pkg->AutoCheck() ); + setSelected( autoCheckDeps, pkg->AutoCheck() ); + + return true; +} + +bool NCPkgMenuDeps::setVerifySystem() +{ + pkg->setVerifySystem( !pkg->VerifySystem() ); + setSelected( verifySystemOpt, pkg->VerifySystem() ); + + return true; +} + +bool NCPkgMenuDeps::setCleanDepsOnRemove() +{ + pkg->setCleanDepsOnRemove( !pkg->isCleanDepsOnRemove() ); + setSelected( cleanDepsOnRemove, pkg->isCleanDepsOnRemove() ); + + return true; +} + +bool NCPkgMenuDeps::setInstallRecommended() +{ + pkg->setInstallRecommended( !pkg->InstallRecommended() ); + setSelected( installRecommendedOpt, pkg->InstallRecommended() ); + + return true; +} + + +bool NCPkgMenuDeps::setAllowVendorChange() +{ + pkg->setAllowVendorChange( !pkg->isAllowVendorChange() ); + setSelected( allowVendorChange, pkg->isAllowVendorChange() ); + + return true; +} + +bool NCPkgMenuDeps::verify() +{ + bool ok = false; + + yuiMilestone() << "Verifying system" << endl; + + pkg->saveState(); + // call the solver (with S_Verify it displays no popup) + pkg->systemVerification( &ok ); + + // display the popup with automatic changes + NCPkgPopupTable * autoChangePopup = + new NCPkgPopupTable( wpos( 3, 8 ), pkg, + // headline of a popup with packages + _("Automatic Changes"), + // part 1 of a text explaining the list of packages which follow + _("To fulfill the dependencies of already installed packages following"), + // part 2 of the text + _("packages have been automatically selected for installation:") + ); + NCursesEvent input = autoChangePopup->showInfoPopup(); + + if ( input == NCursesEvent::cancel ) + { + // user clicked on Cancel + pkg->restoreState(); + } + if ( ok && input == NCursesEvent::button ) + { + // dependencies OK, no automatic changes/the user has accepted the changes + popupInfo(wsze(5, 35), _( "System dependencies verify OK." )); + } + + YDialog::deleteTopmostDialog(); // delete NCPopupInfo dialog + + pkg->updatePackageList(); + pkg->showDiskSpace(); + // the verify call sets the option verify to true + setSelected( verifySystemOpt, true ); + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuDeps.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuDeps.h new file mode 100644 index 0000000000000000000000000000000000000000..c3b7c39c140784d9cb267526656b545a68034e26 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuDeps.h @@ -0,0 +1,89 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuDeps.cc + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgMenuDeps_h +#define NCPkgMenuDeps_h + +#include + +#include +#include +#include +#include + +#include "NCPkgPopupTable.h" +#include "NCZypp.h" + + +class NCPackageSelector; + +class NCPkgMenuDeps : public NCMenuButton +{ + NCPkgMenuDeps & operator=( const NCPkgMenuDeps & ); + NCPkgMenuDeps ( const NCPkgMenuDeps & ); + +public: + + NCPackageSelector *pkg; + + YItemCollection items; + + YMenuItem *autoCheckDeps; + YMenuItem *checkNow; + YMenuItem *verifySystem; + YMenuItem *verifySystemOpt; + YMenuItem *installRecommendedOpt; + YMenuItem *installRecommendedNow; + YMenuItem *cleanDepsOnRemove; + YMenuItem *allowVendorChange; + YMenuItem *testCase; + + NCPkgMenuDeps (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuDeps(); + + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + + bool checkDependencies(); + + bool generateTestcase(); + + bool setAutoCheck(); + + bool setCleanDepsOnRemove(); + + bool setInstallRecommended(); + + bool doInstallRecommended(); + + bool setAllowVendorChange(); + + bool setVerifySystem(); + + bool verify(); + + void setSelected( YMenuItem *item, bool selected); +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuExtras.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuExtras.cc new file mode 100644 index 0000000000000000000000000000000000000000..28e25f3e5f81084130b21052ed9aa47f8e3ea2ae --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuExtras.cc @@ -0,0 +1,330 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuExtras.cc + Author: Hedgehog Painter + +*/ + + +#include +#include +#include + +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include "NCPackageSelector.h" +#include "NCPkgMenuExtras.h" + + +using std::endl; + +typedef zypp::syscontent::Reader::Entry ZyppReaderEntry; +typedef std::pair importMapPair; + +#define DEFAULT_EXPORT_FILE_NAME "user-packages.xml" + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgMenuExtras::NCPkgMenuExtras (YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMenuButton( parent, label) + , pkg (pkger) +{ + createLayout(); +} + +NCPkgMenuExtras::~NCPkgMenuExtras() +{ + +} + +void NCPkgMenuExtras::createLayout() +{ + exportFile = new YMenuItem( _( "&Export Package List to File" ) ); + items.push_back( exportFile ); + + importFile = new YMenuItem( _( "&Import Package List from File" ) ); + items.push_back( importFile ); + + diskSpace = new YMenuItem( _( "&Show Available Disk Space" ) ); + items.push_back( diskSpace ); + + if ( pkg->isOnlineSearchEnabled() ) { + onlineSearch = new YMenuItem(_("Search &Online")); + items.push_back(onlineSearch); + } + + addItems( items ); +} + +bool NCPkgMenuExtras::handleEvent ( const NCursesEvent & event) +{ + if (!event.selection) + return false; + + if ( event.selection == exportFile ) + exportToFile(); + else if ( event.selection == importFile ) + importFromFile(); + else if ( event.selection == diskSpace ) + showDiskSpace(); + else if ( event.selection == onlineSearch ) { + const_cast(event).result = "online_search"; + yuiMilestone() << "Launching online search " << endl; + + //and close the main loop + return false; + } + + /*else if ( event.selection == repoManager ) + { + // return :repo_mgr symbol to the Ruby module (FaTE #302517) + const_cast(event).result = "repo_mgr"; + yuiMilestone() << "Launching repository manager " << endl; + + // and close the main loop + return false; + }*/ + return true; +} + +void NCPkgMenuExtras::importSelectable( ZyppSel selectable, bool isWanted, const char*kind ) +{ + ZyppStatus oldStatus = selectable->status(); + ZyppStatus newStatus = oldStatus; + + // Package/Pattern is on the list + if (isWanted) + { + switch (oldStatus) + { + // Keep status for installed ones + case S_Install: + case S_AutoInstall: + case S_Update: + case S_AutoUpdate: + case S_KeepInstalled: + case S_Protected: + newStatus = oldStatus; + break; + + // Keep also those marked for deletion + case S_Del: + case S_AutoDel: + newStatus = S_KeepInstalled; + yuiDebug() << "Keeping " << kind << " " << selectable->name().c_str() << endl; + break; + + // Add not yet installed pkgs (if they have candidate available) + case S_NoInst: + case S_Taboo: + if ( selectable->hasCandidateObj() ) + { + newStatus = S_Install; + yuiDebug() << "Adding " << kind << " " << selectable->name().c_str() << endl; + } + else + { + yuiDebug() << "Cannot add " << kind << " " << selectable->name().c_str() << + " " << " - no candidate." << endl; + } + break; + } + } + // Package/Pattern is not on the list + else + { + switch (oldStatus) + { + // Mark installed ones for deletion + case S_Install: + case S_AutoInstall: + case S_Update: + case S_AutoUpdate: + case S_KeepInstalled: + case S_Protected: + newStatus = S_Del; + yuiDebug() << "Deleting " << kind << " " << selectable->name().c_str() << endl; + break; + + // Keep status for not installed, taboo and to-be-deleted + case S_Del: + case S_AutoDel: + case S_NoInst: + case S_Taboo: + newStatus = oldStatus; + break; + } + } + + if (oldStatus != newStatus) + selectable->setStatus( newStatus ); +} + + +bool NCPkgMenuExtras::exportToFile() +{ // Ask for file to save into + std::string filename = YUI::app()->askForSaveFileName( DEFAULT_EXPORT_FILE_NAME, + "*.xml", + _( "Export List of All Packages and Patterns to File" )); + + if ( ! filename.empty() ) + { + zypp::syscontent::Writer writer; + const zypp::ResPool & pool = zypp::getZYpp()->pool(); + + // some strange C++ magic (c) by ma + for_each( pool.begin(), pool.end(), + boost::bind( &zypp::syscontent::Writer::addIf, + boost::ref(writer), + boost::placeholders::_1)); + + try + { + // open file for writing and try to dump syscontent into it + std::ofstream exportFile( filename.c_str() ); + exportFile.exceptions(std::ios_base::badbit | std::ios_base::failbit ); + exportFile << writer; + + yuiMilestone() << "Exported list of packages and patterns to " << filename << endl; + } + + catch (std::exception & exception) + { + yuiWarning() << "Error exporting list of packages and patterns to " << filename << endl; + + // delete partially written file (don't care if it doesn't exist) + (void) unlink( filename.c_str() ); + + // present error popup to the user + NCPopupInfo * errorMsg = new NCPopupInfo( wpos( (NCurses::lines()-5)/2, (NCurses::cols()-40)/2 ), + NCPkgStrings::ErrorLabel(), + _( "Error exporting list of packages and patterns to " ) + // FIXME: String addition is evil for translators! + + filename, + NCPkgStrings::OKLabel(), + ""); + errorMsg->setPreferredSize(40, 5); + NCursesEvent input = errorMsg->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + } + + return true; + } + + return false; +} + +bool NCPkgMenuExtras::importFromFile() +{ + // ask for file to open + std::string filename = YUI::app()->askForExistingFile( DEFAULT_EXPORT_FILE_NAME, + "*.xml", + _( "Import List of All Packages and Patterns from File" )); + if ( ! filename.empty() ) + { + NCPkgTable * packageList = pkg->PackageList(); + yuiMilestone() << "Importing list of packages and patterns from " << filename << endl; + + try + { + std::ifstream importFile ( filename.c_str() ); + zypp::syscontent::Reader reader (importFile); + + // maps to store package/pattern data into + std::map importPkgs; + std::map importPatterns; + + // Import syscontent reader to a map $[ "package_name" : pointer_to_data] + for (zypp::syscontent::Reader::const_iterator it = reader.begin(); + it != reader.end(); + it ++ ) + { + std::string kind = it->kind(); + + // importMapPair => std::pair + if ( kind == "package" ) + importPkgs.insert( importMapPair( it->name(), *it ) ); + else if ( kind == "pattern" ) + importPatterns.insert( importMapPair( it->name(), *it ) ); + } + + yuiMilestone() << "Found " << importPkgs.size() << " packages and " << importPatterns.size() << " patterns." << endl; + + // Change status of appropriate packages and patterns + for (ZyppPoolIterator it = zyppPkgBegin(); + it != zyppPkgEnd(); + it++ ) + { + ZyppSel selectable = *it; + // isWanted => package name found in importPkgs map + importSelectable ( *it, importPkgs.find( selectable->name() ) != importPkgs.end(), "package" ); + } + + for (ZyppPoolIterator it = zyppPatternsBegin(); + it != zyppPatternsEnd(); + it++ ) + { + ZyppSel selectable = *it; + importSelectable ( *it, importPatterns.find( selectable->name() ) != importPatterns.end(), "pattern" ); + } + + // Switch to installation summary filter + packageList->fillSummaryList(NCPkgTable::L_Changes); + + //... and finally display the result + packageList->showInformation(); + packageList->setKeyboardFocus(); + + return true; + } + catch ( const zypp::Exception & exception ) + { + yuiWarning() << "Error importing list of packages and patterns from" << filename << endl; + + NCPopupInfo * errorMsg = new NCPopupInfo( wpos( (NCurses::lines()-5)/2, (NCurses::cols()-40)/2) , + NCPkgStrings::ErrorLabel(), + _( "Error importing list of packages and patterns from " ) + // FIXME: String addition is evil for translators! + + filename, + NCPkgStrings::OKLabel(), + ""); + errorMsg->setPreferredSize(40, 5); + NCursesEvent input = errorMsg->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + } + } + return true; + +} + +bool NCPkgMenuExtras::showDiskSpace() +{ + pkg->diskSpacePopup()->showInfoPopup( NCPkgStrings::DiskspaceLabel() ); + // FIXME: move focus back to pkg table? + + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuExtras.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuExtras.h new file mode 100644 index 0000000000000000000000000000000000000000..1a6c256a564d8623b0de5bad0e24b596b54fbe0a --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuExtras.h @@ -0,0 +1,73 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuExtras.cc + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgMenuExtras_h +#define NCPkgMenuExtras_h + +#include + +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCPkgPopupDiskspace.h" + + +class NCPackageSelector; + + +class NCPkgMenuExtras : public NCMenuButton +{ + NCPkgMenuExtras & operator=( const NCPkgMenuExtras & ); + NCPkgMenuExtras ( const NCPkgMenuExtras & ); + +public: + + YItemCollection items; + + YMenuItem *exportFile; + YMenuItem *importFile; + YMenuItem *diskSpace; + YMenuItem *onlineSearch; + + NCPackageSelector *pkg; + + NCPkgMenuExtras (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuExtras(); + + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + + void importSelectable ( ZyppSel selectable, bool isWanted, const char*kind ); + + bool exportToFile(); + + bool importFromFile(); + + bool showDiskSpace(); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuFilter.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuFilter.cc new file mode 100644 index 0000000000000000000000000000000000000000..000e5e56a7b0fd6342a6356a7977b6819b2d12cf --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuFilter.cc @@ -0,0 +1,139 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuFilter.cc + Author: Gabriele Mohr + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgPatchSearch.h" +#include "NCPkgTable.h" +#include "NCPackageSelector.h" +#include "NCPkgMenuFilter.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgMenuFilter::NCPkgMenuFilter (YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMenuButton( parent, label) + , pkg (pkger) +{ + createLayout(); +} + +NCPkgMenuFilter::~NCPkgMenuFilter() +{ + +} + +void NCPkgMenuFilter::createLayout() +{ + // menu items of the filter menu for patches - keep them short + // and use unique hotkeys from begin: to end: + // begin: + needed = new YMenuItem( _( "&Needed Patches" ) ); + // _( "Re&levant Patches" ) + unneeded = new YMenuItem( _( "&Installed Patches" ) ); + // _( "&Satisfied Patches" ) ); + recommended = new YMenuItem( _( "&Recommended" ) ); + security = new YMenuItem( _( "&Security" ) ); + optional = new YMenuItem( _( "&Optional" ) ); + allPatches = new YMenuItem( _( "&All Patches" ) ); + // end: + search = new YMenuItem( _( "S&earch" ) ); + + items.push_back( needed ); + items.push_back( unneeded ); + items.push_back( recommended ); + items.push_back( security ); + items.push_back( optional ); + items.push_back( allPatches ); + items.push_back( search ); + + addItems( items ); +} + + +bool NCPkgMenuFilter::handleEvent ( const NCursesEvent & event) +{ + if ( !event.selection) + { + yuiError() << "Menu selection failed" << endl; + return false; + } + + NCPkgTable *pkgList = pkg->PackageList(); + + if ( !pkgList ) + { + yuiError() << "No package list available" << endl; + return false; + } + + yuiMilestone() << "Handle event NCPkgMenuFilter" << endl; + + // Call the appropriate method from NCPackageSelector for + // the selected menu entry. + + if ( event.selection == needed ) + pkg->fillPatchList( F_Needed ); // show needed patches + else if ( event.selection == unneeded ) + pkg->fillPatchList( F_Unneeded ); // show unneeded patches + else if ( event.selection == allPatches ) + pkg->fillPatchList( F_All ); // show all patches + else if ( event.selection == recommended ) + pkg->fillPatchList( F_Recommended ); // patch kind recommended + else if ( event.selection == security ) + pkg->fillPatchList( F_Security ); // patch kind security + else if ( event.selection == optional ) + pkg->fillPatchList( F_Optional ); // patch kind optional + else if ( event.selection == search ) + { + searchPopup = new NCPkgPatchSearch( wpos( 1, 1 ), pkg ); + + if ( searchPopup ) + { + NCursesEvent retEvent = searchPopup->showSearchPopup(); + + if ( retEvent == NCursesEvent::button ) + { + yuiMilestone() << "Searching for: " << retEvent.result << endl; + pkgList->showInformation(); + } + else + { + yuiMilestone() << "Search is canceled" << endl; + } + searchPopup->destroy(); // (or call YDialog::deleteTopmostDialog()) + searchPopup = 0; + } + } + + pkgList->setKeyboardFocus(); + + pkgList->showInformation(); + + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuFilter.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..eab42dbc6cedb74a6c83476fc00fdd7b9f5fb9c1 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuFilter.h @@ -0,0 +1,88 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuFilter.cc + Author: Gabriele Mohr + +*/ + + +#ifndef NCPkgMenuFilter_h +#define NCPkgMenuFilter_h + +#include + +#include +#include + +#include +#include +#include + +#include "NCPkgPatchSearch.h" + + +class NCPackageSelector; + +#include "NCZypp.h" + +class NCPkgMenuFilter : public NCMenuButton +{ +public: + + enum PatchFilter + { + F_Needed, + F_Unneeded, + F_All, + F_Recommended, + F_Security, + F_Optional, + F_Unknown + }; + + NCPkgMenuFilter & operator=( const NCPkgMenuFilter & ); + NCPkgMenuFilter ( const NCPkgMenuFilter & ); + +private: + NCPackageSelector *pkg; + + NCPkgPatchSearch *searchPopup; + + YItemCollection items; + + YMenuItem *needed; + YMenuItem *unneeded; + YMenuItem *allPatches; + YMenuItem *recommended; + YMenuItem *security; + YMenuItem *optional; + YMenuItem *search; + + +public: + + NCPkgMenuFilter (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuFilter(); + + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuHelp.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuHelp.cc new file mode 100644 index 0000000000000000000000000000000000000000..df991d2f92fdfce7346b65b9df1e9a3937c4c13b --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuHelp.cc @@ -0,0 +1,146 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuHelp.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgMenuHelp.h" +#include "NCPkgStrings.h" +#include "NCPackageSelector.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgMenuHelp::NCPkgMenuHelp (YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMenuButton( parent, label) + , pkg( pkger) +{ + createLayout(); + setFunctionKey( 1 ); +} + +NCPkgMenuHelp::~NCPkgMenuHelp() +{ + +} + +void NCPkgMenuHelp::createLayout() +{ + if ( !pkg->isYouMode()) + { + generalHelp = new YMenuItem( _( "&General Help" ) ); + items.push_back( generalHelp ); + + statusHelp = new YMenuItem( _( "&Package Status and Symbols" ) ); + items.push_back( statusHelp ); + + filterHelp = new YMenuItem( _( "&How to Use the Filters" ) ); + items.push_back( filterHelp ); + + menuHelp = new YMenuItem( _( "&Useful Functions in Menu" ) ); + items.push_back( menuHelp ); + } + else + { + patchHelp = new YMenuItem( _( "&Patch Status and Patch Installation" )); + items.push_back ( patchHelp ); + } + + addItems( items); +} + +bool NCPkgMenuHelp::handleEvent ( const NCursesEvent & event) +{ + if (!event.selection) + return false; + + std::string text = ""; + std::string headline = ""; + + if ( event.selection == generalHelp ) + { + headline = NCPkgStrings::PackageHelp(); + text += NCPkgStrings::HelpPkgGen1(); + text += NCPkgStrings::HelpPkgGen2(); + text += NCPkgStrings::HelpPkgGen3(); + text += NCPkgStrings::HelpPkgGen4(); + text += NCPkgStrings::HelpPkgGen5(); + text += NCPkgStrings::HelpPkgGen6(); + + } + else if ( event.selection == statusHelp ) + { + headline = NCPkgStrings::PackageStatusHelp(); + text += NCPkgStrings::HelpOnStatus1(); + text += NCPkgStrings::HelpOnStatus2(); + text += NCPkgStrings::HelpOnStatus3(); + text += NCPkgStrings::HelpOnStatus4(); + text += NCPkgStrings::HelpOnStatus5(); + } + else if ( event.selection == menuHelp ) + { + headline = NCPkgStrings::PackageMenuHelp(); + text += NCPkgStrings::HelpPkgMenu1(); + text += NCPkgStrings::HelpPkgMenu2(); + text += NCPkgStrings::HelpPkgMenu2_2(); + text += NCPkgStrings::HelpPkgMenu2_3(); + text += NCPkgStrings::HelpPkgMenu3(); + text += NCPkgStrings::HelpPkgMenu4(); + text += NCPkgStrings::HelpPkgMenu5(); + } + else if ( event.selection == filterHelp ) + { + headline = NCPkgStrings::PackageFiltersHelp(); + text += NCPkgStrings::HelpOnFilters1(); + text += NCPkgStrings::HelpOnFilters2(); + text += NCPkgStrings::HelpOnFilters3(); + text += NCPkgStrings::HelpOnFilters4(); + text += NCPkgStrings::HelpOnFilters5(); + } + else if ( event.selection == patchHelp ) + { + headline = NCPkgStrings::YouHelp(); + text += NCPkgStrings::YouHelp1(); + text += NCPkgStrings::YouHelp2(); + text += NCPkgStrings::YouHelp3(); + text += NCPkgStrings::YouHelp4(); + text += NCPkgStrings::YouHelp5(); + } + else + yuiError() << "zatim nic" << endl; + + NCPopupInfo * pkgHelp = new NCPopupInfo( wpos( (NCurses::lines()*8)/100, (NCurses::cols()*18)/100 ), + headline, + text + ); + pkgHelp->setPreferredSize( (NCurses::cols()*65)/100, (NCurses::lines()*85)/100 ); + pkgHelp->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuHelp.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuHelp.h new file mode 100644 index 0000000000000000000000000000000000000000..c083af485d41c60c600e1e88280da8c87e37c9d4 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuHelp.h @@ -0,0 +1,64 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuHelp.cc + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgMenuHelp_h +#define NCPkgMenuHelp_h + +#include + +#include +#include +#include +#include + +#include "NCZypp.h" + + +class NCPackageSelector; + +class NCPkgMenuHelp : public NCMenuButton +{ + NCPkgMenuHelp & operator=( const NCPkgMenuHelp & ); + NCPkgMenuHelp ( const NCPkgMenuHelp & ); + +public: + NCPackageSelector *pkg; + + YItemCollection items; + + YMenuItem *generalHelp; + YMenuItem *statusHelp; + YMenuItem *filterHelp; + YMenuItem *menuHelp; + YMenuItem *patchHelp; + + NCPkgMenuHelp (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuHelp(); + + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuView.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuView.cc new file mode 100644 index 0000000000000000000000000000000000000000..4baaac87d7ef21992f5d4bd56d74a9426f4ced04 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuView.cc @@ -0,0 +1,169 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuView.cc + Author: Hedgehog Painter + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgMenuView.h" +#include "NCPackageSelector.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgMenuView::NCPkgMenuView (YWidget *parent, std::string label, NCPackageSelector *pkger) + : NCMenuButton( parent, label) + , pkg (pkger) +{ + createLayout(); +} + +NCPkgMenuView::~NCPkgMenuView() +{ + +} + +void NCPkgMenuView::createLayout() +{ + if ( !pkg->isYouMode() ) + { + // begin: menu items of the view (package information) menu + // please note: use unique hotkeys until end: + technical = new YMenuItem( _( "&Technical Data" ) ); + description = new YMenuItem( _( "&Package Description" ) ); + versions = new YMenuItem( _( "Package &Versions" ) ); + files = new YMenuItem( _( "&File List" ) ); + // end: menu items of the view menu + deps = new YMenuItem( _( "&Dependencies" ) ); + + items.push_back( technical ); + items.push_back( description ); + items.push_back( versions ); + items.push_back( files ); + items.push_back( deps ); + + addItems( items ); + } + else + { + // menu items of the patch view menu - keep them short and + // use unique hotkeys from begin: to end: + // begin: + patchDescription = new YMenuItem( _( "&Long Description" ) ); + patchPackages = new YMenuItem( _( "&Package List" ) ); + // end: menu items of the view menu + patchPkgVersions = new YMenuItem( _( "&Versions" ) ); + + items.push_back( patchDescription ); + items.push_back( patchPackages ); + items.push_back( patchPkgVersions ); + addItems( items ); + } +} + + +bool NCPkgMenuView::handleEvent ( const NCursesEvent & event) +{ + if ( !event.selection) + return false; + + NCPkgTable *pkgList = pkg->PackageList(); + + if ( pkgList->getNumLines() == 0 ) + { + yuiWarning() << "package list empty" << endl; + return true; + } + + int idx = pkgList->getCurrentItem(); + + ZyppObj pkgPtr = pkgList->getDataPointer( idx ); + ZyppSel slbPtr = pkgList->getSelPointer( idx ); + + if ( !pkgPtr || !slbPtr) + { + yuiWarning() << "no package pointer" << endl; + return true; + } + + // Call the appropriate method from NCPackageSelector for + // the selected menu entry. + // Set the information type of the package list (NCPkgTable) + // acccordingly to to able to show the required information while + // scrolling the list (NCPkgTable::updateList()) + + if ( event.selection == versions ) + { + pkg->showVersionsList(); + pkgList->setVisibleInfo (NCPkgTable::I_Versions); + } + else if ( event.selection == patchPackages ) + { + pkg->showPatchPackages(); + pkgList->setVisibleInfo (NCPkgTable::I_PatchPkgs); + } + else if ( event.selection == patchPkgVersions ) + { + pkg->showPatchPkgVersions(); // opens a popup + pkgList->setVisibleInfo (NCPkgTable::I_PatchPkgs); // info remains patch pkgs + } + else + { + pkg->showInformation(); + + if ( !pkg->InfoText() ) + return false; + + if (event.selection == description) + { + pkg->InfoText()->longDescription( pkgPtr ); + pkgList->setVisibleInfo (NCPkgTable::I_Descr); + } + else if (event.selection == technical ) + { + pkg->InfoText()->technicalData( pkgPtr, slbPtr ); + pkgList->setVisibleInfo (NCPkgTable::I_Technical); + } + else if (event.selection == files ) + { + pkg->InfoText()->fileList( slbPtr ); + pkgList->setVisibleInfo (NCPkgTable::I_Files); + } + else if (event.selection == deps ) + { + pkg->InfoText()->dependencyList( pkgPtr, slbPtr ); + pkgList->setVisibleInfo (NCPkgTable::I_Deps); + } + else if ( event.selection == patchDescription ) + { + pkg->InfoText()->patchDescription( pkgPtr, slbPtr ); + pkgList->setVisibleInfo (NCPkgTable::I_PatchDescr); + } + } + + + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuView.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuView.h new file mode 100644 index 0000000000000000000000000000000000000000..addb0c6ba9528d0e6e4d4df7552c1f24c83a01bd --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgMenuView.h @@ -0,0 +1,72 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgMenuView.cc + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgMenuView_h +#define NCPkgMenuView_h + +#include + +#include +#include + +#include +#include +#include + +#include "NCZypp.h" + +class NCPackageSelector; + +class NCPkgMenuView : public NCMenuButton +{ + NCPkgMenuView & operator=( const NCPkgMenuView & ); + NCPkgMenuView ( const NCPkgMenuView & ); + +private: + NCPackageSelector *pkg; + +public: + + YItemCollection items; + + YMenuItem *description; + YMenuItem *technical; + YMenuItem *versions; + YMenuItem *files; + YMenuItem *deps; + + // Online Update + YMenuItem * patchDescription; + YMenuItem * patchPackages; + YMenuItem * patchPkgVersions; + + NCPkgMenuView (YWidget *parent, std::string label, NCPackageSelector *pkger); + virtual ~NCPkgMenuView(); + + void createLayout(); + + bool handleEvent (const NCursesEvent & event); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPackageDetails.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPackageDetails.cc new file mode 100644 index 0000000000000000000000000000000000000000..1ea8d7845c6a8fc2ebf921a19876f543ea5b21c3 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPackageDetails.cc @@ -0,0 +1,427 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPackageDetails.cc + +*/ + + +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgTable.h" +#include "NCPkgPackageDetails.h" +#include "NCPackageSelector.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgPackageDetails::NCPkgPackageDetails ( YWidget *parent, std::string initial_text, NCPackageSelector *pkger) + : NCRichText (parent, initial_text) + , pkg (pkger) +{ + +} + +std::string NCPkgPackageDetails::createRelLine( const zypp::Capabilities & info ) +{ + std::string text = ""; + zypp::Capabilities::const_iterator + b = info.begin(), + e = info.end(), + it; + unsigned int i, n = info.size(); + + for ( it = b, i = 0; it != e; ++it, ++i ) + { + text = text + (*it).asString(); + if ( i < n - 1 ) + { + text = text + ", "; + } + } + + return text; +} + +std::string NCPkgPackageDetails::createText( std::list info, bool oneline ) +{ + std::list::iterator it; + std::string text = ""; + unsigned int i; + + for ( i = 0, it = info.begin(); it != info.end() && i < 1000; ++it, i++ ) + { + text += (*it); + if ( i < info.size()-1 ) + { + if ( oneline && i < 999 ) + { + if ( boost::ends_with( text, ":" ) ) + text += " "; + else + text += ", "; + } + else + { + text += "
"; + } + } + if ( i == 999 ) + { + text += "..."; + } + } + + return text; +} + +std::string NCPkgPackageDetails::commonHeader( ZyppObj pkgPtr ) +{ + std::string text = ""; + + if ( !pkgPtr ) + return text; + + text += "

" + pkgPtr->name() + " - "; + text += pkgPtr->summary() + "

"; + + return text; +} + +void NCPkgPackageDetails::longDescription ( ZyppObj pkgPtr ) +{ + std::string text = ""; + + if ( !pkgPtr ) + return; + + // text += commonHeader( pkgPtr ); + text += pkgPtr->description(); + + // show the description + setValue( createHtmlText(text) ); +} + +void NCPkgPackageDetails::technicalData( ZyppObj pkgPtr, ZyppSel slbPtr ) +{ + std::string instVersion = ""; + std::string version = ""; + std::string text = ""; + + if ( !pkgPtr || !slbPtr ) + return; + + text += commonHeader( pkgPtr ); + + if ( slbPtr->hasBothObjects() ) + { + ZyppObj io = slbPtr->installedObj(); + instVersion = io->edition().version(); + instVersion += "-"; + instVersion += io->edition().release(); + ZyppObj co = slbPtr->candidateObj(); + version = co->edition().version(); + version += "-"; + version += co->edition().release(); + } + else + { + version = pkgPtr->edition().version(); + version += "-"; + version += pkgPtr->edition().release(); + } + + text += NCPkgStrings::Version(); + text += version; + if ( instVersion != "" ) + { + text += " "; + text += NCPkgStrings::InstVersion(); + text += instVersion; + } + text += "
"; + + // show the size + text += NCPkgStrings::Size(); + text += pkgPtr->installSize().asString(); + text += " "; + + ZyppPkg package = tryCastToZyppPkg( pkgPtr ); + ZyppPkg candidate = tryCastToZyppPkg( slbPtr->candidateObj() ); + ZyppPkg installed = tryCastToZyppPkg( slbPtr->installedObj() ); + + if ( installed ) + package = installed; + else if ( candidate ) + package = candidate; + + if ( package ) + { + // add the media nr + text += NCPkgStrings::MediaNo(); + char num[5]; + int medianr = package->mediaNr(); + sprintf( num, "%d", medianr ); + text += num; + text += "
"; + + // the license + text += NCPkgStrings::License(); + text += package->license(); + text += " "; + text += "
"; + + // name of the source package + text += "" + _( "Source Package: " ) + ""; + text += package->sourcePkgName(); + text += "-"; + text += package->sourcePkgEdition().asString(); + text += "
"; + + std::list authors = package->authors(); // zypp::Package + if ( !authors.empty() ) + { + std::string author_text; + text += NCPkgStrings::Authors(); + // authors, in one line + author_text = createText( authors, true ); + // escape html + boost::replace_all( author_text, "<", "<" ); + boost::replace_all( author_text, ">", ">" ); + text += author_text; + } + } + + setValue (text); + +} + +void NCPkgPackageDetails::fileList( ZyppSel slbPtr ) +{ + std::string text = ""; + // the file list is available only for installed packages + ZyppPkg package = tryCastToZyppPkg (slbPtr->installedObj()); + + if ( package ) + { + text += commonHeader( slbPtr->theObj() ); + text += NCPkgStrings::ListOfFiles(); + // get the file list from the package manager/show the list + zypp::Package::FileList pkgfilelist( package->filelist() ); + std::list fileList( pkgfilelist.begin(), pkgfilelist.end() ); + text += createText( fileList, false ); + } + + else + text = _( "This information is available for installed packages only." ); + + setValue(text); +} + +void NCPkgPackageDetails::dependencyList( ZyppObj pkgPtr, ZyppSel slbPtr ) +{ + std::string text = commonHeader( pkgPtr ); + // show the relations, all of them except provides which is above + zypp::Dep deptypes[] = { + zypp::Dep::PROVIDES, + zypp::Dep::PREREQUIRES, + zypp::Dep::REQUIRES, + zypp::Dep::CONFLICTS, + zypp::Dep::OBSOLETES, + zypp::Dep::RECOMMENDS, + zypp::Dep::SUGGESTS, + zypp::Dep::ENHANCES, + zypp::Dep::SUPPLEMENTS, + }; + for (size_t i = 0; i < sizeof (deptypes)/sizeof(deptypes[0]); ++i) + { + zypp::Dep deptype = deptypes[i]; + zypp::Capabilities relations = pkgPtr->dep (deptype); + std::string relline = createRelLine (relations); + if (!relline.empty()) + { + // FIXME: translate + text += "" + deptype.asString() + ": " + + relline + "
"; + } + } + + setValue (text); + +} + +std::string NCPkgPackageDetails::createHtmlText( std::string value ) +{ + yuiDebug() << "Description: " << value << endl; + + // check RichText tag + if ( value.find( std::string(DOCTYPETAG) ) != std::string::npos ) + { + return value; // input is rich text + } + // escape html + boost::replace_all( value, "&", "&" ); + boost::replace_all( value, "<", "<" ); + boost::replace_all( value, ">", ">" ); + + NCstring input( value ); + NCtext descr( input ); + NCtext html_descr( NCstring("

") ); + std::string description = ""; + bool ul_begin = false; + bool ul_found = false; + std::list::const_iterator line; + + for ( line = descr.Text().begin(); line != descr.Text().end(); ++line ) + { + NCstring curr_line( *line ); + + if ( curr_line.Str().empty() ) + { + if ( ul_found ) // empty line after list + { + html_descr.append( NCstring("

") ); + ul_found = false; + ul_begin = false; + } + else + { + html_descr.append( NCstring("

") ); + } + } + else if ( curr_line.Str().substr(0, 2) == "- " + || curr_line.Str().substr(0, 2) == "* ") // list item found + { + ul_found = true; + if ( !ul_begin ) + { + html_descr.append( NCstring("

  • ") ); + ul_begin = true; + } + else + { + html_descr.append( NCstring("
  • ") ); + } + html_descr.append( NCstring(curr_line.Str().substr(2)) ); + } + else if ( curr_line.Str().substr(0, 2) == " " ) // white spaces at begin + { + // just append the line (is added to list item or to paragraph) + html_descr.append( NCstring( curr_line.Str() ) ); + } + else + { + if ( ul_found ) // first line after list + { + html_descr.append( NCstring("

") ); + ul_found = false; + ul_begin = false; + } + html_descr.append( NCstring(" " + curr_line.Str()) ); + } + } + + if ( ul_found ) + html_descr.append( NCstring("") ); + else + html_descr.append( NCstring("

") ); + + // create description + for ( line = html_descr.Text().begin(); line != html_descr.Text().end(); ++line ) + { + NCstring curr_line( *line ); + description += curr_line.Str(); + } + // reduce number of empty lines + boost::replace_all( description, "

", "

" ); + + return description; +} + +bool NCPkgPackageDetails::patchDescription( ZyppObj objPtr, ZyppSel selectable ) +{ + ZyppPatch patchPtr = tryCastToZyppPatch( objPtr ); + + if ( !patchPtr || !selectable ) + { + yuiError() << "Patch not valid" << endl; + return false; + } + + std::string descr; + descr += "

"; + descr += NCPkgStrings::Patch(); + descr += selectable->name(); + descr += " "; + // the patch size is not available + // descr += NCPkgStrings::Size(); + // descr += patchPtr->size().asString( 8 ); + descr += ""; + descr += NCPkgStrings::PatchKind(); + descr += ": "; + descr += patchPtr->category(); + descr += " "; + descr += NCPkgStrings::Version(); + descr += patchPtr->edition().asString(); + descr += "

"; + + // get and format the patch description + std::string value = patchPtr->description(); + std::string html_text = ""; + const std::string htmlIdent(DOCTYPETAG); + + if ( value.find( htmlIdent ) != std::string::npos ) + { + html_text = value; // HTML text + } + else + { + // escape html + boost::replace_all( value, "&", "&" ); + boost::replace_all( value, "<", "<" ); + boost::replace_all( value, ">", ">" ); + html_text = "
" + value + "
"; // add
 to preserve newlines and spaces
+    }
+
+    descr += html_text;
+
+    descr +=  _( "References:
" ); + for ( zypp::Patch::ReferenceIterator rit = patchPtr->referencesBegin(); + rit != patchPtr->referencesEnd(); + ++rit ) + { + descr += rit.id().c_str(); + descr += " "; + descr += "("; + descr += rit.type().c_str(); + descr += "):"; + descr += " "; + descr += rit.title().c_str(); + descr += "
"; + } + // show the description + setValue( descr ); + + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPackageDetails.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPackageDetails.h new file mode 100644 index 0000000000000000000000000000000000000000..a1a2d057b9294779e2772e7cfdb2c474dcbfe67e --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPackageDetails.h @@ -0,0 +1,64 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPackageDetails.h + +*/ + + +#ifndef NCPkgPackageDetails_h +#define NCPkgPackageDetails_h + +#include + +#include "NCZypp.h" + + +class NCPackageSelector; + + +class NCPkgPackageDetails : public NCRichText +{ + NCPkgPackageDetails & operator=( const NCPkgPackageDetails & ); + NCPkgPackageDetails ( const NCPkgPackageDetails & ); + +private: + NCPackageSelector *pkg; + +public: + + NCPkgPackageDetails( YWidget *parent, std::string initial_text, NCPackageSelector * pkger ); + + std::string createText( std::list info, bool oneline ); + + std::string createHtmlText( std::string description ); + + std::string createRelLine( const zypp::Capabilities & info ); + + std::string commonHeader( ZyppObj pkgPtr ); + + void longDescription( ZyppObj pkgPtr ); + + void technicalData( ZyppObj pkgPtr, ZyppSel slbPtr ); + + void fileList (ZyppSel slbPtr); + + void dependencyList( ZyppObj objPtr, ZyppSel slbPtr ); + + bool patchDescription( ZyppObj objPtr, ZyppSel selectable ); +}; +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPatchSearch.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPatchSearch.cc new file mode 100644 index 0000000000000000000000000000000000000000..5f2158c7e5e99537d5a3f0322e0b99bbb9d0b787 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPatchSearch.cc @@ -0,0 +1,256 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPatchSearch.cc + Author: Gabriele Strattner + +*/ + + +#include +#include + +#include +#include +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCPackageSelector.h" + +#include "NCPkgPatchSearch.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::NCPkgPatchSearch +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgPatchSearch::NCPkgPatchSearch( const wpos at, NCPackageSelector * pkger ) + : NCPopup( at, false ) + , searchExpr( 0 ) + , packager( pkger ) +{ + createLayout( _( "Search for Patches" ) ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::~NCPkgPatchSearch +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgPatchSearch::~NCPkgPatchSearch() +{ +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::createLayout +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgPatchSearch::createLayout( const std::string & headline ) +{ + // vertical split is the (only) child of the dialog + NCLayoutBox * vSplit = new NCLayoutBox( this, YD_VERT ); + + new NCSpacing( vSplit, YD_VERT, false, 0.8 ); // stretchable = false + + new NCLabel( vSplit, headline, true, false ); // isHeading = true + + new NCSpacing( vSplit, YD_VERT, false, 0.6 ); + + NCFrame * frame0 = new NCFrame( vSplit, "" ); + + // add the input field (a editable combo box) + searchExpr = new NCComboBox( frame0, + NCPkgStrings::SearchPhrase(), + true ); // editable = true + + searchExpr->setStretchable( YD_HORIZ, true ); + + searchExpr->addItem( new YTableItem() ); + + new NCSpacing( vSplit, YD_VERT, false, 0.6 ); + + NCMultiSelectionBox * settings = new NCMultiSelectionBox( vSplit, NCPkgStrings::SearchIn() ); + YItemCollection items; + searchName = new YItem ( _( "Name of the Patch" ), true); + items.push_back( searchName ); + searchSum = new YItem ( _( "Summary" ), true); + items.push_back( searchSum ); + settings->addItems( items ); + + new NCSpacing( vSplit, YD_VERT, false, 0.6 ); + NCLayoutBox * hSplit3 = new NCLayoutBox( vSplit, YD_HORIZ ); + new NCSpacing( hSplit3, YD_HORIZ, true, 0.2 ); + + // add the cancel and the ok button + okButton = new NCPushButton( hSplit3, NCPkgStrings::OKLabel() ); + okButton->setFunctionKey( 10 ); + + new NCSpacing( hSplit3, YD_HORIZ, true, 0.4 ); + + cancelButton = new NCPushButton( hSplit3, NCPkgStrings::CancelLabel() ); + cancelButton->setFunctionKey( 9 ); + + new NCSpacing( hSplit3, YD_HORIZ, true, 0.2 ); + new NCSpacing( vSplit, YD_VERT, false, 0.6 ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::showSearchPopup +// METHOD TYPE : void +// +// DESCRIPTION : +// +NCursesEvent & NCPkgPatchSearch::showSearchPopup() +{ + postevent = NCursesEvent(); + do + { + popupDialog(); + if ( searchExpr ) + { + searchExpr->setKeyboardFocus(); + } + } while ( postAgain() ); + + popdownDialog(); + + return postevent; +} + +/////////////////////////////////////////////////////////////////// +// +// DESCRIPTION : +// +std::string NCPkgPatchSearch::getSearchExpression() const +{ + std::string value; + + if ( searchExpr ) + { + // get the expression and store it in combo box list + // value = searchExpr->getValue(); + + value = searchExpr->text(); + searchExpr->getListSize(); + + searchExpr->addItem( value, true ); + } + + return value; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::preferredWidth +// METHOD TYPE : int +// +int NCPkgPatchSearch::preferredWidth() +{ + return NCurses::cols()/2; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::preferredHeight +// METHOD TYPE : int +// +int NCPkgPatchSearch::preferredHeight() +{ + return 16; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopup::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCPkgPatchSearch::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + // start package search if Return is pressed + if ( ch == KEY_RETURN ) + return NCursesEvent::button; + + return NCDialog::wHandleInput( ch ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPatchSearch::postAgain +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgPatchSearch::postAgain() +{ + if ( ! postevent.widget ) + return false; + + postevent.result = ""; + + if ( postevent.widget == cancelButton ) + { + postevent = NCursesEvent::cancel; + } + else if ( postevent == NCursesEvent::button ) + { + // get the search expression + postevent.result = getSearchExpression(); + + std::string filter = postevent.result; + bool checkName = searchName->selected(); + bool checkSum = searchSum->selected(); + packager->fillPatchSearchList( filter, checkName, checkSum ); + + } + + if ( postevent == NCursesEvent::button || postevent == NCursesEvent::cancel ) + { + // return false means: close the popup dialog + return false; + } + return true; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPatchSearch.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPatchSearch.h new file mode 100644 index 0000000000000000000000000000000000000000..5beaa749a047b209737914639974bc178a39f35d --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPatchSearch.h @@ -0,0 +1,89 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPatchSearch.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgPatchSearch_h +#define NCPkgPatchSearch_h + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +class NCPackageSelector; + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgPatchSearch +// +// DESCRIPTION : +// +class NCPkgPatchSearch : public NCPopup +{ + NCPkgPatchSearch & operator=( const NCPkgPatchSearch & ); + NCPkgPatchSearch ( const NCPkgPatchSearch & ); + +private: + + NCComboBox * searchExpr; + + YItem * searchName; + YItem * searchSum; + + NCPushButton * cancelButton; + NCPushButton * okButton; + + NCPackageSelector * packager; // connection to the package selector + +protected: + + std::string getSearchExpression() const; + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCPkgPatchSearch( const wpos at, NCPackageSelector *pkger ); + virtual ~NCPkgPatchSearch(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + void createLayout( const std::string & headline ); + + NCursesEvent & showSearchPopup(); + +}; + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgPatchSearch_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDeps.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDeps.cc new file mode 100644 index 0000000000000000000000000000000000000000..1fc41722beffabdbea838573ad63711e875d4edb --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDeps.cc @@ -0,0 +1,624 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupDeps.cc + + Authors: Gabriele Strattner + Bubli + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCPkgPopupDeps.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +class NCProblemSelectionBox : public NCSelectionBox +{ + typedef NCProblemSelectionBox Self; + NCProblemSelectionBox (const Self &); // prohibit copying + Self & operator= (const Self &); // prohibit assignment + + NCPkgPopupDeps * depsPopup; // to notify about changes + +protected: + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + NCProblemSelectionBox (YWidget * parent, const std::string & label, + NCPkgPopupDeps * aDepsPopup) + : NCSelectionBox( parent, label), + depsPopup( aDepsPopup ) + {} + + virtual ~NCProblemSelectionBox() {} +}; + +class NCSolutionSelectionBox : public NCMultiSelectionBox +{ + typedef NCSolutionSelectionBox Self; + NCSolutionSelectionBox (const Self &); // prohibit copying + Self & operator= (const Self &); // prohibit assignment + + NCPkgPopupDeps * depsPopup; + std::map detailsMap; + +protected: + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + NCSolutionSelectionBox (YWidget * parent, const std::string & label, + NCPkgPopupDeps * aDepsPopup) + : NCMultiSelectionBox( parent, label) + , depsPopup( aDepsPopup ) + {} + + virtual ~NCSolutionSelectionBox() {} + + void saveDetails( YItem * item, std::string details ) + { + detailsMap[item] = details; + } +}; + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::NCPkgPopupDeps +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgPopupDeps::NCPkgPopupDeps( const wpos at, NCPackageSelector * pkger ) + : NCPopup( at, false ) + , cancelButton( 0 ) + , solveButton( 0 ) + , solutionw( 0 ) + , head( 0 ) + , details( 0 ) + , solDetails( 0 ) + , packager( pkger ) + , problemw( 0 ) + +{ + createLayout(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::~NCPkgPopupDeps +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgPopupDeps::~NCPkgPopupDeps() +{ +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopupSelDeps::createLayout +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgPopupDeps::createLayout() +{ + + // vertical split is the (only) child of the dialog + NCLayoutBox * vSplit = new NCLayoutBox( this, YD_VERT ); + + vSplit->setNotify( true ); + + new NCSpacing( vSplit, YD_VERT, false, 1 ); + + head = new NCLabel( vSplit, "", true ); // isHeading = true + + // only add spacings if there's enough space + if ( this->preferredHeight() > 25 ) + new NCSpacing( vSplit, YD_VERT, false, 1 ); + + NCAlignment * left = new NCAlignment( vSplit, YAlignBegin, YAlignUnchanged ); + left->setWeight(YD_VERT, 30 ); + + // the list containing the problems (the unresolved package dependencies) + problemw = new NCProblemSelectionBox( left, _( "&Problems" ), this); + problemw->setStretchable( YD_HORIZ, true ); + + NCAlignment * left1 = new NCAlignment( vSplit, YAlignBegin, YAlignUnchanged ); + left1->setWeight(YD_VERT, 10 ); + + // show the details of the problem + details = new NCLabel ( left1, "", false, true ); // heading = false, + details->setStretchable( YD_HORIZ, true ); // outputField = true + + if ( this->preferredHeight() > 25 ) + new NCSpacing( vSplit, YD_VERT, false, 0.5 ); // stretchable = false + + NCAlignment * left2 = new NCAlignment( vSplit, YAlignBegin, YAlignUnchanged ); + left2->setWeight( YD_VERT, 30 ); + + // the list containing the solutions of a dependency problem + solutionw = new NCSolutionSelectionBox ( left2, _( "Possible &Solutions" ), this); + + if ( this->preferredHeight() > 25 ) + new NCSpacing( vSplit, YD_VERT, false, 1 ); + + NCAlignment * left3 = new NCAlignment( vSplit, YAlignBegin, YAlignUnchanged ); + left3->setWeight( YD_VERT, 30 ); + + // show the details of the solution + solDetails = new NCRichText ( left3, "", true ); // plain text mode = true + + if ( this->preferredHeight() > 25 ) + new NCSpacing( vSplit, YD_VERT, false, 1 ); // stretchable = false + + NCLayoutBox * hSplit = new NCLayoutBox( vSplit, YD_HORIZ ); + + // add the solve button + solveButton = new NCPushButton( hSplit, NCPkgStrings::SolveLabel() ); + solveButton->setFunctionKey( 10 ); + + new NCSpacing( hSplit, YD_HORIZ, true, 0.2 ); // stretchable = true + + // add the cancel button + cancelButton = new NCPushButton( hSplit, NCPkgStrings::CancelLabel() ); + cancelButton->setFunctionKey( 9 ); + + if ( this->preferredHeight() > 25 ) + new NCSpacing( vSplit, YD_VERT, false, 0.5 ); // stretchable = false +} + +/////////////////////////////////////////////////////////////////// +// +// showDependencies +// +// +bool NCPkgPopupDeps::showDependencies( NCPkgSolverAction action, bool * ok ) +{ + if ( !problemw ) + return true; + + bool cancel = false; + + // set headline and table type + if ( head ) + head->setLabel( NCPkgStrings::PackageDeps() ); + + // evaluate the result and fill the list with packages + // which have unresolved deps + bool success = solve (problemw, action ); + *ok = success; + + if (!success) + { + // show first dependency + showSolutions( problemw->getCurrentItem() ); + NCursesEvent input = showDependencyPopup( action ); // show the dependencies + + if ( input == NCursesEvent::cancel + && input.detail != NCursesEvent::USERDEF ) + { + cancel = true; + } + problemw->setKeyboardFocus(); + } + + return cancel; +} + + +bool NCPkgPopupDeps::solve( NCSelectionBox * problemw, NCPkgSolverAction action ) +{ + if ( !problemw ) + return false; + + yuiDebug() << "Solving..." << endl; + + NCPopupInfo * info = new NCPopupInfo( wpos( (NCurses::lines()-4)/2, (NCurses::cols()-18)/2 ), + "", + NCPkgStrings::Solving(), + NCPkgStrings::OKLabel() + ); + info->setPreferredSize( 18, 4 ); + info->popup(); + + zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver(); + + bool success = false; + switch ( action ) + { + case S_Solve: + success = resolver->resolvePool(); + break; + case S_Verify: + success = resolver->verifySystem(); // check hardware + break; + default: + yuiError() << "Unknown action for resolve" << endl; + } + + info->popdown(); + + YDialog::deleteTopmostDialog(); + + if (success) + return true; + + // clear list + problems.clear(); + problemw->deleteAllItems(); + + zypp::ResolverProblemList rproblems = resolver->problems(); + zypp::ResolverProblemList::iterator + b = rproblems.begin(), + e = rproblems.end(), + i; + int idx; + + for (i = b, idx = 0; i != e; ++i, ++idx) + { + yuiMilestone() << "Problem: " << (*i)->description() << endl; + yuiMilestone() << "Details: " << (*i)->details() << endl; + + // no solution yet + problems.push_back (std::make_pair (*i, zypp::ProblemSolution_Ptr())); + + problemw->addItem( (*i)->description(), false ); // selected: false + } + + return false; +} + +bool NCPkgPopupDeps::showSolutions( int index ) +{ + if (!solutionw) + return false; + + unsigned int size = problems.size(); + + if ( index < 0 || (unsigned int)index >= size ) + return false; + + solutionw->startMultipleChanges(); + solutionw->deleteAllItems(); + + zypp::ResolverProblem_Ptr problem = problems[index].first; + zypp::ProblemSolution_Ptr user_solution = problems[index].second; + + details->setText( problem->details() ); + + zypp::ProblemSolutionList solutions = problem->solutions(); + zypp::ProblemSolutionList::iterator + bb = solutions.begin(), + ee = solutions.end(), + ii; + + bool showDetails = true;; + std::string description; + + for ( ii = bb; ii != ee; ++ii) + { + yuiMilestone() << "Solution: " << (*ii)->description() << endl; + yuiMilestone() << "Details: " << (*ii)->details() << endl; + yuiMilestone() << "User decision: " << user_solution << endl; + + description = (*ii)->description(); + + if ( !((*ii)->details().empty()) ) + // hint for the user: more information below + description += _( " see below" ); + + if ( showDetails ) + { + showSolutionDetails( (*ii)->details() ); // show details of 1. solution + showDetails = false; + } + + YItem *newItem = new YItem ( description, // text + (user_solution == *ii) ); // selected ? + + solutionw->addItem( newItem ); + solutionw->saveDetails( newItem, (*ii)->details() ); + + yuiDebug() << "Solution: " << (*ii) << endl; // Complete info + } + + solutionw->doneMultipleChanges(); + + return true; +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::showDependencyPopup +// METHOD TYPE : void +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupDeps::showDependencyPopup( NCPkgSolverAction action ) +{ + postevent = NCursesEvent(); + + do + { + popupDialog(); + } while ( postAgain( action ) ); + + popdownDialog(); + + return postevent; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::preferredWidth +// METHOD TYPE : int +// +// DESCRIPTION : +// +int NCPkgPopupDeps::preferredWidth() +{ + return NCurses::cols()-8; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::preferredHeight +// METHOD TYPE : int +// +// DESCRIPTION : +// +int NCPkgPopupDeps::preferredHeight() +{ + return NCurses::lines()-5; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopup::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupDeps::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + return NCDialog::wHandleInput( ch ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::postAgain +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgPopupDeps::postAgain( NCPkgSolverAction action ) +{ + if ( ! postevent.widget ) + return false; + + if ( postevent.widget == cancelButton ) + { + // close the dialog + postevent = NCursesEvent::cancel; + } + else if ( postevent.widget == solveButton ) + { + // apply the solution here + zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver(); + ProblemSolutionCorrespondence::iterator + b = problems.begin(), + e = problems.end(), + i; + zypp::ProblemSolutionList solutions; + for (i = b; i != e; ++i) + { + // *i is std::pair< zypp::ResolverProblem_Ptr, + // zypp::ProblemSolution_Ptr > + if (i->second) + { + solutions.push_back (i->second); + } + } + resolver->applySolutions (solutions); + + // and solve again + bool success = solve (problemw, action ); + + if ( !success ) + { + problemw->setKeyboardFocus(); + showSolutions( problemw->getCurrentItem() ); + } + else // everything ok + { + // close the dialog + postevent = NCursesEvent::cancel; + } + } + + if ( postevent == NCursesEvent::cancel ) + { + // return false means: close the popup dialog + return false; + } + return true; +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDeps::setSolution +// METHOD TYPE : bool +// +// DESCRIPTION : +// +void NCPkgPopupDeps::setSolution (int index) +{ + // we must search the list :( bad design here + // but the solution list is short + int prob_num = problemw->getCurrentItem(); + zypp::ResolverProblem_Ptr problem = problems[prob_num].first; + zypp::ProblemSolution_Ptr sol = zypp::ProblemSolution_Ptr(); + + zypp::ProblemSolutionList solutions = problem->solutions(); + zypp::ProblemSolutionList::iterator + bb = solutions.begin(), + ee = solutions.end(), + ii; + int idx; + + for (ii = bb, idx = 0; ii != ee && idx < index; ++ii, ++idx) + { + // empty + } + + if (ii != ee) + sol = *ii; + + problems[prob_num] = std::make_pair (problem, sol); +} + +void NCPkgPopupDeps::showSolutionDetails( std::string details ) +{ + std::string text; + if ( details.empty() ) + // hint for the user: there isn't any additional information + // (for the currently selected solution of a dependency problem) + text = _( "No further solution details available" ); + else + text = details; + + if ( solDetails ) + solDetails->setText( text ); + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCProblemSelectionBox::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCProblemSelectionBox::wHandleInput( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + + // call handleInput of NCPad + handleInput( key ); + + switch ( key ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + // show the corresponding information + depsPopup->showSolutions (getCurrentItem()); + ret = NCursesEvent::handled; + break; + + default: + break; + } + + return ret; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCSolutionSelectionBox::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCSolutionSelectionBox::wHandleInput( wint_t key ) +{ + NCursesEvent ret = NCMultiSelectionBox::wHandleInput( key ); + + switch ( key ) + { + case KEY_SPACE: + case KEY_RETURN: + { + // act like a radio button + // make sure that only one item is selected + YItem *cur = currentItem(); + bool on = isItemSelected( cur ); + if (on) + { + deselectAllItems(); + selectItem (cur, true); + depsPopup->setSolution ( cur->index() ); + } + break; + } + + case KEY_UP: + case KEY_DOWN: + // show details + depsPopup->showSolutionDetails( detailsMap[currentItem()] ); + break; + + default: + break; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDeps.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDeps.h new file mode 100644 index 0000000000000000000000000000000000000000..5317e75b9c7acb999a2d8c6e9bb707c5a5c56f95 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDeps.h @@ -0,0 +1,125 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupDeps.h + + Authors: Gabriele Strattner + Bubli + +*/ + + +#ifndef NCPkgPopupDeps_h +#define NCPkgPopupDeps_h + +#include +#include +#include + +#include + +#include +#include + +#include "NCZypp.h" + + +class NCPushButton; +class NCSelectionBox; +class NCPackageSelector; +class NCRichText; +class NCSolutionSelectionBox; + + +namespace PkgDep +{ + class ErrorResult; + class ErrorResultList; + class ResultList; +}; + + +class NCPkgPopupDeps : public NCPopup +{ + NCPkgPopupDeps & operator=( const NCPkgPopupDeps & ); + NCPkgPopupDeps ( const NCPkgPopupDeps & ); + +public: + enum NCPkgSolverAction + { + S_Solve, + S_Verify, + S_Unknown + }; + +private: + + typedef std::vector > ProblemSolutionCorrespondence; + // indexed by widget position, + // keeps the user selected solution (or 0) for each problem + ProblemSolutionCorrespondence problems; + + NCPushButton * cancelButton; + NCPushButton * solveButton; + + NCSolutionSelectionBox * solutionw; // resolver problem solutions + + NCLabel * head; // the headline + + NCLabel *details; // problem details + NCRichText *solDetails; // solution details + + NCPackageSelector * packager; // connection to the package selector + + void createLayout(); + +protected: + + NCSelectionBox * problemw; // resolver problems + + virtual bool postAgain( NCPkgSolverAction action ); + using NCPopup::postAgain; // unhide overriden base method + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCPkgPopupDeps( const wpos at, NCPackageSelector * pkger ); + virtual ~NCPkgPopupDeps(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + NCursesEvent showDependencyPopup( NCPkgSolverAction action ); + + bool showDependencies( NCPkgSolverAction action, bool * ok ); + + bool solve( NCSelectionBox * problemw, NCPkgSolverAction action ); + + bool showSolutions( int index ); + // for the currently selected problem, choose this solution + void setSolution (int index); + // show details + void showSolutionDetails( std::string details ); +}; + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgPopupDeps_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDescr.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDescr.cc new file mode 100644 index 0000000000000000000000000000000000000000..33dc5e925b583bd7f9fde0ed510cae8f8eba9812 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDescr.cc @@ -0,0 +1,228 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupDescr.cc + Author: Gabriele Strattner + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCPkgStrings.h" +#include "NCPkgTable.h" +#include "NCZypp.h" +#include "NCPkgPopupDescr.h" + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::NCPkgPopupDescr +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgPopupDescr::NCPkgPopupDescr( const wpos at, NCPackageSelector * pkger ) + : NCPopup( at, false ) + , pkgTable( 0 ) + , okButton( 0 ) + , headline( 0 ) + , packager( pkger ) +{ + createLayout(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::~NCPkgPopupDescr +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgPopupDescr::~NCPkgPopupDescr() +{ +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::createLayout +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgPopupDescr::createLayout() +{ + // the vertical split is the (only) child of the dialog + NCLayoutBox * split = new NCLayoutBox( this, YD_VERT ); + + new NCSpacing( split, YD_VERT, false, 0.8 ); // stretchable = false + + headline = new NCLabel( split, "", true, false ); // isHeading = true + new NCSpacing( split, YD_VERT, false, 0.4 ); + + // add the rich text widget for the package description + descrText = new NCRichText( split, "" ); + + new NCSpacing( split, YD_VERT, true, 0.6 ); // stretchable = true + + YTableHeader * tableHeader = new YTableHeader(); + + // add the package table (use default type T_Packages) + pkgTable = new NCPkgTable( split, tableHeader ); + pkgTable->setPackager( packager ); + pkgTable->fillHeader(); + + new NCSpacing( split, YD_VERT, true, 0.6 ); + + // a help line for the dependency popup + new NCLabel( split, _( " [+] Select [-] Delete [>] Update " ), false, false ); + + new NCSpacing( split, YD_VERT, false, 0.6 ); // stretchable = false + + // add the OK button + okButton = new NCPushButton( split, NCPkgStrings::OKLabel() ); + okButton->setFunctionKey( 10 ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::fillData +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgPopupDescr::fillData( ZyppPkg pkgPtr, ZyppSel slbPtr ) +{ + if ( !pkgPtr ) + return false; + + pkgTable->itemsCleared(); // clear the table + + pkgTable->createListEntry( pkgPtr, slbPtr ); + + pkgTable->drawList(); + + headline->setLabel( pkgPtr->summary() ); + + descrText->setText( pkgPtr->description() ); + + return true; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::showInfoPopup +// METHOD TYPE : NCursesEvent event +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupDescr::showInfoPopup( ZyppPkg pkgPtr, ZyppSel slbPtr ) +{ + postevent = NCursesEvent(); + + fillData( pkgPtr, slbPtr ); + + do + { + // show the popup + popupDialog(); + } while ( postAgain() ); + + popdownDialog(); + + return postevent; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::niceSize +// METHOD TYPE : void +// +// DESCRIPTION : +// + +long NCPkgPopupDescr::nicesize(YUIDimension dim) +{ + long vdim; + if ( NCurses::lines() > 17 ) + vdim = 17; + else + vdim = NCurses::lines()-4; + + return ( dim == YD_HORIZ ? NCurses::cols()*2/3 : vdim ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopup::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupDescr::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + if ( ch == KEY_RETURN ) + return NCursesEvent::button; + + return NCDialog::wHandleInput( ch ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDescr::postAgain +// METHOD TYPE : bool +// +// DESCRIPTION : +// x +bool NCPkgPopupDescr::postAgain() +{ + if ( ! postevent.widget ) + return false; + + if ( postevent == NCursesEvent::button || postevent == NCursesEvent::cancel ) + { + // return false means: close the popup dialog + return false; + } + return true; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDescr.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDescr.h new file mode 100644 index 0000000000000000000000000000000000000000..ca088b5a86d942bc9d60bf41dc9b0b3b26fdb6ed --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDescr.h @@ -0,0 +1,84 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupDescr.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgPopupDescr_h +#define NCPkgPopupDescr_h + +#include + +#include +#include + +#include + +class NCPkgTable; +class NCPushButton; +class NCRichText; + + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgPopupDescr +// +// DESCRIPTION : +// +class NCPkgPopupDescr : public NCPopup +{ + NCPkgPopupDescr & operator=( const NCPkgPopupDescr & ); + NCPkgPopupDescr ( const NCPkgPopupDescr & ); + +private: + + NCPkgTable * pkgTable; + NCPushButton * okButton; + NCRichText *descrText; + NCLabel *headline; + + NCPackageSelector * packager; + +protected: + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCPkgPopupDescr( const wpos at, NCPackageSelector * pkger ); + + virtual ~NCPkgPopupDescr(); + + virtual long nicesize(YUIDimension dim); + + bool fillData( ZyppPkg pkgPtr, ZyppSel slbPtr ); + + void createLayout(); + + NCursesEvent showInfoPopup( ZyppPkg pkgPtr, ZyppSel slbPtr ); + +}; + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgPopupDescr_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDiskspace.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDiskspace.cc new file mode 100644 index 0000000000000000000000000000000000000000..a64d78ff6ca3ed74f6ab8e5dc1601adf066a4366 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDiskspace.cc @@ -0,0 +1,650 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2018-2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupDiskspace.cc + Author: Gabriele Strattner + +*/ + + +// zypp::str::form() +#include + +// arbitrary precision integer +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCZypp.h" +#include "NCPkgPopupDiskspace.h" + + +// set values as set in YQPkgDiskUsageList.cc +#define MIN_FREE_MB_WARN 400 +#define MIN_FREE_MB_PROXIMITY 700 + +#define MIN_PERCENT_WARN 90 +#define MIN_PERCENT_PROXIMITY 80 + +#define OVERFLOW_MB_WARN 0 +#define OVERFLOW_MB_PROXIMITY 300 + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +namespace +{ + /** + * Local helper method, obtain the current disk usage. Initializes the libzypp + * disk usage with the current values from the system if needed. + * @return Libzypp disk usage + */ + ZyppDuSet get_du() + { + ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage(); + + if ( diskUsage.empty() ) + { + zypp::getZYpp()->setPartitions( zypp::DiskUsageCounter::detectMountPoints() ); + diskUsage = zypp::getZYpp()->diskUsage(); + } + + return diskUsage; + } + + /** + * Compute used percent for the used and the total size. + * @param used the used size + * @param total the total size + * @return used percent (returns zero when 'total' is zero to avoid + * division by zero) + */ + int usedPercentInt(const FSize &used, const FSize &total) + { + int percent = 0; + + if ( total != 0 ) + percent = int(( 100 * used ) / total); + + return percent; + } + + /** + * Compute the dialog width, try to make all fields visible. Make it + * dependant on the longest mount point path. + * @return width + */ + int dialogWidth() + { + int width = 0; + for (const ZyppPartitionDu &du: get_du()) + { + if ( int(du.dir.length()) > width ) + width = du.dir.length(); + } + yuiDebug() << "The longest mount point path: " << width << " characters" << endl; + + // add the width of the other columns + small extra space + // (e.g. buffer for longer translations) + width += 50; + + // cannot be wider than the screen, keep some minimal space around the popup + if (width > NCurses::cols() - 6) + width = NCurses::cols() - 6; + + yuiDebug() << "Dialog width: " << width << endl; + + return width; + } + + /** + * Compute the dialog X position on the screen. + * @return X position + */ + int dialogXpos() + { + return (NCurses::cols() - dialogWidth()) / 2; + } +} + + /////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::NCPkgDiskspace +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgDiskspace::NCPkgDiskspace( bool testMode ) + : testmode( testMode ) + , popupWin( 0 ) +{ + + if ( testMode ) + { + yuiMilestone() << "TESTMODE Diskspace" << endl; + zypp::getZYpp()->setPartitions(zypp::DiskUsageCounter::detectMountPoints()); + testDiskUsage = zypp::getZYpp()->diskUsage(); + } +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::~NCPkgDiskspace +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgDiskspace::~NCPkgDiskspace() +{ +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::fillPartitionTable +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgDiskspace::fillPartitionTable() +{ + NCTable * partitions = popupWin->Partitions(); + partitions->deleteAllItems(); // clear table + + ZyppDuSet du = get_du(); + for (const ZyppPartitionDu &item: du) + { + if (item.readonly) + continue; + + FSize pkg_used (item.pkg_size, FSize::Unit::K); + FSize pkg_available ((item.total_size - item.pkg_size), FSize::Unit::K); + FSize total (item.total_size, FSize::Unit::K); + + YTableItem *newItem = new YTableItem( item.dir, + pkg_used.form(8), + pkg_available.form(8), + total.form(8), + usedPercent( pkg_used, total ) ); + + partitions->addItem( newItem ); + } +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::checkDiskSpace +// METHOD TYPE : std::string +// +// DESCRIPTION : called to check disk space before installation +// (after OK button is pressed) +// +std::string NCPkgDiskspace::checkDiskSpace() +{ + ZyppDuSet diskUsage = get_du(); + + std::string text = ""; + for (const ZyppPartitionDu &du: diskUsage) + { + if (du.readonly) + continue; + + FSize pkg_available(du.total_size - du.pkg_size, FSize::Unit::K); + if ( pkg_available < 0 ) + { + // make it positive + pkg_available *= -1; + text += "\""; + text += du.dir; + text += "\""; + text += " "; + text += NCPkgStrings::MoreText(); + text += " "; + text += pkg_available.asString(); + text += " "; + text += NCPkgStrings::MoreSpaceText(); + text += "
"; + } + } + return text; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::checkRemainingDiskSpace +// METHOD TYPE : void +// +// DESCRIPTION : check whether remaining disk space enters +// warning or error range +// +void NCPkgDiskspace::checkRemainingDiskSpace( const ZyppPartitionDu & partition ) +{ + if ( partition.readonly ) + return; + + FSize usedSize ( partition.pkg_size, FSize::Unit::K ); + FSize totalSize ( partition.total_size, FSize::Unit::K ); + + int percent = usedPercentInt(usedSize, totalSize); + + // free size in MiB + boost::multiprecision::cpp_int free = ( totalSize - usedSize ).in_unit(FSize::Unit::M); + + yuiMilestone() << "Partition: " << partition.dir << " Used percent: " + << percent << " Free: " << free << endl; + + if ( percent > MIN_PERCENT_WARN ) + { + // Modern hard disks can be huge, so a warning based on percentage only + // can be misleading - check the absolute value, too. + if ( free < MIN_FREE_MB_PROXIMITY ) + { + yuiWarning() << "free < MIN_FREE_MB_PROXIMITY (" << MIN_FREE_MB_PROXIMITY << ")" << endl; + runningOutWarning.enterProximity(); + } + if ( free < MIN_FREE_MB_WARN ) + { + yuiWarning() << "free < MIN_FREE_MB_WARN (" << MIN_FREE_MB_WARN << ")" << endl; + runningOutWarning.enterRange(); + } + } + + if ( free < MIN_FREE_MB_PROXIMITY ) + { + if ( percent > MIN_PERCENT_PROXIMITY ) + runningOutWarning.enterProximity(); + } + + if ( free < OVERFLOW_MB_WARN ) + overflowWarning.enterRange(); + + if ( free < OVERFLOW_MB_PROXIMITY ) + overflowWarning.enterProximity(); + +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::setDiskSpace +// METHOD TYPE : void +// +// DESCRIPTION : For testing only; called from NCPkgTable if the PackageSelector +// running in testMode +// TESTDESCRIPTION: Call PackageSelector with Opt(:testMode) (Ruby example). +// With focus on the package list press '+' or '-' to +// increase/decrease used diskspace (see y2log). +// Use the 'Actions' menu to select/delete a package. +// +void NCPkgDiskspace::setDiskSpace( wint_t ch ) +{ + // set diskspace values in ZyppDuSet testDiskSpace + for ( const ZyppPartitionDu &partitionDu: testDiskUsage ) + { + FSize usedSize ( partitionDu.pkg_size, FSize::Unit::K ); + FSize totalSize ( partitionDu.total_size, FSize::Unit::K ); + int percent = usedPercentInt(usedSize, totalSize); + + if ( ch == '+' ) + percent += 3; + else if ( ch == '-' ) + percent -= 3; + + if ( percent < 0 ) + percent = 0; + + partitionDu.pkg_size = partitionDu.total_size / 100 * percent; + + FSize newSize ( partitionDu.pkg_size, FSize::Unit::K ); + + yuiMilestone() << "Used size (MiB): " << newSize.in_unit(FSize::Unit::M) << endl; + yuiMilestone() << "Total size (MiB): " << totalSize.in_unit(FSize::Unit::M) << endl; + } +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::checkDiskSpaceRange +// METHOD TYPE : void +// +// DESCRIPTION : calls checkRemaingDiskspace for every partition +// +void NCPkgDiskspace::checkDiskSpaceRange() +{ + // see YQPkgDiskUsageList::updateDiskUsage() + runningOutWarning.clear(); + overflowWarning.clear(); + ZyppDuSet diskUsage; + + if ( testmode ) + diskUsage = testDiskUsage; + else + diskUsage = zypp::getZYpp()->diskUsage(); + + for (const ZyppPartitionDu &du: diskUsage) + { + // Exclude readonly dirs from the check (#384368) + if ( du.readonly ) + continue; + checkRemainingDiskSpace( du ); + } + + // see YQPkgDiskUsageList::postPendingWarnings() + if ( overflowWarning.needWarning() ) + { + showInfoPopup( _( "Error: Out of disk space!" ) ); + + overflowWarning.warningPostedNotify(); + runningOutWarning.warningPostedNotify(); // Suppress this ( now redundant ) other warning + } + + if ( runningOutWarning.needWarning() ) + { + showInfoPopup( _( "Warning: Disk space is running out!" ) ); + + runningOutWarning.warningPostedNotify(); + } + + if ( overflowWarning.leavingProximity() ) + overflowWarning.clearHistory(); + + if ( runningOutWarning.leavingProximity() ) + runningOutWarning.clearHistory(); + + if ( testmode ) + { + yuiMilestone() << "Running out Warning:" << endl; + runningOutWarning.logSettings(); + + yuiMilestone() << "Overflow Warning:" << endl; + overflowWarning.logSettings(); + } +} + +std::string NCPkgDiskspace::usedPercent( const FSize &used, const FSize &total ) +{ + int percent = usedPercentInt(used, total); + return zypp::str::form( "%2d%%", percent ); +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgDiskspace::showInfoPopup +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgDiskspace::showInfoPopup( std::string headline ) +{ + + popupWin = new NCPkgPopupDiskspace (wpos( (NCurses::lines() - 15)/2, dialogXpos() ), headline ); + // update values in partition table + fillPartitionTable(); + popupWin->doit(); + YDialog::deleteTopmostDialog(); +} + +FSize NCPkgDiskspace::calculateDiff() +{ + ZyppDuSet diskUsage = get_du(); + + FSize diff = 0; + for (const ZyppPartitionDu &du: diskUsage) + { + diff += FSize(du.pkg_size - du.used_size, FSize::Unit::K); + } + + return diff; +} + +////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDiskspace::NCPkgPopupDiskspace +// METHOD TYPE : Constructor +// +NCPkgPopupDiskspace::NCPkgPopupDiskspace( const wpos at, std::string headline ) + : NCPopup( at, false ) + , partitions( 0 ) + , okButton( 0 ) + , head( 0 ) +{ + createLayout( headline ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDiskspace::~NCPkgPopupDiskspace +// METHOD TYPE : Destructor +// +NCPkgPopupDiskspace::~NCPkgPopupDiskspace() +{ +} + +////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDiskspace::createLyout +// METHOD TYPE : void +// +// DESCRIPTION : create layout (partition table) +// +void NCPkgPopupDiskspace::createLayout( std::string headline ) +{ + // the vertical split is the (only) child of the dialog + NCLayoutBox * split = new NCLayoutBox( this, YD_VERT ); + + head = new NCLabel( split, "", true, false ); // isHeading = true + head->setLabel( headline ); + + YTableHeader * tableHeader = new YTableHeader(); + tableHeader->addColumn( NCPkgStrings::Partition(), YAlignBegin ); + tableHeader->addColumn( NCPkgStrings::UsedSpace(), YAlignBegin ); + tableHeader->addColumn( NCPkgStrings::FreeSpace(), YAlignBegin ); + tableHeader->addColumn( NCPkgStrings::TotalSpace(), YAlignBegin ); + tableHeader->addColumn( "% ", YAlignBegin ); + + // add the partition table + partitions = new NCTable( split, tableHeader ); + + // add the ok button + okButton = new NCPushButton( split, NCPkgStrings::OKLabel() ); + okButton->setFunctionKey( 10 ); + okButton->setKeyboardFocus(); +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDiskspace::preferredWidth +// METHOD TYPE : int +// +int NCPkgPopupDiskspace::preferredWidth() +{ + return dialogWidth(); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDiskspace::preferredHeight +// METHOD TYPE : int +// +int NCPkgPopupDiskspace::preferredHeight() +{ + if ( NCurses::lines() > 15 ) + return 15; + else + return NCurses::lines()-4; +} + +void NCPkgPopupDiskspace::doit() +{ + postevent = NCursesEvent(); + do + { + // show the popup + popupDialog(); + } while ( postAgain() ); + + popdownDialog(); + +} +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopup::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupDiskspace::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + if ( ch == KEY_RETURN ) + return NCursesEvent::button; + + return NCDialog::wHandleInput( ch ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupDiskspace::postAgain +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgPopupDiskspace::postAgain() +{ + if ( ! postevent.widget ) + return false; + + if ( postevent == NCursesEvent::button || postevent == NCursesEvent::cancel ) + { + // return false means: close the popup dialog + return false; + } + return true; +} + + + + +NCPkgWarningRangeNotifier::NCPkgWarningRangeNotifier() +{ + clearHistory(); +} + + +void +NCPkgWarningRangeNotifier::clear() +{ + _inRange = false; + _hasBeenClose = _isClose; + _isClose = false; +} + + +void +NCPkgWarningRangeNotifier::clearHistory() +{ + clear(); + _hasBeenClose = false; + _warningPosted = false; +} + + +void +NCPkgWarningRangeNotifier::enterRange() +{ + _inRange = true; + enterProximity(); +} + + +void +NCPkgWarningRangeNotifier::enterProximity() +{ + _isClose = true; + _hasBeenClose = true; +} + + +void +NCPkgWarningRangeNotifier::warningPostedNotify() +{ + _warningPosted = true; +} + + +bool +NCPkgWarningRangeNotifier::inRange() const +{ + return _inRange; +} + + +bool +NCPkgWarningRangeNotifier::leavingProximity() const +{ + return ! _isClose && ! _hasBeenClose; +} + + +bool +NCPkgWarningRangeNotifier::needWarning() const +{ + return _inRange && ! _warningPosted; +} + +void +NCPkgWarningRangeNotifier::logSettings() const +{ + yuiMilestone() << "in range: " << (_inRange?"true":"false") << endl; + yuiMilestone() << "is close: " << (_isClose?"true":"false") << endl; + yuiMilestone() << "has been close: " << (_hasBeenClose?"true":"false") << endl; + yuiMilestone() << "warning posted: " << (_warningPosted?"true":"false") << endl; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDiskspace.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDiskspace.h new file mode 100644 index 0000000000000000000000000000000000000000..eb4b5ff8d69e761ad40580494f7be6be66d00059 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupDiskspace.h @@ -0,0 +1,229 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupDiskspace.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgPopupDiskspace_h +#define NCPkgPopupDiskspace_h + +#include +#include +#include + +#include +#include +#include + +#include "NCZypp.h" + + +typedef zypp::DiskUsageCounter::MountPoint ZyppPartitionDu; +typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet; +typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator; + +class NCTable; +class NCPushButton; + +/////////////////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgWarningRangeNotifier +// +// Class YQPkgWarningRangeNotifier from YQPkgDiskUsageList.h +// + +/** + * Helper class to manage warnings that are to be issued when a value enters a + * predefined range, but repeated only when that value leaves a (wider) + * "proximity" range and then re-enters the (narrower) "inner" range. + * + * Example: Disk space usage: + * + * 70% + * 75% + * 80% [proximity range start] + * 85% + * 90% [inner range start] + * 95% + * 100% + * + * A warning is to be posted when there is only 90% disk space left. After the + * warning is displayed, there shall be no more warning until disk usage decreases + * below 80% (the proximity range) and then later increases again to 90%. + * + * The net effect of all that is to avoid posting the warning over and over + * again while the value changes back and forth around the boundary of the + * ( inner ) warning range. + **/ +class NCPkgWarningRangeNotifier +{ +public: + + /** + * Constructor. + **/ + NCPkgWarningRangeNotifier(); + + /** + * Notification that the inner range is entered. + * The caller has to decide the criteria for that. + **/ + void enterRange(); + + /** + * Notification that the proximity range is entered, i.e. that the value is + * getting near the inner range. + * 'enterRange()' automatically includes this, too. + **/ + void enterProximity(); + + /** + * Notification that a warning has been posted. + **/ + void warningPostedNotify(); + + /** + * Check if the value is in range, i.e. if anybody from the outside has + * called 'enterRange()' since the last call to 'clear()'. + **/ + bool inRange() const; + + /** + * Check if a warning should be posted, i.e. if the value is currently in + * range ( see 'inRange() ) and there has been no notification yet that a + * warning has already been posted. + **/ + bool needWarning() const; + + /** + * Check if the value is leaving the proximity range. + **/ + bool leavingProximity() const; + + /* + * Log settings to y2log + */ + void logSettings() const; + + /** + * Clear the current values, i.e. prepare for a new round of checks + **/ + void clear(); + + /** + * Clear everything, including all history values such as if a warning has + * been posted. + **/ + void clearHistory(); + + +protected: + + bool _inRange; + bool _isClose; + bool _hasBeenClose; + bool _warningPosted; +}; + +class NCPkgPopupDiskspace : public NCPopup +{ +private: + NCTable * partitions; + NCPushButton * okButton; + NCLabel * head; + +protected: + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + NCPkgPopupDiskspace( const wpos at, std::string headline ); + + virtual ~NCPkgPopupDiskspace(); + + void createLayout( std::string headline ); + void doit(); + + NCTable *Partitions() { return partitions; } + + virtual int preferredWidth(); + virtual int preferredHeight(); + +}; + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgPopupDiskspace +// +// DESCRIPTION : +// +class NCPkgDiskspace +{ + NCPkgDiskspace & operator=( const NCPkgDiskspace & ); + NCPkgDiskspace ( const NCPkgDiskspace & ); + +private: + + bool testmode; + NCPkgPopupDiskspace *popupWin; + ZyppDuSet testDiskUsage; + + std::string usedPercent( const FSize &used, const FSize &total ); + + /** + * Warning range notifier about running out of disk space warning. + **/ + NCPkgWarningRangeNotifier runningOutWarning; + + /** + * Warning range notifier about disk space overflow warning. + **/ + NCPkgWarningRangeNotifier overflowWarning; + + +public: + + NCPkgDiskspace( bool testSpaceMode ); + + virtual ~NCPkgDiskspace(); + + + void fillPartitionTable(); + + std::string checkDiskSpace(); + + void setDiskSpace( wint_t key ); // used for testing + + void checkDiskSpaceRange(); + + void showInfoPopup( std::string headline ); + + void checkRemainingDiskSpace( const ZyppPartitionDu & partition ); + + FSize calculateDiff(); +}; + + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgPopupDiskspace_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupTable.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupTable.cc new file mode 100644 index 0000000000000000000000000000000000000000..e11081667ab6bfb9878eab608b3fc599ef123091 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupTable.cc @@ -0,0 +1,355 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupTable.cc + Author: Gabriele Strattner + +*/ + + +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCPkgPopupTable.h" +#include "NCPkgStrings.h" +#include "NCPkgTable.h" + + +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::NCPkgPopupTable +// METHOD TYPE : Constructor +// +// DESCRIPTION : +// +NCPkgPopupTable::NCPkgPopupTable( const wpos at, NCPackageSelector * pkger, + std::string headline, + std::string label1, + std::string label2, + bool add_cancel ) + : NCPopup( at, false ) + , pkgTable( 0 ) + , okButton( 0 ) + , cancelButton( 0 ) + , packager( pkger ) +{ + createLayout( headline, label1, label2, add_cancel ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::~NCPkgPopupTable +// METHOD TYPE : Destructor +// +// DESCRIPTION : +// +NCPkgPopupTable::~NCPkgPopupTable() +{ +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::createLayout +// METHOD TYPE : void +// +// DESCRIPTION : +// +void NCPkgPopupTable::createLayout( std::string headline, + std::string label1, + std::string label2, + bool add_cancel ) +{ + // the vertical split is the (only) child of the dialog + NCLayoutBox * split = new NCLayoutBox( this, YD_VERT ); + + new NCSpacing( split, YD_VERT, false, 0.6 ); // stretchable = false + + // the headline of the popup containing a list with packages with status changes + new NCLabel( split, headline, true, false ); // isHeading = true + + new NCSpacing( split, YD_VERT, false, 0.6 ); + + if ( label1 != "" ) + { + // text part 1 + new NCLabel( split, label1, false, false ); + } + if ( label2 != "" ) + { + // text part 2 + new NCLabel( split, label2, false, false ); + } + YTableHeader * tableHeader = new YTableHeader(); + // add the package table (use default type T_Packages) + pkgTable = new NCPkgTable( split, tableHeader ); + pkgTable->setPackager( packager ); + pkgTable->fillHeader(); + + // HBox for the buttons + NCLayoutBox * hSplit = new NCLayoutBox( split, YD_HORIZ ); + new NCSpacing( hSplit, YD_HORIZ, true, 0.2 ); // stretchable = true + + // add the OK button + okButton = new NCPushButton( hSplit, NCPkgStrings::OKLabel() ); + okButton->setFunctionKey( 10 ); + okButton->setKeyboardFocus(); + + if ( add_cancel ) + { + new NCSpacing( hSplit, YD_HORIZ, true, 0.4 ); + + // add the Cancel button + cancelButton = new NCPushButton( hSplit, NCPkgStrings::CancelLabel() ); + cancelButton->setFunctionKey( 9 ); + } + new NCSpacing( hSplit, YD_HORIZ, true, 0.2 ); + + new NCSpacing( split, YD_VERT, false, 0.6 ); +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::fillAutoChanges +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgPopupTable::fillAutoChanges( NCPkgTable * pkgTable ) +{ + if ( !pkgTable ) + return false; + + pkgTable->itemsCleared(); // clear the table + + std::set ignoredNames; + std::set userWantedNames = zypp::ui::userWantedPackageNames(); + // these are the packages already selected for autoinstallation in previous 'verify system' run + std::set verifiedNames = packager->getVerifiedPkgs(); + + // initialize storage for the new set + std::insert_iterator< std::set > result (ignoredNames, ignoredNames.begin()); + + if (!verifiedNames.empty()) + { + // if we have some leftovers from previous run, do the union of the sets + set_union(userWantedNames.begin(), userWantedNames.end(), + verifiedNames.begin(), verifiedNames.end(), result ); + } + else + // else just take userWanted stuff + ignoredNames = userWantedNames; + + for ( std::set::iterator it = ignoredNames.begin(); it != ignoredNames.end(); ++it ) + yuiMilestone() << "Ignoring: " << *it << endl; + + ZyppPoolIterator + b = zyppPkgBegin(), + e = zyppPkgEnd(), + it; + + for (it = b; it != e; ++it) + { + ZyppSel slb = *it; + + // show all packages which are automatically selected for installation + if ( slb->toModify() && slb->modifiedBy() != zypp::ResStatus::USER ) + { + if ( ! inContainer( ignoredNames, slb->name() ) ) + { + ZyppPkg pkgPtr = tryCastToZyppPkg (slb->theObj()); + if ( pkgPtr ) + { + yuiMilestone() << "The status of " << pkgPtr->name() << " has automatically changed" << endl; + pkgTable->createListEntry( pkgPtr, slb ); + // also add to 'already verified' set + packager->insertVerifiedPkg( pkgPtr->name() ); + } + } + } + } + + pkgTable->drawList(); + + if ( pkgTable->getNumLines() > 0 ) + { + return true; + } + else + { + return false; + } +} + +bool NCPkgPopupTable::fillAvailables( NCPkgTable * pkgTable, ZyppSel sel ) +{ + if ( !pkgTable ) + return false; + + pkgTable->itemsCleared(); // clear the table + pkgTable->fillAvailableList( sel ); + + pkgTable->drawList(); + + return true; +} + + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::showInfoPopup +// METHOD TYPE : NCursesEvent event +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupTable::showInfoPopup() +{ + postevent = NCursesEvent(); + + if ( !fillAutoChanges( pkgTable ) ) + { + postevent = NCursesEvent::button; + return postevent; + } + + do + { + // show the popup + popupDialog(); + } while ( postAgain() ); + + popdownDialog(); + + return postevent; +} + +NCursesEvent NCPkgPopupTable::showAvailablesPopup( ZyppSel sel ) +{ + postevent = NCursesEvent(); + + if ( !fillAvailables( pkgTable, sel ) ) + { + postevent = NCursesEvent::button; + return postevent; + } + + do + { + // show the popup + popupDialog(); + } while ( postAgain() ); + + popdownDialog(); + + return postevent; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::preferredWidth +// METHOD TYPE : int +// +int NCPkgPopupTable::preferredWidth() +{ + return NCurses::cols()-15; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::preferredHeight +// METHOD TYPE : int +// +int NCPkgPopupTable::preferredHeight() +{ + return NCurses::lines()-5; +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPopup::wHandleInput +// METHOD TYPE : NCursesEvent +// +// DESCRIPTION : +// +NCursesEvent NCPkgPopupTable::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + if ( ch == KEY_RETURN ) + return NCursesEvent::button; + + return NCDialog::wHandleInput( ch ); +} + +/////////////////////////////////////////////////////////////////// +// +// +// METHOD NAME : NCPkgPopupTable::postAgain +// METHOD TYPE : bool +// +// DESCRIPTION : +// +bool NCPkgPopupTable::postAgain() +{ + if ( ! postevent.widget ) + return false; + + if ( postevent.widget == cancelButton ) + { + // user hit cancel - discard set of changes (if not empty) + packager->clearVerifiedPkgs(); + + // close the dialog + postevent = NCursesEvent::cancel; + } + + if ( postevent == NCursesEvent::button || postevent == NCursesEvent::cancel ) + { + // return false means: close the popup dialog + return false; + } + return true; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupTable.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupTable.h new file mode 100644 index 0000000000000000000000000000000000000000..efc055ddf692a192630421348064d4af7f72d1ca --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgPopupTable.h @@ -0,0 +1,95 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgPopupTable.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgPopupTable_h +#define NCPkgPopupTable_h + +#include +#include +#include +#include + +#include + +#include "NCZypp.h" + +class NCPkgTable; +class NCPushButton; +class NCPackageSelector; + + +/////////////////////////////////////////////////////////////////// +// +// CLASS NAME : NCPkgPopupTable +// +// DESCRIPTION : +// +class NCPkgPopupTable : public NCPopup +{ + NCPkgPopupTable & operator=( const NCPkgPopupTable & ); + NCPkgPopupTable ( const NCPkgPopupTable & ); + +private: + + NCPkgTable * pkgTable; + NCPushButton * okButton; + NCPushButton * cancelButton; + NCPackageSelector * packager; + +protected: + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCPkgPopupTable( const wpos at, NCPackageSelector * pkger, + std::string headline, + std::string label1, + std::string label2, + bool add_cancel = true ); + + virtual ~NCPkgPopupTable(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + bool fillAutoChanges( NCPkgTable * pkgTable ); + + bool fillAvailables( NCPkgTable * pkgTable, ZyppSel sel ); + + void createLayout( std::string headline, + std::string label1, + std::string label2, + bool add_cancel ); + + NCursesEvent showInfoPopup(); + NCursesEvent showAvailablesPopup( ZyppSel sel ); + +}; + +/////////////////////////////////////////////////////////////////// + + +#endif // NCPkgPopupTable_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgSearchSettings.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSearchSettings.cc new file mode 100644 index 0000000000000000000000000000000000000000..cb36a48a6b8cad5623391667f9465d969102baeb --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSearchSettings.cc @@ -0,0 +1,84 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterMain.cc + Author: Hedgehog Painter + +*/ + + +#include "NCPkgSearchSettings.h" +#include "NCPkgStrings.h" + +/* + Textdomain "ncurses-pkg" +*/ + +NCPkgSearchSettings::NCPkgSearchSettings ( YWidget *parent, std::string label) + : NCMultiSelectionBox ( parent, label) +{ + createLayout(); +} + +NCPkgSearchSettings::~NCPkgSearchSettings() +{ + +} + +void NCPkgSearchSettings::createLayout() +{ + checkName = new YItem ( _( "Name of the Package" ), true); + items.push_back (checkName); + checkSummary = new YItem ( _( "Summary" ), true); + items.push_back (checkSummary); + checkKeywords = new YItem ( _( "Keywords" )); + items.push_back (checkKeywords); + checkDescr = new YItem ( _( "Description (time-consuming)" )); + items.push_back (checkDescr); + checkProvides = new YItem ( _( "Provides" )); + items.push_back (checkProvides); + checkRequires = new YItem ( _( "Required by" )); + items.push_back (checkRequires); + + addItems( items ); +} + +bool NCPkgSearchSettings::doCheckName() +{ + return checkName->selected(); +} +bool NCPkgSearchSettings::doCheckSummary() +{ + return checkSummary->selected(); +} +bool NCPkgSearchSettings::doCheckKeywords() +{ + return checkKeywords->selected(); +} +bool NCPkgSearchSettings::doCheckDescr() +{ + return checkDescr->selected(); +} +bool NCPkgSearchSettings::doCheckProvides() +{ + return checkProvides->selected(); +} +bool NCPkgSearchSettings::doCheckRequires() +{ + return checkRequires->selected(); +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgSearchSettings.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSearchSettings.h new file mode 100644 index 0000000000000000000000000000000000000000..87783f4f9e17bef4a5cfb5116b338baa7a3fde09 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSearchSettings.h @@ -0,0 +1,64 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgFilterMain.h + Author: Hedgehog Painter + +*/ + + +#ifndef NCPkgSearchSettings_h +#define NCPkgSearchSettings_h + +#include + +#include +#include +#include + + +class NCPkgSearchSettings : public NCMultiSelectionBox +{ + NCPkgSearchSettings & operator=( const NCPkgSearchSettings & ); + NCPkgSearchSettings ( const NCPkgSearchSettings & ); + +public: + + YItemCollection items; + YItem *checkName; + YItem *checkSummary; + YItem *checkKeywords; + YItem *checkDescr; + YItem *checkProvides; + YItem *checkRequires; + + + NCPkgSearchSettings (YWidget *parent, std::string label); + virtual ~NCPkgSearchSettings(); + + void createLayout(); + + bool doCheckName(); + bool doCheckSummary(); + bool doCheckKeywords(); + bool doCheckDescr(); + bool doCheckProvides(); + bool doCheckRequires(); + +}; + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgSelMapper.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSelMapper.cc new file mode 100644 index 0000000000000000000000000000000000000000..e30425f84d26b6820565a4b0ab0920c9b25ccedf --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSelMapper.cc @@ -0,0 +1,108 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgSelMapper.cc + Author: Stefan Hundhammer + +*/ + + +#define YUILogComponent "ncurses-pkg" +#include + +#include "NCPkgSelMapper.h" + + +using std::endl; + + +int NCPkgSelMapper::_refCount = 0; +NCPkgSelMapper::Cache NCPkgSelMapper::_cache; + + +NCPkgSelMapper::NCPkgSelMapper() +{ + if ( ++_refCount == 1 ) + rebuildCache(); +} + + +NCPkgSelMapper::~NCPkgSelMapper() +{ + if ( --_refCount == 0 ) + { + yuiDebug() << "Destroying pkg -> selectable cache" << endl; + _cache.clear(); + } +} + + +void NCPkgSelMapper::rebuildCache() +{ + _cache.clear(); + yuiDebug() << "Building pkg -> selectable cache" << endl; + + for ( ZyppPoolIterator sel_it = zyppPkgBegin(); + sel_it != zyppPkgEnd(); + ++sel_it ) + { + ZyppSel sel = *sel_it; + + if ( sel->installedObj() ) + { + // The installed package (if there is any) may or may not be in the list + // of available packages. Better make sure to insert it. + + ZyppPkg installedPkg = tryCastToZyppPkg( sel->installedObj() ); + + if ( installedPkg ) + _cache.insert( CachePair( installedPkg, sel ) ); + } + + zypp::ui::Selectable::available_iterator it = sel->availableBegin(); + + while ( it != sel->availableEnd() ) + { + ZyppPkg pkg = tryCastToZyppPkg( *it ); + + if ( pkg ) + _cache.insert( CachePair( pkg, sel ) ); + + ++it; + } + } + + yuiDebug() << "Building pkg -> selectable cache done" << endl; +} + + +ZyppSel +NCPkgSelMapper::findZyppSel( ZyppPkg pkg ) +{ + NCPkgSelMapper mapper; // This will build a cache, if there is none yet + ZyppSel sel; + + NCPkgSelMapper::CacheIterator it = NCPkgSelMapper::_cache.find( pkg ); + + if ( it != NCPkgSelMapper::_cache.end() ) + sel = it->second; + else + yuiWarning() << "No selectable found for package %s" << pkg->name().c_str() << endl; + + return sel; +} + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgSelMapper.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSelMapper.h new file mode 100644 index 0000000000000000000000000000000000000000..c7cf03e226abec936962b9bc6e143658a410e4f3 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgSelMapper.h @@ -0,0 +1,88 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgSelMapper.h + Author: Stefan Hundhammer + +*/ + + +#ifndef NCPkgSelMapper_h +#define NCPkgSelMapper_h + +#include "NCZypp.h" +#include + + + +/** + * Mapping from ZyppPkg to the correspoinding ZyppSel. + * + * All instances of this class share the same cache. The cache remains alive as + * long as any instance of this class exists. + **/ +class NCPkgSelMapper +{ +public: + + /** + * Constructor. Builds a cache, if necessary. + **/ + NCPkgSelMapper(); + + /** + * Destructor. Clears the cache if this was the last NCPkgSelMapper + * (i.e. if refCount() reaches 0) + **/ + virtual ~NCPkgSelMapper(); + + /** + * Find the corresponding ZyppSel to a ZyppPkg. + * Returns 0 if there is no corresponding ZyppSel. + **/ + + ZyppSel findZyppSel( ZyppPkg pkg ); + + /** + * Reference count - indicates how many instances of this class are alive + * right now. + **/ + static int refCount() { return _refCount; } + + /** + * Rebuild the shared cache. This is expensive. Call this only when the + * ZyppPool has changed, i.e. after installation sources were added or + * removed. + * + * Since the cache is shared, this affects all instances of this class. + **/ + void rebuildCache(); + + +protected: + + typedef std::map Cache; + typedef std::pair CachePair; + typedef Cache::iterator CacheIterator; + + static int _refCount; + static Cache _cache; +}; + + + +#endif // NCPkgSelMapper_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgStatusStrategy.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStatusStrategy.cc new file mode 100644 index 0000000000000000000000000000000000000000..c75f75c4f2e0f527b6d3a230f1d2461af0b6bf46 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStatusStrategy.cc @@ -0,0 +1,855 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgStatusStrategy.cc + Author: Gabriele Strattner + +*/ + + +#include +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include +#include + +#include "NCPkgStatusStrategy.h" +#include "NCPkgStrings.h" +#include "NCZypp.h" + + +using std::endl; + + +//------------------------------------------------------------ +// Base class for strategies to handle status +//------------------------------------------------------------ + +// +// Constructor +// +NCPkgStatusStrategy::NCPkgStatusStrategy() +{ +} + +// +// Destructor - must be defined here (because it is pure virtual) +// +NCPkgStatusStrategy::~NCPkgStatusStrategy() +{ +} + + +/////////////////////////////////////////////////////////////////// +// +// NCPkgStatusStrategy::getPackageStatus() +// +// Gets status from package manager +// +ZyppStatus NCPkgStatusStrategy::getPackageStatus( ZyppSel slbPtr, + ZyppObj objPtr ) +{ + if ( slbPtr ) + { + return slbPtr->status(); + } + else + { + yuiError() << "Selectable pointer not valid" << endl; + return S_NoInst; + } +} + + +///////////////////////////////////////////////////////////////// +// +// NCPkgStatusStrategy::setObjectStatus() +// +// Informs the package manager about the status change +// +bool NCPkgStatusStrategy::setObjectStatus( ZyppStatus newstatus, ZyppSel slbPtr, ZyppObj objPtr ) +{ + bool ok = false; + + if ( !slbPtr ) + { + yuiError() << "Invalid package object" << endl; + return false; + } + + ok = slbPtr->setStatus( newstatus ); + + yuiMilestone() << "Set status of: " << slbPtr->name() << " to: " + << newstatus << " returns: " << ( ok ? "true" : "false" ) << endl; + + return ok; +} + + +/////////////////////////////////////////////////////////////////// +// +// NCPkgStatusStrategy::keyToStatus() +// +// Returns the corresponding status +// +bool NCPkgStatusStrategy::keyToStatus( const int & key, + ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat ) +{ + if ( !slbPtr ) + return false; + + bool valid = true; + ZyppStatus retStat = S_NoInst; + ZyppStatus oldStatus = getPackageStatus( slbPtr, objPtr ); + bool installed = !slbPtr->installedEmpty(); + + // get the new status + switch ( key ) + { + case '-': + if ( installed ) // installed package -> always set status to delete + { + // if required, NCPkgTable::changeStatus() shows the delete notify + retStat = S_Del; + } + else + { + retStat = S_NoInst; + } + break; + + case '+': + if ( oldStatus == S_NoInst + || oldStatus == S_AutoInstall ) + { + // if required, NCPkgTable::changeStatus() shows the notify message + retStat = S_Install; + } + else if ( oldStatus == S_Del + || oldStatus == S_AutoDel) + { + retStat = S_KeepInstalled; + } + else if ( oldStatus == S_AutoUpdate ) + { + retStat = S_Update; + } + else + { + valid = false; + } + break; + + case '>': + if ( oldStatus == S_KeepInstalled + || oldStatus == S_Del + || oldStatus == S_AutoDel ) + { + if ( slbPtr->hasCandidateObj() ) + { + retStat = S_Update; + } + } + else + { + valid = false; + } + break; + + // this is the case for 'going back' i.e. S_Install -> S_NoInst, S_Update -> S_KeepInstalled + // not for S_Del, since '+' key does this + case '<': + if ( oldStatus == S_Install + || oldStatus == S_AutoInstall ) + { + retStat = S_NoInst; + } + else if ( oldStatus == S_Update + || oldStatus == S_AutoUpdate ) + { + retStat = S_KeepInstalled; + } + break; + + case '!': // set S_Taboo + if ( !installed ) + { + retStat = S_Taboo; + } + break; + + case '*': // set S_Protected + if ( installed ) + { + retStat = S_Protected; + } + break; + + default: + yuiDebug() << "Key not valid" << endl; + valid = false; + break; + } + + if ( valid ) + newStat = retStat; + + return valid; +} + + +// +// Cycle the status patch to a new one and return the new status in +// newStat_ret. +// +// The function return value is 'true' if ok, 'false' if not. +// +bool NCPkgStatusStrategy::cycleStatus( ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat_ret ) +{ + if ( !slbPtr ) + return false; + + bool ok = true; + + ZyppStatus oldStatus = getPackageStatus( slbPtr, objPtr ); + ZyppStatus newStatus = oldStatus; + ZyppPattern patPtr = tryCastToZyppPattern (objPtr); + + switch ( oldStatus ) + { + case S_Del: + newStatus = S_KeepInstalled; + break; + + case S_Install: + newStatus =S_NoInst; + break; + + case S_Update: + newStatus = S_Del; + break; + + case S_KeepInstalled: + if ( patPtr ) + newStatus = S_Install; + + else if ( slbPtr->hasCandidateObj() ) + { + newStatus = S_Update; + } + else + { + newStatus = S_Del; + } + break; + + case S_NoInst: + if ( slbPtr->hasCandidateObj() || patPtr ) + { + newStatus = S_Install; + } + else + { + yuiWarning() << "No candidate object for " << slbPtr->theObj()->name().c_str() << endl; + newStatus = S_NoInst; + } + break; + + case S_AutoInstall: + // this used to be taboo before, but now ZYpp supports + // saving weak locks (unselected packages) + newStatus = S_NoInst; + break; + + case S_AutoDel: + newStatus = S_KeepInstalled; + break; + + case S_AutoUpdate: + newStatus = S_KeepInstalled; + break; + + case S_Taboo: + newStatus = S_NoInst; + break; + + case S_Protected: + newStatus = S_KeepInstalled; + break; + } + + yuiMilestone() << "Status toogled: old " << oldStatus << ", new " << newStatus << endl; + newStat_ret = newStatus; + + return ok; +} + + +/////////////////////////////////////////////////////////////////// +// +// NCPkgStatusStrategy::solveResolvableCollections() +// +// Do a "small" solver run +// +void NCPkgStatusStrategy::solveResolvableCollections() +{ + zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver(); + resolver->resolvePool(); +} + + + +//------------------------------------------------------------ +// Class for strategies to get status for packages +//------------------------------------------------------------ + +// +// Constructor +// +PackageStatStrategy::PackageStatStrategy() + : NCPkgStatusStrategy() +{ +} + + + + +//------------------------------------------------------------ +// Class for strategies to get status for patches +//------------------------------------------------------------ + +// +// Constructor +// +PatchStatStrategy::PatchStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +/////////////////////////////////////////////////////////////////// +// +// PatchStatStrategy::keyToStatus() +// +// Returns the corresponding status +// +bool PatchStatStrategy::keyToStatus( const int & key, + ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat ) +{ + if ( !slbPtr || !slbPtr->hasCandidateObj() ) + return false; + + bool valid = true; + ZyppStatus retStat = S_NoInst; + ZyppStatus oldStatus = getPackageStatus( slbPtr, objPtr ); + bool toBeInst = slbPtr->candidateObj().status().isToBeInstalled(); + bool isRelevant = slbPtr->candidateObj().isRelevant(); + bool isBroken = slbPtr->candidateObj().isBroken(); + + yuiMilestone() << slbPtr->name() << ": " << (toBeInst?"to be installed" : "not to be installed,") + << " old status: " << oldStatus << endl; + + // get the new status + switch ( key ) + { + case '-': + // To be installed includes S_Install and S_AutoInstall + if ( toBeInst ) + { + retStat = S_NoInst; + } + else if ( oldStatus == S_Taboo ) + { + if ( isBroken ) + { + retStat = S_Install; + } + else + { + retStat = S_NoInst; + } + } + else // patches cannot be deleted + { + valid = false; + } + break; + case '+': + // only relevant patches can be installed + if ( isRelevant && + ( oldStatus == S_NoInst || + oldStatus == S_AutoInstall || + oldStatus == S_KeepInstalled ) ) + { + retStat = S_Install; + } + else + { + valid = false; + } + break; + case '!': + { + // For patches there isn't an installed object available (patches are not installed, + // they can be satisfied because required version/s of the patch package/s is/are + // installed). Therefore they only can be set to S_Taboo (not to S_Protected). + retStat = S_Taboo; + } + break; + default: + yuiDebug() << "Key not valid" << endl; + valid = false; + } + + if ( valid ) + { + newStat = retStat; + } + yuiMilestone() << "New status: " << newStat << endl; + + return valid; +} + + +// +// Cycle the status patch to a new one and return the new status in +// newStat_ret. +// +// The function return value is 'true' if ok, 'false' if not. +// +bool PatchStatStrategy::cycleStatus( ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat_ret ) +{ + if ( !slbPtr || !slbPtr->hasCandidateObj() ) + return false; + + bool ok = true; + + ZyppStatus oldStatus = getPackageStatus( slbPtr, objPtr ); + bool isBroken = slbPtr->candidateObj().isBroken(); + ZyppStatus newStatus = oldStatus; + + switch ( oldStatus ) + { + case S_Install: + case S_AutoInstall: + newStatus = S_NoInst; + break; + + case S_KeepInstalled: + newStatus = S_Install; + break; + + case S_NoInst: + newStatus = S_Install; + break; + + case S_Taboo: + if ( isBroken ) + { + newStatus = S_Install; + } + else + { + newStatus = S_NoInst; + } + break; + + default: + newStatus = oldStatus; + break; + } + + yuiMilestone() << "Status toogled: old " << oldStatus << ", new " << newStatus << endl; + newStat_ret = newStatus; + + return ok; +} + + +///////////////////////////////////////////////////////////////// +// +// PatchStatStrategy::setObjectStatus() +// +// Inform the package manager about the status change +// of the patch +// +bool PatchStatStrategy::setObjectStatus( ZyppStatus newstatus, ZyppSel slbPtr, ZyppObj objPtr ) +{ + bool ok = false; + + if ( !slbPtr ) + { + yuiError() << "Invalid patch object" << endl; + return false; + } + + ok = slbPtr->setStatus( newstatus ); + yuiMilestone() << "Set status of: " << slbPtr->name() << " to: " + << newstatus << " returns: " << ( ok ? "true" : "false" ) << endl; + + // do a solver run + solveResolvableCollections(); + + return ok; +} + + +//------------------------------------------------------------ +// Class for strategies for selections +//------------------------------------------------------------ + +// +// Constructor +// +SelectionStatStrategy::SelectionStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +///////////////////////////////////////////////////////////////// +// +// SelectionStatStrategy::setObjectStatus() +// +// Inform the package manager about the status change +// of the selection +// +bool SelectionStatStrategy::setObjectStatus( ZyppStatus newstatus, ZyppSel slbPtr, ZyppObj objPtr ) +{ + bool ok = false; + + if ( !slbPtr || !objPtr ) + { + yuiError() << "Invalid selection" << endl; + return false; + } + + ok = slbPtr->setStatus( newstatus ); + yuiMilestone() << "Set status of: " << slbPtr->name() << " to: " + << newstatus << " returns: " << ( ok ? "true" : "false" ) << endl; + + // do a solver run -> solver runs in NCPkgTable::changeStatus() + // solveResolvableCollections(); + + return ok; +} + + +//------------------------------------------------------------ +// Class for strategies for depndencies +//------------------------------------------------------------ + +// +// Constructor +// +DependencyStatStrategy::DependencyStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +//------------------------------------------------------------ +// Class for strategies to get status for available packages +//------------------------------------------------------------ + +// +// Constructor +// +AvailableStatStrategy::AvailableStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +/////////////////////////////////////////////////////////////////// +// +// AvailableStatStrategy::setObjectStatus +// +// Informs the package manager about the new status (sets the candidate) +// +bool AvailableStatStrategy::setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, + ZyppObj objPtr ) +{ + bool ok = false; + + if ( !slbPtr || !objPtr ) + { + return false; + } + + ZyppObj newCandidate = objPtr; + + if ( newCandidate != slbPtr->candidateObj() ) + { + yuiMilestone() << "CANDIDATE changed" << endl; + + // Change status of selectable + ZyppStatus status = slbPtr->status(); + + if ( slbPtr->installedObj() && + slbPtr->installedObj()->edition() == newCandidate->edition() && + slbPtr->installedObj()->vendor() == newCandidate->vendor() ) + { + yuiMilestone() << "Identical package installed" << endl; + // Switch back to the original instance - + // the version that was previously installed + status = S_KeepInstalled; + } + else + { + switch ( status ) + { + case S_KeepInstalled: + case S_Protected: + case S_AutoDel: + case S_AutoUpdate: + case S_Del: + case S_Update: + + status = S_Update; + break; + + case S_NoInst: + case S_Taboo: + case S_Install: + case S_AutoInstall: + status = S_Install; + break; + } + } + + // Set candidate + ok = bool( slbPtr->setCandidate( newCandidate ) ); + yuiMilestone() << "Set user candidate returns: " << ( ok ? "true" : "false" ) << endl; + if ( ok ) + { + // Set status + ok = slbPtr->setStatus( status ); + yuiMilestone() << "Set status of: " << slbPtr->name() << " to: " + << status << " returns: " << ( ok ? "true" : "false" ) << endl; + } + } + + return ok; +} + + +//------------------------------------------------------------ +// Class for strategies to get status for multi version packages +//------------------------------------------------------------ + +// +// Constructor +// +MultiVersionStatStrategy::MultiVersionStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +/////////////////////////////////////////////////////////////////// +// +// MultiVersionStatStrategy::getPackageStatus() +// +// Gets status from package manager +// +ZyppStatus MultiVersionStatStrategy::getPackageStatus( ZyppSel slbPtr, + ZyppObj objPtr ) +{ + if ( !slbPtr || !objPtr ) + { + yuiError() << "Selectable pointer not valid" << endl; + return S_NoInst; + } + + zypp::PoolItem itemPtr ( objPtr->satSolvable() ); + return slbPtr->pickStatus( itemPtr ); +} + + +/////////////////////////////////////////////////////////////////// +// +// MultiVersionStatStrategy::setObjectStatus +// +// Checking for multiversion and not-multiversion conflicts and +// informs the package manager about the new status. +// +bool MultiVersionStatStrategy::setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, + ZyppObj objPtr ) +{ + bool ok = false; + + if ( !slbPtr || !objPtr ) + { + return false; + } + zypp::PoolItem itemPtr ( objPtr->satSolvable() ); + + bool multiVersion = itemPtr->multiversionInstall(); + yuiMilestone() << "Selected: " + << ( multiVersion ? "Multiversion " : "Non-Multiversion " ) + << itemPtr; + + if ( anyMultiVersionToInstall( slbPtr, !multiVersion ) ) + { + yuiMilestone() << "Multiversion and non-multiversion conflict!" << endl; + + if ( mixedMultiVersionPopup( multiVersion ) ) + { + ok = slbPtr->setPickStatus( itemPtr, newstatus ); + yuiMilestone() << "Set new status of: "<< slbPtr->name() << ", " << objPtr->edition() + << " to: " << newstatus << " returns: " << ( ok ? "true" : "false" ) << endl; + } + else + { + yuiMilestone() << "Selection canceled by the user."; + } + } + else + { + ok = slbPtr->setPickStatus( itemPtr, newstatus ); + yuiMilestone() << "Set new status of: "<< slbPtr->name() << ", " << objPtr->edition() + << " to: " << newstatus << " returns: " << ( ok ? "true" : "false" ) << endl; + } + + return ok; +} + + +// +// Check if any package version is marked for installation where its +// 'multiversion' flag is set to 'multiversion'. +// +bool MultiVersionStatStrategy::anyMultiVersionToInstall( ZyppSel slbPtr, bool multiversion ) const +{ + if ( ! slbPtr ) + return false; + + zypp::ui::Selectable::available_iterator it = slbPtr->availableBegin(); + + while ( it != slbPtr->availableEnd() ) + { + if ( it->multiversionInstall() == multiversion ) + { + switch ( slbPtr->pickStatus( *it ) ) + { + case S_Install: + case S_AutoInstall: + yuiMilestone() << "Found " << ( multiversion ? "multiversion" : "non-multiversion" ) + << " to install" << endl; + return true; + case S_KeepInstalled: + yuiMilestone() << "Found " << ( multiversion ? "multiversion" : "non-multiversion" ) + << " wich is already installed" << endl; + return true; + default: + break; + } + } + + ++it; + } + + yuiMilestone() << "No " << ( multiversion ? "multiversion" : "non-multiversion" ) + << " to install" << endl; + return false; +} + + +/////////////////////////////////////////////////////////////////// +// +// MultiVersionStatStrategy::mixedMultiVersionPopup +// +// Ask user if he really wants to install incompatible package versions. +// Return 'true' if he hits [Continue], 'false' if [Cancel]. +// +bool MultiVersionStatStrategy::mixedMultiVersionPopup( bool multiversion ) const +{ + std::string msg = NCPkgStrings::MultiversionIntro(); + + if ( multiversion ) + { + msg += NCPkgStrings::MultiversionText(); + } + else + { + msg += NCPkgStrings::NotMultiversionText(); + } + + NCPopupInfo * cancelMsg = new NCPopupInfo( wpos( (NCurses::lines()-22)/2, (NCurses::cols()-45)/2 ), + NCPkgStrings::MultiversionHead(), + msg, + NCPkgStrings::ContinueLabel(), + NCPkgStrings::CancelLabel() + ); + cancelMsg->setPreferredSize( 60, 15 ); + cancelMsg->focusCancelButton(); + NCursesEvent input = cancelMsg->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + + return !(input == NCursesEvent::cancel); +} + + +//------------------------------------------------------------ +// Class for strategies to get status for update packages +//------------------------------------------------------------ + +// +// Constructor +// +UpdateStatStrategy::UpdateStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +//------------------------------------------------------------ +// Class for strategies to get status for patch packages +//------------------------------------------------------------ + +// +// Constructor +// +PatchPkgStatStrategy::PatchPkgStatStrategy() + : NCPkgStatusStrategy() +{ +} + + +bool PatchPkgStatStrategy::setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, + ZyppObj objPtr ) +{ + // it is not possible to set the status of the packages belonging to a certain patch + return false; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgStatusStrategy.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStatusStrategy.h new file mode 100644 index 0000000000000000000000000000000000000000..1af3a8470864eda3d9756baca8c1d6d25cbcbb67 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStatusStrategy.h @@ -0,0 +1,294 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgStatusStrategy.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgStatusStrategy_h +#define NCPkgStatusStrategy_h + +#include "NCZypp.h" +#include + + +//------------------------------------------------------------ +// Abstract base class for strategies to get status for packages or patches +//------------------------------------------------------------ +class NCPkgStatusStrategy +{ + +public: + + NCPkgStatusStrategy(); + + virtual ~NCPkgStatusStrategy() = 0; + + /** + * Gets the status information from the package manager. + * @param slbPtr The package whose status to calculate. + * @return UI_Status The new status of the given package + * + **/ + virtual ZyppStatus getPackageStatus ( ZyppSel slbPtr, ZyppObj objPtr ); + + /** + * Informs the package manager about the new status. + * @param newStatus The new package status + * @param slbPtr The selectable pointer (e.g. a package pointer) + * @param pkgPtr The object pointer (used for candidate selection) + * @return bool + */ + virtual bool setObjectStatus ( ZyppStatus newstatus, + ZyppSel slbPtr, + ZyppObj objPtr + ); + /** + * Returns the new status to the given key (respecting the old + * status of th eobject). + * @param key The userinput (the key which is pressed) + * @param slbPtr The object pointer (e.g. a package pointer) + * @param newStatus The new package status + * @return bool + */ + virtual bool keyToStatus( const int & key, + ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat ); + + /** + * Cyle the package status (e.g. from installed to delete) + */ + virtual bool cycleStatus( ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat_ret ); + /** + * Do a "small" solver run for all "resolvable collections", i.e., for + * selections, patterns, languages, patches. + **/ + void solveResolvableCollections(); + +}; + + +//------------------------------------------------------------ +// Class for strategies to handle status of packages +//------------------------------------------------------------ +class PackageStatStrategy : public NCPkgStatusStrategy +{ +public: + + PackageStatStrategy(); + + virtual ~PackageStatStrategy() {} + +}; + +//------------------------------------------------------------ +// Class for strategies to handle dependencies +//------------------------------------------------------------ +class DependencyStatStrategy : public NCPkgStatusStrategy +{ +public: + + DependencyStatStrategy(); + + virtual ~DependencyStatStrategy() {} + +}; + +//------------------------------------------------------------ +// Class for strategies of update +//------------------------------------------------------------ +class UpdateStatStrategy : public NCPkgStatusStrategy +{ +public: + + UpdateStatStrategy(); + + virtual ~UpdateStatStrategy() {} + +}; + +//------------------------------------------------------------ +// Class for strategies of selections +//------------------------------------------------------------ +class SelectionStatStrategy : public NCPkgStatusStrategy +{ +public: + + SelectionStatStrategy(); + + virtual ~SelectionStatStrategy() {} + + /** + * Sets the status of the selection + * @param newStatus The new selection status + * @param slbPtr The selectable pointer + * @qparam objPtr The object (selection) pointer + * @return bool + */ + virtual bool setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, + ZyppObj objPtr ); + +}; + +//------------------------------------------------------------ +// Class for strategies to handle status of packages belonging to a patch +//------------------------------------------------------------ +class PatchPkgStatStrategy : public NCPkgStatusStrategy +{ +public: + + PatchPkgStatStrategy(); + + virtual ~PatchPkgStatStrategy() {} + + /** + * It is not possible to std::set the package status for packages belonging to a patch, + * i.e. returns always false. + */ + virtual bool setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, + ZyppObj objPtr ); + +}; + + + +//------------------------------------------------------------ +// Class for strategies to handle status of patches +//------------------------------------------------------------ +class PatchStatStrategy : public NCPkgStatusStrategy +{ +public: + + PatchStatStrategy(); + + virtual ~PatchStatStrategy() {} + + /** + * Returns the new status to the given key (respecting the old + * status of the patch). + * @param key The userinput (the key which is pressed) + * @param slbPtr The object pointer (the patch pointer) + * @param newStatus The new package status + * @return bool + */ + virtual bool keyToStatus( const int & key, + ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat ); + + /** + * Cycle the patch status (e.g. from selected to unselected) + */ + virtual bool cycleStatus( ZyppSel slbPtr, + ZyppObj objPtr, + ZyppStatus & newStat_ret ); + + /** + * Sets the status of the patch AND the status of the patch packages + * @param newStatus The new package status + * @param slbPtr The object pointer (e.g. a package pointer) + * @return bool + */ + virtual bool setObjectStatus( ZyppStatus newstatus, ZyppSel slbPtr, ZyppObj objPtr ); +}; + + + +//------------------------------------------------------------ +// Class for strategies to handle status of available packages +//------------------------------------------------------------ +class AvailableStatStrategy : public NCPkgStatusStrategy +{ +public: + + AvailableStatStrategy(); + + virtual ~AvailableStatStrategy() {} + + /** + * Informs the package manager about the new status and + * additionally sets the candidate object to the user chosen object. + * @param newStatus The new package status + * @param slbPtr The package pointer + * @param pkgPtr The object pointer (used for candidate selection) + * @return bool + */ + virtual bool setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, ZyppObj objPtr ); + +}; + +//---------------------------------------------------------------- +// Class for strategies to handle status of multi version packages +//---------------------------------------------------------------- +class MultiVersionStatStrategy : public NCPkgStatusStrategy +{ +public: + + MultiVersionStatStrategy(); + + virtual ~MultiVersionStatStrategy() {} + + /** + * Gets the status information from the package manager. + * @param slbPtr The package whose status to calculate. + * @return UI_Status The new status of the given package + * + **/ + virtual ZyppStatus getPackageStatus ( ZyppSel slbPtr, ZyppObj objPtr ); + + /** + * Informs the package manager about the new status and + * additionally sets the candidate object to the user chosen object. + * @param newStatus The new package status + * @param slbPtr The package pointer + * @param pkgPtr The object pointer (used for candidate selection) + * @return bool + */ + virtual bool setObjectStatus( ZyppStatus newstatus, + ZyppSel slbPtr, ZyppObj objPtr ); + + + /** + * Check if any package version is marked for installation where its + * 'multiversion' flag is set to 'multiversion'. + * @param slbPtr The selectable whose status has to be calculated. + * @param multiversion Check for multiversion or non-multiversion packages. + * @return bool + * + **/ + virtual bool anyMultiVersionToInstall( ZyppSel slbPtr, bool multiversion ) const; + + /** + * Ask user if he really wants to install incompatible package versions. + * @param multiversion Selected package is a multiversion package. + * @return bool Return 'true' if he hits [Continue], 'false' if [Cancel]. + * + **/ + virtual bool mixedMultiVersionPopup( bool multiversion ) const; + +}; + + +#endif diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgStrings.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStrings.cc new file mode 100644 index 0000000000000000000000000000000000000000..099322978c952daae3a015bbf4afbe2ecc8bb442 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStrings.cc @@ -0,0 +1,843 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgStrings.cc + Author: Gabriele Strattner + +*/ + + +#include +#include +#include "NCPkgStrings.h" + + +/* + Textdomain "ncurses-pkg" +*/ + +const std::string NCPkgStrings::Deps() +{ + // menu entry 1 - all about pkg dependencies + static const std::string value = _( "&Dependencies" ); + return value; +} + +const std::string NCPkgStrings::View() +{ + // menu entry 2 - display different kinds of info on pkgs + static const std::string value = _( "&View" ); + return value; +} + +const std::string NCPkgStrings::Extras() +{ + // menu entry 3 - miscellaneous stuff + static const std::string value = _( "&Extras" ); + return value; +} + +const std::string NCPkgStrings::Filter() +{ + // pick a package filter - patterns, langs, repos, search,... + static const std::string value = _( "&Filter" ); + return value; +} + + +const std::string NCPkgStrings::InstPkg() +{ + // All installed Packages + static const std::string value = _( "Installed Packages" ); + return value; +} + +const std::string NCPkgStrings::PackageName() +{ + // Label under the pkg table - pkg name follows + static const std::string value = _( "Package: " ); + return value; +} + +const std::string NCPkgStrings::Actions() +{ + // Actions on pkgs (install, remove,..) + static const std::string value = _( "A&ctions" ); + return value; +} + +const std::string NCPkgStrings::Help() +{ + // Help button + static const std::string value = _( "&Help" ); + return value; +} + +const std::string NCPkgStrings::PackageHelp() +{ + // the headline of the help window + static const std::string value = _( "General Help" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgGen1() +{ + // part1 of help text package installation + static const std::string value = _( "

Welcome to the package selector

This tool will help you to manage the software on your system. You can install, update or remove single packages, as well as patterns (sets of packages serving certain purpose) or languages. Usually, you do not need to care about package dependencies when installing or removing anything, the solver will do it for you. The package selector consists of three main parts: filters, package table and menu.

" ); + return value; + +} + +const std::string NCPkgStrings::HelpPkgGen2() +{ + // part of help text package installation + static const std::string value = _( "

Filter on left panel is designed for easy orientation in a large amount of packages. Use filters to display only packages from a certain repository or in a selected pattern (for example, Games or C/C++ Development) or to search for particular keywords. More information on filters can be found in How to use filters.

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgGen3() +{ + // additional help text for post installation + static const std::string value = _( "

Package table is the main component of the package selector. You will see a list of packages matching the current filter (for example, the selected RPM group or search result). Each line of the package table has several columns:

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgGen4() +{ + // part2 of help text package installation + static const std::string value = _( "
  1. Package status (for more information see Package Status and Symbols)
  2. Package name
  3. Package summary
  4. Available version (in some of the configured repositories)
  5. Installed version(empty for not yet installed packages)
  6. Package size
" ); + + return value; +} + +const std::string NCPkgStrings::HelpPkgGen5() +{ + // part3 of help text package installation + static const std::string value = _( "

The Actions menu below the table allows you to change the status of a selected package (or all packages in the list), for example, to delete a package or select an additional package for installation. The status change can also be done directly by pressing the key specified in the menu item (for detailed information about the package status, see Package Status and Symbols).

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgGen6() +{ + // part4 of help text package installation + static const std::string value = _( "

Menu provides functions related to the handling of package dependencies. Display relevant information on packages or perform actions like opening the repository editor. For more information, see Useful Functions in Menu.

" ); + return value; +} + +const std::string NCPkgStrings::PackageStatusHelp() +{ + // the headline of the help window + static const std::string value = _( "Package Status and Symbols" ); + return value; +} + +const std::string NCPkgStrings::HelpOnStatus1() +{ + // part 1 of help text package status + static const std::string value = _( "

The package status can be changed using the Actions menu or the keys specified in the menu items. For example, use '+' to install an additional package.

The \"Taboo\" status means the package should never be installed. On the contrary, the \"Locked\" status means that the installed version of a package should always be kept.

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnStatus2() +{ + // part 2 of help text package status + static const std::string value = _( "

You can also use RET or SPACE to toggle the package status. The Actions menu also allows you to change the status for all packages in the list (select 'All Listed Packages').

" ); + return value; +} +const std::string NCPkgStrings::HelpOnStatus3() +{ + // part 3 of help text package status + static const std::string value = _( "

The meaning of the status flags:

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnStatus4() +{ + // help text package status + static const std::string value = _( "

+ : package will be installed

a+ : package will be installed automatically

> : package will be updated

a> : package will be automatically updated

i : package is installed

- : package will be deleted

---: never install this package (taboo)

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnStatus5() +{ + // help text package status + static const std::string value = _( "

-i-: keep the installed version and never update or delete it ( package locked )

Status information for pattern and languages:

i : All requirements of this pattern/language are satisfied

" ); + return value; +} + +const std::string NCPkgStrings::PackageFiltersHelp() +{ + // label for an error popup + static const std::string value = _( "How to Use Filters" ); + return value; +} + +const std::string NCPkgStrings::HelpOnFilters1() +{ + // help text package status + static const std::string value = _( "

Filter allow you to filter all available packages according to the selected criteria. Package filters are based on package properties (repository, RPM group), package \"containers\" (patterns, languages), package classification or search results. Select the desired filter from the drop-down menu. Specific filters are described below.

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnFilters2() +{ + // help text package status + static const std::string value = _( "

Patterns describe the features and functions a system should have (for example, X server or Console tools). Each pattern contains a set of packages it requires (must have), recommends (should have) and suggests (may have). If you select a pattern for installation, update, or deletion, the solver will run and change the status of subordinate packages accordingly.

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnFilters3() +{ + // help text package status + static const std::string value = _( "

Languages are package containers very much like patterns. They contain packages with translations, dictionaries and other language-specific files for a selected language. RPM Groups are not package containers that can be installed. Instead, membership in a certain RPM group is a property of the package itself. They have a hierarchical (tree) structure. The Repositories filter displays packages available from a specific repository.

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnFilters4() +{ + // help text package search + static const std::string value = _( "

To use the Search filter, enter a keyword (or part of keyword) for the package search. For example, search for all 3D packages using the expression \"3d\". You can also search in package descriptions, RPM provides or requires. Select the appropriate check box and click the 'Search' button.

" ); + return value; +} + +const std::string NCPkgStrings::HelpOnFilters5() +{ + // help text package status +static const std::string value = _( "

The Installation summary presents an overview of packages whose status has changed during this session (e.g. marked for installation or removal), either by the user or automatically by the solver. The filter Package Classification provides information about Recommended, Suggested, Orphaned and Unneeded packages.

" ); + return value; +} + +const std::string NCPkgStrings::PackageMenuHelp() +{ + // label for an error popup + static const std::string value = _( "Useful Functions in Menu" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgMenu1() +{ + static const std::string value = _( "

Dependencies:
This menu offers various actions related to the handling of package dependencies. By default, package dependencies are checked with every status change. You will be informed about package conflicts in a dialog proposing possible conflict resolutions. To resolve the conflict, select one of the offered solutions and press 'OK -- Try Again'.

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgMenu2() +{ + static const std::string value = _( "

To disable dependency checking on every status change, toggle Automatic Dependency Check OFF. You can check dependencies manually by selecting Check Dependencies Now. The Verify system entry will check the dependencies of already installed packages and resolve conflicts non-interactively, marking missing packages for automatic installation if necessary. For debugging purposes, use Generate Dependency Solver Testcase. It will dump package dependencies data into the directory /var/log/YaST2/solverTestcase. This is usually what you need when asked for a \"solver testcase\" in Bugzilla.

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgMenu2_2() +{ + static const std::string value = _( + "

Available options for dependency checking are:
" + "Automatic Dependency Check (see above), " + "Install Recommended Packages: if ON, weak dependencies will be honored, " + "System Verification Mode: repair dependencies of installed packages and solve immediately. " + "Please note: after checking the system with Verify System Now the option System Verification Mode is ON (uncheck the option, if desired). " + "These options are saved in the YaST configuration file /etc/sysconfig/yast2.

" + ); + return value; +} + +const std::string NCPkgStrings::HelpPkgMenu2_3() + { + static const std::string value = _("

Advanced options:
Cleanup when deleting packages: remove dependent unused packages. Allow vendor change: package vendor may differ from vendor of installed package. These options will not be saved, they can only be set in the configuration file of the package library /etc/zypp/zypp.conf.

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgMenu3() +{ + static const std::string value = _( "

View:
Choose which information about the selected package will be displayed in the window below the package table. Available options are: package description, technical data (version, size, license etc.) package versions (all available), file list (all files included in the package) and dependencies (provides, requires etc.).

" ); + return value; +} + +const std::string NCPkgStrings::HelpPkgMenu4() +{ + static const std::string value = _( "

Configuration:
This menu integrates package selector with the rest of package management utils. From here, you can Launch Repository Manager and edit configured repositories or register to update repository and configure periodic download of available updates (Launch Online Update Configuration). Also, you can pick one of the three possible behaviours of package selector at exit - in Action after Package Installation menu.

" ); + return value; +} +const std::string NCPkgStrings::HelpPkgMenu5() +{ + static const std::string value = _( "

Extras:
Miscellaneous functions reside here. Export Package List to File will dump data on installed packages, patterns and languages into specified XML file. This file can be later read by Import Package List from File option e.g. on different computer. It will bring the set of packages on the target computer into the same state as described in provided XML file. Show Available Disk Space will show a popup table displaying disk usage and free disk space on currently mounted partition.

" ); + return value; +} + + +const std::string NCPkgStrings::SearchIn() +{ + // label of a frame with search settings + static const std::string value = _( "&Search in " ); + return value; +} + +const std::string NCPkgStrings::SearchPhrase() +{ + // begin: text/labels for search popups (use unique hotkeys until the end:) + // text for the package search popup + static const std::string value = _( "Search &Phrase" ); + return value; +} + +const std::string NCPkgStrings::PkgStatus() +{ + // column header status + static const std::string value = std::string(" "); + return value; +} + +const std::string NCPkgStrings::PatternsLabel() +{ + // the label of the selections + static const std::string value = _( "Patterns" ); + return value; +} + +const std::string NCPkgStrings::LangCode() +{ + static const std::string value = _( "Code" ); + return value; +} + +const std::string NCPkgStrings::LangName() +{ + static const std::string value = _( "Language" ); + return value; +} + +const std::string NCPkgStrings::RepoURL() +{ + static const std::string value = _( "URL" ); + return value; + +} + +const std::string NCPkgStrings::PkgName() +{ + // column header package name (keep it short!) + static const std::string value = _( "Name" ); + return value; +} + +const std::string NCPkgStrings::PkgVersion() +{ + // column header installed package version (keep it short!) + static const std::string value = _( "Version" ); + return value; +} + +const std::string NCPkgStrings::PkgInstSource() +{ + // column header - repository of the package (e.g. openSUSE 10.3) + static const std::string value = _( "Repository" ); + return value; +} + +const std::string NCPkgStrings::PkgVersionNew() +{ + // column header available package version (keep it short - use abbreviation!) + static const std::string value = _( "Avail. Vers." ); + return value; +} + +const std::string NCPkgStrings::PkgVersionInst() +{ + // column header installed package version (keep it short - use abbreviation!) + static const std::string value = _( "Inst. Vers." ); + return value; +} + +const std::string NCPkgStrings::PkgSummary() +{ + // column header package description (keep it short!) + static const std::string value = _( "Summary" ); + return value; +} + + +const std::string NCPkgStrings::PkgSize() +{ + // column header package size (keep it short!) + static const std::string value = _( "Size" ); + return value; +} + +const std::string NCPkgStrings::PkgArch() +{ + // column header package architecture (keep it short!) + static const std::string value = _( "Architecture" ); + return value; +} + +const std::string NCPkgStrings::PatchKind() +{ + // column header patch kind (keep it short!) + static const std::string value = _( "Kind" ); + return value; +} + +const std::string NCPkgStrings::Solving() +{ + // a text for a small popup which is shown during package dependency checking + static const std::string value = _( "Solving..." ); + return value; +} +const std::string NCPkgStrings::Saving() +{ + // a text for a small popup which is shown during writing package selection to a file + static const std::string value = _( "Saving..." ); + return value; +} +const std::string NCPkgStrings::Loading() +{ + // a text for a samll popup which is shown during loading package selections from a file + static const std::string value = _( "Loading..." ); + return value; +} + +const std::string NCPkgStrings::DiskspaceLabel() +{ + // the headline of the disk space popup + static const std::string value = _( "Disk Usage Overview" ); + return value; +} + +const std::string NCPkgStrings::Partition() +{ + // column header name of the partition (keep it short!) + static const std::string value = _( "Partition" ); + return value; +} + +const std::string NCPkgStrings::UsedSpace() +{ + // column header used disk space (keep it short!) + static const std::string value = _( "Used" ); + return value; +} + +const std::string NCPkgStrings::FreeSpace() +{ + // column header free disk space (keep it short!) + static const std::string value = _( "Free" ); + return value; +} + +const std::string NCPkgStrings::TotalSpace() +{ + // column header total disk space (keep it short!) + static const std::string value = _( "Total" ); + return value; +} + +const std::string NCPkgStrings::DiskSpaceError() +{ + // + static const std::string value = _( "Out of disk space!" ); + return value; +} + +const std::string NCPkgStrings::DiskSpaceWarning() +{ + // + static const std::string value = _( "Disk space is running out!" ); + return value; +} + +const std::string NCPkgStrings::MoreText() +{ + // part of a text + static const std::string value = _( "needs" ); + return value; +} + +const std::string NCPkgStrings::MoreSpaceText() +{ + // part of a text + static const std::string value = _( "more disk space." ); + return value; +} + +const std::string NCPkgStrings::Version() +{ + // part of the package description + static const std::string value = _( "Version: " ); + return value; +} + +const std::string NCPkgStrings::Size() +{ + // part of the package description + static const std::string value = _( "Size: " ); + return value; +} + +const std::string NCPkgStrings::InstVersion() +{ + // part of the package description + static const std::string value = _( "Installed: " ); + return value; +} + +const std::string NCPkgStrings::Authors() +{ + // part of the package description + static const std::string value = _( "Authors: " ); + return value; +} + +const std::string NCPkgStrings::License() +{ + // part of the package description + static const std::string value = _( "License: " ); + return value; +} + +const std::string NCPkgStrings::MediaNo() +{ + // part of the package description + static const std::string value = _( "Media No.: " ); + return value; +} + +const std::string NCPkgStrings::Provides() +{ + // part of the package description + static const std::string value = _( "Provides: " ); + return value; +} + +const std::string NCPkgStrings::Requires() +{ + // part of the package description + static const std::string value = _( "Requires: " ); + return value; +} + +const std::string NCPkgStrings::PreRequires() +{ + // part of the package description + static const std::string value = _( "Prerequires: " ); + return value; + +} + +const std::string NCPkgStrings::Conflicts() +{ + // part of the package description + static const std::string value = _( "Conflicts with: " ); + return value; +} + +const std::string NCPkgStrings::ListOfFiles() +{ + // headline for a list of installed files + static const std::string value = _( "List of Installed Files:
" ); + return value; +} + +const std::string NCPkgStrings::LanguageDescription() +{ + static const std::string value = _( "Translations, dictionaries and other language-related files for " ); + return value; +} + +const std::string NCPkgStrings::AutoChangeLabel() +{ + // the headline of the popup containing a list with packages with status changes + static const std::string value = _( "Automatic Changes" ); + return value; +} + +const std::string NCPkgStrings::AutoChangeText1() +{ + // text part1 of popup with automatic changes (it's a label; text continous) + static const std::string value = _( "In addition to your manual selections, the following" ); + return value; +} + +const std::string NCPkgStrings::AutoChangeText2() +{ + // text part1 of popup with automatic changes continous + static const std::string value = _( "packages have been changed to resolve dependencies:" ); + return value; +} + +const std::string NCPkgStrings::YouHelp() +{ + // the headline of the help popup + static const std::string value = _( "Patch Status and Patch Installation" ); + return value; +} + +const std::string NCPkgStrings::YouHelp1() +{ + // help text online udpate + // Do NOT translate 'recommended' and 'security'! because the patch kind is always shown as english text. + static const std::string value = _( "

General information about patches:

The patches of kind security are solving security issues and we highly recommend to install it. You should also install recommended patches, they usually contain important bug-fixes. Install feature patches if you are interested in the feature.

" ); + return value; +} + +const std::string NCPkgStrings::YouHelp2() +{ + // help text online udpate continue + static const std::string value = _( "

Patches for \"libzypp\" (Package, Patch, Pattern and Product Management) will always get installed first. Other patches must be installed on a second run.

" ); + return value; +} + +const std::string NCPkgStrings::YouHelp3() +{ + // help text online udpate continue + static const std::string value = _( "

Meaning of the status flags:

a+ : Patches concerning your installation are preselected. They will be downloaded and installed on your system. If you do not want a certain patch, deselect it with '-'.

i : All requirements of this patch are satisfied.

+ : You have selected this patch for installation.

" ); + return value; +} + +const std::string NCPkgStrings::YouHelp4() +{ + // help text online udpate continue + static const std::string value = _( "

More details about the status:
If there are several patches for a package (or a set of packages) which aren't yet applied to the system all got preselected and have status a+. If one of these patches is deselected with '-' it might show the status i afterwards. This is because any of the other patches concerning the same package(s) is still selected. The newer version(s) of the package(s) will be installed and with it this patch is satisfied. Deselecting of all patches is required if the patches are not wanted.

"); + return value; +} + +const std::string NCPkgStrings::YouHelp5() +{ + // help text online udpate continue + static const std::string value = _( "

The menus:

The Filter menu allows to filter the patches, e.g. show the 'Installed' ones or list 'Security' patches. It also provides to search for patches.
Use the Actions menu to change the status of a patch.
The View menu offers the possibility to see which packages are concerned by the patch. Please note: If the filter is 'All Patches' the package list for some patches might be empty. This means no packages are concerned because none of the patch packages is installed on the system.
The Dependencies menu contains dependencies checks and the 'Generate Solver Testcase' entry.

"); + return value; +} +// +// label, text for translation +// +const std::string NCPkgStrings::WarningLabel() +{ + // label for a warning popup + static const std::string value = _( "Warning" ); + return value; +} + +const std::string NCPkgStrings::ErrorLabel() +{ + // label for an error popup + static const std::string value = _( "Error" ); + return value; +} + +const std::string NCPkgStrings::NotifyLabel() +{ + // label for a notify popup + static const std::string value = _( "Notify" ); + return value; +} + + +const std::string NCPkgStrings::OKLabel() +{ + // the label of an OK button + static const std::string value = _( "&OK" ); + return value; +} + +const std::string NCPkgStrings::ContinueLabel() +{ + // begin: the label of the Contiunue button + static const std::string value = _( "C&ontinue" ); + return value; +} + +const std::string NCPkgStrings::CancelLabel() +{ + // begin: the label of the Cancel button + static const std::string value = _( "&Cancel" ); + return value; +} + +const std::string NCPkgStrings::YesLabel() +{ + // the label of the Yes button + static const std::string value = _( "&Yes" ); + return value; +} + +const std::string NCPkgStrings::AcceptLabel() +{ + // the label of an Accept button + static const std::string value = _( "&Accept" ); + return value; +} + +const std::string NCPkgStrings::NoLabel() +{ + // the label of the No button + static const std::string value = _( "&No" ); + return value; +} + +const std::string NCPkgStrings::SolveLabel() +{ + // the label of the Solve button - 'try again' implies that user + // has to make some action (#213602) + static const std::string value = _( "&OK -- Try Again" ); + return value; +} + + +const std::string NCPkgStrings::CancelText() +{ + // text for a Notify popup + static const std::string value = _( "

All changes in the package, patch or pattern selection will be lost.
Really exit?

" ); + return value; +} + +// FIXME: remove these if possible +const std::string NCPkgStrings::LanguageLabel() +{ + // the label of language table + static const std::string value = _( "Available Languages" ); + return value; +} + +const std::string NCPkgStrings::RepoLabel() +{ + // the label of language table + static const std::string value = _( "Available Repositories" ); + return value; +} + +const std::string NCPkgStrings::YOUPatches() +{ + // A label for a list of YOU Patches - keep it short - max 25 chars! + // (the list shows all patches which are needed) + // static const std::string value = _( "Installable Patches" ); + // static const std::string value = _( "Relevant Patches" ); + static const std::string value = _( "Needed Patches" ); + return value; +} + +const std::string NCPkgStrings::InstPatches() +{ + // A label for a list of YOU Patches - keep it short - max. 25 chars! + // (the list shows all patches which are already installed) + static const std::string value = _( "Installed Patches" ); + // static const std::string value = _( "Satisfied Patches" ); + return value; +} + +const std::string NCPkgStrings::Patches() +{ + // A common label for a list of YOU Patches - keep it short - max. 25 chars! + static const std::string value = _( "Online Update Patches" ); + return value; +} + +const std::string NCPkgStrings::UpdateProblem() +{ + // the label Filter: Update Problem ( keep it short - max. 25 chars ) + static const std::string value = _( "Update Problem -- see help" ); + return value; +} + +const std::string NCPkgStrings::SearchResults() +{ + // the label for Filter: Search results + static const std::string value = _( "Search Results" ); + return value; +} + +const std::string NCPkgStrings::PackageDeps() +{ + // the headline of the dependency popup + static const std::string value = _( "Package Dependencies" ); + return value; +} + +const std::string NCPkgStrings::HelpOnUpdate() +{ + // help text package status + static const std::string value = _( "Update Problem List

The packages in the list cannot be updated automatically.

Possible reasons:

They are obsoleted by other packages.

There is no newer version to which to update on any installation media.

They are third-party packages

Manually select what to do with them. The safest course of action is to delete them.

" ); + return value; +} + +const std::string NCPkgStrings::PkgSource() +{ + // column header source RPM installation (keep it short!) + static const std::string value = _( "Source" ); + return value; +} + +const std::string NCPkgStrings::Patch() +{ + // part of the patch description + static const std::string value = _( "Patch: " ); + return value; +} + +const std::string NCPkgStrings::NoPatches() +{ + // info line is shown if YOU patch list is empty + static const std::string value = _( "No patches available" ); + return value; +} + +const std::string NCPkgStrings::Script() +{ + static const std::string value = _( "Script" ); + return value; +} + +const std::string NCPkgStrings::MultiversionHead() +{ + static const std::string value = _( "Incompatible Package Versions" ); + return value; +} + +const std::string NCPkgStrings::MultiversionIntro() +{ + static const std::string value = + _( "

You are trying to install multiversion-capable " + "and non-multiversion-capable versions of this " + "package at the same time.

" ); + return value; +} + +const std::string NCPkgStrings::MultiversionText() +{ + static const std::string value = + _( "

This version is multiversion-capable.

" + "

Press \"Continue\" to install this version " + "and unselect the non-multiversion-capable version, " + "\"Cancel\" to unselect this version and keep the other one.

" ); + return value; +} + +const std::string NCPkgStrings::NotMultiversionText() +{ + static const std::string value = + _( "

This version is not multiversion-capable.

" + "

Press \"Continue\" to install only this version " + "and unselect all other versions, " + "\"Cancel\" to unselect this version and keep the other ones.

" ); + return value; +} + +const std::string NCPkgStrings::RetractedLabel() +{ + // Special status for versions of a package that are retracted, i.e. that + // were released, but it was later realized that a broken version was + // published that should rather not be used. This is a very exceptional + // case that requires special attention by the user. + static const std::string value = _( "[RETRACTED]" ); + return value; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgStrings.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStrings.h new file mode 100644 index 0000000000000000000000000000000000000000..ef6b58758f733008486cea37f76be446de1faee0 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgStrings.h @@ -0,0 +1,338 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgStrings.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgStrings_h +#define NCPkgStrings_h + +#include + +#include + + +// Class to make available globally used names in package selection dialog, +// such as widget ids, text which has to be translated and so on + +class NCPkgStrings +{ +public: + + // Main menu entry Dependencies + static const std::string Deps(); + + // Main menu entry View + static const std::string View(); + + // Main menu entry 'Extras' + static const std::string Extras(); + + // Package Filters combo box label + static const std::string Filter(); + + static const std::string InstPkg(); + + // Label below the table - pkg name follows + static const std::string PackageName(); + + // Actions menu (what to do with the pkg) + static const std::string Actions(); + + static const std::string Help(); + + // The headline of the help popup + static const std::string PackageHelp(); + + // strings in 'General Help' + static const std::string HelpPkgGen1(); + static const std::string HelpPkgGen2(); + static const std::string HelpPkgGen3(); + static const std::string HelpPkgGen4(); + static const std::string HelpPkgGen5(); + static const std::string HelpPkgGen6(); + + // The headline of the help popup + static const std::string PackageStatusHelp(); + + // strings in 'Package Status and symbols' + static const std::string HelpOnStatus1(); + static const std::string HelpOnStatus2(); + static const std::string HelpOnStatus3(); + static const std::string HelpOnStatus4(); + static const std::string HelpOnStatus5(); + + // The headline of the help popup + static const std::string PackageFiltersHelp(); + + // string in 'How to use filters' + static const std::string HelpOnFilters1(); + static const std::string HelpOnFilters2(); + static const std::string HelpOnFilters3(); + static const std::string HelpOnFilters4(); + static const std::string HelpOnFilters5(); + + // The headline of the help popup + static const std::string PackageMenuHelp(); + + // strings in 'Useful functions in menu' + static const std::string HelpPkgMenu1(); + static const std::string HelpPkgMenu2(); + static const std::string HelpPkgMenu2_2(); + static const std::string HelpPkgMenu2_3(); + static const std::string HelpPkgMenu3(); + static const std::string HelpPkgMenu4(); + static const std::string HelpPkgMenu5(); + + // Search settings + static const std::string SearchIn(); + static const std::string SearchPhrase(); + + // table column headlines + static const std::string PkgStatus(); + static const std::string PatternsLabel(); + static const std::string LangCode(); + static const std::string LangName(); + static const std::string RepoURL(); + static const std::string PkgName(); + static const std::string PkgSummary(); + static const std::string PkgVersion(); + static const std::string PkgInstSource(); + static const std::string PkgVersionNew(); + static const std::string PkgVersionInst(); + static const std::string PkgSize(); + static const std::string PkgArch(); + static const std::string PkgSource(); + static const std::string PatchKind(); + + // Useful busy popups + static const std::string Solving(); + static const std::string Saving(); + static const std::string Loading(); + + /** + * The headline of the disk space popup + */ + static const std::string DiskspaceLabel(); + + // column headers, diskspace table + static const std::string Partition(); + static const std::string UsedSpace(); + static const std::string FreeSpace(); + static const std::string TotalSpace(); + /** + * The headline of the disk space popup + */ + static const std::string DiskSpaceError(); + static const std::string DiskSpaceWarning(); + static const std::string MoreText(); + static const std::string MoreSpaceText(); + + /** + * bold text Version: (richtext) + */ + static const std::string Version(); + + /** + * bold text Installed version: (richtext) + */ + static const std::string InstVersion(); + + /** + * bold text License: (richtext) + */ + static const std::string License(); + + /** + * bold text Media No.: (richtext) + */ + static const std::string MediaNo(); + + /** + * bold text Size: (richtext) + */ + static const std::string Size(); + + /** + * bold text Authors: (richtext) + */ + static const std::string Authors(); + + /** + * bold text Provides: (richtext) + */ + static const std::string Provides(); + + /** + * bold text Requires: (richtext) + */ + static const std::string Requires(); + + /** + * bold text Required by: (richtext) + */ + static const std::string PreRequires(); + + /** + * bold text Conflicts with: (richtext) + */ + static const std::string Conflicts(); + + static const std::string ListOfFiles(); + static const std::string LanguageDescription(); + /** + * text used for automatic changes popup + */ + static const std::string AutoChangeLabel(); + static const std::string AutoChangeText1(); + static const std::string AutoChangeText2(); + + /** + * The headline of the help YOU popup + */ + static const std::string YouHelp(); + + /** + * help text package status + */ + static const std::string YouHelp1(); + static const std::string YouHelp2(); + static const std::string YouHelp3(); + static const std::string YouHelp4(); + static const std::string YouHelp5(); + + static const std::string WarningLabel(); + static const std::string ErrorLabel(); + static const std::string NotifyLabel(); + + /** + * The label of the OK button + */ + static const std::string OKLabel(); + + /** + * The label of the Cancel button + */ + static const std::string CancelLabel(); + + /** + * The label of the Continue button + */ + static const std::string ContinueLabel(); + + /** + * The label of the Yes button + */ + static const std::string YesLabel(); + + /** + * The label of the Accept button + */ + static const std::string AcceptLabel(); + + /** + * The label of the No button + */ + static const std::string NoLabel(); + + /** + * The label of the Solve button + */ + static const std::string SolveLabel(); + + + static const std::string CancelText(); + /** + * The label of the language selections popup + */ + static const std::string LanguageLabel(); + + /** + * The label of the repositories selections popup + */ + static const std::string RepoLabel(); + + /** + * The label Filter: YOU Patches + */ + static const std::string YOUPatches(); + static const std::string InstPatches(); + static const std::string Patches(); + + /** + * The label for Filter: Search results + */ + static const std::string SearchResults(); + + /** + * The label for Filter: Update problem + */ + static const std::string UpdateProblem(); + + /** + * The headline of the dependency popup + */ + static const std::string PackageDeps(); + + static const std::string HelpOnUpdate(); + + /** + * bold text Patch: (richtext) + */ + static const std::string Patch(); + + /** + * Info line in empty patch list + */ + static const std::string NoPatches(); + + static const std::string MenuList(); + static const std::string Script(); + + /** + * Info about multiversion packages + */ + static const std::string MultiversionHead(); + static const std::string MultiversionIntro(); + static const std::string MultiversionText(); + static const std::string NotMultiversionText(); + + /** + * Marking for package versions that are retracted. + **/ + static const std::string RetractedLabel(); + + +private: + + // Need no object of this class: hide default constructor + NCPkgStrings(); + + static int do_something(){ return 0; } + +}; + + +/////////////////////////////////////////////////////////////////// + +#endif // NCPkgStrings_h + + + diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgTable.cc b/deps/libyui/libyui-ncurses-pkg/src/NCPkgTable.cc new file mode 100644 index 0000000000000000000000000000000000000000..110760231bf76490b7b297ac7f254e50e57a11de --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgTable.cc @@ -0,0 +1,1206 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgTable.cc + Author: Gabriele Strattner + +*/ + + +#include +#include + +#define YUILogComponent "ncurses-pkg" +#include + +#include + +#include +#include +#include +#include + +#include "NCPackageSelector.h" +#include "NCPkgPopupDiskspace.h" +#include "NCPkgStrings.h" +#include "NCZypp.h" +#include "NCPkgTable.h" + +#define SOURCE_INSTALL_SUPPORTED 0 + +using std::string; +using std::vector; +using std::endl; + +/* + Textdomain "ncurses-pkg" +*/ + + +NCPkgTableTag::NCPkgTableTag( ZyppObj objPtr, ZyppSel selPtr, ZyppStatus stat ) + : YTableCell( " " ) + , status ( stat ) + , dataPointer( objPtr ) + , selPointer( selPtr ) +{ + setLabel( statusToString(stat) ); +} + + +string NCPkgTableTag::statusToString( ZyppStatus stat ) const +{ + // convert ZyppStatus to string + switch ( stat ) + { + case S_NoInst: // Is not installed and will not be installed + return " "; + + case S_KeepInstalled: // Is installed - keep this version + return " i "; + + case S_Install: // Will be installed + return " + "; + + case S_Del: // Will be deleted + return " - "; + + case S_Update: // Will be updated + return " > "; + + case S_AutoInstall: // Will be automatically installed + return " a+ "; + + case S_AutoDel: // Will be automatically deleted + return " a- "; + + case S_AutoUpdate: // Will be automatically updated + return " a> "; + + case S_Taboo: // Never install this + return " ---"; + + case S_Protected: // Always keep installed version + return " -i-"; + + default: + return "####"; + } + + return " "; +} + + +NCPkgTable::NCPkgTable( YWidget * parent, YTableHeader * tableHeader ) + : NCTable( parent, tableHeader ) + , packager( 0 ) + , statusStrategy( new PackageStatStrategy ) // default strategy: packages + , tableType( T_Packages ) // default type: packages + , haveInstalledVersion( false ) + , visibleInfo( I_Technical ) +{ + yuiDebug() << "NCPkgTable created" << endl; +} + + +NCPkgTable::~NCPkgTable() +{ + delete statusStrategy; + yuiDebug() << endl; +} + + +void NCPkgTable::addLine( ZyppStatus stat, + const vector & elements, + ZyppObj objPtr, + ZyppSel slbPtr ) +{ + YTableItem *tabItem = new YTableItem(); + + // fill first column (containing the status information and the package pointers) + tabItem->addCell( new NCPkgTableTag( objPtr, slbPtr, stat )); + + for ( const string& s: elements ) + tabItem->addCell( s ); + + // use all-at-once insertion mode - DrawPad() is called only after the loop + addItem( tabItem, true ); +} + + +void NCPkgTable::itemsCleared() +{ + return NCTable::deleteAllItems(); +} + + +// +// Set the new status in the first column of the package table and in libzypp +// +bool NCPkgTable::changeStatus( ZyppStatus newstatus, + const ZyppSel & slbPtr, + ZyppObj objPtr, // this is candidatePtr or what the user selected instead of it + bool singleChange ) +{ + if ( !packager || !slbPtr ) + return false; + + yuiMilestone() << "Changing status of " << slbPtr->name() << endl; + + string notify; + string license; + bool confirmed = true; + ZyppPkg pkgPtr = NULL; + string header; + bool ok = true; + + switch ( newstatus ) + { + case S_Del: + case S_NoInst: + case S_Taboo: + if ( objPtr ) + { + notify = objPtr->delnotify(); + yuiMilestone() << "DELETE message: " << notify << endl; + header = NCPkgStrings::WarningLabel(); + } + break; + + // display notify msg only if we mark pkg for installation + // disregard update, to be consistent with Qt (#308410) + case S_Install: + if ( objPtr ) + { + notify = objPtr->insnotify(); + yuiMilestone() << "NOTIFY message: " << notify << endl; + header = NCPkgStrings::NotifyLabel(); + } + // FALLTHROUGH + case S_Update: + case S_AutoInstall: + case S_AutoUpdate: + if ( objPtr ) + { + if ( objPtr->isRetracted() ) + confirmed = confirmRetracted( objPtr, slbPtr ); + + if ( confirmed ) + license = objPtr->licenseToConfirm(); + } + break; + + default: break; + } + + string pkgName = slbPtr->name(); + + if ( ! license.empty() ) + { + if ( ! slbPtr->hasLicenceConfirmed() ) + confirmed = packager->showLicensePopup( pkgName, license); + + if ( confirmed ) + { + yuiMilestone() << "User confirmed license agreement for " << pkgName << endl; + slbPtr->setLicenceConfirmed (true); + } + } + + if ( ! confirmed ) + { + // make sure the package won't be installed + switch ( newstatus ) + { + case S_Install: + case S_AutoInstall: + newstatus = S_Taboo; + break; + + case S_Update: + case S_AutoUpdate: + newstatus = S_Protected; + break; + + default: + break; + } + + ok = false; + } + + if ( ok && ! notify.empty() ) + { + int cols = NCurses::cols(); + int lines = NCurses::lines(); + + string html_text = packager->InfoText()->createHtmlText( notify ); + NCPopupInfo * info = new NCPopupInfo( wpos( (lines * 35)/100, (cols * 25)/100), + header, + "" + pkgName + "

" + html_text ); + info->setPreferredSize( (cols * 50)/100, (lines * 30)/100); + info->showInfoPopup(); + + YDialog::deleteTopmostDialog(); + } + + // inform the package manager + ok = statusStrategy->setObjectStatus( newstatus, slbPtr, objPtr ); + + if ( ok && singleChange ) + { + switch ( tableType ) + { + case T_Packages: + case T_PatchPkgs: + case T_Update: + // check/show dependencies of packages + packager->showPackageDependencies( false ); // only check if automatic check is ON + // show the required diskspace + packager->showDiskSpace(); + break; + + case T_Availables: + // check/show dependencies of packages + packager->showPackageDependencies( false ); + // don't show diskspace (type T_Availables is also used in YOU mode) + break; + + case T_Selections: + // check/show dependencies of selections + packager->showSelectionDependencies(); + packager->showDiskSpace(); + break; + + case T_Patches: + // show the download size for all selected patches + packager->showDownloadSize(); + packager->showPackageDependencies( false ); + break; + + default: + break; + } + + // update this list to show the status changes + updateTable(); + + if ( tableType == T_Availables || tableType == T_MultiVersion ) + { + // additionally update the package list + packager->updatePackageList(); + } + } + + return ok; +} + + +// +// Set the new status info if status has changed +// +bool NCPkgTable::updateTable() +{ + unsigned int size = getNumLines(); + unsigned int index = 0; + bool ret = true; + + while ( index < size ) + { + // get the table line + NCTableLine * cl = myPad()->ModifyLine( index ); + + if ( !cl ) + { + ret = false; + break; + } + + // get first column (the column containing the status info) + YTableItem *it = dynamic_cast (cl->origItem() ); + YTableCell *tcell = it->cell(0); + NCPkgTableTag * cc = static_cast( tcell ); + // get the object pointer + ZyppSel slbPtr = getSelPointer( index ); + ZyppObj objPtr = getDataPointer( index ); + + if ( !cc ) + { + ret = false; + break; + } + + ZyppStatus newstatus = S_NoInst; + if ( slbPtr && objPtr) + { + if ( tableType == T_Availables && !slbPtr->multiversionInstall() ) + { + string isCandidate = " "; + if ( objPtr == slbPtr->candidateObj() ) + isCandidate = " x "; + + cl->AddCol( 2, new NCTableCol( isCandidate ) ); + } + else + { + // get the new status and replace old status + newstatus = statusStrategy->getPackageStatus( slbPtr, objPtr ); + + // set new status (if status has changed) + if ( getStatus(index) != newstatus ) + { + cc->setStatus( newstatus ); + setCell( index, 0, cc->statusToString (newstatus) ); + } + } + } + index++; + } + + DrawPad(); + + return ret; +} + + +static bool slbHasInstalledObj (const ZyppSel & slb) +{ + return ! slb->installedEmpty(); +} + + +// +// Fill the column headers of the package table +// +void NCPkgTable::fillHeader() +{ + vector header; + + switch ( tableType ) + { + case T_Packages: + case T_Update: + { + bool haveInstalledPkgs = find_if (zyppPkgBegin(), zyppPkgEnd(), + slbHasInstalledObj) != zyppPkgEnd(); + + header.reserve(7); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgName() ); + header.push_back( NCPkgStrings::PkgSummary() ); + + if ( haveInstalledPkgs > 0 ) + { + header.push_back( NCPkgStrings::PkgVersionNew() ); + header.push_back( NCPkgStrings::PkgVersionInst() ); + haveInstalledVersion = true; + } + else + { + header.push_back( NCPkgStrings::PkgVersion() ); + } + + header.push_back( NCPkgStrings::PkgSize() ); + +#if SOURCE_INSTALL_SUPPORTED + header.push_back( NCPkgStrings::PkgSource() ); +#endif + break; + } + case T_PatchPkgs: + { + header.reserve(7); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgName() ); + header.push_back( NCPkgStrings::PkgVersionNew() ); + header.push_back( NCPkgStrings::PkgVersionInst() ); + header.push_back( NCPkgStrings::PkgSummary() ); + header.push_back( NCPkgStrings::PkgSize() ); + break; + } + case T_Patches: + { + header.reserve(6); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgName() ); + header.push_back( NCPkgStrings::PatchKind() ); + header.push_back( NCPkgStrings::PkgSummary() ); + header.push_back( NCPkgStrings::PkgVersion() ); + // header.push_back( NCPkgStrings::PkgSize() ); + break; + } + case T_Selections: + { + header.reserve(3); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PatternsLabel() ); + break; + } + case T_Languages: + { + header.reserve(4); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::LangCode() ); + header.push_back( NCPkgStrings::LangName() ); + break; + } + case T_Availables: + { + header.reserve(6); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgName() ); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgVersion() ); + header.push_back( NCPkgStrings::PkgInstSource() ); + header.push_back( NCPkgStrings::PkgSize() ); + header.push_back( NCPkgStrings::PkgArch() ); + break; + } + case T_MultiVersion: + { + header.reserve(5); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgName() ); + header.push_back( NCPkgStrings::PkgVersion() ); + header.push_back( NCPkgStrings::PkgInstSource() ); + header.push_back( NCPkgStrings::PkgSize() ); + header.push_back( NCPkgStrings::PkgArch() ); + break; + } + default: { + header.reserve(4); + header.push_back( NCPkgStrings::PkgStatus() ); + header.push_back( NCPkgStrings::PkgName() ); + header.push_back( NCPkgStrings::PkgSummary() ); + break; + } + } + setHeader( header ); +} + + +bool NCPkgTable::createListEntry( ZyppPkg pkgPtr, ZyppSel slbPtr ) +{ + vector pkgLine; + pkgLine.reserve(6); + + if ( !pkgPtr || !slbPtr ) + { + yuiError() << "No valid package available" << endl; + return false; + } + + // add the package name + pkgLine.push_back( slbPtr->name() ); + + string instVersion = ""; + string version = ""; + ZyppStatus status; + + switch ( tableType ) + { + case T_PatchPkgs: + { + // if the package is installed, get the installed version + if ( ! slbPtr->installedEmpty() ) + { + instVersion = slbPtr->installedObj()->edition().asString(); + } + + // if a candidate is available, get the candidate version + if ( slbPtr->hasCandidateObj() ) + { + version = slbPtr->candidateObj()->edition().asString(); + } + else + { + version = pkgPtr->edition().asString(); + } + pkgLine.push_back( version ); + + // in case of YOU there are always installed packages + // => always add installed version (or empty column) + pkgLine.push_back( instVersion ); + + pkgLine.push_back( pkgPtr->summary() ); // short description + + status = slbPtr->status(); // the package status + yuiMilestone() << "Status of " << slbPtr->name() << ": " << status << endl; + FSize size(zypp::ByteCount::SizeType(pkgPtr->installSize())); // installed size + pkgLine.push_back( size.form( 8 ) ); // format size + + break; + } + + case T_Availables: + { + string isCandidate = " "; + if ( pkgPtr == slbPtr->candidateObj() ) + isCandidate = " x "; + pkgLine.push_back( isCandidate ); + + version = pkgPtr->edition().asString(); + + if ( pkgPtr->isRetracted() ) + version += " " + NCPkgStrings::RetractedLabel(); + + pkgLine.push_back( version ); + // show the name of the repository (the installation source) + pkgLine.push_back( pkgPtr->repository().info().name() ); + + // set package status either to S_NoInst or S_KeepInstalled + status = S_NoInst; + zypp::ui::Selectable::installed_iterator it = slbPtr->installedBegin(); + + while ( it != slbPtr->installedEnd() ) + { + if ( pkgPtr->edition() == (*it)->edition() && + pkgPtr->arch() == (*it)->arch() && + pkgPtr->vendor() == (*it)->vendor() ) + { + status = S_KeepInstalled; + } + ++it; + } + + FSize size(zypp::ByteCount::SizeType(pkgPtr->installSize())); // installed size + pkgLine.push_back( size.form( 8 ) ); // format size + pkgLine.push_back( pkgPtr->arch().asString()); // architecture + + break; + } + + case T_MultiVersion: + { + version = pkgPtr->edition().asString(); + + if ( pkgPtr->isRetracted() ) + version += " " + NCPkgStrings::RetractedLabel(); + + pkgLine.push_back( version ); + // show the name of the repository (the installation source) + pkgLine.push_back( pkgPtr->repository().info().name() ); + + zypp::PoolItem itemPtr( pkgPtr->satSolvable() ); + status = slbPtr->pickStatus( itemPtr ); + yuiMilestone() << "Multi version: status of " << version << ": " << status << endl; + + FSize size(zypp::ByteCount::SizeType(pkgPtr->installSize())); // installed size + pkgLine.push_back( size.form( 8 ) ); // format size + pkgLine.push_back( pkgPtr->arch().asString()); // architecture + break; + } + + default: + { + // if the package is installed, get the installed version + pkgLine.push_back( pkgPtr->summary() ); // short description + + if ( ! slbPtr->installedEmpty() ) + { + instVersion = slbPtr->installedObj()->edition().version(); + + // if a candidate is available, get the candidate version + if ( slbPtr->hasCandidateObj() ) + { + version = slbPtr->candidateObj()->edition().version(); + } + } + else + { + version = pkgPtr->edition().version(); + } + pkgLine.push_back( version ); // the available version (the candidate) + + if ( haveInstalledVersion ) + { + pkgLine.push_back( instVersion ); // installed version + } + + status = slbPtr->status(); // the package status + + FSize size(zypp::ByteCount::SizeType(pkgPtr->installSize())); // installed size + pkgLine.push_back( size.form( 8 ) ); // format size + +#if SOURCE_INSTALL_SUPPORTED + if ( slbPtr->source_install() ) + { + pkgLine.push_back( " x " ); + } + else +#endif + { + pkgLine.push_back( " " ); + } + } + } + + addLine( status, // the package status + pkgLine, // the package data + pkgPtr, // the corresponding package pointer + slbPtr ); + + return true; +} + + +bool NCPkgTable::createInfoEntry ( string text ) +{ + vector pkgLine; + pkgLine.reserve(2); + + pkgLine.push_back( text ); + addLine( S_NoInst, // use status NoInst + pkgLine, + ZyppObj(), + ZyppSel() ); // null pointer + + return true; +} + + +bool NCPkgTable::createPatchEntry ( ZyppPatch patchPtr, ZyppSel slb ) +{ + vector pkgLine; + pkgLine.reserve(5); + + if ( !patchPtr || !slb ) + { + yuiError() << "No valid patch available" << endl; + return false; + } + + pkgLine.push_back( slb->name() ); // show the patch name + + pkgLine.push_back( patchPtr->category() ); // patch kind + + if ( !patchPtr->summary().empty() ) + pkgLine.push_back( patchPtr->summary() ); // short description + else + pkgLine.push_back( slb->name() ); // name + + pkgLine.push_back( patchPtr->edition().asString() ); // patch version + + // zypp::ByteCount size = patchPtr->size(); + // pkgLine.push_back( size.asString( 8 ) ); + + + addLine( slb->status(), // get the status + pkgLine, + patchPtr, + slb ); // the corresponding pointer + + return true; +} + + +bool NCPkgTable::showInformation() +{ + if ( getCurrentItem() == -1 ) + { + yuiWarning() << "no selected package" << endl; + return false; + } + + ZyppObj objPtr = getDataPointer( getCurrentItem() ); + ZyppSel slbPtr = getSelPointer( getCurrentItem() ); + + if ( !packager || !objPtr || !slbPtr ) + return false; + + yuiMilestone() << "show information for " << slbPtr->name() << endl; + + switch ( tableType ) + { + case T_Packages: + case T_Update: + // show the required package info + updateInfo( objPtr, slbPtr, VisibleInfo() ); + packager->PackageLabel()->setLabel( slbPtr->name() ); + break; + + case T_Patches: + // show the patch info + updateInfo( objPtr, slbPtr, VisibleInfo() ); + break; + + default: + break; + } + + return true; +} + + +NCursesEvent NCPkgTable::wHandleInput( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + + // call handleInput of NCPad + handleInput( key ); + + if ( packager->isTestMode() ) + { + if ( packager->diskSpacePopup() ) + packager->diskSpacePopup()->setDiskSpace( key ); + return ret; + } + + switch ( key ) + { + case KEY_UP: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_PPAGE: + case KEY_END: + case KEY_HOME: + showInformation(); + break; + + case KEY_SPACE: + case KEY_RETURN: + cycleObjStatus(); + break; + + // Inherited from the parent class to enable sorting + case CTRL('o'): + NCTable::wHandleInput( key); + break; + + case '-': + case '+': + case '>': + case '<': + case '!': + case '*': + // set the new status + changeObjStatus( key ); + + default: + break; + } + + NCDialog * currentDialog = static_cast(YDialog::topmostDialog()); + if ( currentDialog ) + currentDialog->setStatusLine(); + + return NCursesEvent::handled; +} + + +// +// Get the status of the package of the selected line +// +ZyppStatus NCPkgTable::getStatus( int index ) +{ + NCPkgTableTag * cc = getTag( index); + if ( !cc ) + return S_NoInst; + + return cc->getStatus(); +} + + +ZyppObj NCPkgTable::getDataPointer( int index ) +{ + NCPkgTableTag *cc = getTag( index ); + if ( !cc ) + return ZyppObj(); + + return cc->getDataPointer(); +} + + +ZyppSel NCPkgTable::getSelPointer( int index ) +{ + NCPkgTableTag *cc = getTag( index ); + if ( !cc ) + return ZyppSel(); + + return cc->getSelPointer(); +} + + +NCPkgTableTag * NCPkgTable::getTag( const int & index ) +{ + NCTableLine * cl = myPad()->ModifyLine( index ); + if ( !cl ) + return 0; + + // get first column (the column containing the status info) + YTableItem *it = dynamic_cast (cl->origItem() ); + YTableCell *tcell = it->cell(0); + NCPkgTableTag * cc = static_cast( tcell ); + + return cc; +} + + +#if SOURCE_INSTALL_SUPPORTED + +bool NCPkgTable::SourceInstall( bool install ) +{ + int index = getCurrentItem(); + ZyppObj objPtr = getDataPointer( index ); + bool ok; + + if ( !objPtr ) + { + yuiError() << "Invalid Pointer" << endl; + return false; + } + ZyppSel selPtr = objPtr->getSelectable(); + NCTableLine * currentLine = myPad()->ModifyLine( index ); + + if ( !selPtr || !currentLine ) + { + yuiError() << "Invalid Selectable" << endl; + return false; + } + + NCTableCol * currentCol = currentLine->GetCol( currentLine->Cols()-1 ); + + if ( install && selPtr->providesSources() ) + { + ok = selPtr->set_source_install( true ); + yuiMilestone() << "Set source install returns: " << ( ok ? "true" : "false" ) << endl; + if ( currentCol ) + currentCol->SetLabel( NClabel( " x " ) ); + } + else if ( !install && selPtr->source_install() ) + { + ok = selPtr->set_source_install( false ); + yuiMilestone() << "ReSet source install returns: " << ( ok ? "true" : "false" ) << endl; + if ( currentCol ) + currentCol->SetLabel( NClabel( " " ) ); + } + + return true; +} +#endif + + +bool NCPkgTable::cycleObjStatus() +{ + ZyppSel slbPtr = getSelPointer( getCurrentItem() ); + ZyppObj objPtr = getDataPointer( getCurrentItem() ); + + if ( !slbPtr ) + return false; + + ZyppStatus newStatus; + + bool ok = statusStrategy->cycleStatus( slbPtr, objPtr, newStatus ); + + if ( ok ) + { + changeStatus( newStatus, slbPtr, objPtr, true ); + } + + return true; +} + + +bool NCPkgTable::changeObjStatus( int key ) +{ + ZyppSel slbPtr = getSelPointer( getCurrentItem() ); + ZyppObj objPtr = getDataPointer( getCurrentItem() ); + + if ( !slbPtr ) + return false; + + ZyppStatus newStatus; + + bool ok = statusStrategy->keyToStatus( key, slbPtr, objPtr, newStatus ); + + if ( ok ) + changeStatus( newStatus, slbPtr, objPtr, true ); + + return true; +} + + +bool NCPkgTable::changeListObjStatus( NCPkgTableListAction type ) +{ + ZyppStatus newStatus; + unsigned int size = getNumLines(); + unsigned int index = 0; + + while ( index < size ) + { + // get the object pointer + ZyppSel slbPtr = getSelPointer( index ); + ZyppObj objPtr = getDataPointer( index ); + bool ok = false; + + if ( slbPtr ) + { + switch ( type ) + { + case A_Install: + { + if ( slbPtr->status() == S_NoInst ) + ok = statusStrategy->keyToStatus( '+', slbPtr, objPtr, newStatus ); + break; + } + + case A_Delete: + { + if ( slbPtr->installedObj() && slbPtr->status() != S_Protected ) + ok = statusStrategy->keyToStatus( '-', slbPtr, objPtr, newStatus ); + break; + } + + case A_UpdateNewer: + { + // set status to update respecting "vendor change" settings + if ( slbPtr->installedObj() && slbPtr->status() != S_Protected && slbPtr->updateCandidateObj() ) + { + slbPtr->setOnSystem( slbPtr->updateCandidateObj() ); + ok = statusStrategy->keyToStatus( '>', slbPtr, objPtr, newStatus ); + } + break; + } + + case A_Update: + { + if ( slbPtr->installedObj() && slbPtr->status() != S_Protected ) + ok = statusStrategy->keyToStatus( '>', slbPtr, objPtr, newStatus ); + break; + } + + case A_Keep: + { + if ( slbPtr->status() == S_Install + || slbPtr->status() == S_AutoInstall + || slbPtr->status() == S_Update + || slbPtr->status() == S_AutoUpdate ) + ok = statusStrategy->keyToStatus( '<', slbPtr, objPtr, newStatus ); + else if ( slbPtr->status() == S_Del + || slbPtr->status() == S_AutoDel ) + ok = statusStrategy->keyToStatus( '+', slbPtr, objPtr, newStatus ); + break; + } + + default: + yuiError() << "Unknown list action" << endl; + break; + } + + if ( ok ) + { + changeStatus( newStatus, + slbPtr, + objPtr, + false ); // do not do the updates with every change + } + } + + index++; + } + + // do the updates now + packager->showPackageDependencies( false ); + packager->showDiskSpace(); + updateTable(); + + return true; +} + + +bool NCPkgTable::fillAvailableList( ZyppSel slb ) +{ + if ( !slb ) + { + yuiError() << "Package pointer not valid" << endl; + return false; + } + + // clear the package table + itemsCleared(); + + NCPkgStatusStrategy * strategy; + NCPkgTableType type; + + if ( slb->multiversionInstall() || slb->installedSize() > 1 ) + { + // Either the selectable has at least one multiversion + // package or there are more than one installed package + // instances. + // The last case can also happens by an previous package + // installation error. + type = T_MultiVersion; + strategy = new MultiVersionStatStrategy(); + yuiMilestone() << "Multi version package " << slb->name() << endl; + } + else + { + type = T_Availables; + strategy = new AvailableStatStrategy(); + } + + setTableType( type, strategy ); + this->fillHeader(); + + // pick list contains installed and available packages (valid for single and multi version) + zypp::ui::Selectable::picklist_iterator it = slb->picklistBegin(); + while ( it != slb->picklistEnd() ) + { + createListEntry( tryCastToZyppPkg(*it), slb ); + ++it; + } + + // show the package list + drawList(); + scrollToFirstItem(); + + return true; + +} + + +bool NCPkgTable::fillSummaryList( NCPkgTable::NCPkgTableListType type ) +{ + // clear the package table + itemsCleared(); + + // get the package list and sort it + std::list pkgList( zyppPkgBegin(), zyppPkgEnd() ); + pkgList.sort( sortByName ); + + // fill the package table + std::list::iterator listIt; + ZyppPkg pkgPtr; + + // If the dependency check is off, the dependencies will not be solved for + // the installation summary. + // This is not necessary because the dependencies will be solved and the + // "Automatic Changes" list will be shown if the OK button is pressed. + // + // if ( !autoCheck ) + // { + // showPackageDependencies( true ); + // } + + for ( listIt = pkgList.begin(); listIt != pkgList.end(); ++listIt ) + { + ZyppSel selectable = *listIt; + ZyppPkg pkg = tryCastToZyppPkg( selectable->theObj() ); + // show all matching packages + switch ( type ) + { + case NCPkgTable::L_Changes: + if ( selectable->status() != S_NoInst + && selectable->status() != S_KeepInstalled ) + { + createListEntry( pkg, selectable ); + } + break; + + case NCPkgTable::L_Installed: + if ( selectable->status() == S_KeepInstalled ) + { + createListEntry( pkg, selectable ); + } + break; + + default: + break; + } + } + + // show the package list + drawList(); + + return true; +} + + +void NCPkgTable::updateInfo( ZyppObj pkgPtr, ZyppSel slbPtr, NCPkgTableInfoType mode ) +{ + switch ( mode ) + { + case I_Descr: + if ( packager->InfoText() ) + packager->InfoText()->longDescription( pkgPtr ); + break; + + case I_Technical: + if ( packager->InfoText() ) + packager->InfoText()->technicalData( pkgPtr, slbPtr ); + break; + + case I_Files: + if ( packager->InfoText() ) + packager->InfoText()->fileList( slbPtr ); + break; + + case I_Deps: + if ( packager->InfoText() ) + packager->InfoText()->dependencyList( pkgPtr, slbPtr ); + break; + + case I_Versions: + if ( packager->VersionsList() ) + packager->VersionsList()->fillAvailableList( slbPtr ); + break; + + case I_PatchDescr: + if ( packager->InfoText() ) + packager->InfoText()->patchDescription( pkgPtr, slbPtr ); + break; + + case I_PatchPkgs: + if ( packager->PatchPkgs() ) + packager->fillPatchPackages( packager->PatchPkgs(), pkgPtr ); + break; + + // Intentionally omitting 'default' branch so the compiler can + // catch unhandled enum states + } +} + + +bool NCPkgTable::confirmRetracted( ZyppObj pkg, ZyppSel sel ) +{ + yuiMilestone() << "Retracted object " << sel->name() << " " << pkg->edition() << endl; + + // Headline of confirmation popup + string heading = _( "Please confirm" ); + + std::ostringstream msg; + // %s is a package name + msg << boost::format( _( "

Really install a retracted version of \"%s\" ?

" ) ) % sel->name(); + int width = msg.str().size() + 2; + int height = 7; + + NCPopupInfo * info = new NCPopupInfo( wpos( ( NCurses::lines() - height ) / 2, + ( NCurses::cols() - width ) / 2 ), + heading, + msg.str(), + NCPkgStrings::YesLabel(), + NCPkgStrings::NoLabel() ); + info->setPreferredSize( width, height ); + NCursesEvent event = info->showInfoPopup(); + YDialog::deleteTopmostDialog(); + bool confirmed = ( event != NCursesEvent::cancel ); + + yuiMilestone() << "User " << ( confirmed ? "confirmed" : "rejected" ) + << " retracted object " << sel->name() << " " << pkg->edition() + << endl; + + return confirmed; +} diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCPkgTable.h b/deps/libyui/libyui-ncurses-pkg/src/NCPkgTable.h new file mode 100644 index 0000000000000000000000000000000000000000..4616db3d1f14c29801b78f20df55772c86df91ee --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCPkgTable.h @@ -0,0 +1,472 @@ +/* + Copyright (c) 2002-2011 Novell, Inc. + Copyright (c) 2020-2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCPkgTable.h + Author: Gabriele Strattner + +*/ + + +#ifndef NCPkgTable_h +#define NCPkgTable_h + +#include +#include +#include +#include // for STL std::pair + +#include + +#include +#include +#include +#include + +#include "NCPkgStrings.h" +#include "NCPkgStatusStrategy.h" + + +class NCPackageSelector; + +/** + * This class is used for the first column of the package table + * which contains the status information of the package (installed, + * not installed, to be deleted and so on). + **/ +class NCPkgTableTag : public YTableCell +{ +private: + + ZyppStatus status; + ZyppObj dataPointer; + // cannot get at it from dataPointer + ZyppSel selPointer; + +public: + + NCPkgTableTag( ZyppObj pkgPtr, + ZyppSel selPtr, + ZyppStatus stat = S_NoInst ); + + ~NCPkgTableTag() {} + + void setStatus( ZyppStatus stat ) { status = stat; } + ZyppStatus getStatus() const { return status; } + // returns the corresponding std::string value to given package status + std::string statusToString( ZyppStatus stat ) const; + + ZyppObj getDataPointer() const { return dataPointer; } + ZyppSel getSelPointer() const { return selPointer; } +}; + + +class NCPkgTableSort : public NCTableSortStrategyBase +{ +public: + + NCPkgTableSort( const std::vector & head ) + : _header( head ) + {} + + virtual void sort( YItemIterator itemsBegin, + YItemIterator itemsEnd ) override + { + if ( _header[ sortCol() ] == NCPkgStrings::PkgSize() ) + { + std::sort( itemsBegin, itemsEnd, CompareSize() ); + } + else if ( _header[ sortCol() ] == NCPkgStrings::PkgName() ) + { + std::sort( itemsBegin, itemsEnd, CompareName( sortCol() ) ); + } + else + { + std::sort( itemsBegin, itemsEnd, Compare( sortCol() ) ); + } + + if ( reverse() ) + std::reverse( itemsBegin, itemsEnd ); + } + +private: + + std::vector _header; + + + /** + * Return the content of column no. 'col' for an item. + **/ + static std::wstring cellContent( YItem * item, int col ) + { + std::wstring empty; + + if ( ! item ) + return empty; + + YTableItem * tableItem = dynamic_cast( item ); + + if ( ! tableItem ) + return empty; + + YTableCell * tableCell = tableItem->cell( col ); + + if ( ! tableCell ) + return empty; + + return NCstring( tableCell->label() ).str(); + } + + + class CompareSize + { + public: + CompareSize() + {} + + bool operator() ( YItem * item1, YItem * item2 ) const + { + YTableItem * tableItem1 = dynamic_cast( item1 ); + YTableItem * tableItem2 = dynamic_cast( item2 ); + + if ( ! tableItem1 ) return true; + if ( ! tableItem2 ) return true; + + const NCPkgTableTag * tag1 = static_cast( tableItem1->cell(0) ); + const NCPkgTableTag * tag2 = static_cast( tableItem2->cell(0) ); + + return tag1->getDataPointer()->installSize() < + tag2->getDataPointer()->installSize(); + } + }; + + + class CompareName + { + public: + CompareName( int uiCol ) + : _uiCol( uiCol ) + {} + + bool operator() ( YItem * item1, YItem * item2 ) const + { + std::wstring w1 = cellContent( item1, _uiCol ); + std::wstring w2 = cellContent( item2, _uiCol ); + + // It is safe to use collate unaware wscasecmp() here because package names + // are 7 bit ASCII only. Better yet, we don't even want this to be sorted + // by locale specific rules: "ch" for example would be sorted after "h" in + // Czech which in the context of package names (which are English) would be + // plain wrong. + int result = wcscasecmp( w1.data(), w2.data() ); + + return result < 0; + } + + private: + const int _uiCol; + }; + + + class Compare + { + public: + Compare( int uiCol ) + : _uiCol( uiCol ) + {} + + bool operator() ( YItem * item1, YItem * item2 ) const + { + std::wstring w1 = cellContent( item1, _uiCol ); + std::wstring w2 = cellContent( item2, _uiCol ); + + int result = wcscoll ( w1.data(), w2.data() ); + + return result < 0; + } + + private: + const int _uiCol; + }; +}; + + +/** + * The package table class. Provides methods to fill the table, + * set the status info and so on. + * Has a connection to the PackageSelector which is used to do + * changes which affect other widgets. + * + **/ +class NCPkgTable : public NCTable +{ +public: + + enum NCPkgTableType + { + T_Packages, + T_Availables, + T_Patches, + T_Update, + T_PatchPkgs, + T_Selections, + T_Languages, + T_MultiVersion, + T_Unknown + }; + + enum NCPkgTableListAction + { + A_Install, + A_Delete, + A_Keep, + A_UpdateNewer, + A_Update, + A_Unknown + }; + + enum NCPkgTableListType + { + L_Changes, + L_Installed, + L_Unknown + }; + + enum NCPkgTableInfoType + { + I_Descr, + I_Technical, + I_Versions, + I_Files, + I_Deps, + I_PatchDescr, + I_PatchPkgs + }; + +private: + + NCPkgTable & operator=( const NCPkgTable & ); + NCPkgTable ( const NCPkgTable & ); + + NCPackageSelector * packager; // connection to the PackageSelector, + + NCPkgStatusStrategy * statusStrategy; // particular methods to get the status + + NCPkgTableType tableType; // the type (e.g. table of packages, patches) + bool haveInstalledVersion; // for T_Packages and T_Update + + // returns the first column of line with 'index' (the tag) + NCPkgTableTag * getTag ( const int & index ); + + NCPkgTableInfoType visibleInfo; + + std::vector header; // the table header + + +public: + + /** + * Constructor + */ + NCPkgTable( YWidget * parent, YTableHeader * tableHeader ); + + virtual ~NCPkgTable(); + + + /** + * This method is called to add a line to the package list. + * @param status The package status (first column of the table) + * @param elements A std::vector containing the package data + * @param objPtr The pointer to the packagemanager object + * @param objPtr The pointer to the selectable object + * @return void + */ + virtual void addLine( ZyppStatus status, + const std::vector & elements, + ZyppObj objPtr, + ZyppSel slbPtr ); + + /** + * Draws the package list (has to be called after the loop with addLine() calls) + */ + void drawList() { sortItems( 1 ); return DrawPad(); } + + /** + * Clears the package list + */ + virtual void itemsCleared(); + + /** + * Returns the contents of a certain cell in table + * @param index The table line + * @param column The column + * @eturn NClabel + */ + NClabel getCellContents( int index, int colnum ); + + /** + * Handles the events concerning the package table (e.g. scroll the list, + * change the package status, ...) + * @param key The key which is pressed + * @return NCursesEvent + */ + virtual NCursesEvent wHandleInput( wint_t key ); + + /** + * Sets the member variable PackageSelector *packager + * @param pkg The PackageSelector pointer + * @return void + */ + void setPackager( NCPackageSelector * pkg ) { packager = pkg; } + + /** + * Informs the package manager about the status change of + * the currently selected package and updates the states + * of all packages in the list + * @param newstat The new status + * @param slbPtr The pointer to the object to change + * @param objPtr is candidatePtr or what the user selected instead of it. + * @return bool + */ + bool changeStatus( ZyppStatus newstat, + const ZyppSel & slbPtr, + ZyppObj objPtr, + bool singleChange ); + + bool changeObjStatus( int key ); + + bool changeListObjStatus( NCPkgTableListAction key ); + + bool cycleObjStatus(); + + /** + * Set the status information if status has changed + * @return bool + */ + bool updateTable(); + + /** + * Gets the currently displayed package status. + * @param index The index in package table (the line) + * @return ZyppStatus + */ + ZyppStatus getStatus( int index ); + +#ifdef FIXME + /** + * Toggles the installation of the source package. + * @param install + * @return bool + */ + bool SourceInstall( bool install ); +#endif + + /** + * Sets the type of the table and the status strategy (which means call particular methods + * to set/get the status for different zypp::ResObjects (zypp::Patch, zypp::Package or available zypp::Package) + * @param type The type (see enum NCPkgTableType) + * @param strategy The certain strategy (available strategies see NCPkgStatusStrategy.h). + * Has to be allocated with new - is deleted by NCPkgTable. + * @return bool + */ + bool setTableType( NCPkgTableType type, NCPkgStatusStrategy * strategy ) + { + if ( !strategy ) + return false; + + delete statusStrategy; + statusStrategy = strategy; + tableType = type; + + return true; + } + + NCPkgTableType getTableType() { return tableType; } + + /** + * Gets the data pointer of a certain package. + * @param index The index in package table (the line) + * @return ZyppObj + */ + ZyppObj getDataPointer( int index ); + + /** + * Gets the selectable pointer of a certain package. + * @param index The index in package table (the line) + * @return ZyppSel + */ + ZyppSel getSelPointer( int index ); + + /** + * Returns the number of lines in the table (the table size) + * @return unsigned int + */ + unsigned int getNumLines() { return myPad()->Lines(); } + + /** + * Fills the header of the table + * @return void + */ + void fillHeader(); + + /** + * Creates a line in the package table. + * @param pkgPtr The package pointer + * @param slbPtr The selectable pointer + * @return bool + */ + bool createListEntry ( ZyppPkg pkgPtr, ZyppSel slbPtr ); + + /** + * Creates a line in the YOU patch table. + * @param pkgPtr The YOU patch pointer + * @return bool + */ + bool createPatchEntry ( ZyppPatch pkgPtr, ZyppSel slbPtr ); + + /** + * Creates a line in the table shwing an info text. + * @param text The information + * @return bool + */ + bool createInfoEntry ( std::string text ); + + /** + * Show the corresponding information (e.g. the package description). + * @return bool + */ + bool showInformation(); + + /** + * Ask the user for confirmation of installing a retracted package. + * This returns 'true' if the user confirmed, 'false' if not. + **/ + bool confirmRetracted( ZyppObj pkg, ZyppSel sel ); + + void setVisibleInfo( NCPkgTableInfoType info) { visibleInfo = info; } + + NCPkgTableInfoType VisibleInfo() { return visibleInfo; } + + bool fillAvailableList ( ZyppSel slb ); + bool fillSummaryList ( NCPkgTableListType type ); + + void updateInfo( ZyppObj pkgPtr, ZyppSel slbPtr, NCPkgTableInfoType mode ); + +}; + +/////////////////////////////////////////////////////////////////// + +#endif // NCPkgTable_h diff --git a/deps/libyui/libyui-ncurses-pkg/src/NCZypp.h b/deps/libyui/libyui-ncurses-pkg/src/NCZypp.h new file mode 100644 index 0000000000000000000000000000000000000000..8cbbf1d26760b497fa05247b6e667b59f3f2ae99 --- /dev/null +++ b/deps/libyui/libyui-ncurses-pkg/src/NCZypp.h @@ -0,0 +1,125 @@ +/* + Copyright (c) [2002-2011] Novell, Inc. + Copyright (c) 2021 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA + + + File: NCZypp.h + Author: Stefan Hundhammer + +*/ + + +#ifndef NCZypp_h +#define NCZypp_h + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using zypp::ui::S_Protected; +using zypp::ui::S_Taboo; +using zypp::ui::S_Del; +using zypp::ui::S_Update; +using zypp::ui::S_Install; +using zypp::ui::S_AutoDel; +using zypp::ui::S_AutoUpdate; +using zypp::ui::S_AutoInstall; +using zypp::ui::S_KeepInstalled; +using zypp::ui::S_NoInst; + + +// +// Typedefs to make those nested namespaces human-readable +// + +typedef zypp::ui::Status ZyppStatus; +typedef zypp::ui::Selectable::Ptr ZyppSel; +typedef zypp::ResObject::constPtr ZyppObj; +typedef zypp::Package::constPtr ZyppPkg; +typedef zypp::Pattern::constPtr ZyppPattern; +typedef zypp::Patch::constPtr ZyppPatch; +typedef zypp::Product::constPtr ZyppProduct; +typedef zypp::Repository ZyppRepo; + +typedef zypp::ResPoolProxy ZyppPool; +typedef zypp::ResPoolProxy::const_iterator ZyppPoolIterator; +typedef zypp::ResPoolProxy::repository_iterator ZyppRepositoryIterator; + + +inline ZyppPool zyppPool() { return zypp::getZYpp()->poolProxy(); } + +template ZyppPoolIterator zyppBegin() { return zyppPool().byKindBegin(); } +template ZyppPoolIterator zyppEnd() { return zyppPool().byKindEnd(); } + +inline ZyppPoolIterator zyppPkgBegin() { return zyppBegin(); } +inline ZyppPoolIterator zyppPkgEnd() { return zyppEnd(); } + +inline ZyppPoolIterator zyppPatternsBegin() { return zyppBegin(); } +inline ZyppPoolIterator zyppPatternsEnd() { return zyppEnd(); } + +inline ZyppPoolIterator zyppPatchesBegin() { return zyppBegin(); } +inline ZyppPoolIterator zyppPatchesEnd() { return zyppEnd(); } + +inline ZyppPoolIterator zyppProductsBegin() { return zyppBegin(); } +inline ZyppPoolIterator zyppProductsEnd() { return zyppEnd(); } + +inline ZyppRepositoryIterator ZyppRepositoriesBegin() { return zyppPool().knownRepositoriesBegin(); } +inline ZyppRepositoryIterator ZyppRepositoriesEnd() { return zyppPool().knownRepositoriesEnd(); } + + +inline ZyppPkg tryCastToZyppPkg( ZyppObj zyppObj ) +{ + return zypp::dynamic_pointer_cast( zyppObj ); +} + +inline ZyppPattern tryCastToZyppPattern( ZyppObj zyppObj ) +{ + return zypp::dynamic_pointer_cast( zyppObj ); +} + +inline ZyppPatch tryCastToZyppPatch( ZyppObj zyppObj ) +{ + return zypp::dynamic_pointer_cast( zyppObj ); +} + +inline ZyppProduct tryCastToZyppProduct( ZyppObj zyppObj ) +{ + return zypp::dynamic_pointer_cast( zyppObj ); +} + +template bool inContainer( const std::set & container, T search ) +{ + return container.find( search ) != container.end(); +} + +template bool bsearch( const std::vector & sorted_vector, T search ) +{ + return binary_search( sorted_vector.begin(), sorted_vector.end(), search); +} + +inline bool sortByName( ZyppSel ptr1, ZyppSel ptr2 ) +{ + return( ptr1->name() < ptr2->name() ); +} +#endif // NCZypp_h diff --git a/deps/libyui/libyui-ncurses-rest-api/.gitignore b/deps/libyui/libyui-ncurses-rest-api/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b7797e40d60d62bb787649f204d9203cb86a725c --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/.gitignore @@ -0,0 +1,19 @@ + +*.o +*.so +*.so.* + +CMakeCache.txt +CMakeFiles +CMakeDoxyfile.in +Doxyfile +Doxygen.warnings +Makefile + +build*/ +package/*.tar.* + +*~ +*.bak +*.auto + diff --git a/deps/libyui/libyui-ncurses-rest-api/CMakeLists.txt b/deps/libyui/libyui-ncurses-rest-api/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b6ee4a4e6c0da75aee62d891051965616c5f9f4 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/CMakeLists.txt @@ -0,0 +1,76 @@ +# CMakeLists.txt for libyui-ncurses-rest-api +# +# Usage: +# +# mkdir build +# cd build +# cmake .. +# +# make +# sudo make install +# +# Restart with a clean build environment: +# rm -rf build +# +# Show the complete compiler commands with all arguments: +# make VERBOSE=1 + +cmake_minimum_required( VERSION 3.10 ) +project( libyui-ncurses-rest-api ) + +# Options usage: +# +# cmake -DBUILD_DOC=on -DBUILD_EXAMPLES=off .. + +option( BUILD_SRC "Build in src/ subdirectory" on ) +option( BUILD_DOC "Build class documentation" off ) +option( WERROR "Treat all compiler warnings as errors" on ) + + +#---------------------------------------------------------------------- + + +# We use /usr as the default CMAKE_INSTALL_PREFIX, but it can be set on the +# cmake command line with +# +# cmake -DCMAKE_INSTALL_PREFIX=/my/install/prefix .. +# +# or in the environment with +# +# CMAKE_INSTALL_PREFIX=/usr/local cmake .. + +if ( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) + if ( DEFINED ENV{CMAKE_INSTALL_PREFIX} ) + set( CIP $ENV{CMAKE_INSTALL_PREFIX} ) + else() + set( CIP /usr ) + endif() + set( CMAKE_INSTALL_PREFIX "${CIP}" CACHE PATH "Install path prefix" FORCE) +endif() + +message( "-- CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}" ) + + +set( CMAKE_INSTALL_MESSAGE LAZY ) # Suppress "up-to-date" messages during "make install" + + +# Initialize compiler flags for all targets in all subdirectories +add_compile_options( "-Wall" ) +add_compile_options( "-Os" ) # Optimize for size (overrides CMake's -O3 in RELEASE builds) + +if ( WERROR ) + add_compile_options( "-Werror" ) +endif() + + +# +# Descend into subdirectories +# + +if ( BUILD_SRC ) + add_subdirectory( src ) +endif() + +if ( BUILD_DOC ) + add_subdirectory( doc ) +endif() diff --git a/deps/libyui/libyui-ncurses-rest-api/Makefile.repo b/deps/libyui/libyui-ncurses-rest-api/Makefile.repo new file mode 100644 index 0000000000000000000000000000000000000000..4dcfa98f1e42b677ba38d6c7aac05ddca6be9c6c --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/Makefile.repo @@ -0,0 +1,64 @@ +# +# Makefile.repo for libyui-qt-rest-api +# + +# Local Variables: +# mode: Makefile +# End: + + +all: clean configure build-hint + +build-hint: + @echo "" + @echo "To build:" + @echo "" + @echo " cd build" + @echo " make" + @echo "" + +configure: + mkdir build; \ + cd build; \ + cmake .. + +build: clean configure + cd build; \ + make -j $$(nproc) + +# This needs root privileges, of course +install: configure + cd build; \ + make -j $$(nproc) && make install + +clean: + rm -rf build + +package: + rake package + +doc: + test -d build || mkdir build + cd build; \ + cmake -DBUILD_DOC=on .. ; \ + make doc + +version-bump: + rake version:bump + +so-version-bump: + rake so_version:bump + +# Just some aliases +bump-version: version-bump + +bump-so-version: so-version-bump + + +# Enforce rebuilding some targets unconditionally, even if a file or directory +# with that name exists; otherwise the timestamp of that file or directory +# would be checked. +# +# We need this because we have a subdirectory doc/, a subdirectory package/ +# and possibly a subdirectory build/ here. +.PHONY: doc package build diff --git a/deps/libyui/libyui-ncurses-rest-api/doc/CMakeLists.txt b/deps/libyui/libyui-ncurses-rest-api/doc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..45bc32b56ad52e008fcda2c8a0b58726ba0687df --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/doc/CMakeLists.txt @@ -0,0 +1,24 @@ +# CMakeLists.txt for libyui*/doc + +include( ../../VERSION.cmake ) + +find_package( Doxygen REQUIRED dot ) + + +# +# Doxygen-generated autodocs +# + +if ( DOXYGEN_FOUND ) + + set( DOXYGEN_GENERATE_TREEVIEW yes ) # Enable views tree HTML frame + set( DOXYGEN_QUIET yes ) # Less verbose output + set( DOXYGEN_WARN_LOGFILE doxygen-warnings.log ) + # See build/CMakeDoxyfile.in for more supported variables + + doxygen_add_docs( doc ../src ) + +else() + message( WARNING "Missing doxygen package" ) +endif() + diff --git a/deps/libyui/libyui-ncurses-rest-api/src/CMakeLists.txt b/deps/libyui/libyui-ncurses-rest-api/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5d91fc6daee474070f4d52e842aba1ab14e1afb3 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/CMakeLists.txt @@ -0,0 +1,133 @@ +# CMakeLists.txt for libyui-ncurses-rest-api/src + +include( ../../VERSION.cmake ) +include( GNUInstallDirs ) # set CMAKE_INSTALL_INCLUDEDIR, ..._LIBDIR + + +# +# libyui-rest-api plugin specific +# + +set( TARGETLIB libyui-ncurses-rest-api ) +set( TARGETLIB_BASE yui-ncurses-rest-api ) + +set( HEADERS_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/yui/ncurses-rest-api ) +set( PLUGIN_DIR ${CMAKE_INSTALL_LIBDIR}/yui ) # /usr/lib64/yui + +# if DESTDIR is set, CMAKE_INSTALL_INCLUDEDIR already contains it +# during "make install" (but not for other make targets!): +# +# sudo make install DESTDIR=/work/foo +# or +# DESTDIR=/work/foo sudo make install +# +# -> the include files are installed to /work/foo/usr/include/... +# We need that for RPM builds to install everything to $RPM_BUILD_ROOT. + + +set( SOURCES + YNCHttpUI.cc + YNCHttpWidgetsActionHandler.cc + YNCWidgetActionHandler.cc + NCHttpApplication.cc + NCHttpWidgetFactory.cc + NCHttpDialog.cc + ) + + +set( HEADERS + YNCHttpUI.h + YNCHttpWidgetsActionHandler.h + YNCWidgetActionHandler.h + NCHttpApplication.h + NCHttpWidgetFactory.h + NCHttpDialog.h + ) + + +# Add shared lib to be built +add_library( ${TARGETLIB} SHARED + ${SOURCES} + ${HEADERS} + ) + + +# +# Include directories and compile options +# + + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + +# Create an include dir with some symlinks to include headers from sibling projects: +# build/src/include/yui/yui -> ../../libyui/src +# build/src/include/yui/ncurses -> ../../libyui-ncurses/src +# build/src/include/yui/rest-api -> ../../libyui-rest-api/src +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR}/yui ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../libyui/src ${LOCAL_INCLUDE_DIR}/yui/yui SYMBOLIC ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../libyui-ncurses/src ${LOCAL_INCLUDE_DIR}/yui/ncurses SYMBOLIC ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../libyui-rest-api/src ${LOCAL_INCLUDE_DIR}/yui/rest-api SYMBOLIC ) + +# from build/src/include/yui/ncurses -> ../../libyui-ncurses/src +# from build/src/include/yui/rest-api -> ../../libyui-rest-api/src +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) + +# from build/src/include/yui/yui -> ../../libyui/src +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR}/yui ) + + +# FIXME start +# Also add those directories directly until the full transition is done: +# The headers of older libyui-rest-api packages still #include "YSomeWidget.h" +target_include_directories( ${TARGETLIB} BEFORE PUBLIC /usr/include/yui ) +# Remove this when those old packages are history. +# FIXME end + +# Make the version from ../../VERSION.cmake available as a #define +target_compile_definitions( ${TARGETLIB} PUBLIC VERSION="${VERSION}" ) + +# Add more compile options to this target in addition to those +# added in the toplevel CMakeLists.txt. +# +# Notice that CMake will automatically add -fPIC etc. where needed, +# like for this shared lib. +### target_compile_options( ${TARGETLIB} PUBLIC "-Dfoo" ) + +# Show the complete compiler commands with all arguments: +# make VERBOSE=1 + +# Add more compile options to an individual source file: +### set_source_files_properties( YUI.cc PROPERTIES COMPILE_OPTIONS "-Dfoo" ) + + +# +# Linking +# + +# Find yui during a combined build +target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../libyui/build/src ) + + +# Libraries that are needed to build this shared lib +# +# If in doubt what is really needed, check with "ldd -u" which libs are unused. +target_link_libraries( ${TARGETLIB} + yui + ) + + +# https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#target-properties +set_target_properties( ${TARGETLIB} PROPERTIES + VERSION ${SONAME} # From ../../VERSION.cmake + SOVERSION ${SONAME_MAJOR} # From ../../VERSION.cmake + OUTPUT_NAME ${TARGETLIB_BASE} + ) + + +# +# Install +# + +# Install the headers first so the message about the lib does not scroll away +install( FILES ${HEADERS} DESTINATION ${HEADERS_INSTALL_DIR} ) +install( TARGETS ${TARGETLIB} LIBRARY DESTINATION ${PLUGIN_DIR} ) diff --git a/deps/libyui/libyui-ncurses-rest-api/src/NCHttpApplication.cc b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpApplication.cc new file mode 100644 index 0000000000000000000000000000000000000000..ad79a2c21017639ce04131f3f483f741b05caeb7 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpApplication.cc @@ -0,0 +1,41 @@ +/* + Copyright (C) 2023 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +#include "NCHttpApplication.h" + +int +NCHttpApplication::runInTerminal( const std::string & cmd ) +{ + // temporarily stop the REST API server to avoid conflicts + // when running another program which also uses libyui with REST API + // (like YaST), the started process will open its own REST API server + YHttpServer::yserver()->stop(); + // run the base class implementation + int ret = NCApplication::runInTerminal(cmd); + YHttpServer::yserver()->start(); + return ret; +} + +NCHttpApplication::NCHttpApplication() +{ +} + +NCHttpApplication::~NCHttpApplication() +{ +} diff --git a/deps/libyui/libyui-ncurses-rest-api/src/NCHttpApplication.h b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpApplication.h new file mode 100644 index 0000000000000000000000000000000000000000..8473192283a9cc1836d273de6ce7e85620873135 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpApplication.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2023 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef NCHttpApplication_h +#define NCHttpApplication_h + +#include + +class NCHttpApplication: public NCApplication +{ + + protected: + + friend class YNCHttpUI; + + /** + * Constructor. + * + * Use YUI::app() to get the singleton for this class. + **/ + NCHttpApplication(); + + /** + * Destructor. + **/ + virtual ~NCHttpApplication(); + + + public: + + virtual int runInTerminal( const std::string & command ) override; +}; + + +#endif // NCHttpApplication_h diff --git a/deps/libyui/libyui-ncurses-rest-api/src/NCHttpDialog.cc b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpDialog.cc new file mode 100644 index 0000000000000000000000000000000000000000..b9b768776fa7492c9c1c196a3f5408620409eab4 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpDialog.cc @@ -0,0 +1,208 @@ +/* + Copyright (C) 2018-2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#define YUILogComponent "ncurses-rest-api" +#include + +#include + +#include "NCHttpDialog.h" + + +NCHttpDialog::NCHttpDialog( YDialogType dialogType, + YDialogColorMode colorMode ) + : NCDialog( dialogType, colorMode ) +{ + yuiDebug() << "Constructor NCHttpDialog(YDialogType t, YDialogColorMode c)" << std::endl; +} + +int NCHttpDialog::wait_for_input(int timeout_millisec) +{ + struct timeval tv; + fd_set fdset_read, fdset_write, fdset_excpt; + + // infinite timout => do blocking select() + timeval *tv_ptr = (timeout_millisec < 0) ? nullptr : &tv; + + // remember the original value + int timeout_millisec_orig = timeout_millisec; + + do + { + std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now(); + + tv.tv_sec = 0; + tv.tv_usec = timeout_millisec * 1000; + + FD_ZERO( &fdset_read ); + FD_ZERO( &fdset_write ); + FD_ZERO( &fdset_excpt ); + FD_SET( 0, &fdset_read ); + + // the higest fd number to watch + int fd_max = 0; + + // watch HTTP server fd + yuiDebug() << "Adding HTTP server notifiers NC dialog..." << std::endl; + YHttpServerSockets sockets = YHttpServer::yserver()->sockets(); + + for(int fd: sockets.read()) + { + FD_SET( fd, &fdset_read ); + if (fd_max < fd) fd_max = fd; + } + + for(int fd: sockets.write()) + { + FD_SET( fd, &fdset_write ); + if (fd_max < fd) fd_max = fd; + } + + for(int fd: sockets.exception()) + { + FD_SET( fd, &fdset_excpt ); + if (fd_max < fd) fd_max = fd; + } + + yuiDebug() << "Calling select()... " << std::endl; + int retval = select( fd_max + 1, &fdset_read, &fdset_write, &fdset_excpt, tv_ptr ); + yuiDebug() << "select() result: " << retval << std::endl; + + if ( retval < 0 ) + { + if ( errno != EINTR ) + yuiError() << "error in select() (" << errno << ')' << std::endl; + } + else if ( retval != 0 ) + { + YHttpServerSockets sockets = YHttpServer::yserver()->sockets(); + bool server_ready = false; + + for(int fd: sockets.read()) + { + if (FD_ISSET( fd, &fdset_read )) + server_ready = true; + } + + for(int fd: sockets.write()) + { + if (FD_ISSET( fd, &fdset_write )) + server_ready = true; + } + + for(int fd: sockets.exception()) + { + if (FD_ISSET( fd, &fdset_excpt )) + server_ready = true; + } + + yuiDebug() << "Server ready: " << server_ready << std::endl; + + if (server_ready) + { + bool redraw = YHttpServer::yserver()->process_data(); + yuiWarning() << "redraw: " << redraw << std::endl; + + if (timeout_millisec > 0) + { + std::chrono::steady_clock::time_point finish = std::chrono::steady_clock::now(); + + int elapsed = std::chrono::duration_cast(finish - start).count(); + yuiDebug() << "Elapsed time (ms): " << elapsed << std::endl; + timeout_millisec -= elapsed; + yuiDebug() << "Remaining time out (ms): " << timeout_millisec << std::endl; + + // spent too much time + if (timeout_millisec <= 0) + timeout_millisec = 0; + } + + // the request might have changed something in the UI, let's redraw it... + if (redraw) + NCurses::Redraw(); + + // finish the loop if there is any event added by the server call + if (getPendingEvent()) + { + yuiDebug() << "Found a pending event: " << getPendingEvent() << std::endl; + return 0; + } + } + } + // no input within timeout + else + { + yuiDebug() << "Timeout " << timeout_millisec << "ms reached" << std::endl; + return timeout_millisec_orig; + } + } + while ( !FD_ISSET( 0, &fdset_read ) ); + + // if there is an user input we do not need to spent the time + return 0; +} + + +wint_t NCHttpDialog::getch( int timeout_millisec ) +{ + wint_t got = WEOF; + + yuiDebug() << "NCHttpDialog::getch timeout: " << timeout_millisec << std::endl; + + if ( timeout_millisec < 0 ) + { + // wait for input (block) + wait_for_input(timeout_millisec); + got = getinput(); + } + else if ( timeout_millisec ) + { + do + { + // wait for input + int slept = wait_for_input(timeout_millisec); + yuiDebug() << "slept: " << slept << std::endl; + timeout_millisec -= slept; + yuiDebug() << "new timeout: " << timeout_millisec << std::endl; + + got = getinput(); + } + while ( got == WEOF && timeout_millisec > 0 ); + } + else + { + // no wait (non blocking) + wait_for_input(0); + ::nodelay( ::stdscr, true ); + got = getinput(); + } + + if ( got == KEY_RESIZE ) + { + NCurses::ResizeEvent(); + int i = 100; + // after resize sometimes WEOF is returned -> skip this in no timeout mode + + do + { + got = NCHttpDialog::getch( timeout_millisec ); + } + while ( timeout_millisec < 0 && got == WEOF && --i ); + } + + return got; +} diff --git a/deps/libyui/libyui-ncurses-rest-api/src/NCHttpDialog.h b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpDialog.h new file mode 100644 index 0000000000000000000000000000000000000000..81c93077fd9efca9715ee9836fcd69181025e031 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpDialog.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2018-2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + File: NCHttpDialog.h + Purpose: Introducing rest-api related changes to ncurses libyui library. + We need to override getch method to process events properly +/-*/ + +#ifndef NCHttpDialog_h +#define NCHttpDialog_h + +#include + + +class NCHttpDialog: public NCDialog +{ + public: + NCHttpDialog( YDialogType dialogType, + YDialogColorMode colorMode = YDialogNormalColor ); + ~NCHttpDialog() { }; + protected: + wint_t getch( int timeout_millisec = -1 ); + private: + int wait_for_input(int timeout_millisec); +}; + +#endif // NCHttpDialog_h diff --git a/deps/libyui/libyui-ncurses-rest-api/src/NCHttpWidgetFactory.cc b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpWidgetFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..119d6336182f48046f11a4f7b4f12edf8fd4180f --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpWidgetFactory.cc @@ -0,0 +1,33 @@ +/* + Copyright (C) 2018-2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#define YUILogComponent "ncurses-rest-api" +#include + +#include "NCHttpDialog.h" +#include "NCHttpWidgetFactory.h" + + +NCDialog * +NCHttpWidgetFactory::createDialog( YDialogType dialogType, YDialogColorMode colorMode ) +{ + yuiMilestone() << "Flush input buffer - new dialog" << std::endl; + ::flushinp(); + + NCHttpDialog * dialog = new NCHttpDialog( dialogType, colorMode ); + YUI_CHECK_NEW( dialog ); + + return dialog; +} diff --git a/deps/libyui/libyui-ncurses-rest-api/src/NCHttpWidgetFactory.h b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpWidgetFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..49df2fca049d5c70246f22c21d76a6a7fc087784 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/NCHttpWidgetFactory.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2018-2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + File: NCHttpWidgetFactory.h + Purpose: Introducing rest-api related changes to ncurses libyui library + We need to override NCDialog dialog methods to handle rest api + events, so have to override creation of those too. +/-*/ + +#ifndef NCHttpWidgetFactory_h +#define NCHttpWidgetFactory_h + +#include + + +/** + * Concrete widget factory for mandatory widgets. + **/ +class NCHttpWidgetFactory: public NCWidgetFactory +{ +public: + // Need to override just single method to use NCHttpDialog instead of + // just NCDialog. + + // + // Dialogs + // + + virtual NCDialog * createDialog ( YDialogType dialogType, YDialogColorMode colorMode = YDialogNormalColor ); +}; + +#endif //NCHttpWidgetFactory_h diff --git a/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpUI.cc b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpUI.cc new file mode 100644 index 0000000000000000000000000000000000000000..4d61d630f1c925d30d482ea5b42542f6717692ce --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpUI.cc @@ -0,0 +1,181 @@ +/* + Copyright (C) 2018-2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +/*-/ + Author: Author: Rodion Iafarov +/-*/ + +#define YUILogComponent "ncurses-rest-api" +#include + +#include + +#include "YNCHttpUI.h" +#include "YNCHttpWidgetsActionHandler.h" +#include "NCHttpApplication.h" +#include "NCHttpWidgetFactory.h" +#include "NCHttpDialog.h" + + +YNCHttpUI::YNCHttpUI( bool withThreads ) + : YNCursesUI( withThreads, false ) +{ + yuiMilestone() << "YNCHttpUI constructor start" << std::endl; + yuiMilestone() << "This is libyui-ncurses with http " << VERSION << std::endl; + _ui = this; + yuiMilestone() << "YNCHttpUI constructor finished" << std::endl; + topmostConstructorHasFinished(); +} + +extern YUI * createYNCHttpUI( bool withThreads ) +{ + + if (!YHttpServer::yserver()) { + yuiMilestone() << "Creating HTTP server" << std::endl; + YHttpServer * yserver = new YHttpServer( new YNCHttpWidgetsActionHandler() ); + yserver->start(); + } + if ( ! YNCHttpUI::ui() ) + new YNCHttpUI( withThreads ); + + return YNCHttpUI::ui(); +} + +void YNCHttpUI::idleLoop( int fd_ycp ) +{ + int timeout = 5; + + struct timeval tv; + fd_set fdset_read, fdset_write, fdset_excpt; + int retval; + + do + { + tv.tv_sec = timeout; + tv.tv_usec = 0; + + FD_ZERO( &fdset_read ); + FD_ZERO( &fdset_write ); + FD_ZERO( &fdset_excpt ); + FD_SET( 0, &fdset_read ); + FD_SET( fd_ycp, &fdset_read ); + + // the higest fd number to watch + int fd_max = fd_ycp; + + // watch HTTP server fd + yuiDebug() << "Adding HTTP server notifiers..." << std::endl; + YHttpServerSockets sockets = YHttpServer::yserver()->sockets(); + + for(int fd: sockets.read()) + { + FD_SET( fd, &fdset_read ); + if (fd_max < fd) fd_max = fd; + } + + for(int fd: sockets.write()) + { + FD_SET( fd, &fdset_write ); + if (fd_max < fd) fd_max = fd; + } + + for(int fd: sockets.exception()) + { + FD_SET( fd, &fdset_excpt ); + if (fd_max < fd) fd_max = fd; + } + + yuiDebug() << "Calling select()... " << std::endl; + retval = select( fd_max + 1, &fdset_read, &fdset_write, &fdset_excpt, &tv ); + yuiDebug() << "select() result: " << retval << std::endl; + + if ( retval < 0 ) + { + if ( errno != EINTR ) + yuiError() << "idleLoop error in select() (" << errno << ')' << std::endl; + } + else if ( retval != 0 ) + { + YHttpServerSockets sockets = YHttpServer::yserver()->sockets(); + bool server_ready = false; + + for(int fd: sockets.read()) + { + if (FD_ISSET( fd, &fdset_read )) + server_ready = true; + } + + for(int fd: sockets.write()) + { + if (FD_ISSET( fd, &fdset_write )) + server_ready = true; + } + + for(int fd: sockets.exception()) + { + if (FD_ISSET( fd, &fdset_excpt )) + server_ready = true; + } + + yuiDebug() << "Server ready: " << server_ready << std::endl; + + if (server_ready) + { + bool redraw = YHttpServer::yserver()->process_data(); + if (redraw) + NCurses::Redraw(); + } + + //do not throw here, as current dialog may not necessarily exist yet + //if we have threads + YDialog *currentDialog = YDialog::currentDialog( false ); + + if ( currentDialog ) + { + NCHttpDialog * ncd = static_cast( currentDialog ); + + if ( ncd ) + { + yuiDebug() << "Casted to NCHttpDialog" << std::endl; + extern NCBusyIndicator* NCBusyIndicatorObject; + + if ( NCBusyIndicatorObject ) + NCBusyIndicatorObject->handler( 0 ); + + ncd->idleInput(); + } + } + } // else no input within timeout sec. + } + while ( !FD_ISSET( fd_ycp, &fdset_read ) ); +} + +YWidgetFactory * +YNCHttpUI::createWidgetFactory() +{ + NCHttpWidgetFactory * factory = new NCHttpWidgetFactory(); + YUI_CHECK_NEW( factory ); + + return factory; +} + +YApplication * +YNCHttpUI::createApplication() +{ + NCHttpApplication * app = new NCHttpApplication(); + YUI_CHECK_NEW( app ); + + return app; +} diff --git a/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpUI.h b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpUI.h new file mode 100644 index 0000000000000000000000000000000000000000..211ea5bebe8f5f78297f41f571f546d6c0958060 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpUI.h @@ -0,0 +1,80 @@ +/* + Copyright (C) 2018-2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + File: YNCursesUI.h + Author: Rodion Iafarov + Purpose: Introducing rest-api related changes to ncurses libyui library +/-*/ + +#ifndef YNCHttpUI_h +#define YNCHttpUI_h + +#include +#include +#include +#include +#include + +class YNCHttpUI: public YNCursesUI +{ + +public: + /** + * Constructor. + **/ + YNCHttpUI( bool withThreads ); + + /** + * Destructor. + **/ + ~YNCHttpUI() { }; + + /** + * Idle around until fd_ycp is readable + */ + virtual void idleLoop( int fd_ycp ); + +protected: + + /** + * Widget factory that provides all the createXY() methods for + * standard (mandatory, i.e. non-optional) widgets. + * + * Reimplemented from YNCursesUI as we need to override methods NCDialog, + * so need to create NCHttpDialog instead there. + **/ + virtual YWidgetFactory * createWidgetFactory(); + + /* + * Create the YApplication object that provides global methods. + * + * Reimplemented from YNCursesUI. + **/ + virtual YApplication * createApplication(); +}; + +/** + * Create a new UI if there is none yet or return the existing one if there is. + * + * This is the UI plugin's interface to the outside world, so don't change the + * name or signature! + **/ +extern "C" { + YUI * createYNCHttpUI( bool withThreads ); +} + +#endif // YNCHttpUI_h diff --git a/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpWidgetsActionHandler.cc b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpWidgetsActionHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..7b8c4e4df94c49ba41c0a4bdc2c48a5d6e54d6c4 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpWidgetsActionHandler.cc @@ -0,0 +1,29 @@ +/* + Copyright (C) 2020 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#define YUILogComponent "ncurses-rest-api" +#include + +#include "YNCHttpWidgetsActionHandler.h" +#include "YNCWidgetActionHandler.h" + + +YWidgetActionHandler* YNCHttpWidgetsActionHandler::get_widget_handler() { + if( !widget_action_handler ){ + widget_action_handler = new YNCWidgetActionHandler(); + } + return widget_action_handler; +} diff --git a/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpWidgetsActionHandler.h b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpWidgetsActionHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..2b613b691535ec042a050dffabf5ff9a40c097ac --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/YNCHttpWidgetsActionHandler.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2020 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef YNCHttpWidgetsActionHandler_h +#define YNCHttpWidgetsActionHandler_h + +#include + + +class YNCHttpWidgetsActionHandler : public YHttpWidgetsActionHandler +{ + +public: + + YNCHttpWidgetsActionHandler() {} + virtual ~YNCHttpWidgetsActionHandler() {} + +protected: + virtual YWidgetActionHandler* get_widget_handler(); + +}; + +#endif // YNCHttpWidgetsActionHandler_h diff --git a/deps/libyui/libyui-ncurses-rest-api/src/YNCWidgetActionHandler.cc b/deps/libyui/libyui-ncurses-rest-api/src/YNCWidgetActionHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..e618359bf636062c3c7deb5ce6808abdce3c1bde --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/YNCWidgetActionHandler.cc @@ -0,0 +1,49 @@ +/* + Copyright (C) 2020 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#include "YNCWidgetActionHandler.h" + +#include "NCHttpWidgetFactory.h" + +void YNCWidgetActionHandler::activate_widget( YCheckBoxFrame * widget ) +{ + activate_nc_widget( widget ); +} + +void YNCWidgetActionHandler::activate_widget( YComboBox * widget ) +{ + activate_nc_widget( widget ); +} + +void YNCWidgetActionHandler::activate_widget( YDateField * widget ) +{ + activate_nc_widget( widget ); +} + +void YNCWidgetActionHandler::activate_widget( YSelectionBox * widget ) +{ + activate_nc_widget( widget ); +} + +void YNCWidgetActionHandler::activate_widget( YTimeField * widget ) +{ + activate_nc_widget( widget ); +} + +void YNCWidgetActionHandler::activate_widget ( YMultiSelectionBox * widget, YItem * item ) +{ + activate_nc_widget( widget, item ); +} diff --git a/deps/libyui/libyui-ncurses-rest-api/src/YNCWidgetActionHandler.h b/deps/libyui/libyui-ncurses-rest-api/src/YNCWidgetActionHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..598210f5c78ea0f90ca3d7bd0447cbff6047fee3 --- /dev/null +++ b/deps/libyui/libyui-ncurses-rest-api/src/YNCWidgetActionHandler.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2020 SUSE LLC + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef YNCWidgetActionHandler_h +#define YNCWidgetActionHandler_h + +#include +#include + +#include "YNCHttpUI.h" + + +class YNCWidgetActionHandler : public YWidgetActionHandler +{ + +protected: + + virtual void activate_widget( YCheckBoxFrame * widget ); + virtual void activate_widget( YComboBox * widget ); + virtual void activate_widget( YDateField * widget ); + virtual void activate_widget( YSelectionBox * widget ); + virtual void activate_widget( YTimeField * widget ); + + virtual void activate_widget ( YMultiSelectionBox * widget, YItem * item ); + +private: + + template + void activate_nc_widget( T * widget ) { + if( widget->notify() && dynamic_cast( widget ) ) + { + NCursesEvent event = NCursesEvent::Activated; + event.widget = dynamic_cast( widget ); + YNCHttpUI::ui()->sendEvent( event ); + } + } + + template + void activate_nc_widget( T * widget , I * item) { + if( widget->notify() && dynamic_cast( widget ) ) + { + NCursesEvent event( NCursesEvent::menu ); + event.selection = (YMenuItem *) item; + event.widget = dynamic_cast( widget ); + YNCHttpUI::ui()->sendEvent( event ); + } + } + +}; + +#endif //YNCWidgetActionHandler_h diff --git a/deps/libyui/libyui-ncurses/.editorconfig b/deps/libyui/libyui-ncurses/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..4efde3d7e2e9a857d8358e7157ddaf1131bb5a45 --- /dev/null +++ b/deps/libyui/libyui-ncurses/.editorconfig @@ -0,0 +1,18 @@ +# https://EditorConfig.org -*- ini -*- +# Copyright (c) 2020 SUSE LLC +# MIT license +# +# This is a unified way to tell all your editors +# about the proper indentation style in this repo. +# +# Emacs: https://github.com/editorconfig/editorconfig-emacs#readme +# Vim: https://github.com/editorconfig/editorconfig-vim#readme +# VS Code: https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig + +# don't continue looking in upper directories, this is the top level +root = true + +[*.{h,cc}] +indent_style = tab +indent_size = 4 +tab_width = 8 diff --git a/deps/libyui/libyui-ncurses/.gitignore b/deps/libyui/libyui-ncurses/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b7797e40d60d62bb787649f204d9203cb86a725c --- /dev/null +++ b/deps/libyui/libyui-ncurses/.gitignore @@ -0,0 +1,19 @@ + +*.o +*.so +*.so.* + +CMakeCache.txt +CMakeFiles +CMakeDoxyfile.in +Doxyfile +Doxygen.warnings +Makefile + +build*/ +package/*.tar.* + +*~ +*.bak +*.auto + diff --git a/deps/libyui/libyui-ncurses/CMakeLists.txt b/deps/libyui/libyui-ncurses/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2000bb58d5a0d42accc6edd68214210bb2e3acf3 --- /dev/null +++ b/deps/libyui/libyui-ncurses/CMakeLists.txt @@ -0,0 +1,88 @@ +# CMakeLists.txt for libyui-ncurses +# +# Usage: +# +# mkdir build +# cd build +# cmake .. +# +# make +# sudo make install +# +# Restart with a clean build environment: +# rm -rf build +# +# Show the complete compiler commands with all arguments: +# make VERBOSE=1 + +cmake_minimum_required( VERSION 3.10 ) +project( libyui-ncurses ) + +# Options usage: +# +# cmake -DBUILD_DOC=on -DBUILD_EXAMPLES=off .. + +option( BUILD_SRC "Build in src/ subdirectory" on ) +option( BUILD_DOC "Build class documentation" off ) +option( BUILD_PKGCONFIG "Build pkg-config support files" on ) +option( WERROR "Treat all compiler warnings as errors" on ) + + +#---------------------------------------------------------------------- + + +# We use /usr as the default CMAKE_INSTALL_PREFIX, but it can be set on the +# cmake command line with +# +# cmake -DCMAKE_INSTALL_PREFIX=/my/install/prefix .. +# +# or in the environment with +# +# CMAKE_INSTALL_PREFIX=/usr/local cmake .. + +if ( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT ) + if ( DEFINED ENV{CMAKE_INSTALL_PREFIX} ) + set( CIP $ENV{CMAKE_INSTALL_PREFIX} ) + else() + set( CIP /usr ) + endif() + set( CMAKE_INSTALL_PREFIX "${CIP}" CACHE PATH "Install path prefix" FORCE) +endif() + +message( "-- CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}" ) + + +set( CMAKE_INSTALL_MESSAGE LAZY ) # Suppress "up-to-date" messages during "make install" + + +# Initialize compiler flags for all targets in all subdirectories +add_compile_options( "-Wall" ) +add_compile_options( "-Os" ) # Optimize for size (overrides CMake's -O3 in RELEASE builds) +add_compile_options( "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ) # Enable largefile support +if ( WERROR ) + add_compile_options( "-Werror" ) +endif() + + +# +# Descend into subdirectories +# + +enable_testing() +add_subdirectory( tests ) + +# Build and install auxiliary files first so this doesn't scroll away any important messages + +if ( BUILD_PKGCONFIG ) + add_subdirectory( pkgconfig ) +endif() + +#---------------------------------------------------------------------- + +if ( BUILD_SRC ) + add_subdirectory( src ) +endif() + +if ( BUILD_DOC ) + add_subdirectory( doc ) +endif() diff --git a/deps/libyui/libyui-ncurses/Makefile.repo b/deps/libyui/libyui-ncurses/Makefile.repo new file mode 100644 index 0000000000000000000000000000000000000000..c4914feecbdd3cc01697332668142b65070f13ff --- /dev/null +++ b/deps/libyui/libyui-ncurses/Makefile.repo @@ -0,0 +1,64 @@ +# +# Makefile.repo for libyui-ncurses +# + +# Local Variables: +# mode: Makefile +# End: + + +all: clean configure build-hint + +build-hint: + @echo "" + @echo "To build:" + @echo "" + @echo " cd build" + @echo " make" + @echo "" + +configure: + mkdir build; \ + cd build; \ + cmake .. + +build: clean configure + cd build; \ + make -j $$(nproc) + +# This needs root privileges, of course +install: configure + cd build; \ + make -j $$(nproc) && make install + +clean: + rm -rf build + +package: + rake package + +doc: + test -d build || mkdir build + cd build; \ + cmake -DBUILD_DOC=on .. ; \ + make doc + +version-bump: + rake version:bump + +so-version-bump: + rake so_version:bump + +# Just some aliases +bump-version: version-bump + +bump-so-version: so-version-bump + + +# Enforce rebuilding some targets unconditionally, even if a file or directory +# with that name exists; otherwise the timestamp of that file or directory +# would be checked. +# +# We need this because we have a subdirectory doc/, a subdirectory package/ +# and possibly a subdirectory build/ here. +.PHONY: doc package build diff --git a/deps/libyui/libyui-ncurses/doc/CMakeLists.txt b/deps/libyui/libyui-ncurses/doc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..45bc32b56ad52e008fcda2c8a0b58726ba0687df --- /dev/null +++ b/deps/libyui/libyui-ncurses/doc/CMakeLists.txt @@ -0,0 +1,24 @@ +# CMakeLists.txt for libyui*/doc + +include( ../../VERSION.cmake ) + +find_package( Doxygen REQUIRED dot ) + + +# +# Doxygen-generated autodocs +# + +if ( DOXYGEN_FOUND ) + + set( DOXYGEN_GENERATE_TREEVIEW yes ) # Enable views tree HTML frame + set( DOXYGEN_QUIET yes ) # Less verbose output + set( DOXYGEN_WARN_LOGFILE doxygen-warnings.log ) + # See build/CMakeDoxyfile.in for more supported variables + + doxygen_add_docs( doc ../src ) + +else() + message( WARNING "Missing doxygen package" ) +endif() + diff --git a/deps/libyui/libyui-ncurses/doc/curses-concepts.md b/deps/libyui/libyui-ncurses/doc/curses-concepts.md new file mode 100644 index 0000000000000000000000000000000000000000..8da52df46bd7de42c8422111520578e24801c53f --- /dev/null +++ b/deps/libyui/libyui-ncurses/doc/curses-concepts.md @@ -0,0 +1,53 @@ +# Curses Concepts + +This is a *short* introduction, or refresher, to supplement the [reference +materials][ref] and [tutorials][tut]. + +[ref]: https://invisible-island.net/ncurses/man/index.html +[tut]: https://invisible-island.net/ncurses/ncurses-intro.html + +The important concepts being defined are set in bold: **foo**. + +## Terminal Concepts + +A **terminal** screen is a rectangular grid of **cells**, each having a +**character** and some **attributes**, like foreground and background color, +or bold font. + +The program controls the position and attributes of printable characters by +printing **control sequences** (which start with a nonprintable character). + +For input, some (printing) keys send the program a single character, other +(control) keys send a sequence of characters. + +The input may be buffered and sent to the program a line at a time (**cooked +mode**), or unbuffered with keys sent directly (**raw mode**). + +The terminal may **echo** the typed keys: print them without the program doing +it. This is a mode that can be enabled and disabled. + +Now back to: + +## Curses Concepts + +The output goes to the **screen**. + +The **cursor** is the screen position where text will be output if coordinates +are not specified. **Coordinates** begin at top left (0, 0), in the order +(**line**, **column**), in other words (y, x). + +A **window** is a rectangular part of the *screen*. They may *not* +overlap. (For overlapping things, see *panel*.) + +Curses optimizes for minimal changes to the terminal to accommodate slow +networking over modems. Therefore it needs a **`refresh`** call to actually +update the terminal. When using multiple windows, *`refresh`*-ing them all +would flicker. But a *`refresh`* is implemented as **`noutrefresh`** + +**`doupdate`**, so we should call the former for all windows and then the +latter for the *screen*. + +A **pad** is a virtual window that may be bigger than the screen. Create it +with a size and no origin, its *`refresh`* call will display a section of it +at a chosen position of the screen. + +A **panel** is a member of a global stack of overlapping windows. diff --git a/deps/libyui/libyui-ncurses/doc/keyboard_shortcuts.md b/deps/libyui/libyui-ncurses/doc/keyboard_shortcuts.md new file mode 100644 index 0000000000000000000000000000000000000000..3ee3f69e030dc9c7380cbd380adb31c9d4e43f6c --- /dev/null +++ b/deps/libyui/libyui-ncurses/doc/keyboard_shortcuts.md @@ -0,0 +1,45 @@ +# Libyui-ncurses Keyboard Shortcuts + +The libyui-ncurses interface implements several keyboard shortcuts. + +## Widget Shortcuts + +Some widgets use special keyboard shortcuts. Make sure that the respective +widget is active (the cursor is placed there). + +### Table + +- `Ctrl+O` - Change the ordering. After pressing it a list with the column + names is displayed. Select which column should be used for ordering, to + change the direction (ascending/descending) select the same column again. + +## Global Shortcuts + +These shortcuts can be used anytime, it does not matter which widget is active +(or if any widget is active at all). + +- `Shift+F1` - Display a hot key help. + +- `Ctrl+L` - Redraw the current screen. If for whatever reason the screen + content it not displayed properly you can force redrawing the whole screen. + +- `Shift+F4` - Change the color style. This cycles over the built-in color styles. + +- `Shift+F6` - Ask for widget ID. Enter the ID of the button which should be + activated. This is intended for automated tests. + +- `Ctrl+D Shift+D` - Dump the current dialog into the log. It dumps the screenshot + and also the logical structure of the dialog (the widget tree). + +- `Ctrl+D Shift+Y` - Start the widget inspector. Displays a special dialog which + can navigate in the widget tree and display detailed widget properties. It can + also change some widget properties and even delete or add new widgets. + +- `Ctrl+D Shift+G` - Send a debug event. This should start the debugger in the + running application. + +- `Ctrl+D Shift+C` - Send a configuration event. This should display a special + dialog for configuring the application. + +- `Ctrl+D Shift+S` (only when `Y2NCDBG` environment variable is set) - Display + a special style testing dialog. diff --git a/deps/libyui/libyui-ncurses/doc/nctable-and-nctree.md b/deps/libyui/libyui-ncurses/doc/nctable-and-nctree.md new file mode 100644 index 0000000000000000000000000000000000000000..60970b0ba3961c378d304eb8e0bdc8db6e50eaae --- /dev/null +++ b/deps/libyui/libyui-ncurses/doc/nctable-and-nctree.md @@ -0,0 +1,441 @@ +# libyui-ncurses: The Scary Widgets + +Author: Stefan Hundhammer + +Initial document: 2020-09-22 23:30 - 1:30 + +_This started as a midnight brain dump to write down what was still fresh in my +head after a long, very deep dive into the NCurses UI._ + +_If it sounds somewhat incoherent in some places, you may be right._ + + +# NCTable and NCTree + +NCTable and NCTree are by far the most powerful widgets that libyui-ncurses has +to offer, thus also the most complex and scariest ones. Here is some +higher-level documentation about them. + +NCTable is a multi-column table widget that supports multi-selection and (as of +9/2020) also _nested_ items, i.e. a tree-like structure. Each item is one line +of the table with multiple _cells_. Each cell can have its own label (text). + +NCTable is a tree widget that also supports multi-selection, unlimited tree +depth, collapsing and expanding tree branches. Each item has one label (text). + +Both widgets can scroll in both dimensions. See section _Pads_ below. + + +## UI Events: _notify_ and _immediate_ + +Both widgets can give instant feedback to the calling application if the +_notify_ option is set, and even more immediate when the _immediate_ option is +also set. + +Normally in libyui, `UI.UserInput()` or `UI.WaitForEvent()` only return when +the user presses a PushButton or activates a MenuButton's item, not when +anything is going on in an input field or in a selection widget like a +SelectionBox, ComboBox, or a Table or Tree. Setting the _notify_ option changes +that: A widget with that option also maks `UI.UserInput()` return, and the +application can react immediately. + +Notice that this is not always desirable: When a dialog is mostly an input form +waiting for the user to enter or select values, it makes perfect sense to wait +until the "OK" or "Next" button is pressed. + +But when the status of other widgets depends on what the user selected in a +ComboBox or a Table, it makes sense to add the _notify_ option to that ComboBox +or Table so the dialog can handle that changed status. + +In the Qt UI, there is not much difference between _notify_ and _immediate_. + +But NCurses is special in that it does not just always return, even when a +widget has the _notify_ option set; since the user can only use the keyboard, +that would mean that each CursorDown press in a selection widget would already +make the application react because the selected item just changed. If that +causes major screen updates in other widgets, performance suffers; so typically +only when the user explicitly confirms a selection with the Return key (or +sometimes the Space key), `UI.UserInput()` returns. + +The old language selection in the YaST installer was such an example: Moving +the selection up or down the SelectionBox caused translations for that language +to be loaded, all texts in that dialog retranslated, the complete dialog +completely redisplayed. That was slow; a really bad user experience. + +So, this only happens with the _immediate_ option in addition to _notify_. + + +## Virtual Scrollable Windows: _Pads_ + +In NCurses, a _pad_ is a virtual window that can scroll in both dimension, and +that can provide (more or less) unlimited screen space. Thus, all scrollable +widgets in libyui-ncurses use a _pad_; they all inherit _NCPadWidget_ which +provides a method _myPad()_ that returns an NCPad. **NCPad is not a widget.** +It is a stand-alone class very closely related to the low-level NCurses +_window_. + +Since most widgets use a specialized subclass of NCPad, they overwrite +_myPad()_ with a type cast that returns the kind of pad they are dealing with: + +- NCTable::myPad() returns an NCTablePad +- NCTree::myPad() returns an NCTreePad + +- NCTablePad inherits NCTablePadBase inherits NCPad +- NCTreePad inherits NCTablePadBase inherits NCPad + +- NCTable inherits YTable and NCPadWidget and has an NCTablePad +- NCTree inherits YTree and NCPadWidget and has an NCTreePad + + +A _pad_ deals with lines: + +- NCTablePad has NCTableLines +- NCTreePad has NCTreeLines which inherit NCTableLines + +Lines have a flat structure, even when we are dealing with tree-structured +items. + + +## YSelectionWidgets + +All selection widgets in libyui inherit YSelectionWidget: + +- YTable inherits YSelectionWidget +- YTree inherits YSelectionWidget +- YMenuBar inherits YMenuWidget inherits YSelectionWidget +- YMenuButton inherits YMenuWidget inherits YSelectionWidget +- YComboBox inherits YSelectionWidget +- YSelectionBox inherits YSelectionWidget +- YMultiSelectionBox inherits YSelectionWidget +- YDumbTab inherits YSelectionWidget + +They all deal with YItems of some kind. + + +## YItems + +YItem on the libyui level is a simple class with basically just a _label_ text +and a _selected_ status. But since we always need a connection to some other +object, it can also store a transparent _data_ pointer. YItem never does +anything with that pointer, it only stores it. + +A widget in a concrete UI can use that to store a counterpart to a different +type of item, for example a Qt QListWidgetItem. This serves as a connection +between the abstract libyui world and a concrete toolkit like Qt or NCurses. + +On the downside, YItem can only store a void pointer, and you have to type-cast +that pointer (without any type checking for safety) to the correct pointer type +every time you use it. + +On the side of the concrete Qt or NCurses widget it is advisable to store a +pointer to the corresponding YItem in each item to access the YItem efficiently. + +YItem also provides an _index_ by which it can be uniquely identified. +Similarly to the _data_ pointer, YItem only stores it for use from the outside; +the application has to set the index and make sure it is really unique within +its context. + +YItem has some subclasses: + +- YTreeItem inherits YItem +- YTableItem inherits YTreeItem inherits YItem + +YTreeItem adds tree structure, YTableItem adds multiple columns (cells). + +Notice how (for historical reasons) the inheritance hierarchy is the other way +round as with NCurses item classes: + +- NCTreeLine inherits NCTableLine +- YTableItem inherits YTreeItem inherits YItem + +YSelectionWidget has an YItemCollection which is just a +std::vector. Use YSelectionWidget::itemsBegin() and +YSelectionWidget::itemsEnd() to iterate over them. + +Notice that for tree-structured (nested) items, the YItemCollection itself only +contains the toplevel items. But each YItem provides iterators +YItem::childrenBegin() and YItem::childrenEnd() to dive deeper into the hierarchy. + +On the YItem level, the children-related methods are only empty stubs that do +nothing; YTreeItem (and thus YTableItem) provides the real functionality and +holds a YItemCollection for its (direct) children. + +All that means that you can safely operate recursively on tree-structured items +on the YItem level without using a dynamic cast. + +YItems are **always** owned by the YSelectionWidget. Never attempt to delete +one! Always use methods of YSelectionWidget and its libyui subclasses. + +Where toplevel YItems live in their YSelectionWidget's YItemCollection, a child +YItem lives in its parent's YItemCollection (childrenBegin(), childrenEnd()). + +YItems are managed on the libyui level. They serve as the original to copy from +when creating counterparts on the UI toolkit (Qt, NCurses) level. + +But don't just copy their data away and forget them; there is no need to +duplicate a YItem's label text in an NCurses item. As long as the NCurses item +is relevant, the YItem is always there to fetch data from; similar with +YTableItem cells. + + +## NCPad Lines: NCTableLine, NCTreeLine + +NCPad-related items like NCTableLine and NCTreeLine each correspond to one +YTableItem or NCTreeItem, but they do not inherit any libyui item class. + +They store a pointer to the YItem counterpart, and that pointer typically needs +a lot of dynamic casting to do anything useful. Thus there is an unfortunate +tendency in the NCurses classes to duplicate a lot of data that would actually +be available directly from the YItem: NCTableLine stores a vector of NCTableCol +pointers to hold each _cell_. + +There are also pointers for the tree structure (_parent_, _nextSibling_, +_firstChild_) and a number of tree-related methods. + +There are also some state variables for the item's attribute flags: _normal_, +_active_(the currently selected item), _disabled_, _hidden_, _headline_. Those +influence the visual appearance (background / foreground color attributes) or, +in the case of _hidden_, if the item is displayed at all; for example, if a +tree branch is collapsed, each of the collapsed items would have the _hidden_ +attribute set. + +Those attributes are handled on the NCPad level. It is usually enough to set +the correctly initially. + + +## NCTableCol + +NCTableCol corresponds to one cell in an NCTableLine; it has a _label_ text and +a _style_ attribute. And it can draw itself. + +Of course an NCTableLine can also draw itself, but what it does is only to +iterate over its cells (its NCTableCols) and let them draw themselves at the +correct screen positions. + + +## items vs. visibleItems + +NCTreePad NCTablePad store a vector of their NCTreeLine / NCTableLine items in +_items_. That is where they live, and where they are owned. _Lines()_ returns +the number of items there, and you can safely iterate with a simple _for_ loop +with an _unsigned_ (!) loop counter over them one by one. + +But that's not what you see on the screen; that contains everything, even +the content of collapsed tree branches. + +_visibleItems_ on the other hand is a vector of those NCTreeLine / NCTableLine +items that are currently visible on screen, and _visibleLines()_ returns their +number. This loop iterates over all the visible lines, i.e. all that can be +made visible by scrolling the pad around: + +```C++ + for ( unsigned i=0; i < visibleLines(); i++ ) + { + doSomething( _visibleItems[i] ); + } +``` + +_visibleItems_ does not own any of the NCTableLines; it stores only pointers to +the NCTableLines owned by _items_. + + +## NCTableTags + +Some pads need to display status information that is independent on an item's +label text; things like selection markers, for example: + +``` + [ ] +``` + +or + +``` + [x] +``` + +That is sometimes done (e.g. in NCTableLine) with a special subclass of +NCTableCol called NCTableTag: This is only yet another table cell that draws +itself, but not with a text that it gets from a YItem, but with a fixed text +like those selection markers depending on its internal status: + +```C++ + if ( selected() ) + draw( "[x]" ); + else + draw( "[ ]" ); +``` + +Having such a special class even for this primitive purpose takes care of +reserving screen space in a table for drawing such status information. + + + +# Key Event Handlers + +For an NCTable, we have the NCTable widget, the NCTablePad, and +NCTableLines. But where are keyboard events handled? What happens when the user +presses the _Space_ bar or the cursor keys? Who handles the events? + +The answer is: All of them, in the right sequence, and all the way up and down +the inheritance hierarchy. + +The NCurses UI first identifies the widget with the keyboard focus and sends +the key event there; more exactly, it calls its `wHandleInput()` method. This +is inherited from NCWidget but reimplemented in basically every widget +subclass. + +The NCTable widget first hands the key event over to its NCTablePad; the pad +forwards it to it current NCTableLine item. If the item doesn't know what to do +with the key event, it signals that with a _false_ return code, and the pad +checks if it can do anything with it; if not, it goes back up to the widget. + +The underlying idea is to handle each key event as locally as possible: The +item might know how to handle pressing the `+` key to open a tree branch. It +knows if it even has children so there is a branch that can be opened. + +One level higher, the pad knows how to move the cursor (the currently selected +item) up or down or how to scroll the pad. + +On the widget level, the widget can assemble an NCursesEvent to return to +`UI.UserInput()` if the _notify_ and/or _immediate_ flags are set. + +The complete sequence for NCTable is: + +- NCTable::wHandleInput() +- NCTablePad::handleInput() +- NCTablePadBase::handleInput() +- NCTableLine::handleInput() + +For NCTree it goes through more inherited class layers: + +- NCTree::wHandleInput() +- NCTreePad::handleInput() +- NCTablePadBase::handleInput() +- NCTreeLine::handleInput() +- NCTableLine::handleInput() + +Many of those methods are only stubs that do nothing, only propagating the +event further to the next layer. But they are there in case they need to be +extended. The reasoning is that xit's not at all easy to figure out what method +to override in what class and how to make sure that it is actually called. So +the infrastructure for this is now already in place for the NCTable / NCTree +familiy, waiting to be used when necessary. + + +# NCurses-Pkg + +When doing any change in libyui-ncurses or more specifically in NCTable / +NCTree, beware that the NCPackageSelector in libyui-ncurses-pkg makes heavy use +of those widgets. + +For application code, libyui-ncurses is **not** a valid API to use; +applications are to use strictly the libyui API, either in C++, or via Ruby +with the UI interpreter (yast-ycp-ui-bindings), or with the SWIG bindings. + +But NCurses-Pkg, being an extension of the NCurses UI to provide package +management functionality, is an exception: It uses widgets like NCTable and +NCTree directly, and often it uses them in very creative ways. + +So make sure to always also build libyui-ncurses-pkg and _test_ it. You need to +build and install both libyui-ncurses and libyui-ncurses-pkg: + + +```Shell + cd ~/src/libyui-ncurses/build + make && sudo make install + + cd ~/src/libyui-ncurses-pkg/build + make && sudo make install +``` + + +# Misc + +## NCTable multiSelection + +NCTable has a widget option to enable multi-selection. In that case, a user can +select more than one item. + +Each item gets a marker `[ ]` or `[x]` in its first column. This uses an +NCTableTag (see below) to add another cell before the real content cells are +added. + + + +## NCTable nestedItems + +NCTable displays line graphics for the tree when it detects that at least one +item has children; it does that fully automatically. + +Most applications won't even notice because they don't add child items; the +widget behaves like a flat table. + +But that automatic detection depends on the application behaving nicely: If it +adds all its items at once with `YSelectionWidget::addItems( YItemCollection )`, +everything works right out of the box. + +But it might stop working when an application adds items one by one, and the +first few don't have child items; those would be added in normal _flat_ table +mode, and later ones (starting from the first item with a child item) would be +added in _nested_ mode, leaving space for tree indentation where line graphics +will later be drawn. + +The fix is simple: Build a YItemCollection and add all items at once. + +This is a known limitation of that nested items feature; but it saves the +application developers having to remember to set a special flag or widget +option like _nestedItems_. + + +## NCTable Sorting + +With the advent of the nested items feature it is no longer simple to sort a +table: The tree structure of the items has to be taken into account, sorting +each tree branch on each level individually. + +NCTableLines are flat lines by nature, living in a vector with no tree +structure; that makes sorting difficult. + +So NCTable goes an unorthodox way: When sorting is requested, it simply deletes +all NCTableLines, sorts the YItems on the YItem level recursively, and +recreates the NCTableLines from the now sorted YItems. + + +### NCTable sortStrategy + +NCTable has an auxiliary _sortStrategy_ object that can be exchanged for another +one. This _sortStrategy_ handles comparisons between YItems, by default on the +basis of one column. + +The default _sortStrategy_ uses the _sortKey_ that each YTableCell supports, and +if none was set (which is the usual case), it uses the _label_ of that cell. + +It tries to be smart, attempting to convert the content to a numeric value and +doing a numeric comparison when possible. + + +The NCurses-Pkg NCPkgTable widget has its own sort strategy that uses libzypp +calls for comparing packages against each other, e.g. by package size. + + +### Interactive Sorting + +Ctrl-O (for "Order") in an NCTable opens a pop-up with the table headers to let +the user interactively choose a column to sort by. Sorting by the same column +again reverses the sort order, sorting by the same column once more reverses it +back to normal. + +The _keepSorting_ flag / widget option diables this, leaving the item insertion +order intact. + + +# Testing + +See document [testing-ncurses.md](testing-ncurses.md) in the same directory. + + +## Further Reading + +- "libyui-ncurses: Testing" [testing-ncurses.md](testing-ncurses.md) in the same + directory diff --git a/deps/libyui/libyui-ncurses/doc/testing-ncurses.md b/deps/libyui/libyui-ncurses/doc/testing-ncurses.md new file mode 100644 index 0000000000000000000000000000000000000000..4f28308547a3d2c4c23db95082aeacca5f3201d3 --- /dev/null +++ b/deps/libyui/libyui-ncurses/doc/testing-ncurses.md @@ -0,0 +1,243 @@ +# libyui-ncurses: Testing + +Author: Stefan Hundhammer + +Initial document: 2020-09-24 + +# Automated Testing + +At the time of this writing, there is no automated test suite for +libyui-ncurses. + + +# Manual Testing Basics + + +## Ruby UI Examples + + +There are lots of example programs in the yast-ycp-ui-bindings package: + +https://github.com/yast/yast-ycp-ui-bindings/tree/master/examples + +The package name is deceiving; it no longer deals with the old YCP scripting +language. It's about Ruby now; but it deals with YCPValue containers to +transport data. + +For NCTable, look at the `Table*.rb` examples; for NCTree, it's `Tree*.rb`. + +In general, examples start simple and become increasingly more complex: +`Table1.rb` demonstrates the most basic use of a table widget, `Table2.rb` +becomes a little bit more complex etc. + +For everything related to UI event handling, use the `Events.rb` example. It +also serves as a widget gallery for (almost?) all available widget types. + +Call an example with + +```Shell + y2base ./Events.rb ncurses +``` + +or + +```Shell + y2base ./Events.rb qt +``` + +(make sure to have a symlink to the `/usr/lib/YaST2/bin/y2base` binary from a +convenient directory like `$HOME/bin` that you have in your `$PATH`). + +The Ruby examples are logging to `$HOME/.y2log`. + + +## C++ Examples + +There are also some C++ examples in libyui/examples: + +https://github.com/libyui/libyui/tree/master/examples + +Make sure to test them as well; some details tend to be subtly different from +using libyui from Ruby via the UI interpreter. The C++ examples tend to be +fewer, but more elaborate, showcasing more features. + +Each example is a standalone binary. You can invoke it directly: + +```Shell + cd libyui/build/examples + ./Table-nested-items +``` + +if `$DISPLAY` is set, this will start it with the Qt UI. To start it with +NCurses, make sure `$DISPLAY` is not set: + +```Shell + DISPLAY="" ./Table-nested-items +``` + +or + +```Shell + unset DISPLAY + ./Table-nested-items +``` + +The C++ examples are logging to `/tmp/libyui-examples.log`. + + +## Quick Test: Events.rb + +- Start the Events.rb example. It showcases more or less all widgets. + + - Do all the selection widgets have items? From left to right, there are + - A tree + - A SelectionBox + - A MultiSelectionBox + - A Table + - A RichText + + Below that, there are + - A ComboBox + - A MultiLineEdit ("Address") + - A RadioBox + + The "Address" multi-line input field starts up emtpy; this is normal and expected. + All other widgets should have content. + + - The widgets should also react when you select something in them: You should + see the description of an event in the white "Event" OutputField. After a + few seconds, the event is overwritten by a TimeoutEvent; this is normal. + + - Watch the y2log while you are experimenting. Are there any errors or + warnings from the UI? + + +## Deeper Test: MyWidget*.rb + +Check out the examples/ directory in yast-ycp-ui-bindings. If you changed any +specific widget, invoke the examples one by one. + +In an ideal world, we would have more of the elaborate examples like Events.rb +where you can do more experimenting. This is work in progress. + +For more recent widgets like ItemSelector or MenuBar, there are such examples, +usually even in a C++ version and in a Ruby version. Make sure to invoke both; +for Ruby, there is the UI interpreter as an intermediate layer that subtly +changes things like adding YCPValue-based IDs to widgets and items. + +The C++ API on the other hand gives an application developer more freedom, so +there are more cases to consider. + + +## Testing the Work Horse: NCTable(Pad) and Friends + +Any change to NCTablePad and its base class NCTablePadBase can have effects on +a lot of widgets: + +- NCTable (as expected) +- NCTree (which uses an NCTreePad which inherits NCTablePad) + +- NCFileSelection +- NCItemSelector +- NCMultiSelectionBox +- NCSelectionBox + +...and in the future possibly even more. + +So make sure to test all of them after changes to NCTablePad or NCTablePadBase. + +Also, the table classes from libyui-ncurses-pkg are using it heavily: + +- NCPkgTable +- NCPkgLocaleTable +- NCPkgRepoTable + +So if you change anything here, make sure to test all those classes. + + +### Testing Nested Table Items + +Use those UI examples: + +- Table-nested-items.rb +- Table-nested-multiSel.rb +- Table-flat-items.rb +- Table-flat-multiSel.rb + +That uses all combination of nested vs. flat items with or without +multi-selection. Also, test the Tree with and without multi-selection, +e.g. with: + +- Tree2.rb +- Tree-Checkbox1.rb + + + +## Testing the PackageSelector + + +### UI Examples + +There are some UI examples for the PackageSelector widget. They use libzypp, +but without root permissions, so some operations are not possible. + + +```Shell + cd src/yast-ycp-ui-bindings/examples + + y2base ./PackageSelector.rb ncurses + y2base ./PackageSelector-YOU.rb ncurses +``` + +or + +```Shell + cd src/yast-ycp-ui-bindings/examples + + y2base ./PackageSelector.rb qt + y2base ./PackageSelector-YOU.rb qt +``` + + +### The YaST Software Module + +For a full-blown test of all PackageSelector features, you will need to start +the YaST software module with root permissions. + +**Make sure to use a virtual machine that you can easily revert to a working +snapshot** in case anything goes horribly wrong. + +NCurses: + +```Shell + sudo yast sw_single +``` + +or + +```Shell + sudo DISPLAY="" yast2 sw_single +``` + +Qt: + +```Shell + xhost + + sudo yast2 sw_single +``` + +### What to Watch out For + +- When you select a package in the packages list on the right, are the details + for the correct package displayed in the "Details" panel below the list? + +- When you change the status of a package, is the status set for the correct package? + Does the status indicator change? Is it displayed in the correct table line? + +- When you switch to "Installation Summary", does it show your change? + + +## Further Reading + +- "libyui-ncurses: The Scary Widgets; NCTable and NCTree" +[nctable-and-nctree.md](nctable-and-nctree.md) in the same directory diff --git a/deps/libyui/libyui-ncurses/pkgconfig/CMakeLists.txt b/deps/libyui/libyui-ncurses/pkgconfig/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b77a5e362d7a39663f49dc5ef9f84501155c1abe --- /dev/null +++ b/deps/libyui/libyui-ncurses/pkgconfig/CMakeLists.txt @@ -0,0 +1,33 @@ +# CMakeLists.txt for libyui-ncurses/pkgconfig +# +# Support for pkg-config: +# +# Generate a libyui-ncurses.pc file from libyui-ncurses.pc.in and install it to +# /usr/lib64/pkgconfig. +# +# A .pc file specifies how to use a development package, in particular linker +# flags (-lyui), compiler flags (including include directories) and paths. +# See man pkg-config. +# +# This .pc file is intended for extensions of the NCurses UI plug-in, not for +# applications using libyui. + +include( ../../VERSION.cmake ) +include( GNUInstallDirs ) # set CMAKE_INSTALL_LIBDIR + +# See https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html +# CMAKE_INSTALL_FULL_ +# The absolute path generated from the corresponding CMAKE_INSTALL_ value. +# If the value is not already an absolute path, an absolute path is constructed +# typically by prepending the value of the CMAKE_INSTALL_PREFIX variable. +# So that covers also cmake directive -DCMAKE_INSTALL_LIBDIR=/usr/lib64 with full +# pathname. +# CMAKE_INSTALL_FULL_LIBDIR is used to install libyuy-ncurses.pc and inside it +# to set "libdir" and "plugindir" pkg-config variables +set( PKGCONFIG_INSTALL_DIR ${DESTDIR}${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig ) + +# Generate libyui-ncurses.pc where some CMake variables are expanded from libyui-ncurses.pc.in, +# but only expand @VARIABLE@, not ${VARIABLE} +configure_file( libyui-ncurses.pc.in libyui-ncurses.pc @ONLY ) + +install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libyui-ncurses.pc DESTINATION ${PKGCONFIG_INSTALL_DIR} ) diff --git a/deps/libyui/libyui-ncurses/pkgconfig/libyui-ncurses.pc.in b/deps/libyui/libyui-ncurses/pkgconfig/libyui-ncurses.pc.in new file mode 100644 index 0000000000000000000000000000000000000000..e5f37ff0ae6ee5b4b286ec8b857dc184a4e730bc --- /dev/null +++ b/deps/libyui/libyui-ncurses/pkgconfig/libyui-ncurses.pc.in @@ -0,0 +1,23 @@ +# +# Pkg-Config file for libyui-ncurses +# +# Generated by CMake from libyui-ncurses.pc.in +# + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} + +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=${exec_prefix}/include +plugindir=@CMAKE_INSTALL_FULL_LIBDIR@/yui + +soversion_major=@SONAME_MAJOR@ +soversion_minor=@SONAME_MINOR@ +soversion_patch=@SONAME_PATCH@ +soversion=@SONAME@ + +Name: libyui-ncurses +Version: @VERSION@ +Description: libyui-ncurses - NCurses plug-in for libyui +Libs: -L${plugindir} -lyui-ncurses +Cflags: -I${includedir} -I${includedir}/yui -I${includedir}/yui/ncurses diff --git a/deps/libyui/libyui-ncurses/src/CMakeLists.txt b/deps/libyui/libyui-ncurses/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..58b9eedfedaab7758fc66033d04d159d10ad7ebb --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/CMakeLists.txt @@ -0,0 +1,275 @@ +# CMakeLists.txt for libyui-ncurses/src + +include( ../../VERSION.cmake ) +include( GNUInstallDirs ) # set CMAKE_INSTALL_INCLUDEDIR, ..._LIBDIR +find_package( PkgConfig REQUIRED ) # pkg_check_modules() + + +# Check if the libs we link against are available. +# They are all part of package ncurses-devel. + + +pkg_check_modules( NCurses REQUIRED IMPORTED_TARGET ncursesw panelw ) + + +# +# libyui plugin specific +# + +set( TARGETLIB libyui-ncurses ) +set( TARGETLIB_BASE yui-ncurses ) + +set( HEADERS_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/yui/ncurses ) +set( PLUGIN_DIR ${CMAKE_INSTALL_LIBDIR}/yui ) # /usr/lib64/yui + +# if DESTDIR is set, CMAKE_INSTALL_INCLUDEDIR already contains it +# during "make install" (but not for other make targets!): +# +# sudo make install DESTDIR=/work/foo +# or +# DESTDIR=/work/foo sudo make install +# +# -> the include files are installed to /work/foo/usr/include/... +# We need that for RPM builds to install everything to $RPM_BUILD_ROOT. + + +set( SOURCES + YNCursesUI.cc + NCApplication.cc + NCWidgetFactory.cc + NCOptionalWidgetFactory.cc + + NCurses.cc + NCStyleDef.cc + NCstring.cc + NCstyle.cc + NCtext.cc + NCtoY2Event.cc + NCtypes.cc + lang2encoding.cc + ncursesp.cc + ncursesw.cc + position.cc + stringutil.cc + + NCAlignment.cc + NCAskForDirectory.cc + NCAskForFile.cc + NCBusyIndicator.cc + NCButtonBox.cc + NCCheckBox.cc + NCCheckBoxFrame.cc + NCComboBox.cc + NCCustomStatusItemSelector.cc + NCDateField.cc + NCDialog.cc + NCDumbTab.cc + NCEmpty.cc + NCFileSelection.cc + NCFrame.cc + NCImage.cc + NCInputField.cc + NCInputTextBase.cc + NCIntField.cc + NCItemSelector.cc + NCLabel.cc + NCLayoutBox.cc + NCLogView.cc + NCMenuBar.cc + NCMenuButton.cc + NCMultiLineEdit.cc + NCMultiSelectionBox.cc + NCPackageSelectorPluginStub.cc + NCPad.cc + NCPadWidget.cc + NCPopup.cc + NCPopupInfo.cc + NCPopupList.cc + NCPopupMenu.cc + NCPopupTable.cc + NCPopupTextEntry.cc + NCProgressBar.cc + NCPushButton.cc + NCRadioButton.cc + NCRadioButtonGroup.cc + NCReplacePoint.cc + NCRichText.cc + NCSelectionBox.cc + NCSpacing.cc + NCSquash.cc + NCTable.cc + NCTableItem.cc + NCTablePad.cc + NCTablePadBase.cc + NCTableSort.cc + NCTextPad.cc + NCTimeField.cc + NCTree.cc + NCTreePad.cc + NCWidget.cc + NCWordWrapper.cc + ) + + +set( HEADERS + YNCursesUI.h + NCApplication.h + NCWidgetFactory.h + NCOptionalWidgetFactory.h + + NCurses.h + NCi18n.h + NCstring.h + NCstyle.h + NCtext.h + NCtoY2Event.h + NCtypes.h + CyclicContainer.h + ncursesp.h + ncursesw.h + position.h + stdutil.h + stringutil.h + tnode.h + + NCAlignment.h + NCAskForDirectory.h + NCAskForFile.h + NCBusyIndicator.h + NCButtonBox.h + NCCheckBox.h + NCCheckBoxFrame.h + NCComboBox.h + NCCustomStatusItemSelector.h + NCDateField.h + NCDialog.h + NCDumbTab.h + NCEmpty.h + NCFileSelection.h + NCFrame.h + NCImage.h + NCInputField.h + NCInputTextBase.h + NCIntField.h + NCItemSelector.h + NCLabel.h + NCLayoutBox.h + NCLogView.h + NCMenuBar.h + NCMenuButton.h + NCMultiLineEdit.h + NCMultiSelectionBox.h + NCPackageSelectorPluginIf.h + NCPackageSelectorPluginStub.h + NCPad.h + NCPadWidget.h + NCPopup.h + NCPopupInfo.h + NCPopupList.h + NCPopupMenu.h + NCPopupTable.h + NCPopupTextEntry.h + NCProgressBar.h + NCPushButton.h + NCRadioButton.h + NCRadioButtonGroup.h + NCReplacePoint.h + NCRichText.h + NCSelectionBox.h + NCSpacing.h + NCSquash.h + NCStyleDef.h + NCTable.h + NCTableItem.h + NCTablePad.h + NCTablePadBase.h + NCTableSort.h + NCTextPad.h + NCTimeField.h + NCTree.h + NCTreePad.h + NCWidget.h + NCWordWrapper.h + + NCstyle.braille.h + NCstyle.highcontrast.h + NCstyle.inverted.h + NCstyle.linux.h + NCstyle.mono.h + NCstyle.rxvt.h + NCstyle.xterm.h + ) + + + +# Add shared lib to be built +add_library( ${TARGETLIB} SHARED ${SOURCES} ${HEADERS} ) + + +# +# Include directories and compile options +# + +set( LOCAL_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) + +# Symlink ../../libyui/src to build/src/include/yui +# so the headers there can be included as +file( MAKE_DIRECTORY ${LOCAL_INCLUDE_DIR} ) +file( CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/../../libyui/src ${LOCAL_INCLUDE_DIR}/yui SYMBOLIC ) + +target_include_directories( ${TARGETLIB} BEFORE PUBLIC ${LOCAL_INCLUDE_DIR} ) + + +# Allow operator<<() to output internal values of NCurses WINDOW etc. +target_compile_definitions( ${TARGETLIB} PUBLIC NCURSES_INTERNALS=1 ) + + +# Add more compile options to this target in addition to those +# added in the toplevel CMakeLists.txt and target_compile_definitions(). +# +# Notice that CMake will automatically add -fPIC etc. where needed, +# like for this shared lib. +### target_compile_options( ${TARGETLIB} PUBLIC "-Dfoo" ) + +# Show the complete compiler commands with all arguments: +# make VERBOSE=1 + +# Add more compile options to an individual source file: +### set_source_files_properties( YUI.cc PROPERTIES COMPILE_OPTIONS "-Dfoo" ) + + +# +# Linking +# + +# Find yui during a combined build +target_link_directories( ${TARGETLIB} BEFORE PUBLIC ../../libyui/build/src ) + + +# Libraries that are needed to build this shared lib +# +# If in doubt what is really needed, check with "ldd -u" which libs are unused. +target_link_libraries( ${TARGETLIB} PRIVATE + yui + PkgConfig::NCurses + ) + + +# https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#target-properties +set_target_properties( ${TARGETLIB} PROPERTIES + VERSION ${SONAME} # From ../../VERSION.cmake + SOVERSION ${SONAME_MAJOR} # From ../../VERSION.cmake + OUTPUT_NAME ${TARGETLIB_BASE} + ) + + +# +# Install +# + +# Install the headers first so the message about the lib does not scroll away +install( FILES ${HEADERS} DESTINATION ${HEADERS_INSTALL_DIR} ) +install( TARGETS ${TARGETLIB} LIBRARY DESTINATION ${PLUGIN_DIR} ) + +# This script is collected in the .spec file as the contents of the -tools subpackage +install( PROGRAMS libyui-terminal DESTINATION bin ) diff --git a/deps/libyui/libyui-ncurses/src/CyclicContainer.h b/deps/libyui/libyui-ncurses/src/CyclicContainer.h new file mode 100644 index 0000000000000000000000000000000000000000..50b6a0ca03720bacdccf904dacaf382b3c5a233b --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/CyclicContainer.h @@ -0,0 +1,146 @@ +/* + Copyright (C) 2020 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: CyclicContainer.h + + Author: Jose Iván López + +/-*/ + + +#ifndef CyclicContainer_h +#define CyclicContainer_h + +#include +#include +#include + +/** Container class that allows cyclic navigation between its elements by moving to the next/previous + * element. + * + * @note This class holds pointers, but it does not own the pointers. + **/ +template +class CyclicContainer +{ +public: + + using Iterator = typename std::vector::iterator; + using ReverseIterator = std::reverse_iterator; + + Iterator begin() { return _elements.begin(); } + Iterator end() { return _elements.end(); } + + CyclicContainer() : _elements(), _current( nullptr ) + {} + + + ~CyclicContainer() + { + clear(); + } + + + void clear() + { + _elements.clear(); + _current = nullptr; + } + + + void add( T * element ) + { + _elements.push_back(element); + } + + + void setCurrent(Iterator element) + { + if ( element != _elements.end() ) + _current = *element; + } + + + Iterator current() + { + return std::find( _elements.begin(), _elements.end(), _current ); + } + + + Iterator next() + { + Iterator current = this->current(); + + if ( current == _elements.end() ) + return findNext( _elements.begin() ); + + Iterator next = findNext( std::next( current, 1 ) ); + + if ( next == _elements.end() ) + return findNext( _elements.begin() ); + + return next; + } + + + Iterator previous() + { + Iterator current = this->current(); + + ReverseIterator rbegin; + + if ( current == _elements.end() ) + rbegin = _elements.rbegin(); + else + rbegin = ReverseIterator( current ); + + ReverseIterator previous = findPrevious( rbegin ); + + if ( previous == _elements.rend() && rbegin != _elements.rbegin() ) + previous = findPrevious( _elements.rbegin() ); + + if ( previous == _elements.rend() ) + return _elements.end(); + + return find( _elements.begin(), _elements.end(), *previous ); + } + +private: + + Iterator findNext( Iterator begin ) + { + return find_if( begin, _elements.end(), [](const T * element) { + return element->isSelectable(); + }); + } + + + ReverseIterator findPrevious( ReverseIterator rbegin ) + { + return find_if( rbegin, _elements.rend(), [](const T * element) { + return element->isSelectable(); + }); + } + + + std::vector _elements; + + T * _current; +}; + +#endif // CyclicContainer_h diff --git a/deps/libyui/libyui-ncurses/src/NCAlignment.cc b/deps/libyui/libyui-ncurses/src/NCAlignment.cc new file mode 100644 index 0000000000000000000000000000000000000000..e242fb5f4e4187e9f6a1ff7967933589cbd86784 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCAlignment.cc @@ -0,0 +1,73 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCAlignment.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCAlignment.h" + + +NCAlignment::NCAlignment( YWidget * parent, + YAlignmentType halign, + YAlignmentType valign ) + : YAlignment( parent, halign, valign ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; +} + + +NCAlignment::~NCAlignment() +{ + // yuiDebug() << std::endl; +} + + +void NCAlignment::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); + YAlignment::setSize( newwidth, newheight ); +} + + +void NCAlignment::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YAlignment::setEnabled( do_bv ); +} + + +void NCAlignment::moveChild( YWidget * child, int newx, int newy ) +{ + NCWidget * cw = dynamic_cast( child ); + + if ( !( cw && IsParentOf( *cw ) ) ) + { + yuiError() << DLOC << cw << " is not my child" << std::endl; + return; + } + + wMoveChildTo( *cw, wpos( newy, newx ) ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCAlignment.h b/deps/libyui/libyui-ncurses/src/NCAlignment.h new file mode 100644 index 0000000000000000000000000000000000000000..54c38c4cb90403b4e7cf07076cfbdda999c9b1a6 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCAlignment.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCAlignment.h + + Author: Michael Andres + +/-*/ + +#ifndef NCAlignment_h +#define NCAlignment_h + +#include + +#include +#include "NCWidget.h" + + +class NCAlignment : public YAlignment, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCAlignment & obj ); + + NCAlignment & operator=( const NCAlignment & ); + NCAlignment( const NCAlignment & ); + + +protected: + + virtual const char * location() const { return "NCAlignment"; } + +public: + + NCAlignment( YWidget * parent, YAlignmentType halign, YAlignmentType valign ); + virtual ~NCAlignment(); + + virtual int preferredWidth() { return YAlignment::preferredWidth(); } + virtual int preferredHeight() { return YAlignment::preferredHeight(); } + + virtual void setSize( int newWidth, int newHeight ); + + virtual void moveChild( YWidget * child, int newx, int newy ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCAlignment_h diff --git a/deps/libyui/libyui-ncurses/src/NCApplication.cc b/deps/libyui/libyui-ncurses/src/NCApplication.cc new file mode 100644 index 0000000000000000000000000000000000000000..0f91456361b956bc83c2f59e58b44dd6ff15b0d4 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCApplication.cc @@ -0,0 +1,277 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCApplication.cc + + Authors: Gabriele Mohr + Stefan Hundhammer + +/-*/ + +#include + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "YNCursesUI.h" +#include "NCApplication.h" +#include "NCAskForDirectory.h" +#include "NCAskForFile.h" + + +NCApplication::NCApplication() +{ + +} + + +NCApplication::~NCApplication() +{ + +} + +void +NCApplication::setLanguage( const std::string & language, + const std::string & encoding ) +{ + // Intentionally NOT calling + // YApplication::setLanguage( language, encoding ); + // This would implicitly overwrite LC_CTYPE which might result in encoding bugs. + + setlocale( LC_NUMERIC, "C" ); // always format numbers with "." + NCurses::Refresh(); + + yuiDebug() << "Language: " << language << " Encoding: " << (( encoding != "" ) ? encoding : "NOT SET" ) << std::endl; + +} + + +std::string +NCApplication::askForSaveFileName( const std::string & startDir, + const std::string & filter, + const std::string & headline ) +{ + NCAskForSaveFileName * filePopup = new NCAskForSaveFileName( wpos( 1, 1 ), startDir, filter, headline ); + YUI_CHECK_NEW( filePopup ); + + NCursesEvent retEvent = filePopup->showDirPopup(); + YDialog::deleteTopmostDialog(); + + yuiMilestone() << "Returning: " << retEvent.result << std::endl; + return retEvent.result; +} + + +std::string +NCApplication::askForExistingFile( const std::string & startDir, + const std::string & filter, + const std::string & headline ) +{ + NCAskForExistingFile * filePopup = new NCAskForExistingFile( wpos( 1, 1 ), startDir, filter, headline ); + YUI_CHECK_NEW( filePopup ); + + NCursesEvent retEvent = filePopup->showDirPopup(); + YDialog::deleteTopmostDialog(); + + yuiMilestone() << "Returning: " << retEvent.result << std::endl; + return retEvent.result; +} + + +std::string +NCApplication::askForExistingDirectory( const std::string & startDir, + const std::string & headline ) +{ + NCAskForExistingDirectory * dirPopup = new NCAskForExistingDirectory( wpos( 1, 1 ), startDir, headline ); + YUI_CHECK_NEW( dirPopup ); + + NCursesEvent retEvent = dirPopup->showDirPopup(); + YDialog::deleteTopmostDialog(); + + yuiMilestone() << "Returning: " << retEvent.result << std::endl; + return retEvent.result; +} + + +void +NCApplication::beep() +{ + ::beep(); +} + + +void NCApplication::redrawScreen() +{ + YNCursesUI::ui()->Refresh(); +} + + +void +NCApplication::initConsoleKeyboard() +{ + /* + * Following code breaks the console keyboard e.g. for czech language during + * installation (bnc #433016). According to bnc #367801 comment #18/#19 the + * line isn't needed at all. + * "dumpkeys | loadkeys -C "$KBD_TTY" --unicode" has been also removed from kbd + * initscript. If dumpkeys has to be called for any reason it definitely needs + * the codepage argument, otherwise it cannot work. + */ +#if 0 + std::string cmd = "/bin/dumpkeys | /bin/loadkeys --unicode"; + + if ( NCstring::terminalEncoding() == "UTF-8" ) + { + int ret = system(( cmd + " >/dev/null 2>&1" ).c_str() ); + + if ( ret != 0 ) + { + yuiError() << "ERROR: /bin/dumpkeys | /bin/loadkeys --unicode returned: " << ret << std::endl; + } + } +#endif +} + + +void +NCApplication::setConsoleFont( const std::string & console_magic, + const std::string & font, + const std::string & screen_map, + const std::string & unicode_map, + const std::string & language ) +{ + /** + * Moving that code from YNCursesUI to this class turned out to be + * impossible (or at least a lot more work than it's worth) that I finally + * gave it up. + * + * - sh@suse.de 2008-02-06 + **/ + YNCursesUI::ui()->setConsoleFont( console_magic, + font, + screen_map, + unicode_map, + language ); +} + +void +NCApplication::closeUI() { + // Save tty modes and end ncurses mode temporarily + ::def_prog_mode(); + ::endwin(); + + // Regenerate saved stdout and stderr, so that app called + // via system() can use them and draw something to the terminal + dup2( YNCursesUI::ui()->stdout_save, 1 ); + dup2( YNCursesUI::ui()->stderr_save, 2 ); + + // stop processing the idle loop to avoid potential collisions + // with the other process running on the terminal, the idle loop might redraw + // the UI and reading the user input would eat some user entered characters + YNCursesUI::ui()->idleLoopSetEnabled(false); +} + +void +NCApplication::openUI() { + // enable the idle loop back + YNCursesUI::ui()->idleLoopSetEnabled(true); + + // Redirect stdout and stderr to y2log again + YNCursesUI::ui()->RedirectToLog(); + + // Resume tty modes and refresh the screen + ::reset_prog_mode(); + + ::refresh(); +} + +int +NCApplication::runInTerminal( const std::string & cmd ) +{ + int ret = 0; + + closeUI(); + + // Call external program + ret = system( cmd.c_str() ); + + if ( ret != 0 ) + { + yuiError() << cmd << " returned:" << ret << std::endl; + } + + openUI(); + + return ret; +} + + +int +NCApplication::displayWidth() +{ + return ::COLS; // exported from ncurses.h +} + + +int +NCApplication::displayHeight() +{ + return ::LINES; // exported from ncurses.h +} + + +int +NCApplication::displayDepth() +{ + return -1; +} + + +long +NCApplication::displayColors() +{ + return NCattribute::colors(); +} + + +int +NCApplication::defaultWidth() +{ + return ::COLS; // exported from ncurses.h +} + + +int +NCApplication::defaultHeight() +{ + return ::LINES; // exported from ncurses.h +} + + +bool +NCApplication::hasFullUtf8Support() +{ + return ( NCstring::terminalEncoding() == "UTF-8" ); +} + +void NCApplication::setApplicationTitle ( const std::string& title ) +{ + YApplication::setApplicationTitle ( title ); + NCurses::SetTitle(title); +} + diff --git a/deps/libyui/libyui-ncurses/src/NCApplication.h b/deps/libyui/libyui-ncurses/src/NCApplication.h new file mode 100644 index 0000000000000000000000000000000000000000..09e47083d8ec083f8b6e7c7d94aba4538d818a2a --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCApplication.h @@ -0,0 +1,216 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCApplication.h + + Author: Gabriele Mohr + +/-*/ + +#ifndef NCApplication_h +#define NCApplication_h + +#include + + +class NCApplication: public YApplication +{ + +protected: + + friend class YNCursesUI; + + /** + * Constructor. + * + * Use YUI::app() to get the singleton for this class. + **/ + NCApplication(); + + /** + * Destructor. + **/ + virtual ~NCApplication(); + +public: + + /** + * Set language and encoding for the locale environment ($LANG). + * + * 'language' is the ISO short code ("de_DE", "en_US", ...). + * + * 'encoding' an (optional) encoding ("utf8", ...) that will be appended if + * present. + * + * Reimplemented from YApplication. + **/ + virtual void setLanguage( const std::string & language, + const std::string & encoding = std::string() ) override; + + /** + * Open a directory selection box and prompt the user for an existing + * directory. + * + * 'startDir' is the initial directory that is displayed. + * + * 'headline' is an explanatory text for the directory selection box. + * Graphical UIs may omit that if no window manager is running. + * + * Returns the selected directory name + * or an empty std::string if the user canceled the operation. + * + * Implemented from YApplication. + **/ + virtual std::string askForExistingDirectory( const std::string & startDir, + const std::string & headline ) override; + + /** + * Open a file selection box and prompt the user for an existing file. + * + * 'startWith' is the initial directory or file. + * + * 'filter' is one or more blank-separated file patterns, e.g. + * "*.png *.jpg" + * + * 'headline' is an explanatory text for the file selection box. + * Graphical UIs may omit that if no window manager is running. + * + * Returns the selected file name + * or an empty std::string if the user canceled the operation. + * + * Implemented from YApplication. + **/ + virtual std::string askForExistingFile( const std::string & startWith, + const std::string & filter, + const std::string & headline ) override; + + /** + * Open a file selection box and prompt the user for a file to save data + * to. Automatically asks for confirmation if the user selects an existing + * file. + * + * 'startWith' is the initial directory or file. + * + * 'filter' is one or more blank-separated file patterns, e.g. + * "*.png *.jpg" + * + * 'headline' is an explanatory text for the file selection box. + * Graphical UIs may omit that if no window manager is running. + * + * Returns the selected file name + * or an empty std::string if the user canceled the operation. + * + * Implemented from YApplication. + **/ + virtual std::string askForSaveFileName( const std::string & startWith, + const std::string & filter, + const std::string & headline ) override; + + /** + * Beep. + * + * Reimplemented from YApplication. + **/ + virtual void beep() override; + + /** + * Redraw the screen. + * + * Reimplemented from YApplication. + **/ + virtual void redrawScreen() override; + + /** + * Initialize the (text) console keyboard. + * + * Reimplemented from YApplication. + **/ + virtual void initConsoleKeyboard() override; + + /** + * Set the (text) console font according to the current encoding etc. + * See the setfont(8) command and the console HowTo for details. + * + * Reimplemented from YApplication. + **/ + virtual void setConsoleFont( const std::string & console_magic, + const std::string & font, + const std::string & screen_map, + const std::string & unicode_map, + const std::string & language ) override; + + /** + * Run a shell command (typically an interactive program using NCurses) + * in a terminal (window). + * + * Here in the NCurses UI, this shuts down the NCurses lib, runs the + * command and then restores the status of the NCurses lib so that the next + * instance of the NCurses lib from the started command doesn't interfere + * with the NCurses UI's instance. + * + * Reimplemented from YApplication. + **/ + virtual int runInTerminal( const std::string & command ) override; + + + /// @{ + /** + * To mix TUI (NCurses) with stdio, enclose the UI parts + * within openUI/closeUI + * + * Reimplemented from YApplication. + */ + virtual void openUI() override; + virtual void closeUI() override; + /// @} + + // Display information and UI capabilities. + // + // All implemented from YApplication. + + virtual int displayWidth() override; + virtual int displayHeight() override; + virtual int displayDepth() override; + virtual long displayColors() override; + + virtual int defaultWidth() override; + virtual int defaultHeight() override; + + virtual bool isTextMode() override { return true; } + + virtual bool hasImageSupport() override { return false; } + + virtual bool hasIconSupport() override { return false; } + + virtual bool hasAnimationSupport() override { return false; } + + virtual bool hasFullUtf8Support() override; + virtual bool richTextSupportsTable() override { return false; } + + virtual bool leftHandedMouse() override { return false; } + + /** + * Set the application title + * + * Reimplemented from YApplication. + **/ + virtual void setApplicationTitle(const std::string& title) override; +}; + + +#endif // NCApplication_h diff --git a/deps/libyui/libyui-ncurses/src/NCAskForDirectory.cc b/deps/libyui/libyui-ncurses/src/NCAskForDirectory.cc new file mode 100644 index 0000000000000000000000000000000000000000..b5a5ec2386963d4502fcad6f841ad05b9c015e24 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCAskForDirectory.cc @@ -0,0 +1,256 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCAskForExistingDirectory.cc + + Author: Gabriele Strattner + +/-*/ + +#include "NCAskForDirectory.h" + + +#define YUILogComponent "ncurses" +#include +#include +#include +#include "NCWidgetFactory.h" +#include "NCWidgetFactory.h" +#include "NCLayoutBox.h" +#include "NCSpacing.h" +#include "NCFrame.h" +#include "NCi18n.h" + +#include +#include +#include +#include + +/* + Textdomain "ncurses" +*/ + + + +NCAskForExistingDirectory::NCAskForExistingDirectory( const wpos & at, + const std::string & iniDir, + const std::string & headline ) + : NCPopup( at, true ) + , okButton( 0 ) + , cancelButton( 0 ) + , dirName( 0 ) + , dirList( 0 ) + , detailed( 0 ) +{ + createLayout( iniDir, headline ); +} + + +NCAskForExistingDirectory::~NCAskForExistingDirectory() +{ +} + + +void NCAskForExistingDirectory::createLayout( const std::string & iniDir, + const std::string & headline ) +{ + std::string old_textdomain = textdomain( NULL ); + setTextdomain( "ncurses" ); + + // the vertical split is the (only) child of the dialog + YLayoutBox * split = YUI::widgetFactory()->createVBox( this ); + + // the headline + new NCLabel( split, headline, true, false ); // isHeading = true + + YFrame * frame = YUI::widgetFactory()->createFrame( split, "" ); + + // label for text field showing the selected dir + dirName = new NCComboBox( frame, _( "Selected Directory:" ), false ); // editable = false + dirName->setNotify( true ); + dirName->setStretchable( YD_HORIZ, true ); + + // add the checkBox detailed + YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( split ); + + // label for checkbox + detailed = new NCCheckBox( hSplit, _( "&Detailed View" ), false ); + detailed->setNotify( true ); + + // create table header for table type T_Overview + YTableHeader * tableHeader = new YTableHeader(); + tableHeader->addColumn( " ", YAlignBegin ); + tableHeader->addColumn( _( "Directory Name" ), YAlignBegin ); + + // add the list of directories + dirList = new NCDirectoryTable( split, + tableHeader, + NCFileTable::T_Overview, + iniDir ); + + YUI::widgetFactory()->createSpacing( split, YD_VERT, false, 1.0 ); + + // HBox for the buttons + YLayoutBox * hSplit1 = YUI::widgetFactory()->createHBox( split ); + + YUI::widgetFactory()->createSpacing( hSplit1, YD_HORIZ, true, 0.2 ); // stretchable = true + + // add the OK button + okButton = new NCPushButton( hSplit1, _( "&OK" ) ); + okButton->setFunctionKey( 10 ); + okButton->setStretchable( YD_HORIZ, true ); + + YUI::widgetFactory()->createSpacing( hSplit1, YD_HORIZ, true, 0.4 ); + + // add the Cancel button + cancelButton = new NCPushButton( hSplit1, _( "&Cancel" ) ); + cancelButton->setFunctionKey( 9 ); + cancelButton->setStretchable( YD_HORIZ, true ); + + YUI::widgetFactory()->createSpacing( hSplit1, YD_HORIZ, true, 0.2 ); + // restore former text domain + setTextdomain( old_textdomain.c_str() ); +} + + +NCursesEvent & NCAskForExistingDirectory::showDirPopup() +{ + postevent = NCursesEvent(); + + if ( !dirList || !dirName ) + return postevent; + + dirList->fillList(); + + dirList->setKeyboardFocus(); + + dirName->addItem( dirList->getCurrentDir(), + true ); // selected + + // event loop + do + { + popupDialog(); + } + while ( postAgain() ); + + popdownDialog(); + + + return postevent; +} + + +int NCAskForExistingDirectory::preferredWidth() +{ + return NCurses::cols() - 10; +} + + +int NCAskForExistingDirectory::preferredHeight() +{ + return NCurses::lines() - 4; +} + + +NCursesEvent NCAskForExistingDirectory::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + return NCDialog::wHandleInput( ch ); +} + + +bool NCAskForExistingDirectory::postAgain() +{ + if ( !postevent.widget ) + return false; + + postevent.detail = NCursesEvent::NODETAIL; + + if ( postevent.widget == okButton ) + { + postevent.result = dirList->getCurrentDir(); + // return false means: close the popup + return false; + } + else if ( postevent.widget == dirList ) + { + if ( postevent.result == "" ) + return true; + + // show the currently selected directory + yuiDebug() << "Add item: " << postevent.result << std::endl; + + dirName->addItem( postevent.result, + true ); + + if ( postevent.reason == YEvent::Activated ) + { + // fill the directory list + dirList->fillList(); + } + } + else if ( postevent.widget == dirName ) + { + dirList->setStartDir( dirName->value() ); + dirList->fillList(); + } + else if ( postevent.widget == detailed ) + { + bool details = getCheckBoxValue( detailed ); + + if ( details ) + { + dirList->setTableType( NCFileTable::T_Detailed ); + } + else + { + dirList->setTableType( NCFileTable::T_Overview ); + } + + dirList->fillList(); + } + else + { + postevent.result = ""; + return false; + } + + if ( postevent.widget == cancelButton || + postevent == NCursesEvent::cancel ) + { + postevent.result = ""; + return false; + } + + return true; +} + + +bool NCAskForExistingDirectory::getCheckBoxValue( NCCheckBox * checkBox ) +{ + if ( checkBox ) + { + // return whether the option is selected or not + return ( checkBox->isChecked() ); + } + + return false; +} diff --git a/deps/libyui/libyui-ncurses/src/NCAskForDirectory.h b/deps/libyui/libyui-ncurses/src/NCAskForDirectory.h new file mode 100644 index 0000000000000000000000000000000000000000..f56eaabfd3a51892a93c0fff9b20a31b14f29426 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCAskForDirectory.h @@ -0,0 +1,88 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCAskForExistingDirectory.h + + Author: Gabriele Strattner + +/-*/ + +#ifndef NCAskForExistingDirectory_h +#define NCAskForExistingDirectory_h + +#include + +#include +#include + +#include "NCPopup.h" +#include "NCLabel.h" +#include "NCFileSelection.h" +#include "NCPushButton.h" +#include "NCComboBox.h" +#include "NCCheckBox.h" + + + +class NCAskForExistingDirectory : public NCPopup +{ +private: + + NCAskForExistingDirectory & operator=( const NCAskForExistingDirectory & ); + NCAskForExistingDirectory( const NCAskForExistingDirectory & ); + + NCPushButton * okButton; + NCPushButton * cancelButton; + NCComboBox * dirName; + NCDirectoryTable *dirList; // directory list + NCCheckBox *detailed; + + bool getCheckBoxValue( NCCheckBox * detailed ); + +protected: + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCAskForExistingDirectory( const wpos & at, + const std::string & startDir, + const std::string & headline ); + + virtual ~NCAskForExistingDirectory(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + /** + * Create layout of file directory selection popup + */ + void createLayout( const std::string & initialDir, + const std::string & headline ); + + /** + * Shows the popup with the std::list of directories. + */ + NCursesEvent & showDirPopup(); + +}; + + +#endif // NCAskForExistingDirectory_h diff --git a/deps/libyui/libyui-ncurses/src/NCAskForFile.cc b/deps/libyui/libyui-ncurses/src/NCAskForFile.cc new file mode 100644 index 0000000000000000000000000000000000000000..44bb81bcbdabe90a22c95c8ef8705bf7f6e3dc71 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCAskForFile.cc @@ -0,0 +1,415 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCAskForFile.cc + + Author: Gabriele Strattner + +/-*/ + +#define YUILogComponent "ncurses" +#include + +#include "NCAskForFile.h" + +#include + +#include "NCWidgetFactory.h" +#include "NCLayoutBox.h" +#include "NCSpacing.h" +#include "NCFrame.h" +#include "NCi18n.h" + +#include +#include +#include +#include +#include + +/* + Textdomain "ncurses" +*/ + + +NCAskForFile::NCAskForFile( const wpos & at, + const std::string & iniDir, + const std::string & filter, + const std::string & headline ) + : NCPopup( at, true ) + , okButton( 0 ) + , cancelButton( 0 ) + , dirName( 0 ) + , dirList( 0 ) + , detailed( 0 ) + , fileList( 0 ) + , fileName( 0 ) +{ + +} + + +NCAskForFile::~NCAskForFile() +{ + +} + + +std::string NCAskForFile::checkIniDir( std::string iniDir ) +{ + std::string dname = ""; + + struct stat statInfo; + stat( iniDir.c_str(), &statInfo ); + + if ( S_ISDIR( statInfo.st_mode ) ) + { + dname = iniDir; + } + else + { + std::string::size_type pos; + + pos = iniDir.find_last_of( "/" ); + + if ( pos != std::string::npos + && pos != 0 ) + { + std::string dir = iniDir.substr( 0, pos ); + stat( dir.c_str(), &statInfo ); + + if ( S_ISDIR( statInfo.st_mode ) ) + { + dname = dir; + iniFileName = iniDir.substr( pos + 1 ); + } + } + } + + return dname; +} + + +void NCAskForFile::createLayout( const std::string & iniDir, + const std::string & filter, + const std::string & headline, + bool edit ) +{ + std::string startDir; + std::string old_textdomain = textdomain( NULL ); + setTextdomain( "ncurses" ); + + startDir = checkIniDir( iniDir ); + + // the vertical split is the (only) child of the dialog + YLayoutBox * split = YUI::widgetFactory()->createVBox( this ); + + new NCLabel( split, headline, true, false ); // isHeading = true + + YFrame * frame = YUI::widgetFactory()->createFrame( split, "" ); + + // label for text field showing the selected dir + dirName = new NCComboBox( frame, _( "Selected Directory:" ), false ); // editable = false; + dirName->setNotify( true ); + dirName->setStretchable( YD_HORIZ, true ); + + // add the checkBox detailed + YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( split ); + + // label for checkbox + detailed = new NCCheckBox( hSplit, _( "&Detailed View" ), false ); + detailed->setNotify( true ); + + // HBox for the lists + YLayoutBox * hSplit1 = YUI::widgetFactory()->createHBox( split ); + + // create table header for table type T_Overview + YTableHeader * dirHeader = new YTableHeader(); + dirHeader->addColumn( " " ); + dirHeader->addColumn( _( "Directory name" ) ); + + // add the list of directories + dirList = new NCDirectoryTable( hSplit1, + dirHeader, + NCFileSelection::T_Overview, + startDir ); + dirList->setSendKeyEvents( true ); + + // create table header for table type T_Overview + YTableHeader * fileHeader = new YTableHeader(); + fileHeader->addColumn( " " ); + fileHeader->addColumn( _( "File name" ) ); + + // add the list of files + fileList = new NCFileTable( hSplit1, + fileHeader, + NCFileSelection::T_Overview, + filter, + startDir ); + + fileList->setSendKeyEvents( true ); + + YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( split ); + + // opt.isEditable.setValue( edit ); + // NCInputField doesn't support mode 'not editable' any longer + // -> an InputField IS editable + + // add the text entry for the file name + fileName = new NCInputField( hSplit2, + // label for text field showing the filename + _( "&File name:" ), + false, // passWordMode = false + 100, + 50 ); + fileName->setValue( iniFileName ); + + // label for text field showing the filter (e.g. *.bak) + NCComboBox * extension = new NCComboBox( hSplit2, _( "Filter:" ), false ); // editable = false + extension->setStretchable( YD_HORIZ, true ); + extension->addItem( filter, + true ); // selected + + YUI::widgetFactory()->createSpacing( split, YD_VERT, false, 1.0 ); + + // HBox for the buttons + YLayoutBox * hSplit3 = YUI::widgetFactory()->createHBox( split ); + + YUI::widgetFactory()->createSpacing( hSplit3, YD_HORIZ, true, 0.2 ); // stretchable = true + + // add the OK button + okButton = new NCPushButton( hSplit3, _( "&OK" ) ); + okButton->setFunctionKey( 10 ); + okButton->setStretchable( YD_HORIZ, true ); + + YUI::widgetFactory()->createSpacing( hSplit3, YD_HORIZ, true, 0.4 ); + + // add the Cancel button + cancelButton = new NCPushButton( hSplit3, _( "&Cancel" ) ); + cancelButton->setFunctionKey( 9 ); + cancelButton->setStretchable( YD_HORIZ, true ); + + YUI::widgetFactory()->createSpacing( hSplit3, YD_HORIZ, true, 0.2 ); + // restore former text domain + setTextdomain( old_textdomain.c_str() ); +} + + +NCursesEvent & NCAskForFile::showDirPopup() +{ + postevent = NCursesEvent(); + + if ( !dirList || !fileList || !dirName ) + return postevent; + + dirList->fillList(); + fileList->fillList(); + dirList->setKeyboardFocus(); + dirName->addItem( dirList->getCurrentDir(), + true ); // selected + + if ( iniFileName == "" ) + // show the currently selected file + fileName->setValue( fileList->getCurrentFile() ); + + // event loop + do + { + popupDialog(); + } + while ( postAgain() ); + + popdownDialog(); + + return postevent; +} + + +int NCAskForFile::preferredWidth() +{ + return NCurses::cols() - 10; +} + + +int NCAskForFile::preferredHeight() +{ + return NCurses::lines() - 4; +} + + +NCursesEvent NCAskForFile::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + return NCDialog::wHandleInput( ch ); +} + + +void NCAskForFile::updateFileList() +{ + // set new start dir and show the file list + fileList->setStartDir( dirList->getCurrentDir() ); + fileList->fillList(); + + if ( iniFileName == "" ) + // show the currently selected file + fileName->setValue( fileList->getCurrentFile() ); +} + + +bool NCAskForFile::postAgain() +{ + if ( !postevent.widget ) + return false; + + postevent.detail = NCursesEvent::NODETAIL; + + if ( postevent.keySymbol == "CursorLeft" ) + { + dirList->setKeyboardFocus(); + return true; + } + else if ( postevent.keySymbol == "CursorRight" ) + { + fileList->setKeyboardFocus(); + fileName->setValue( fileList->getCurrentFile() ); + return true; + } + + if ( postevent.widget == okButton ) + { + postevent.result = dirList->getCurrentDir() + "/" + getFileName(); + // return false means: close the popup + return false; + } + else if (( postevent.widget == dirList ) && + ( postevent.result != "" ) ) + { + // show the currently selected directory + dirName->addItem( postevent.result, + true ); + updateFileList(); + + if ( postevent.reason == YEvent::Activated ) + { + // fill directory and file list + dirList->fillList(); + updateFileList(); + } + } + else if ( postevent.widget == dirName ) + { + dirList->setStartDir( dirName->text() ); + dirList->fillList(); + + updateFileList(); + } + else if ( postevent.widget == detailed ) + { + bool details = getCheckBoxValue( detailed ); + + if ( details ) + { + fileList->setTableType( NCFileTable::T_Detailed ); + dirList->setTableType( NCFileTable::T_Detailed ); + } + else + { + fileList->setTableType( NCFileTable::T_Overview ); + dirList->setTableType( NCFileTable::T_Overview ); + } + + fileList->fillList(); + + dirList->fillList(); + } + else if ( postevent.widget == fileList ) + { + if ( postevent.result != "" ) + { + fileName->setValue( postevent.result ); + } + } + else + { + postevent.result = ""; + return false; + } + + if ( postevent.widget == cancelButton || + postevent == NCursesEvent::cancel ) + { + postevent.result = ""; + return false; + } + + return true; +} + + +bool NCAskForFile::getCheckBoxValue( NCCheckBox * checkBox ) +{ + if ( checkBox ) + { + // return whether the option is selected or not + return ( checkBox->isChecked() ); + } + + return false; +} + + +NCAskForExistingFile::NCAskForExistingFile( const wpos & at, + const std::string & iniDir, + const std::string & filter, + const std::string & headline ) + : NCAskForFile( at, iniDir, filter, headline ) +{ + createLayout( iniDir, + filter, + headline, + false ); // file name is not editable +} + + +std::string NCAskForExistingFile::getFileName() +{ + if ( fileName->value() == "" ) + return fileList->getCurrentFile(); + else + return fileName->value(); +} + + +NCAskForSaveFileName::NCAskForSaveFileName( const wpos & at, + const std::string & iniDir, + const std::string & filter, + const std::string & headline ) + : NCAskForFile( at, iniDir, filter, headline ) +{ + createLayout( iniDir, + filter, + headline, + true ); // file name is editable +} + + +std::string NCAskForSaveFileName::getFileName() +{ + return fileName->value(); +} diff --git a/deps/libyui/libyui-ncurses/src/NCAskForFile.h b/deps/libyui/libyui-ncurses/src/NCAskForFile.h new file mode 100644 index 0000000000000000000000000000000000000000..a0d88c86e282f12b7b4d0e3fe34dc62d866a4b01 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCAskForFile.h @@ -0,0 +1,158 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCAskForFile.h + + Author: Gabriele Strattner + +/-*/ + +#ifndef NCAskForFile_h +#define NCAskForFile_h + +#include + +#include +#include + +#include "NCPopup.h" +#include "NCLabel.h" +#include "NCFileSelection.h" +#include "NCPushButton.h" +#include "NCComboBox.h" +#include "NCCheckBox.h" +#include "NCInputField.h" + + + +class NCAskForFile : public NCPopup +{ +private: + + NCAskForFile & operator=( const NCAskForFile & ); + NCAskForFile( const NCAskForFile & ); + + + NCPushButton * okButton; + NCPushButton * cancelButton; + NCComboBox * dirName; // the selected directory + NCDirectoryTable *dirList; // the directory list + NCCheckBox *detailed; // the 'Details' checkbox + + bool getCheckBoxValue( NCCheckBox * detailed ); + + std::string iniFileName; // initial file name + +protected: + + NCFileTable *fileList; // the file list + NCInputField *fileName; + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + + virtual std::string getFileName() = 0; + + std::string checkIniDir( std::string startDir ); + +public: + + NCAskForFile( const wpos & at, + const std::string & startDir, + const std::string & filter, + const std::string & headline ); + + virtual ~NCAskForFile() = 0; + + /** + * Set the default size + */ + virtual int preferredWidth(); + virtual int preferredHeight(); + + /** + * Create layout of file selection popup + * iniDir: The initial start directory + * filter: pattern what files to show + * headline: popup headline + * editable: file name field editable? + */ + void createLayout( const std::string & iniDir, + const std::string & filter, + const std::string & headline, + bool editable ); + + /** + * Shows the popup with the std::list of directories. + */ + NCursesEvent & showDirPopup(); + + /** + * Show new file information + */ + void updateFileList(); + +}; + + +class NCAskForExistingFile : public NCAskForFile +{ + + NCAskForExistingFile & operator=( const NCAskForFile & ); + NCAskForExistingFile( const NCAskForFile & ); + +public: + + NCAskForExistingFile( const wpos & at, + const std::string & startDir, + const std::string & filter, + const std::string & headline ); + + virtual ~NCAskForExistingFile() {} + +protected: + + virtual std::string getFileName(); +}; + + +class NCAskForSaveFileName : public NCAskForFile +{ + + NCAskForSaveFileName & operator=( const NCAskForFile & ); + NCAskForSaveFileName( const NCAskForFile & ); + +public: + + NCAskForSaveFileName( const wpos & at, + const std::string & startDir, + const std::string & filter, + const std::string & headline ); + + virtual ~NCAskForSaveFileName() {} + +protected: + + virtual std::string getFileName(); + +}; + + + +#endif // NCAskForFile_h diff --git a/deps/libyui/libyui-ncurses/src/NCBusyIndicator.cc b/deps/libyui/libyui-ncurses/src/NCBusyIndicator.cc new file mode 100644 index 0000000000000000000000000000000000000000..76f1623ac2bbf531d58e686b90b6745e01654c3b --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCBusyIndicator.cc @@ -0,0 +1,310 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCBusyIndicator.cc + + Author: Thomas Goettlicher + Maintainer: Thomas Goettlicher + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCBusyIndicator.h" +#include +#include +#include + +#define REPAINT_INTERVAL 100 // in ms +#define STEP_SIZE .05 + +/* + Some words about the timer stuff: + With each SIG_ALRM signal _timer_progress gets incremented by _timer_divisor. + When a tick is received [=setAlive(true) is called] _timer_progress is std::set to 0. + If _timer_progress is larger than 1 the widget goes to stalled state. + + How the timer works: + NCBusyIndicatorHandlerWrapper is registered as signal handler for SIG_ALRM + signal and calls NCBusyIndicatorObject->handler(). This wrapper is needed + because a member function cannot be registered as signal handler. + + LIMITATIONS: + i) Only one BusyIndicator widget works at the same time, because the + wrapper function only calls the handler() member function of the last + created instance of BusyIndicator. + + ii) The UserInput widget cannot be used, because UserInput is a blocking + function. When UserInput waits for UserInput no SIG_ALRM signal is sent + and therefore the BusyIndicator widget doesn't show progress. + Please use the TimeoutUserInput widget in a loop instead. +*/ + +struct itimerval interval; +NCBusyIndicator* NCBusyIndicatorObject; +#if 0 +void NCBusyIndicatorHandlerWrapper( int sig_num ); +#endif + + + +NCBusyIndicator::NCBusyIndicator( YWidget * parent, + const std::string & nlabel, + int timeout ) + : YBusyIndicator( parent, nlabel, timeout ) + , NCWidget( parent ) + , _label( nlabel ) + , _timeout( timeout ) + , _lwin( 0 ) + , _twin( 0 ) + , _position( .5 ) + , _rightwards( true ) + , _alive( true ) +{ + // yuiDebug() << std::endl; + + if ( timeout <= 0 ) + timeout = 1; + + setLabel( nlabel ); + hotlabel = &_label; + wstate = NC::WSdumb; + NCBusyIndicatorObject = this; + _timer_divisor = (double) REPAINT_INTERVAL / (double) timeout; + _timer_progress = 0; + +#if 0 + signal( SIGALRM, NCBusyIndicatorHandlerWrapper ); + interval.it_value.tv_sec = 0; + interval.it_value.tv_usec = REPAINT_INTERVAL * 1000; + setitimer( ITIMER_REAL, &interval, NULL ); +#endif +} + + +NCBusyIndicator::~NCBusyIndicator() +{ + NCBusyIndicatorObject = NULL; + delete _lwin; + delete _twin; + // yuiDebug() << std::endl; +} + + +int NCBusyIndicator::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCBusyIndicator::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCBusyIndicator::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YBusyIndicator::setEnabled( do_bv ); +} + + +void NCBusyIndicator::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCBusyIndicator::setDefsze() +{ + defsze = wsze( _label.height() + 1, + _label.width() < 5 ? 5 : _label.width() ); +} + + +void NCBusyIndicator::wCreate( const wrect & newrect ) +{ + NCWidget::wCreate( newrect ); + + if ( !win ) + return; + + wrect lrect( 0, wsze::min( newrect.Sze, + wsze( _label.height(), newrect.Sze.W ) ) ); + + wrect trect( 0, wsze( 1, newrect.Sze.W ) ); + + if ( lrect.Sze.H == newrect.Sze.H ) + lrect.Sze.H -= 1; + + trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; + + _lwin = new NCursesWindow( *win, + lrect.Sze.H, lrect.Sze.W, + lrect.Pos.L, lrect.Pos.C, + 'r' ); + + _twin = new NCursesWindow( *win, + trect.Sze.H, trect.Sze.W, + trect.Pos.L, trect.Pos.C, + 'r' ); +} + + +void NCBusyIndicator::wDelete() +{ + delete _lwin; + delete _twin; + _lwin = 0; + _twin = 0; + NCWidget::wDelete(); +} + + +void NCBusyIndicator::setLabel( const std::string & nlabel ) +{ + _label = NCstring( nlabel ); + setDefsze(); + YBusyIndicator::setLabel( nlabel ); + Redraw(); +} + + +/** + * handler, called by NCBusyIndicatorHandlerWrapper + **/ +void NCBusyIndicator::handler( int sig_num ) +{ + _timer_progress += _timer_divisor; + + if ( _timer_progress >= 1 ) + { + _timer_progress = 0; + _alive = false; + } + + update(); + +#if 0 + interval.it_value.tv_sec = 0; + interval.it_value.tv_usec = REPAINT_INTERVAL * 1000; + setitimer( ITIMER_REAL, &interval, NULL ); +#endif + +} + + +/** + * static wrapper for member function handler + **/ +#if 0 +void NCBusyIndicatorHandlerWrapper( int sig_num ) +{ + signal( SIGALRM, SIG_IGN ); + NCBusyIndicatorObject->handler( sig_num ); + signal( SIGALRM, NCBusyIndicatorHandlerWrapper ); +} + +#endif + + +/** + * Calculate position of moving bar + **/ +void NCBusyIndicator::update() +{ + if ( !_alive ) + return; + + if ( _position > 1.0 || _position < 0 ) + _rightwards = !_rightwards; + + if ( _rightwards ) + _position += STEP_SIZE; + else + _position -= STEP_SIZE; + + Redraw(); + refresh(); +} + + +/** + * std::set alive or stalled + **/ +void NCBusyIndicator::setAlive( bool newAlive ) +{ + _alive = newAlive; + + if ( newAlive ) + _timer_progress = 0; +} + + +void NCBusyIndicator::setTimeout( int newTimeout ) +{ + if ( newTimeout < 1 ) + newTimeout = 1; + + _timeout = newTimeout; + YBusyIndicator::setTimeout( newTimeout ); + _timer_divisor = (double) REPAINT_INTERVAL / (double) _timeout; +} + + +/** + * draw busy indicator widget + **/ +void NCBusyIndicator::wRedraw() +{ + if ( !win ) + return; + + // label + chtype bg = wStyle().dumb.text; + _lwin->bkgdset( bg ); + _lwin->clear(); + _label.drawAt( *_lwin, bg, bg ); + tUpdate(); +} + + +/** + * Draw busy bar + **/ +void NCBusyIndicator::tUpdate() +{ + if ( !win ) + return; + + int cp = (int) (( _twin->maxx() ) * _position ); + + const NCstyle::StProgbar & style( wStyle().progbar ); + + _twin->bkgdset( style.nonbar.chattr ); + _twin->clear(); + + if ( cp <= _twin->maxx() ) + { + _twin->bkgdset( NCattribute::getNonChar( style.bar.chattr ) ); + _twin->move( 0, cp ); + _twin->addch( NCattribute::getChar( style.bar.chattr ) ); + } +} diff --git a/deps/libyui/libyui-ncurses/src/NCBusyIndicator.h b/deps/libyui/libyui-ncurses/src/NCBusyIndicator.h new file mode 100644 index 0000000000000000000000000000000000000000..7dbb483e15801c68162b067d3e9b68469f920c77 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCBusyIndicator.h @@ -0,0 +1,106 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCBusyIndicator.h + + Author: Thomas Goettlicher + Maintainer: Thomas Goettlicher + +/-*/ + +#ifndef NCBusyIndicator_h +#define NCBusyIndicator_h + +#include + +#include +#include "NCWidget.h" + + +class NCBusyIndicator; + + + + + +class NCBusyIndicator : public YBusyIndicator, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCBusyIndicator & obj ); + + NCBusyIndicator & operator=( const NCBusyIndicator & ); + NCBusyIndicator( const NCBusyIndicator & ); + + typedef long long Value_t; + + NClabel _label; + Value_t _timeout; + NCursesWindow * _lwin; + NCursesWindow * _twin; + + void setDefsze(); + void tUpdate(); + void update(); + + float _position; // the position of the bar + bool _rightwards; // direction the bar moves + bool _alive; // the widget is alive or stalled + float _timer_divisor; // =repaint interval devided by timeout + float _timer_progress; // progress until widget goes to stalled state + + +protected: + + + virtual const char * location() const { return "NCBusyIndicator"; } + + virtual void wCreate( const wrect & newrect ); + virtual void wDelete(); + + virtual void wRedraw(); + +public: + + NCBusyIndicator( YWidget * parent, + const std::string & label, + int timeout = 1000 ); + virtual ~NCBusyIndicator(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setTimeout( int newTimeout ); + + virtual void setAlive( bool newAlive ); + + virtual void setEnabled( bool do_bv ); + + int timeout() const { return _timeout; } + + void handler( int sig_num ); + + static void staticHandler( int sig_num ); +}; + + +#endif // NCBusyIndicator_h diff --git a/deps/libyui/libyui-ncurses/src/NCButtonBox.cc b/deps/libyui/libyui-ncurses/src/NCButtonBox.cc new file mode 100644 index 0000000000000000000000000000000000000000..b99769ff08b623ae0fce445dc646b766c6bf118f --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCButtonBox.cc @@ -0,0 +1,71 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCButtonBox.cc + + Author: Stefan Hundhammer + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCButtonBox.h" + + +NCButtonBox::NCButtonBox( YWidget * parent ) + : YButtonBox( parent ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; +} + + +NCButtonBox::~NCButtonBox() +{ + // yuiDebug() << std::endl; +} + + +void NCButtonBox::setSize( int newWidth, int newHeight ) +{ + wRelocate( wpos( 0 ), wsze( newHeight, newWidth ) ); + YButtonBox::setSize( newWidth, newHeight ); +} + + +void NCButtonBox::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YButtonBox::setEnabled( do_bv ); +} + + +void NCButtonBox::moveChild( YWidget * child, int newX, int newY ) +{ + NCWidget * cw = dynamic_cast( child ); + + if ( !( cw && IsParentOf( *cw ) ) ) + { + yuiError() << DLOC << cw << " is not my child" << std::endl; + return; + } + + wMoveChildTo( *cw, wpos( newY, newX ) ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCButtonBox.h b/deps/libyui/libyui-ncurses/src/NCButtonBox.h new file mode 100644 index 0000000000000000000000000000000000000000..bbb1e37205453c9304ff71fa4005f716ac2b209a --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCButtonBox.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCButtonBox.h + + Author: Michael Andres + +/-*/ + +#ifndef NCButtonBox_h +#define NCButtonBox_h + +#include + +#include +#include "NCWidget.h" + +class NCButtonBox; + + +class NCButtonBox : public YButtonBox, public NCWidget +{ + +public: + + NCButtonBox( YWidget * parent ); + virtual ~NCButtonBox(); + + virtual void moveChild( YWidget * child, int newX, int newY ); + virtual void setSize( int newWidth, int newHeight ); + virtual void setEnabled( bool enabled ); + +private: + + friend std::ostream & operator<<( std::ostream & stream, const NCButtonBox & widget ); + + NCButtonBox & operator=( const NCButtonBox & ); + NCButtonBox( const NCButtonBox & ); + +}; + + +#endif // NCButtonBox_h diff --git a/deps/libyui/libyui-ncurses/src/NCCheckBox.cc b/deps/libyui/libyui-ncurses/src/NCCheckBox.cc new file mode 100644 index 0000000000000000000000000000000000000000..ab26ba532625307258f376425123e2b630a03896 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCCheckBox.cc @@ -0,0 +1,189 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCCheckBox.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCCheckBox.h" +#include "YNCursesUI.h" + + +unsigned char NCCheckBox::statetag[3] = { '?', ' ', 'x' }; + + +NCCheckBox::NCCheckBox( YWidget * parent, + const std::string & nlabel, + bool checked ) + : YCheckBox( parent, nlabel ) + , NCWidget( parent ) + , tristate( false ) + , checkstate( checked ? S_ON : S_OFF ) +{ + // yuiDebug() << std::endl; + setLabel( nlabel ); + hotlabel = &label; +} + + +NCCheckBox::~NCCheckBox() +{ + // yuiDebug() << std::endl; +} + + +int NCCheckBox::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCCheckBox::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCCheckBox::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YCheckBox::setEnabled( do_bv ); +} + + +void NCCheckBox::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCCheckBox::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + defsze = wsze( label.height(), label.width() + 4 ); + YCheckBox::setLabel( nlabel ); + Redraw(); +} + + +void NCCheckBox::setValue( YCheckBoxState state ) +{ + YCheckBoxState old = value(); + + switch ( state ) + { + case YCheckBox_on: + checkstate = S_ON; + tristate = false; + break; + + case YCheckBox_off: + checkstate = S_OFF; + tristate = false; + break; + + case YCheckBox_dont_care: + tristate = true; + checkstate = S_DC; + break; + } + + Redraw(); + + // trigger the notify event if enabled + if (old != state && notify()) + { + NCursesEvent event = NCursesEvent::ValueChanged; + event.widget = this; + YNCursesUI::ui()->sendEvent(event); + } +} + + +YCheckBoxState NCCheckBox::value() +{ + if ( checkstate == S_DC ) + return YCheckBox_dont_care; + + if ( checkstate == S_ON ) + return YCheckBox_on; + else + return YCheckBox_off; +} + + +void NCCheckBox::wRedraw() +{ + if ( !win ) + return; + + const NCstyle::StWidget & style( widgetStyle() ); + + win->bkgdset( style.plain ); + + win->printw( 0, 0, "[ ] " ); + + label.drawAt( *win, style, wpos( 0, 4 ) ); + + win->bkgdset( style.data ); + + win->printw( 0, 1, "%c", statetag[checkstate] ); +} + + +NCursesEvent NCCheckBox::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + + switch ( key ) + { + case KEY_HOTKEY: + case KEY_SPACE: + case KEY_RETURN: + + switch ( checkstate ) + { + case S_DC: + checkstate = S_ON; + break; + + case S_ON: + checkstate = S_OFF; + break; + + case S_OFF: + checkstate = tristate ? S_DC : S_ON; + break; + } + + Redraw(); + + if ( notify() ) + ret = NCursesEvent::ValueChanged; + + break; + } + + return ret; +} diff --git a/deps/libyui/libyui-ncurses/src/NCCheckBox.h b/deps/libyui/libyui-ncurses/src/NCCheckBox.h new file mode 100644 index 0000000000000000000000000000000000000000..6e575229a6167c19786e8258d29b5c03e561553d --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCCheckBox.h @@ -0,0 +1,97 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCCheckBox.h + + Author: Michael Andres + +/-*/ + +#ifndef NCCheckBox_h +#define NCCheckBox_h + +#include + +#include +#include "NCWidget.h" + + +class NCCheckBox : public YCheckBox, public NCWidget +{ + + friend std::ostream & operator<<( std::ostream & str, const NCCheckBox & obj ); + + NCCheckBox & operator=( const NCCheckBox & ); + NCCheckBox( const NCCheckBox & ); + +protected: + + enum State + { + S_DC = 0, + S_OFF = 1, + S_ON = 2 + }; + +private: + + static unsigned char statetag[3]; + + bool tristate; + State checkstate; + NClabel label; + +protected: + + virtual const char * location() const { return "NCCheckBox"; } + + virtual void wRedraw(); + +public: + + NCCheckBox( YWidget * parent, + const std::string & label, + bool checked ); + virtual ~NCCheckBox(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setValue( YCheckBoxState state ); + + virtual YCheckBoxState value(); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } +}; + + +#endif // NCCheckBox_h diff --git a/deps/libyui/libyui-ncurses/src/NCCheckBoxFrame.cc b/deps/libyui/libyui-ncurses/src/NCCheckBoxFrame.cc new file mode 100644 index 0000000000000000000000000000000000000000..88aa993a455fae68bf26aa92045c0795b38e8044 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCCheckBoxFrame.cc @@ -0,0 +1,236 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCCheckBoxFrame.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCCheckBoxFrame.h" + + +NCCheckBoxFrame::NCCheckBoxFrame( YWidget * parent, const std::string & nlabel, + bool checked ) + : YCheckBoxFrame( parent, nlabel, checked ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSnormal; + framedim.Pos = wpos( 1 ); + framedim.Sze = wsze( 2 ); + + setLabel( YCheckBoxFrame::label() ); + hotlabel = &label; + + setValue( checked ); + + // setEnabled( getValue() ); is called in wRedraw() +} + + +NCCheckBoxFrame::~NCCheckBoxFrame() +{ + // yuiDebug() << std::endl; +} + + +int NCCheckBoxFrame::preferredWidth() +{ + defsze.W = hasChildren() ? firstChild()->preferredWidth() : 0; + + if ( label.width() > (unsigned) defsze.W ) + defsze.W = label.width(); + + defsze.W += framedim.Sze.W + 4; // add space for checkbox + + return defsze.W; +} + + +int NCCheckBoxFrame::preferredHeight() +{ + defsze.H = hasChildren() ? firstChild()->preferredHeight() : 0; + defsze.H += framedim.Sze.H; + + return defsze.H; +} + + +void NCCheckBoxFrame::setSize( int newwidth, int newheight ) +{ + wsze csze( newheight, newwidth ); + wRelocate( wpos( 0 ), csze ); + csze = wsze::max( 0, csze - framedim.Sze ); + + if ( hasChildren() ) + firstChild()->setSize( csze.W, csze.H ); +} + + +void NCCheckBoxFrame::setLabel( const std::string & nlabel ) +{ + YCheckBoxFrame::setLabel( nlabel ); + + label = NCstring( YCheckBoxFrame::label() ); + label.stripHotkey(); + + Redraw(); +} + +bool NCCheckBoxFrame::getParentValue( NCWidget * widget, bool initial ) +{ + bool enabled = initial; + + for ( tnode * c = widget->Parent(); + c && widget->IsDescendantOf( c ); + c = c->Parent() ) + { + NCCheckBoxFrame * frame = dynamic_cast( c->Value() ); + if ( frame ) + { + enabled = frame->getValue(); + + // invert value if required + if ( frame->invertAutoEnable() ) + enabled = !enabled; + + // despite of frame->getValue(), don't enable child widgets if state + // of frame is NC::WSdisabled + if ( frame->GetState() == NC::WSdisabled ) + enabled = false; + + break; + } + } + return enabled; +} + +void NCCheckBoxFrame::setEnabled( bool do_bv ) +{ + YWidget::setEnabled( do_bv ); + bool do_it = do_bv; + + for ( tnode * c = this->Next(); + c && c->IsDescendantOf( this ); + c = c->Next() ) + { + if ( c->Value()->GetState() != NC::WSdumb ) + { + do_it = getParentValue( c->Value(), do_it ); + + c->Value()->setEnabled( do_it ); + // explicitely set the state (needed for first run - bug #268352) + c->Value()->SetState( do_it ? NC::WSnormal : NC::WSdisabled, true ); + } + } +} + + +bool NCCheckBoxFrame::gotBuddy() +{ + if ( !label.hasHotkey() ) + return false; + + for ( tnode * c = this->Next(); + c && c->IsDescendantOf( this ); + c = c->Next() ) + { + if ( c->Value()->GetState() != NC::WSdumb ) + return true; + } + + return false; +} + + +void NCCheckBoxFrame::wRedraw() +{ + if ( !win ) + return; + + chtype bg = wStyle().dumb.text; + win->bkgd( bg ); + win->box(); + + if ( gotBuddy() ) + label.drawAt( *win, widgetStyle(), wpos( 0, 5 ), + wsze( 1, win->width() - 6 ), NC::TOPLEFT, false ); + else + label.drawAt( *win, bg, bg, wpos( 0, 5 ), + wsze( 1, win->width() - 6 ), NC::TOPLEFT, false ); + + const NCstyle::StWidget & style( widgetStyle() ); + + win->bkgdset( style.plain ); + win->printw( 0, 1, "[ ] " ); + + if ( getValue() ) + win->printw( 0, 2, "%c", 'x' ); + else + win->printw( 0, 2, "%c", ' ' ); + + if ( autoEnable() ) + setEnabled( getValue() ); +} + + +NCursesEvent NCCheckBoxFrame::wHandleInput( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::handled; + + if ( key == KEY_SPACE || + key == KEY_RETURN || + key == KEY_HOTKEY ) + { + if ( getValue() == true ) // enabled + { + setValue( false ); + } + else + { + setValue( true ); + } + + // No need to call Redraw() here, it is already done in setValue() and + // no need to call setEnabled(), it is called in Redraw(), resp. wRedraw(). + + if ( notify() ) + ret = NCursesEvent::ValueChanged; + } + + return ret; +} + + +bool NCCheckBoxFrame::setKeyboardFocus() +{ + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; +} + + +bool NCCheckBoxFrame::value() +{ + return getValue(); +} diff --git a/deps/libyui/libyui-ncurses/src/NCCheckBoxFrame.h b/deps/libyui/libyui-ncurses/src/NCCheckBoxFrame.h new file mode 100644 index 0000000000000000000000000000000000000000..675675d0e0422ff310f3575bc2d6c47c6ca63b70 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCCheckBoxFrame.h @@ -0,0 +1,89 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCCheckBoxFrame.h + + Author: Michael Andres + +/-*/ + +#ifndef NCCheckBoxFrame_h +#define NCCheckBoxFrame_h + +#include + +#include +#include "NCWidget.h" +#include "NCCheckBox.h" + +class NCCheckBoxFrame; + + +class NCCheckBoxFrame : public YCheckBoxFrame, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCCheckBoxFrame & obj ); + + NCCheckBoxFrame & operator=( const NCCheckBoxFrame & ); + NCCheckBoxFrame( const NCCheckBoxFrame & ); + + + NClabel label; + bool isEnabled; + +protected: + + bool gotBuddy(); + + virtual const char * location() const { return "NCCheckBoxFrame"; } + + virtual void wRedraw(); + +public: + + NCCheckBoxFrame( YWidget * parent, const std::string & label, + bool checked ); + virtual ~NCCheckBoxFrame(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setEnabled( bool do_bv ); + + virtual bool getValue() { return isEnabled; } + + // Do not forget to call Redraw(), so that UI::ChangeWidget works + // correctly - bug #301370 + virtual void setValue( bool enable ) { isEnabled = enable; Redraw();} + + virtual bool setKeyboardFocus(); + + virtual bool value(); + + virtual NCursesEvent wHandleInput( wint_t key ); + + bool getParentValue( NCWidget * widget, bool initial ); +}; + + +#endif // NCCheckBoxFrame_h diff --git a/deps/libyui/libyui-ncurses/src/NCComboBox.cc b/deps/libyui/libyui-ncurses/src/NCComboBox.cc new file mode 100644 index 0000000000000000000000000000000000000000..2bff9d57d20fdd1663b6119704c7d81e8cf3d614 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCComboBox.cc @@ -0,0 +1,627 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCComboBox.cc + + Author: Michael Andres + +/-*/ + +#include + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCComboBox.h" +#include "NCPopupList.h" + + +NCComboBox::NCComboBox( YWidget * parent, const std::string & nlabel, + bool editable ) + : YComboBox( parent, nlabel, editable ) + , NCWidget( parent ) + , mayedit( editable ) + , privText( "" ) + , lwin( 0 ) + , twin( 0 ) + , fldstart( 0 ) + , fldlength( 0 ) + , curpos( 0 ) + , longest_line( 10 ) + , index( -1 ) + , InputMaxLength( -1 ) +{ + // yuiDebug() << std::endl; + setLabel( nlabel ); + hotlabel = &label; + setText( "" ); +} + + +NCComboBox::~NCComboBox() +{ + delete lwin; + delete twin; + // yuiDebug() << std::endl; +} + + +int NCComboBox::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCComboBox::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCComboBox::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YComboBox::setEnabled( do_bv ); +} + + +void NCComboBox::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCComboBox::setDefsze() +{ + // Height: label h. + 1 (text area) + // Width: longest line + 2 chars ( arrow(s) ) + // (here, we should not rely on label width only as text area may become + // unreasonably small then - #367083 ) + defsze = wsze( label.height() + 1, + ( label.width() > longest_line ) ? label.width() : longest_line + 2 ); +} + + +void NCComboBox::wCreate( const wrect & newrect ) +{ + NCWidget::wCreate( newrect ); + + if ( !win ) + return; + + wrect lrect( 0, wsze::min( newrect.Sze, + wsze( label.height(), newrect.Sze.W ) ) ); + + wrect trect( 0, wsze( 1, newrect.Sze.W ) ); + + if ( lrect.Sze.H == newrect.Sze.H ) + lrect.Sze.H -= 1; + + trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; + + lwin = new NCursesWindow( *win, + lrect.Sze.H, lrect.Sze.W, + lrect.Pos.L, lrect.Pos.C, + 'r' ); + + twin = new NCursesWindow( *win, + trect.Sze.H, trect.Sze.W, + trect.Pos.L, trect.Pos.C, + 'r' ); + + fldlength = trect.Sze.W ? trect.Sze.W - 1 : 0; +} + + +void NCComboBox::wDelete() +{ + delete lwin; + delete twin; + lwin = 0; + twin = 0; + NCWidget::wDelete(); +} + + +void NCComboBox::addItem( YItem * item ) +{ + if ( item ) + { + YComboBox::addItem( item ); + + deflist.push_back( item->label() ); + std::string::size_type this_line = item->label().size(); + + //Is this line longer than the longest one so far? + //(but no greater than 40 chars, we may have only 80x25 screen) + + if (( this_line > longest_line ) && ( this_line <= 40 ) ) + { + //yes, so let's resize the text area) + longest_line = this_line; + setDefsze(); + } + + if ( item->selected() ) + { + index = item->index(); + setText( item->label() ); + } + } +} + + +void NCComboBox::addItem( const std::string & label, bool selected ) +{ + YItem * newItem = new YItem( label, selected ); + YUI_CHECK_NEW( newItem ); + + addItem( newItem ); + +} + + +void NCComboBox::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + setDefsze(); + YComboBox::setLabel( nlabel ); + Redraw(); +} + + +void NCComboBox::setCurrentItem( int nindex ) +{ + int idx = 0; + std::list::iterator entry; + + for ( entry = deflist.begin(); entry != deflist.end(); ++entry, ++idx ) + { + if ( idx == nindex ) + { + std::string strip = *entry; + std::string::size_type h = strip.find( '&' ); + + if ( h != std::string::npos ) + strip.erase( h, 1 ); + + setText( strip ); + + index = idx; + break; + } + } + + Redraw(); +} + + +int NCComboBox::getCurrentItem() const +{ + return index; +} + + +void NCComboBox::setText( const std::string & ntext ) +{ + privText = NCstring( ntext ); + buffer = privText.str(); + modified = false; + fldstart = 0; + curpos = mayedit ? buffer.length() : 0; + + // (Maybe) no need to set default size here, it has been + // alread calculated as the items were added (see addItem() above) + // setDefsze(); + + tUpdate(); + Redraw(); +} + +void NCComboBox::selectItem( YItem * item, bool selected ) +{ + if ( item ) + { + YComboBox::selectItem( item, selected ); + + if ( selected ) + index = item->index(); + } +} + +std::string NCComboBox::text() +{ + if ( modified ) + return NCstring( buffer ).Str(); + + return privText.Str(); +} + + +void NCComboBox::setValidChars( const std::string & validchars ) +{ + validChars = NCstring( validchars ); + YComboBox::setValidChars( validchars ); +} + + +bool NCComboBox::validKey( wint_t key ) const +{ + const std::wstring vwch( validChars.str() ); + + if ( vwch.empty() ) // usually empty -> return true + return true; + + if ( key < 0 || WCHAR_MAX < key ) + return false; + + return( vwch.find(( wchar_t )key ) != std::wstring::npos ); +} + + +void NCComboBox::wRecoded() +{ + if ( modified ) + { + privText = NCstring( buffer ); + modified = false; + } + + buffer = privText.str(); + + wRedraw(); +} + + +void NCComboBox::wRedraw() +{ + if ( !win ) + return; + + // label + const NCstyle::StWidget & style( widgetStyle( true ) ); + + lwin->bkgd( style.plain ); + + lwin->clear(); + + label.drawAt( *lwin, style ); + + tUpdate(); +} + + +void NCComboBox::tUpdate() +{ + if ( !win ) + return; + + const std::wstring & str( buffer ); + + if ( curpos > str.length() ) + { + curpos = str.length(); + } + + // adjust fldstart that cursor is visible + if ( str.length() >= fldlength ) + { + if ( curpos <= fldstart ) + { + fldstart = curpos ? curpos - 1 : 0; + } + + if ( curpos >= fldstart + fldlength - 1 ) + { + fldstart = curpos + ( curpos == str.length() ? 1 : 2 ) - fldlength; + } + } + else if ( fldstart ) + { + fldstart = 0; + } + + const NCstyle::StWidget & style( widgetStyle() ); + + twin->bkgd( widgetStyle( true ).plain ); + + twin->move( 0, 0 ); + + bool utf8 = haveUtf8(); + + if ( fldlength ) + { + unsigned i = 0; + unsigned end = fldlength; + const wchar_t * cp = str.data() + fldstart; + + // draw left scrollhint if + + if ( *cp && fldstart ) + { + twin->bkgdset( style.scrl ); + utf8 ? + twin->add_wch( WACS_LARROW ) + : twin->addch( ACS_LARROW ); + ++i; + ++cp; + } + + // check for right scrollhint + if ( fldstart + fldlength <= str.length() ) + { + --end; + } + + // draw field + twin->bkgdset( style.data ); + + for ( /*adjusted i*/; *cp && i < end; ++i ) + { + twin->addwstr( cp, 1 ); + cp++; + } + + twin->bkgdset( style.plain ); + + for ( /*adjusted i*/; i < end; ++i ) + { + twin->addch( ACS_CKBOARD ); + } + + // draw right scrollhints + twin->bkgdset( style.scrl ); + + if ( end < fldlength ) + { + utf8 ? + twin->add_wch( WACS_RARROW ) + : twin->addch( ACS_RARROW ); + } + } + + utf8 ? + + twin->add_wch( 0, twin->maxx(), WACS_DARROW ) + : twin->addch( 0, twin->maxx(), ACS_DARROW ); + + if ( mayedit && GetState() == NC::WSactive ) + { + twin->move( 0, curpos - fldstart ); + twin->bkgdset( wStyle().cursor ); + + if ( curpos < buffer.length() ) + twin->add_attr_char(); + else + twin->addch( ACS_CKBOARD ); + } +} + + +NCursesEvent NCComboBox::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + bool beep = false; + bool update = true; + std::wstring oval = buffer; + + switch ( key ) + { + case KEY_BACKSPACE: + + if ( mayedit && curpos ) + { + buffer.erase( --curpos, 1 ); + modified = true; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_DC: + + if ( mayedit && curpos < buffer.length() ) + { + buffer.erase( curpos, 1 ); + modified = true; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_SLEFT: + case KEY_HOME: + + if ( curpos && ( mayedit || fldstart ) ) + { + curpos = 0; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_SRIGHT: + case KEY_END: + + if ( curpos < buffer.length() && ( mayedit || fldstart + fldlength <= buffer.length() ) ) + { + curpos = buffer.length(); + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_LEFT: + + if ( curpos ) + { + if ( mayedit ) + --curpos; + else if ( fldstart ) + curpos = fldstart - 1; + else + { + update = false; + beep = true; + } + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_RIGHT: + + if ( mayedit && curpos < buffer.length() ) + { + ++curpos; + } + else if ( fldstart + fldlength <= buffer.length() ) + { + curpos = fldstart + fldlength; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_HOTKEY: + + if ( mayedit ) + break; + + // else fallthrough + + case KEY_DOWN: + listPopup(); + + break; + + default: + bool is_special = false; + + if ( key > 0xFFFF ) + { + is_special = true; + key -= 0xFFFF; + } + + if ( !mayedit || !validKey( key ) + || + ( !is_special && KEY_MIN < key && KEY_MAX > key ) + || + !iswprint( key ) + || + // if we are at limit of input + ( InputMaxLength >= 0 && InputMaxLength <= (int) buffer.length() ) ) + { + update = false; + beep = true; + } + else + { + buffer.insert( curpos, 1, key ); + modified = true; + ++curpos; + } + + break; + } + + if ( update ) + tUpdate(); + + if ( beep ) + ::beep(); + + //if ( notify() && oval != buffer ) + // to be conform to qt UI send event even if value hasn't changed + if ( notify() ) + ret = NCursesEvent::ValueChanged; + + return ret; + +} + + +int NCComboBox::listPopup() +{ + int idx = -1; + + if ( !deflist.empty() ) + { + // add fix heigth of 2 (dont't use win->height() because win might be invalid, bnc#931154) + wpos at( ScreenPos() + wpos( 2, -1 ) ); + NCPopupList * dialog = new NCPopupList( at, "", deflist, index ); + YUI_CHECK_NEW( dialog ); + idx = dialog->post(); + + if ( idx != -1 ) + setCurrentItem( idx ); + + YDialog::deleteTopmostDialog(); + } + + return idx; +} + + +void NCComboBox::deleteAllItems() +{ + YComboBox::deleteAllItems(); + deflist.clear(); + setText( "" ); +} + + +void NCComboBox::setInputMaxLength( int nr ) +{ + // if there is more text then the maximum number of chars, + // truncate the text and update the buffer + if ( nr >= 0 && (int) buffer.length() > nr ) + { + buffer.erase( nr, buffer.length() - nr ); + tUpdate(); + curpos = buffer.length(); + } + + YComboBox::setInputMaxLength( nr ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCComboBox.h b/deps/libyui/libyui-ncurses/src/NCComboBox.h new file mode 100644 index 0000000000000000000000000000000000000000..542739b16fbf781bd70dfc560ff9b23ce94da2e4 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCComboBox.h @@ -0,0 +1,137 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCComboBox.h + + Author: Michael Andres + +/-*/ + +#ifndef NCComboBox_h +#define NCComboBox_h + +#include +#include + +#include +#include "NCWidget.h" +#include "NCApplication.h" +#include + + +class NCComboBox : public YComboBox, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCComboBox & obj ); + + NCComboBox & operator=( const NCComboBox & ); + NCComboBox( const NCComboBox & ); + + + bool mayedit; + NClabel label; + NCstring privText; + std::wstring buffer; + bool modified; + NCursesWindow * lwin; + NCursesWindow * twin; + + std::string::size_type fldstart; + std::string::size_type fldlength; + std::string::size_type curpos; + std::string::size_type longest_line; + + NCstring validChars; + + std::list deflist; + int index; + + void setDefsze(); + void tUpdate(); + + bool haveUtf8() { return YUI::app()->hasFullUtf8Support(); } + +protected: + + virtual const char * location() const { return "NCComboBox"; } + + virtual void wCreate( const wrect & newrect ); + virtual void wDelete(); + + virtual void wRedraw(); + virtual void wRecoded(); + + int listPopup(); + + bool validKey( wint_t key ) const; + + // specifies how much characters can be inserted. -1 for unlimited input + int InputMaxLength; + +public: + + NCComboBox( YWidget * parent, + const std::string & label, + bool editable ); + virtual ~NCComboBox(); + + virtual void addItem( YItem * item ); + virtual void selectItem( YItem * item, bool selected = true ); + + void addItem( const std::string & label, bool selected ); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setText( const std::string & ntext ); + virtual std::string text(); + + virtual void setValidChars( const std::string & validchars ); + + virtual int getCurrentItem() const; + virtual void setCurrentItem( int index ); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + unsigned getListSize() { return deflist.size(); } + + void deleteAllItems(); + + // limits the input to numberOfChars characters and truncates the text + // if appropriate + void setInputMaxLength( int nr ); + +}; + + +#endif // NCComboBox_h diff --git a/deps/libyui/libyui-ncurses/src/NCCustomStatusItemSelector.cc b/deps/libyui/libyui-ncurses/src/NCCustomStatusItemSelector.cc new file mode 100644 index 0000000000000000000000000000000000000000..568dcc1f339b1cb26412f856b3ec8c18f9e9237d --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCCustomStatusItemSelector.cc @@ -0,0 +1,196 @@ +/* + Copyright (C) 2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCCustomStatusItemSelector.cc + + Author: Stefan Hundhammer + +/-*/ + + +#define YUILogComponent "ncurses" +#include +#include "NCLabel.h" +#include "NCCustomStatusItemSelector.h" + +using std::string; + + +NCCustomStatusItemSelector::NCCustomStatusItemSelector( YWidget * parent, + const YItemCustomStatusVector & customStates ) + : NCItemSelectorBase( parent, customStates ) +{ + // yuiDebug() << endl; +} + + +NCCustomStatusItemSelector::~NCCustomStatusItemSelector() +{ + // yuiDebug() << endl; +} + + +NCTableTag * NCCustomStatusItemSelector::createTagCell( YItem * item ) +{ + NCTableTag * tag = new NCCustomStatusTableTag( this, item ); + YUI_CHECK_NEW( tag ); + + return tag; +} + + +NCCustomStatusTableTag * +NCCustomStatusItemSelector::tagCell( int index ) const +{ + NCTableTag * tag = NCItemSelectorBase::tagCell( index ); + + return tag ? dynamic_cast( tag ) : 0; +} + + +void NCCustomStatusItemSelector::updateCustomStatusIndicator( YItem * item ) +{ + if ( ! item ) + return; + + // yuiDebug() << "Updating status indicator for \"" << item->label() << "\"" << endl; + NCCustomStatusTableTag * tag = (NCCustomStatusTableTag *) item->data(); + YUI_CHECK_PTR( tag ); + + tag->updateStatusIndicator(); + DrawPad(); +} + + +void NCCustomStatusItemSelector::cycleCurrentItemStatus() +{ + YItem *item = currentItem(); + + if ( item ) + { + int oldStatus = item->status(); + int newStatus = customStatus( oldStatus ).nextStatus(); + + yuiDebug() << "Cycling status of item \"" + << item->label() << "\": " + << oldStatus << " -> " << newStatus + << endl; + + if ( newStatus != -1 && oldStatus != newStatus ) + { + item->setStatus( newStatus ); + updateCustomStatusIndicator( item ); + } + } +} + + +bool NCCustomStatusItemSelector::statusChangeAllowed( int fromStatus, int toStatus ) +{ + if ( fromStatus == toStatus ) // No use setting to the same status as before + return false; + + if ( ! validCustomStatusIndex( fromStatus ) || ! validCustomStatusIndex( toStatus ) ) + return false; + + return customStatus( fromStatus ).nextStatus() == toStatus; +} + + +NCursesEvent +NCCustomStatusItemSelector::valueChangedNotify( YItem * item ) +{ + NCursesEvent event( NCursesEvent::menu ); + event.selection = (YMenuItem *) item; + + yuiDebug() << "Sending MenuEvent for item \"" << item->label() << "\"" << endl; + + return event; +} + + +// ---------------------------------------------------------------------- + + +NCCustomStatusTableTag::NCCustomStatusTableTag( YItemSelector * parentSelector, YItem * item ) + : NCTableTag( item ) + , _parentSelector( parentSelector ) +{ + YUI_CHECK_PTR( _parentSelector ); + updateStatusIndicator(); +} + + +void NCCustomStatusTableTag::updateStatusIndicator() +{ + YItem * item = origItem(); + + if ( item ) + { + string statusText = _parentSelector->customStatus( item->status() ).textIndicator(); + + // Since the parent class overwrote SetLabel() to do nothing, + // we need to go one class up the class hierarchy to set the text. + NCTableCol::SetLabel( NCstring( statusText ) ); + } +} + + +void NCCustomStatusTableTag::DrawAt( NCursesWindow & w, + const wrect at, + NCTableStyle & tableStyle, + NCTableLine::STATE linestate, + unsigned colidx ) const +{ + // Undo the parent class's overwriting DrawAt(): + // Call the next superclass in the class hierarchy + NCTableCol::DrawAt( w, at, tableStyle, linestate, colidx ); +} + + +int NCCustomStatusTableTag::status() const +{ + YItem * item = origItem(); + + return item ? item->status() : 0; +} + + +void NCCustomStatusTableTag::setStatus( int newStatus ) +{ + YItem * item = origItem(); + + if ( item ) + { + item->setStatus( newStatus ); + updateStatusIndicator(); + } +} + + +void NCCustomStatusTableTag::SetSelected( bool sel ) +{ + setStatus( sel ? 1 : 0 ); +} + + +bool NCCustomStatusTableTag::Selected() const +{ + return status() != 0; +} + diff --git a/deps/libyui/libyui-ncurses/src/NCCustomStatusItemSelector.h b/deps/libyui/libyui-ncurses/src/NCCustomStatusItemSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..c4b05b382bf5c9cf48fa64a8820c834e7974a4fb --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCCustomStatusItemSelector.h @@ -0,0 +1,152 @@ +/* + Copyright (C) 2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCCustomStatusItemSelector.h + + Author: Stefan Hundhammer + +/-*/ + +#ifndef NCCustomStatusItemSelector_h +#define NCCustomStatusItemSelector_h + +#include +#include + +#include "NCItemSelector.h" + + +/** + * Specialized subclass of NCTableTag that can not only handle a boolean + * "selected" flag (and accordingly set "[ ]" / "[x]" or "( )" / "(x)" as a + * status indicator), but extended numeric status values and an assciated text. + **/ +class NCCustomStatusTableTag: public NCTableTag // base class defined in NCTablePadBase.h +{ +public: + + NCCustomStatusTableTag( YItemSelector * parentSelector, YItem * item ); + virtual ~NCCustomStatusTableTag() {} + + virtual void DrawAt( NCursesWindow & w, const wrect at, + NCTableStyle & tableStyle, + NCTableLine::STATE linestate, + unsigned colidx ) const; + + virtual void SetSelected( bool sel ); + + virtual bool Selected() const; + + virtual bool SingleSelection() const { return false; } + + /** + * Return the numeric status value of the associated item. + **/ + int status() const; + + /** + * Set the numeric status value of the associated item and update the + * status indicator. + **/ + void setStatus( int newStatus ); + + /** + * Update the status indicator according to the status of the associated + * item, i.e. display the status text for that custom status. + **/ + void updateStatusIndicator(); + +protected: + + YItemSelector * _parentSelector; +}; + + + +class NCCustomStatusItemSelector : public NCItemSelectorBase +{ + friend std::ostream & operator<<( std::ostream & str, const NCCustomStatusItemSelector & obj ); + +public: + + /** + * Constructor. + **/ + NCCustomStatusItemSelector( YWidget * parent, + const YItemCustomStatusVector & customStates ); + + /** + * Destructor. + **/ + virtual ~NCCustomStatusItemSelector(); + + virtual const char * location() const { return "NCCustomStatusItemSelector"; } + + +protected: + + /** + * Create a tag cell for an item. This is the cell with the "[x]" or "(x)" + * selector. It also stores the item pointer so the item can later be + * referenced by this tag. + **/ + virtual NCTableTag * createTagCell( YItem * item ); + + /** + * Cycle the status of the current item through its possible values. + * For a plain ItemSelector, this means true -> false -> true. + **/ + virtual void cycleCurrentItemStatus(); + + /** + * Return 'true' if a status change (by user interaction) from status + * 'fromStatus' to status 'toStatus' is allowed, 'false' if not. + **/ + virtual bool statusChangeAllowed( int fromStatus, int toStatus ); + + /** + * Notification that a status value was just changed in the input handler + * and the 'notify' flag is set. + **/ + virtual NCursesEvent valueChangedNotify( YItem * item ); + + /** + * Return the tag cell (the cell with the "[x]" or "(x)" selector) for the + * item with the specified index. + **/ + virtual NCCustomStatusTableTag * tagCell( int index ) const; + + /** + * Update the status indicator. + * This is only called if custom status values are used. + * + * Reimplemented from YItemSelector. + **/ + virtual void updateCustomStatusIndicator( YItem * item ); + + +private: + + // Disable assignment operator and copy constructor + + NCCustomStatusItemSelector & operator=( const NCCustomStatusItemSelector & ); + NCCustomStatusItemSelector( const NCCustomStatusItemSelector & ); +}; + + +#endif // NCCustomStatusItemSelector_h diff --git a/deps/libyui/libyui-ncurses/src/NCDateField.cc b/deps/libyui/libyui-ncurses/src/NCDateField.cc new file mode 100644 index 0000000000000000000000000000000000000000..a72436af7cc642d6c9892f8a03a963d9a757c5ad --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCDateField.cc @@ -0,0 +1,323 @@ +/* + Copyright (C) 2014 Angelo Naselli + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCDateField.cc + + Author: Angelo Naselli + +/-*/ +#include +#include +#include +#include + + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCDateField.h" +#include "NCInputTextBase.h" + +using namespace boost::gregorian; + +const unsigned NCDateField::fieldLength = 10; + +NCDateField::NCDateField ( YWidget * parent, + const std::string & nlabel ) + : YDateField ( parent, nlabel ) + , NCInputTextBase ( parent, false, fieldLength, fieldLength ) +{ + // yuiDebug() << std::endl; + + setLabel ( nlabel ); + + // Same value as QT default + setValue ( "2000-01-01" ); +} + + +NCDateField::~NCDateField() +{ + // yuiDebug() << std::endl; +} + +int NCDateField::preferredHeight() +{ + return NCInputTextBase::preferredHeight(); +} + +int NCDateField::preferredWidth() +{ + return NCInputTextBase::preferredWidth(); +} + +void NCDateField::setSize ( int newWidth, int newHeight ) +{ + NCInputTextBase::setSize ( newWidth, newHeight ); +} + + +void NCDateField::setEnabled ( bool do_bv ) +{ + NCInputTextBase::setEnabled ( do_bv ); + YWidget::setEnabled ( do_bv ); +} + +void NCDateField::setLabel ( const std::string & nlabel ) +{ + _label = NCstring ( nlabel ); + _label.stripHotkey(); + YDateField::setLabel ( nlabel ); + setDefsze(); + Redraw(); +} + +bool NCDateField::validDate(const std::string& input_date) +{ + std::wstringstream ss; + wdate_input_facet * fac = new wdate_input_facet(L"%Y-%m-%d"); + ss.imbue(std::locale(std::locale::classic(), fac)); + + date d; + ss << input_date.c_str(); + ss >> d; + + return d != date(); +} + + +void NCDateField::setValue ( const std::string & ntext ) +{ + if ( validDate(ntext) ) + { + buffer = NCstring ( ntext ).str(); + + if ( buffer.length() > maxFldLength ) + { + buffer = buffer.erase ( maxFldLength ); + } + + fldstart = 0; + + curpos = buffer.length(); + tUpdate(); + } +} + + +std::string NCDateField::value() +{ + NCstring text ( buffer ); + + return text.Str(); +} + + +NCursesEvent NCDateField::wHandleInput ( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + bool beep = false; + bool update = true; + + switch ( key ) + { + case '\b': //ctrl-h + case 0x7f: //del + case KEY_BACKSPACE: + + buffer.erase ( curpos, 1 ); + buffer.insert ( std::wstring::size_type ( curpos ), 1, '0' ); + if ( curpos == 5 || curpos == 8 ) + curpos -= 2; + else + if ( curpos ) + curpos--; + + break; + + case KEY_DC: + + if ( curpos < buffer.length() ) + { + buffer.erase ( curpos, 1 ); + buffer.insert ( std::wstring::size_type ( curpos ), 1, '0' ); + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_HOME: + + if ( curpos ) + { + curpos = 0; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_END: + + if ( curpos < maxCursor() ) + { + curpos = maxCursor(); + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_LEFT: + + if ( curpos == 5 || curpos == 8 ) + curpos -= 2; + else + if ( curpos ) + { + --curpos; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_RIGHT: + + if ( curpos == 3 || curpos == 6 ) + curpos += 2; + else + if ( curpos < maxCursor() ) + { + ++curpos; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_RETURN: + update = false; + + if ( notify() || returnOnReturn_b ) + ret = NCursesEvent::Activated; + + break; + + case KEY_HOTKEY: + update = false; + + break; + + default: + bool is_special = false; + + if ( key > 0xFFFF ) + { + is_special = true; + key -= 0xFFFF; + } + + if ( ( !is_special && KEY_MIN < key && KEY_MAX > key ) + || + !iswprint ( key ) ) + { + update = false; + beep = true; + } + else + { + { + switch ( key ) + { + case L'0': + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + { + std::string buf = NCstring(buffer).Str(); + buffer.erase ( curpos, 1 ); + buffer.insert ( std::wstring::size_type ( curpos ), 1, key ); + if (validDate(NCstring(buffer).Str())) + { + if ( curpos == 3 || curpos == 6 ) + curpos += 2; + else + if ( curpos < maxCursor() ) + ++curpos; + } + else + { + update = false; + setValue(buf); + beep = true; + } + } + break; + + default: + update = false; + beep = true; + break; + } + } + + } + + break; + } + + if ( update ) + { + tUpdate(); + + if ( notify() ) + ret = NCursesEvent::ValueChanged; + } + + if ( beep ) + ::beep(); + + return ret; + +} + + diff --git a/deps/libyui/libyui-ncurses/src/NCDateField.h b/deps/libyui/libyui-ncurses/src/NCDateField.h new file mode 100644 index 0000000000000000000000000000000000000000..cc985bfa211f4358de02d8212618504d214a1133 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCDateField.h @@ -0,0 +1,87 @@ +/* + Copyright (C) 2014 Angelo Naselli + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCDateField.h + + Author: Angelo Naselli + +/-*/ + +#ifndef NCDateField_h +#define NCDateField_h + +#include + +#include +#include "NCWidget.h" +#include "NCInputTextBase.h" + +class NCDateField : public YDateField, public NCInputTextBase +{ + + friend std::ostream & operator<< ( std::ostream & str, const NCDateField & obj ); + + NCDateField & operator= ( const NCDateField & ); + NCDateField ( const NCDateField & ); + +private: + static const unsigned fieldLength; + + bool validDate(const std::string& input_date); + +protected: + + virtual const char * location() const + { + return "NCDateField"; + } + +public: + + NCDateField ( YWidget * parent, + const std::string & label + ); + virtual ~NCDateField(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize ( int newWidth, int newHeight ); + + virtual void setLabel ( const std::string & nlabel ); + + virtual void setValue ( const std::string & ntext ); + virtual std::string value(); + + virtual void setEnabled ( bool do_bv ); + + virtual NCursesEvent wHandleInput ( wint_t key ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + +}; + + +#endif // NCDateField_h diff --git a/deps/libyui/libyui-ncurses/src/NCDialog.cc b/deps/libyui/libyui-ncurses/src/NCDialog.cc new file mode 100644 index 0000000000000000000000000000000000000000..186d929f127d2288c5e2a972adf2c00c9e09348c --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCDialog.cc @@ -0,0 +1,1407 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCDialog.cc + + Author: Michael Andres + +just to make the y2makepot script happy: +textdomain "ncurses" + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCDialog.h" +#include "NCstring.h" +#include "NCPopupInfo.h" +#include "NCMenuButton.h" +#include +#include "NCtoY2Event.h" +#include "YNCursesUI.h" +#include +#include + +#include "ncursesw.h" + + +static bool hiddenMenu() +{ + return getenv( "Y2NCDBG" ) != NULL; +} + + +NCDialog::NCDialog( YDialogType dialogType, + YDialogColorMode colorMode ) + : YDialog( dialogType, colorMode ) + , pan( 0 ) + , dlgstyle( 0 ) + , inMultiDraw_i( 0 ) + , active( false ) + , wActive( this ) + , ncdopts( DEFAULT ) + , popedpos( -1 ) +{ + // yuiDebug() << "Constructor NCDialog(YDialogType t, YDialogColorMode c)" << std::endl; + _init(); +} + + +NCDialog::NCDialog( YDialogType dialogType, const wpos & at, bool boxed ) + : YDialog( dialogType, YDialogNormalColor ) + , pan( 0 ) + , dlgstyle( 0 ) + , inMultiDraw_i( 0 ) + , active( false ) + , wActive( this ) + , ncdopts( boxed ? POPUP : POPUP | NOBOX ) + , popedpos( at ) +{ + // yuiDebug() << "Constructor NCDialog(YDialogType t, const wpos & at, bool boxed)" << std::endl; + _init(); +} + + +void NCDialog::_init() +{ + NCurses::RememberDlg( this ); + // don't set text domain to ncurses - other text domains won't work (bnc #476245) + + _init_size(); + wstate = NC::WSdumb; + + if ( colorMode() == YDialogWarnColor ) + { + mystyleset = NCstyle::WarnStyle; + } + else if ( colorMode() == YDialogInfoColor ) + { + mystyleset = NCstyle::InfoStyle; + } + else if ( isPopup() ) + { + mystyleset = NCstyle::PopupStyle; + } + else + { + mystyleset = NCstyle::DefaultStyle; + } + + dlgstyle = &NCurses::style()[mystyleset]; + + eventReason = YEvent::UnknownReason; + // yuiDebug() << "+++ " << this << std::endl; +} + + +void NCDialog::_init_size() +{ + defsze.H = NCurses::lines(); + defsze.W = NCurses::cols(); + hshaddow = vshaddow = false; + + if ( isBoxed() ) + { + switch ( defsze.H ) + { + case 1: + case 2: + defsze.H = 1; + break; + + default: + defsze.H -= 2; + break; + } + + switch ( defsze.W ) + { + case 1: + case 2: + defsze.W = 1; + break; + + default: + defsze.W -= 2; + break; + } + } +} + + +NCDialog::~NCDialog() +{ + NCurses::ForgetDlg( this ); + + // yuiDebug() << "--+START destroy " << this << std::endl; + + if ( pan && !pan->hidden() ) + { + pan->hide(); + doUpdate(); + } + + grabActive( 0 ); + + NCWidget::wDelete(); + delete pan; + pan = 0; + // yuiDebug() << "---destroyed " << this << std::endl; + +} + + +int NCDialog::preferredWidth() +{ + if ( dialogType() == YMainDialog || ! hasChildren() ) + return wGetDefsze().W; + + wsze csze( 0, 0 ); + + if ( hasChildren() ) + { + csze = wsze( firstChild()->preferredHeight(), + firstChild()->preferredWidth() ); + } + + csze = wsze::min( wGetDefsze(), wsze::max( csze, wsze( 1 ) ) ); + + return csze.W; +} + + +int NCDialog::preferredHeight() +{ + if ( dialogType() == YMainDialog || ! hasChildren() ) + { + return wGetDefsze().H; + } + + wsze csze( 0, 0 ); + + if ( hasChildren() ) + { + csze = wsze( firstChild()->preferredHeight(), + firstChild()->preferredWidth() ); + } + + csze = wsze::min( wGetDefsze(), + wsze::max( csze, wsze( 1 ) ) ); + + return csze.H; +} + + +void NCDialog::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); + // yuiDebug() << "setSize() called: width: " << newwidth << " height: " << newheight << std::endl; + YDialog::setSize( newwidth, newheight ); +} + + +void NCDialog::initDialog() +{ + if ( !pan ) + { + // yuiDebug() << "setInitialSize() called!" << std::endl; + setInitialSize(); + } +} + + +void NCDialog::openInternal() +{ + showDialog(); +} + + +void NCDialog::showDialog() +{ + // yuiDebug() << "sd+ " << this << std::endl; + + if ( pan && pan->hidden() ) + { + YPushButton *defaultB = YDialog::defaultButton(); + + if ( defaultB ) + { + defaultB->setKeyboardFocus(); + } + + getVisible(); + + doUpdate(); + DumpOn( yuiDebug(), " " ); + + } + else if ( !pan ) + { + yuiDebug() << "no pan" << std::endl; + } + + activate( true ); + + // yuiDebug() << "sd- " << this << std::endl; +} + + +void NCDialog::closeDialog() +{ + // yuiDebug() << "cd+ " << this << std::endl; + activate( false ); + + if ( pan && !pan->hidden() ) + { + pan->hide(); + doUpdate(); + // yuiDebug() << this << std::endl; + } + + // yuiDebug() << "cd+ " << this << std::endl; +} + + +void NCDialog::activate( bool newactive ) +{ + if ( active != newactive || ( pan && pan->hidden() ) ) + { + active = newactive; + + if ( pan ) + { + pan->show(); // not getVisible() because wRedraw() follows. + wRedraw(); + + if ( active ) + Activate(); + else + Deactivate(); + + NCurses::SetStatusLine( describeFunctionKeys() ); + doUpdate(); + // yuiDebug() << this << std::endl; + } + } +} + + +/** + * Implementation of YDialog::activate(). + * + * This is called e.g. for the next-lower dialog in the dialog stack when the + * topmost dialog is destroyed: That next-lower dialog is now the active + * dialog. + **/ +void NCDialog::activate() +{ + activate( true ); // Forward to NCurses-specific activate() +} + + +void NCDialog::wMoveTo( const wpos & newpos ) +{ + // yuiDebug() << DLOC << this << newpos << std::endl; +} + + +void NCDialog::wCreate( const wrect & newrect ) +{ + if ( win ) + throw NCError( "wCreate: already have win" ); + + wrect panrect( newrect ); + + inparent = newrect; + + if ( isBoxed() ) + { + switch ( NCurses::lines() - panrect.Sze.H ) + { + case 0: + break; + + case 1: + panrect.Sze.H += 1; + inparent.Pos.L += 1; + break; + + default: + panrect.Sze.H += 2; + inparent.Pos.L += 1; + break; + } + + switch ( NCurses::cols() - panrect.Sze.W ) + { + case 0: + break; + + case 1: + panrect.Sze.W += 1; + inparent.Pos.C += 1; + break; + + default: + panrect.Sze.W += 2; + inparent.Pos.C += 1; + break; + } + } + + if ( popedpos.L >= 0 ) + { + if ( popedpos.L + panrect.Sze.H <= NCurses::lines() ) + panrect.Pos.L = popedpos.L; + else + panrect.Pos.L = NCurses::lines() - panrect.Sze.H; + } + else + { + panrect.Pos.L = ( NCurses::lines() - panrect.Sze.H ) / 2; + } + + if ( popedpos.C >= 0 ) + { + if ( popedpos.C + panrect.Sze.W <= NCurses::cols() ) + panrect.Pos.C = popedpos.C; + else + panrect.Pos.C = NCurses::cols() - panrect.Sze.W; + } + else + { + panrect.Pos.C = ( NCurses::cols() - panrect.Sze.W ) / 2; + } + + if ( panrect.Pos.L + panrect.Sze.H < NCurses::lines() ) + { + ++panrect.Sze.H; + hshaddow = true; + } + + if ( panrect.Pos.C + panrect.Sze.W < NCurses::cols() ) + { + ++panrect.Sze.W; + vshaddow = true; + } + + if ( pan && panrect != wrect( wpos( pan->begy(), pan->begx() ), + wsze( pan->maxy() + 1, pan->maxx() + 1 ) ) ) + { + pan->hide(); + doUpdate(); + delete pan; + pan = 0; + } + + if ( !pan ) + { + pan = new NCursesUserPanel( panrect.Sze.H, panrect.Sze.W, + panrect.Pos.L, panrect.Pos.C, + this ); + pan->hide(); + doUpdate(); + } + + win = new NCursesWindow( *pan, + + inparent.Sze.H, inparent.Sze.W, + inparent.Pos.L, inparent.Pos.C, + 'r' ); + win->nodelay( true ); + + // yuiDebug() << DLOC << panrect << '(' << inparent << ')' + // << '[' << popedpos << ']' << std::endl; +} + + +void NCDialog::wRedraw() +{ + if ( pan ) + { + if ( isBoxed() ) + { + pan->bkgdset( wStyle().getDlgBorder( active ).text ); + + if ( pan->height() != NCurses::lines() + || pan->width() != NCurses::cols() ) + { + pan->box(); // not fullscreen + } + else + { + pan->hline( 0, 0, pan->width(), ' ' ); + pan->hline( pan->height() - 1, 0, pan->width(), ' ' ); + pan->vline( 0, 0, pan->height(), ' ' ); + pan->vline( 0, pan->width() - 1, pan->height(), ' ' ); + } + + if ( hshaddow ) + { + pan->copywin( *pan, + pan->maxy(), 0, + pan->maxy() - 1, 0, + pan->maxy() - 1, pan->maxx(), false ); + } + + if ( vshaddow ) + { + pan->copywin( *pan, + 0, pan->maxx(), + 0, pan->maxx() - 1, + pan->maxy(), pan->maxx() - 1, false ); + } + } + + pan->bkgdset( A_NORMAL ); + + if ( hshaddow ) + { + pan->hline( pan->maxy(), 0, pan->width(), ' ' ); + pan->transparent( pan->maxy(), 0 ); + } + + if ( vshaddow ) + { + pan->vline( 0, pan->maxx(), pan->height(), ' ' ); + pan->transparent( 0, pan->maxx() ); + } + } +} + + +void NCDialog::wRecoded() +{ + if ( pan ) + { + if ( &NCurses::style()[mystyleset] != dlgstyle ) + { + dlgstyle = &NCurses::style()[mystyleset]; + } + + pan->bkgdset( wStyle(). getDumb().text ); + + pan->clear(); + wRedraw(); + } +} + + +void NCDialog::startMultipleChanges() +{ + ++inMultiDraw_i; +} + + +void NCDialog::doneMultipleChanges() +{ + if ( inMultiDraw_i > 1 ) + { + --inMultiDraw_i; + } + else + { + inMultiDraw_i = 0; + NCurses::SetStatusLine( describeFunctionKeys() ); + Update(); + } +} + +void NCDialog::setStatusLine() +{ + NCurses::SetStatusLine( describeFunctionKeys() ); + doUpdate(); +} + +void NCDialog::wUpdate( bool forced_br ) +{ + if ( !pan ) + return; + + if ( !forced_br + && ( pan->hidden() || inMultiDraw_i ) ) + return; + + NCWidget::wUpdate( forced_br ); +} + + +void NCDialog::grabActive( NCWidget * nactive ) +{ + if ( wActive && wActive != static_cast( this ) ) + wActive->grabRelease( this ); + + if ( nactive && nactive != static_cast( this ) ) + nactive->grabSet( this ); + + const_cast( wActive ) = nactive; +} + + +void NCDialog::grabNotify( NCWidget * mgrab ) +{ + if ( wActive && wActive == mgrab ) + { + // yuiDebug() << DLOC << mgrab << " active " << std::endl; + ActivateNext(); + + if ( wActive && wActive == mgrab ) + grabActive( this ); + } +} + + +bool NCDialog::wantFocus( NCWidget & ngrab ) +{ + return Activate( ngrab ); +} + + +void NCDialog::wDelete() +{ + if ( pan ) + { + // yuiDebug() << DLOC << "+++ " << this << std::endl; + NCWidget::wDelete(); + // yuiDebug() << DLOC << "--- " << this << std::endl; + } +} + + +NCWidget & NCDialog::GetNormal( NCWidget & startwith, SeekDir Direction ) +{ + NCWidget * c = ( startwith.*Direction )( true )->Value(); + + while ( c != &startwith && ( c->GetState() != NC::WSnormal || !c->winExist() ) ) + { + if ( c->GetState() == NC::WSactive ) + { + yuiWarning() << "multiple active widgets in dialog? " + << startwith << " <-> " << c << std::endl; + c->SetState( NC::WSnormal ); // what else can we do? + break; + } + + c = ( c->*Direction )( true )->Value(); + } + + return *c; +} + + +NCWidget & NCDialog::GetNextNormal( NCWidget & startwith ) +{ + return GetNormal( startwith, &tnode::Next ); +} + + +NCWidget & NCDialog::GetPrevNormal( NCWidget & startwith ) +{ + return GetNormal( startwith, &tnode::Prev ); +} + + +bool NCDialog::Activate( NCWidget & nactive ) +{ + if ( nactive.GetState() == NC::WSactive ) + return true; + + if ( nactive.GetState() == NC::WSnormal ) + { + if ( wActive->GetState() == NC::WSactive ) + wActive->SetState( NC::WSnormal ); + + if ( active ) + { + nactive.SetState( NC::WSactive ); + } + + grabActive( &nactive ); + + return true; + } + + return false; +} + + +void NCDialog::Activate( SeekDir Direction ) +{ + if ( !wActive ) + grabActive( this ); + + if ( Direction == 0 ) + { + if ( Activate( *wActive ) ) + return; // (re)activated widget + + // can't (re)activate widget, so look for next one + Direction = &tnode::Next; + } + + Activate( GetNormal( *wActive, Direction ) ); +} + + +void NCDialog::Activate() +{ + Activate( 0 ); +} + + +void NCDialog::Deactivate() +{ + if ( wActive->GetState() == NC::WSactive ) + { + wActive->SetState( NC::WSnormal ); + } +} + + +void NCDialog::ActivateNext() +{ + Activate( &tnode::Next ); +} + + +void NCDialog::ActivatePrev() +{ + Activate( &tnode::Prev ); +} + + +bool NCDialog::ActivateByKey( int key ) +{ + NCWidget * buddy = 0; + + for ( tnode * c = this->Next(); c; c = c->Next() ) + { + switch ( c->Value()->GetState() ) + { + case NC::WSnormal: + case NC::WSactive: + + if ( c->Value()->HasHotkey( key ) + || c->Value()->HasFunctionHotkey( key ) ) + { + Activate( *c->Value() ); + return true; + } + + if ( buddy ) + { + if ( c->IsDescendantOf( buddy ) ) + { + // yuiDebug() << "BUDDY ACTIVATION FOR " << c->Value() << std::endl; + Activate( *c->Value() ); + return true; + } + + // yuiDebug() << "DROP BUDDY on " << c->Value() << std::endl; + + buddy = 0; + } + + break; + + case NC::WSdumb: + + if ( c->Value()->HasHotkey( key ) + || c->Value()->HasFunctionHotkey( key ) ) + { + // yuiDebug() << "DUMB HOT KEY " << key << " in " << c->Value() << std::endl; + buddy = c->Value(); + } + + default: + + break; + } + } + + return false; +} + + +wint_t NCDialog::getinput() +{ + wint_t got = WEOF; + + if ( NCstring::terminalEncoding() == "UTF-8" ) + { + wint_t gotwch = WEOF; + int ret = ::get_wch( &gotwch ); // get a wide character + + if ( ret != ERR ) // get_wch() returns OK or KEY_CODE_YES on success + { + got = gotwch; + // UTF-8 keys (above KEY_MIN) may deliver same keycode as curses KEY_... + // -> mark this keys + + if ( ret == OK + && got > KEY_MIN ) + { + got += 0xFFFF; + } + } + else + { + got = WEOF; + } + } + else + { + std::wstring to; + int gotch = ::getch(); // get the character in terminal encoding + + if ( gotch != -1 ) + { + if (( KEY_MIN > gotch || KEY_MAX < gotch ) + && + isprint( gotch ) ) + { + std::string str; + str += static_cast( gotch ); + // recode printable chars + NCstring::RecodeToWchar( str, NCstring::terminalEncoding(), &to ); + got = to[0]; + + if ( gotch != (int) got ) + { + got += 0xFFFF; // mark this key + } + + // yuiDebug() << "Recode: " << str << " (encoding: " << NCstring::terminalEncoding() << ") " + // << "to wint_t: " << got << std::endl; + } + else + { + got = gotch; + } + } + else + { + got = WEOF; + } + } + + return got; +} + + +wint_t NCDialog::getch( int timeout_millisec ) +{ + wint_t got = WEOF; + + if ( timeout_millisec < 0 ) + { + // wait for input + ::nodelay( ::stdscr, false ); + + got = getinput(); + + } + else if ( timeout_millisec ) + { + // max halfdelay is 25 seconds (250 tenths of seconds) + do + { + if ( timeout_millisec > 25000 ) + { + ::halfdelay( 250 ); + timeout_millisec -= 25000; + } + else + { + if ( timeout_millisec < 100 ) + { + // min halfdelay is 1/10 second (100 milliseconds) + ::halfdelay( 1 ); + } + else + ::halfdelay( timeout_millisec / 100 ); + + timeout_millisec = 0; + } + + got = getinput(); + } + while ( got == WEOF && timeout_millisec > 0 ); + + ::cbreak(); // stop halfdelay + } + else + { + // no wait + ::nodelay( ::stdscr, true ); + got = getinput(); + } + + if ( got == KEY_RESIZE ) + { + NCurses::ResizeEvent(); + int i = 100; + // after resize sometimes WEOF is returned -> skip this in no timeout mode + + do + { + got = NCDialog::getch( timeout_millisec ); + } + while ( timeout_millisec < 0 && got == WEOF && --i ); + } + + return got; +} + + +bool NCDialog::flushTypeahead() +{ + // Don't throw away keys from the input buffer after a ValueChanged or + // SelectionChanged event but save them e.g. for input in TextEntry, + // MultiLineEdit or to scroll in lists ( bug #245476 ) + if ( eventReason == YEvent::ValueChanged || + eventReason == YEvent::SelectionChanged ) + { + // yuiDebug() << "DON't flush input buffer - reason: " << eventReason << std::endl; + return false; + } + else + { + // yuiDebug() << "Flush input buffer" << std::endl; + return true; + } +} + + +void NCDialog::idleInput() +{ + if ( !pan ) + { + yuiWarning() << DLOC << " called for uninitialized " << this << std::endl; + ::flushinp(); + return; + } + + // yuiDebug() << "idle+ " << this << std::endl; + + if ( !active ) + { + if ( flushTypeahead() ) + { + ::flushinp(); + } + + doUpdate(); + } + else + { + // yuiDebug() << "idle+ " << this << std::endl; + processInput( 0 ); + // yuiDebug() << "idle- " << this << std::endl; + } +} + + +NCursesEvent NCDialog::pollInput() +{ + // yuiDebug() << "poll+ " << this << std::endl; + + if ( !pan ) + { + yuiWarning() << DLOC << " called for uninitialized " << this << std::endl; + return NCursesEvent::cancel; + } + + if ( pendingEvent ) + { + if ( active ) + { + activate( false ); + // yuiDebug() << this << " deactivate" << std::endl; + } + } + else + { + if ( !active ) + { + activate( true ); + // yuiDebug() << this << " activate" << std::endl; + } + } + + NCursesEvent returnEvent = pendingEvent; + + eventReason = returnEvent.reason; + pendingEvent = NCursesEvent::none; + + // yuiDebug() << "poll- " << this << '(' << returnEvent << ')' << std::endl; + return returnEvent; +} + + +NCursesEvent NCDialog::userInput( int timeout_millisec ) +{ + // yuiDebug() << "user+ " << this << std::endl; + + if ( flushTypeahead() ) + { + ::flushinp(); + } + + if ( !pan ) + { + yuiWarning() << DLOC << " called for uninitialized " << this << std::endl; + return NCursesEvent::cancel; + } + + processInput( timeout_millisec ); + + NCursesEvent returnEvent = pendingEvent; + eventReason = returnEvent.reason; + pendingEvent = NCursesEvent::none; + + // yuiDebug() << "user- " << this << '(' << returnEvent << ')' << std::endl; + return returnEvent; +} + + +/** + * Back-end for YDialog::waitForEvent() + **/ +YEvent * NCDialog::waitForEventInternal( int timeout_millisec ) +{ + NCtoY2Event cevent; + activate( true ); + cevent = userInput( timeout_millisec ? timeout_millisec : -1 ); + activate( false ); + + YEvent * yevent = cevent.propagate(); + + return yevent; +} + + +/** + * Back-end for YDialog::pollEvent() + **/ +YEvent * NCDialog::pollEventInternal() +{ + // no activation here, done in pollInput, if.. + NCtoY2Event cevent = pollInput(); + YEvent * yevent = cevent.propagate(); + + return yevent; +} + + +/** + * Process input + * + * timeout -1 -> wait for input + * timeout 0 -> immediate return + * else wait for up to timeout milliseconds + **/ +void NCDialog::processInput( int timeout_millisec ) +{ + // yuiDebug() << "process+ " << this << " active " << wActive + // << " timeout_millisec " << timeout_millisec << std::endl; + + if ( pendingEvent ) + { + // yuiDebug() << this << "(return pending event)" << std::endl; + doUpdate(); + ::flushinp(); + return; + } + + // if no active item return on any input + if ( wActive->GetState() != NC::WSactive ) + { + // yuiDebug() << "noactive item => reactivate!" << std::endl; + Activate(); + } + + if ( wActive->GetState() != NC::WSactive ) + { + // yuiDebug() << "still noactive item!" << std::endl; + + if ( timeout_millisec == -1 ) + { + pendingEvent = NCursesEvent::cancel; + // yuiDebug() << DLOC << this << "(std::set ET_CANCEL since noactive item on pollInput)" << std::endl; + getch( -1 ); + } + else + ::flushinp(); + + // if there is no active widget and we are in timeout, handle properly + // bug #182982 + if ( timeout_millisec > 0 ) + { + usleep( timeout_millisec * 1000 ); + pendingEvent = NCursesEvent::timeout; + } + + return; + } + + // get and process user input + wint_t ch = 0; + + wint_t hch = 0; + + // yuiDebug() << "enter loop..." << std::endl; + + noUpdates = true; + + while ( !pendingEvent.isReturnEvent() && ch != WEOF ) + { + + ch = getch( timeout_millisec ); + + switch ( ch ) + { + // case KEY_RESIZE: is directly handled in NCDialog::getch. + + case WEOF: + + if (pendingEvent) + { +#if VERBOSE_EVENTS + yuiDebug() << "Keeping the pending event" << std::endl; +#endif + } + else + { + if ( timeout_millisec == -1 ) + pendingEvent = NCursesEvent::cancel; + else if ( timeout_millisec > 0 ) + pendingEvent = NCursesEvent::timeout; + } + + break; + + case KEY_F( 13 ): // = Shift-F1 on e.g. a linux console + showHotkeyHelp(); + break; + + case KEY_F( 16 ): // = Shift-F4 on e.g. a linux console + const_cast( NCurses::style() ).nextStyle(); + + NCurses::Redraw(); + + break; + + case KEY_F( 18 ): // = Shift-F6 on e.g. a linux console + { + yuiMilestone() << "Asking for widget ID" << std::endl; + YWidget * widget = YNCursesUI::ui()->askSendWidgetID(); + + if ( widget ) + { + NCPushButton * button = dynamic_cast( widget ); + + if ( button ) + { + Activate( *button ); + pendingEvent = getInputEvent( KEY_RETURN ); + } + } + } + break; + + case CTRL( 'D' ): + hch = getch( -1 ); + + ::flushinp(); + + switch ( hch ) + { + case KEY_F( 1 ): + showHotkeyHelp(); + break; + + case 'D': + yuiMilestone() << "CTRL('D')-'D' DUMP+++++++++++++++++++++" << std::endl; + NCurses::ScreenShot(); + yuiMilestone() << this << std::endl; + DumpOn( yuiMilestone(), " " ); + yuiMilestone() << "CTRL('D')-'D' DUMP---------------------" << std::endl; + break; + + case 'S': + + if ( hiddenMenu() ) + { + yuiMilestone() << "CTRL('D')-'S' STYLEDEF+++++++++++++++++++++" << std::endl; + const_cast( NCurses::style() ).changeSyle(); + NCurses::Redraw(); + yuiMilestone() << "CTRL('D')-'S' STYLEDEF---------------------" << std::endl; + } + + break; + + case 'Y': + YDialogSpy::showDialogSpy(); + break; + + case 'C': + pendingEvent = NCursesEvent::special_key_config; + break; + + case 'G': + pendingEvent = NCursesEvent::debug; + break; + } + + break; + + case KEY_TAB: + + case CTRL( 'F' ): + ActivateNext(); + break; + + case KEY_BTAB: + + case CTRL( 'B' ): + ActivatePrev(); + break; + + case CTRL( 'L' ): + NCurses::Refresh(); + break; + + case CTRL( 'A' ): + pendingEvent = getInputEvent( KEY_SLEFT ); + break; + + case CTRL( 'E' ): + pendingEvent = getInputEvent( KEY_SRIGHT ); + break; + + case KEY_ESC: + + case CTRL( 'X' ): + hch = getch( 0 ); + ::flushinp(); + + switch ( hch ) + { + case WEOF: // no 2nd char, handle ch + pendingEvent = getInputEvent( ch ); + break; + + case KEY_ESC: + + case CTRL( 'X' ): + pendingEvent = getInputEvent( hch ); + break; + + default: + pendingEvent = getHotkeyEvent( hch ); + break; + } + + break; + + default: + if ( ch >= KEY_F( 1 ) && ch <= KEY_F( 24 ) ) + { + pendingEvent = getHotkeyEvent( ch ); + } + else + { + pendingEvent = getInputEvent( ch ); + } + + break; + } + + doUpdate(); + } + + noUpdates = false; + + // yuiDebug() << "process- " << this << " active " << wActive << std::endl; +} + + +NCursesEvent NCDialog::getInputEvent( wint_t ch ) +{ + NCursesEvent ret = NCursesEvent::none; + + if ( wActive->isValid() ) + { + ret = wHandleInput( ch ); + ret.widget = wActive; + } + + return ret; +} + + +NCursesEvent NCDialog::wHandleInput( wint_t ch ) +{ + return wActive->wHandleInput( ch ); +} + + +NCursesEvent NCDialog::getHotkeyEvent( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + + if ( wActive->isValid() ) + { + ret = wHandleHotkey( key ); + ret.widget = wActive; + } + + return ret; +} + + +NCursesEvent NCDialog::wHandleHotkey( wint_t key ) +{ + if ( key >= 0 && ActivateByKey( key ) ) + return wActive->wHandleHotkey( key ); + + return NCursesEvent::none; +} + + +std::ostream & operator<<( std::ostream & str, const NCDialog * obj ) +{ + if ( obj ) + return str << *obj; + + return str << "(NoNCDialog)"; +} + + + +/** + * Create description for function keys: + * + * Get all PushButtons and MenuButtons that have a function key std::set + * (Opt(:key_Fn) in Ruby) and create a std::map: + * $[ 1: "Help", 2: "Info",... ] + * NCurses::SetStatusLine will process this. + **/ +std::map NCDialog::describeFunctionKeys() +{ + std::map fkeys; + + for ( tnode * c = this->Next(); c; c = c->Next() ) + { + YWidget * w = dynamic_cast( c->Value() ); + + if ( w && w->hasFunctionKey() && w->isEnabled() ) + { + // Retrieve the widget's "shortcut property" that describes + // whatever it is - regardless of widget type (PushButton, ...) + + fkeys[ w->functionKey()] = NCstring(w->debugLabel()); + } + } + + return fkeys; +} + + +std::ostream & operator<<( std::ostream & str, const NCDialog & obj ) +{ + str << ( const NCWidget & )obj << ' ' << obj.pan + << ( obj.active ? "{A " : "{i " ) << obj.pendingEvent; + + if ( obj.pendingEvent ) + str << obj.pendingEvent.widget; + + return str << '}'; +} + + +bool NCDialog::getInvisible() +{ + if ( !pan || pan->hidden() ) + return false; // no change in visibility + + // just do it. + // caller is responsible for screen update. + pan->hide(); + + return true; +} + + +bool NCDialog::getVisible() +{ + if ( !pan || !pan->hidden() ) + return false; // no change in visibility + + // just do it. + // caller is responsible for screen update. + pan->show(); + + if ( hshaddow ) + { + pan->transparent( pan->maxy(), 0 ); + } + + if ( vshaddow ) + { + pan->transparent( 0, pan->maxx() ); + } + + return true; +} + + +void NCDialog::resizeEvent() +{ + _init_size(); + + if ( pan ) + { + setInitialSize(); + } +} + +void NCDialog::showHotkeyHelp() +{ + std::string old_textdomain = textdomain( NULL ); + setTextdomain( "ncurses" ); + + YDialog::showText( + _( "

Advanced Hotkeys:

" + "

Shift-F1 Show a list of advanced hotkeys.

" + "

Shift-F4 Change color schema.

" + "

Ctrl-\\ Quit the application.

" + "

Ctrl-L Refresh screen.

" + "

Ctrl-O Change table ordering, selecting the same column again changes the direction.

" + "

Ctrl-D F1 Show a list of advanced hotkeys.

" + "

Ctrl-D Shift-D Dump dialog to the log file as a screen shot.

" + "

Ctrl-D Shift-Y Open YDialogSpy to see the widget hierarchy.

" + "

Ctrl-D Shift-G Send a debug event, start the debugger.

" + "

Ctrl-D Shift-C Send a config event, display special configuration options.

" + "

Depending on your desktop environment some of these key combinations might not work.

" ), + true ); + + // restore former text domain + setTextdomain( old_textdomain.c_str() ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCDialog.h b/deps/libyui/libyui-ncurses/src/NCDialog.h new file mode 100644 index 0000000000000000000000000000000000000000..5910d93606522f34ffa9dd7f9cbf385d0f977eb0 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCDialog.h @@ -0,0 +1,227 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCDialog.h + + Author: Michael Andres + +/-*/ + +#ifndef NCDialog_h +#define NCDialog_h + +#include + +#include +#include "NCWidget.h" +#include "NCPushButton.h" + + +class NCDialog; +class NCPopupInfo; + + +class NCDialog : public YDialog, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCDialog & obj ); + friend std::ostream & operator<<( std::ostream & str, const NCDialog * obj ); + + NCDialog & operator=( const NCDialog & ); + NCDialog( const NCDialog & ); + + typedef tnode * ( tnode::* SeekDir )( bool ); + + NCWidget & GetNormal( NCWidget & startwith, SeekDir Direction ); + void Activate( SeekDir Direction ); + + void _init(); + void _init_size(); + +protected: + + virtual const char * location() const { return "NCDialog"; } + + wint_t getinput(); // get the input (respect terminal encoding) + +private: + + NCursesUserPanel * pan; + NCstyle::StyleSet mystyleset; + const NCstyle::Style * dlgstyle; + + unsigned inMultiDraw_i; + + bool active; + NCWidget *const wActive; + + NCursesEvent pendingEvent; + YEvent::EventReason eventReason; + + // wrapper for wHandle... calls in processInput() + NCursesEvent getInputEvent( wint_t ch ); + NCursesEvent getHotkeyEvent( wint_t key ); + + void grabActive( NCWidget * nactive ); + virtual void grabNotify( NCWidget * mgrab ); + virtual bool wantFocus( NCWidget & ngrab ); + + virtual void wCreate( const wrect & newrect ); + virtual void wMoveTo( const wpos & newpos ); + virtual void wDelete(); + virtual void wRedraw(); + virtual void wRecoded(); + virtual void wUpdate( bool forced_br = false ); + void doUpdate() { wUpdate( true ); } + + NCWidget & GetNextNormal( NCWidget & startwith ); + NCWidget & GetPrevNormal( NCWidget & startwith ); + + bool Activate( NCWidget & nactive ); + void Activate(); + void Deactivate(); + void ActivateNext(); + void ActivatePrev(); + + bool ActivateByKey( int key ); + + void processInput( int timeout_millisec ); + + std::map describeFunctionKeys(); + + bool flushTypeahead(); + +protected: + + virtual wint_t getch( int timeout_millisec = -1 ); + + virtual NCursesEvent wHandleInput( wint_t ch ); + virtual NCursesEvent wHandleHotkey( wint_t key ); + + virtual void startMultipleChanges(); + virtual void doneMultipleChanges(); + + /** + * Internal open() method: Initialize what is left over to initialize after + * all dialog children have been created. + * YDialog::setInitialSize() is already called before this in + * YDailog::open(), so don't call it here again (very expensive!). + * + * This function is called (exactly once during the life time of the + * dialog) in YDialog::open(). + * + * Implemented from YDialog. + **/ + virtual void openInternal(); + + /** + * Wait for a user event. + * + * Implemented from YDialog. + **/ + virtual YEvent * waitForEventInternal( int timeout_millisec ); + + /** + * Check if a user event is pending. If there is one, return it. + * If there is none, do not wait for one - return 0. + * + * Implemented from YDialog. + **/ + virtual YEvent * pollEventInternal(); + + +public: + + NCDialog( YDialogType dialogType, + YDialogColorMode colorMode = YDialogNormalColor ); + virtual ~NCDialog(); + + void showDialog(); + void closeDialog(); + + void activate( bool newactive ); + bool isActive() const { return active; } + + void idleInput(); + + NCursesEvent userInput( int timeout_millisec = -1 ); + NCursesEvent pollInput(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + void setStatusLine(); + + /** + * Activate this dialog: Make sure that it is shown as the topmost dialog + * of this application and that it can receive input. + * + * Implemented from YDialog. + **/ + virtual void activate(); + + // Get the pending event, only for special cases (REST API) + NCursesEvent getPendingEvent() { return pendingEvent;} + // Set the pending event, makes sense only when simulating the user actions (REST API) + void setPendingEvent(NCursesEvent event) { pendingEvent = event;} + +protected: + + enum NCDopts + { + DEFAULT = 0x00, + POPUP = 0x01, + NOBOX = 0x10 + }; + + typedef unsigned NCDoptflag; + + NCDoptflag ncdopts; + wpos popedpos; + bool hshaddow; + bool vshaddow; + + NCDialog( YDialogType dialogType, const wpos & at, bool boxed = true ); + + bool isPopup() const { return ( ncdopts & POPUP ); } + + bool isBoxed() const { return !( ncdopts & NOBOX ); } + + virtual void initDialog(); + + virtual const NCstyle::Style & wStyle() const + { + return dlgstyle ? *dlgstyle : NCurses::style()[NCstyle::DefaultStyle]; + } + + virtual void setEnabled( bool do_bv ) {} + +private: + + friend class NCurses; + bool getInvisible(); + bool getVisible(); + void resizeEvent(); + void showHotkeyHelp(); +}; + + +#endif // NCDialog_h diff --git a/deps/libyui/libyui-ncurses/src/NCDumbTab.cc b/deps/libyui/libyui-ncurses/src/NCDumbTab.cc new file mode 100644 index 0000000000000000000000000000000000000000..af62580d8e8cd299c61e75a3bf5c2226b3ea4aa3 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCDumbTab.cc @@ -0,0 +1,356 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCDumbTab.cc + + Author: Gabriele Mohr + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include +#include "YNCursesUI.h" +#include "NCDialog.h" +#include "NCurses.h" +#include "NCDumbTab.h" +#include "NCPopupList.h" + + +NCDumbTab::NCDumbTab( YWidget * parent ) + : YDumbTab( parent ) + , NCWidget( parent ) + , currentIndex( 0 ) +{ + framedim.Pos = wpos( 1 ); + framedim.Sze = wsze( 2 ); +} + + +NCDumbTab::~NCDumbTab() +{ + // yuiDebug() << std::endl; +} + + +int NCDumbTab::preferredWidth() +{ + defsze.W = hasChildren() ? firstChild()->preferredWidth() : 0; + + YItemIterator listIt = itemsBegin(); + + unsigned tabBarWidth = 0; + NClabel tabLabel; + + while ( listIt != itemsEnd() ) + { + tabLabel = NClabel( (*listIt)->label() ); + tabBarWidth += tabLabel.width() + 1; + ++listIt; + } + ++tabBarWidth; + + if ( tabBarWidth > (unsigned) defsze.W ) + defsze.W = tabBarWidth; + + defsze.W += framedim.Sze.W; + + if ( defsze.W > NCurses::cols() ) + defsze.W = NCurses::cols(); + + return defsze.W; +} + + +int NCDumbTab::preferredHeight() +{ + defsze.H = hasChildren() ? firstChild()->preferredHeight() : 0; + defsze.H += framedim.Sze.H; + + return defsze.H; +} + + +void NCDumbTab::setEnabled( bool do_bv ) +{ + // yuiDebug() << "Set enabled" << std::endl; + NCWidget::setEnabled( do_bv ); + YDumbTab::setEnabled( do_bv ); +} + + +void NCDumbTab::setSize( int newwidth, int newheight ) +{ + wsze csze( newheight, newwidth ); + wRelocate( wpos( 0 ), csze ); + csze = wsze::max( 0, csze - framedim.Sze ); + + if ( hasChildren() ) + firstChild()->setSize( csze.W, csze.H ); +} + + +NCursesEvent NCDumbTab::wHandleInput( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + + switch ( key ) + { + case KEY_LEFT: + if ( currentIndex > 0 && + currentIndex <= (unsigned) itemsCount() - 1 ) + { + currentIndex--; + wRedraw(); + + ret = createMenuEvent( currentIndex ); + } + break; + + case KEY_RIGHT: + if ( currentIndex < (unsigned) itemsCount() - 1 && + currentIndex >= 0 ) + { + currentIndex++; + wRedraw(); + + ret = createMenuEvent( currentIndex ); + } + break; + + case KEY_HOTKEY: + setCurrentTab( hotKey ); + + case KEY_RETURN: + ret = createMenuEvent( currentIndex ); + break; + + } + + return ret; +} + + +void NCDumbTab::setCurrentTab( wint_t key ) +{ + + YItemIterator listIt = itemsBegin(); + NClabel tablabel; + unsigned i = 0; + + while ( listIt != itemsEnd() ) + { + tablabel = NCstring( (*listIt)->label() ); + tablabel.stripHotkey(); + // yuiDebug() << "HOTkey: " << tablabel.hotkey() << " key: " << key << std::endl; + if ( tolower ( tablabel.hotkey() ) == tolower ( key ) ) + { + currentIndex = i; + break; + } + ++listIt; + ++i; + } +} + + +NCursesEvent NCDumbTab::createMenuEvent( unsigned index ) +{ + NCursesEvent ret = NCursesEvent::menu; + YItem * item; + + item = itemAt( index ); + if ( item ) + { + yuiDebug() << "Show tab: " << item->label() << std::endl; + ret.selection = (YMenuItem *)item; + } + + return ret; +} + + +void NCDumbTab::addItem( YItem * item ) +{ + YDumbTab::addItem( item ); + + NClabel tabLabel = NCstring( item->label() ); + // yuiDebug() << "Add item: " << item->label() << std::endl; + + if ( item->selected() ) + currentIndex = item->index(); +} + + +void NCDumbTab::selectItem( YItem * item, bool selected ) +{ + if ( selected ) + { + currentIndex = item->index(); + // yuiDebug() << "Select item: " << item->index() << std::endl; + } + + YDumbTab::selectItem( item, selected ); + + wRedraw(); +} + + +void NCDumbTab::shortcutChanged() +{ + // Any of the items might have its keyboard shortcut changed, but we don't + // know which one. So let's simply set all tab labels again. + + wRedraw(); +} + + +void NCDumbTab::wRedraw() +{ + if ( !win ) + return; + + const NCstyle::StWidget & style( widgetStyle(true) ); + win->bkgd( style.plain ); + win->box(); + + YItemIterator listIt = itemsBegin(); + + int winWidth = win->width() - 2; + unsigned labelPos = 1; + unsigned i = 0; + bool nonActive = false; + NClabel tablabel; + + while ( listIt != itemsEnd() ) + { + tablabel = NCstring( (*listIt)->label() ); + tablabel.stripHotkey(); + hotlabel = &tablabel; + + nonActive = ( i != currentIndex ); + + if ( GetState() == NC::WSactive ) + { + + tablabel.drawAt( *win, + NCstyle::StWidget( widgetStyle( nonActive) ), + wpos( 0, labelPos ), + wsze( 1, winWidth ), + NC::TOPLEFT, false ); + } + else + { + if ( !nonActive ) + { + tablabel.drawAt( *win, + widgetStyle().data, + widgetStyle().data, + wpos( 0, labelPos ), + wsze( 1, winWidth ), + NC::TOPLEFT, false ); + } + else + { + tablabel.drawAt( *win, + NCstyle::StWidget( frameStyle() ), + wpos( 0, labelPos ), + wsze( 1, winWidth ), + NC::TOPLEFT, false ); + } + } + + labelPos += tablabel.width() + 2; + + ++listIt; + ++i; + + if ( listIt != itemsEnd() ) + { + winWidth -= tablabel.width() -1; + } + }; + + if ( firstChild() ) + { + NCWidget * child = dynamic_cast( firstChild() ); + + if ( child ) + child->Redraw(); + + redrawChild( firstChild() ); + } +} + + +bool NCDumbTab::HasHotkey( int key ) +{ + bool ret = false; + + YItemIterator listIt = itemsBegin(); + NClabel tablabel; + + while ( listIt != itemsEnd() ) + { + tablabel = NCstring( (*listIt)->label() ); + tablabel.stripHotkey(); + if ( tablabel.hasHotkey() && tolower ( tablabel.hotkey() ) == tolower ( key ) ) + { + hotKey = tolower( key ) ; + ret = true; + } + ++listIt; + } + + // yuiDebug() << "Has hotkey: " << key << " " << (ret?"yes":"no") << std::endl; + + return ret; +} + + +void NCDumbTab::redrawChild( YWidget *widget ) +{ + NCWidget * child; + + if ( widget->hasChildren() ) + { + YWidgetListConstIterator widgetIt = widget->childrenBegin(); + + while ( widgetIt != widget->childrenEnd() ) + { + child = dynamic_cast( *widgetIt ); + if ( child ) + child->Redraw(); + redrawChild( *widgetIt ); + ++widgetIt; + } + } +} + + +void NCDumbTab::activate() +{ + NCursesEvent event = NCursesEvent::menu; + event.widget = this; + // Set selected item to the event + YItem * item = selectedItem(); + if ( item ) + event.selection = (YMenuItem *) item; + + YNCursesUI::ui()->sendEvent(event); +} diff --git a/deps/libyui/libyui-ncurses/src/NCDumbTab.h b/deps/libyui/libyui-ncurses/src/NCDumbTab.h new file mode 100644 index 0000000000000000000000000000000000000000..bea1c34bfabc7efe631d98de7caae3651a047496 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCDumbTab.h @@ -0,0 +1,95 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCDumbTab.h + + Author: Gabriele Strattner + +/-*/ + +#ifndef NCDumbTab_h +#define NCDumbTab_h + +#include + +#include +#include "NCWidget.h" + + +class NCDumbTab : public YDumbTab, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCDumbTab & obj ); + + NCDumbTab & operator=( const NCDumbTab & ); + NCDumbTab( const NCDumbTab & ); + + unsigned currentIndex; + wint_t hotKey; + +protected: + + virtual const char * location() const { return "NCDumbTab"; } + + virtual void wRedraw(); + void redrawChild( YWidget *widget ); + +public: + + NCDumbTab( YWidget * parent ); + virtual ~NCDumbTab(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void addItem( YItem * item ); + virtual void selectItem( YItem * item, bool selected ); + + virtual void setSize( int newWidth, int newHeight ); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual void shortcutChanged(); + + virtual bool HasHotkey( int key ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + NCursesEvent createMenuEvent( unsigned index); + + void setCurrentTab( wint_t key ); + + /** + * Activate selected tab. Can be used in tests to simulate user input. + * + * Derived classes are required to implement this. + **/ + virtual void activate(); +}; + + +#endif // NCDumbTab_h diff --git a/deps/libyui/libyui-ncurses/src/NCEmpty.cc b/deps/libyui/libyui-ncurses/src/NCEmpty.cc new file mode 100644 index 0000000000000000000000000000000000000000..9e3e44a4582702fb234bc5f1b9866a77e1678c1e --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCEmpty.cc @@ -0,0 +1,56 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCEmpty.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCEmpty.h" + + +NCEmpty::NCEmpty( YWidget * parent ) + : YEmpty( parent ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; +} + + +NCEmpty::~NCEmpty() +{ + // yuiDebug() << std::endl; +} + + +void NCEmpty::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCEmpty::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YEmpty::setEnabled( do_bv ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCEmpty.h b/deps/libyui/libyui-ncurses/src/NCEmpty.h new file mode 100644 index 0000000000000000000000000000000000000000..ac3e5b09f3d4103f4a73d04e28a6bb9a7765fab6 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCEmpty.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCEmpty.h + + Author: Michael Andres + +/-*/ + +#ifndef NCEmpty_h +#define NCEmpty_h + +#include + +#include +#include "NCWidget.h" + + +class NCEmpty : public YEmpty, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCEmpty & obj ); + + NCEmpty & operator=( const NCEmpty & ); + NCEmpty( const NCEmpty & ); + + +protected: + + virtual const char * location() const { return "NCEmpty"; } + +public: + + NCEmpty( YWidget * parent ); + + virtual ~NCEmpty(); + + virtual int preferredWidth() { return YEmpty::preferredWidth(); } + virtual int preferredHeight() { return YEmpty::preferredHeight(); } + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCEmpty_h diff --git a/deps/libyui/libyui-ncurses/src/NCFileSelection.cc b/deps/libyui/libyui-ncurses/src/NCFileSelection.cc new file mode 100644 index 0000000000000000000000000000000000000000..8894dc72028fc0de0cc9bf6f81448b9539cbddff --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCFileSelection.cc @@ -0,0 +1,841 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCFileSelection.cc + + Author: Gabriele Strattner + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCFileSelection.h" +#include "NCTable.h" +#include "NCi18n.h" + +#include +#include +#include +#include // strerror() +#include + +using std::string; +using std::endl; +using std::vector; +using std::list; + +/* + Textdomain "ncurses" +*/ + + + +NCFileInfo::NCFileInfo( string fileName, + struct stat * statInfo, + bool link ) +{ + _name = fileName; + _mode = statInfo->st_mode; + _device = statInfo->st_dev; + _links = statInfo->st_nlink; + _size = statInfo->st_size; + _mtime = statInfo->st_mtime; + + if ( link ) + { + char tmpName[PATH_MAX+1]; + // get actual file name + int len = readlink( fileName.c_str(), tmpName, PATH_MAX ); + + if ( len >= 0 ) + { + tmpName[len] = '\0'; + _realName = tmpName; + } + + _tag = " @"; // set tag + } + else if ( S_ISREG( _mode ) + && ( _mode & S_IXUSR ) ) + _tag = " *"; // user executable files + else + _tag = " "; + + // get user and group name + + struct passwd * pwdInfo = getpwuid( statInfo->st_uid ); + + if ( pwdInfo ) + _user = pwdInfo->pw_name; + + struct group * groupInfo = getgrgid( statInfo->st_gid ); + + if ( groupInfo ) + _group = groupInfo->gr_name; + + if ( _mode & S_IRUSR ) + _perm += "r"; + else + _perm += "-"; + + if ( _mode & S_IWUSR ) + _perm += "w"; + else + _perm += "-"; + + if ( _mode & S_IXUSR ) + _perm += "x"; + else + _perm += "-"; + + if ( _mode & S_IRGRP ) + _perm += "r"; + else + _perm += "-"; + + if ( _mode & S_IWGRP ) + _perm += "w"; + else + _perm += "-"; + + if ( _mode & S_IXGRP ) + _perm += "x"; + else + _perm += "-"; + + if ( _mode & S_IROTH ) + _perm += "r"; + else + _perm += "-"; + + if ( _mode & S_IWOTH ) + _perm += "w"; + else + _perm += "-"; + + if ( _mode & S_IXOTH ) + _perm += "x"; + else + _perm += "-"; +} + + +NCFileInfo::NCFileInfo() +{ + _name = ""; + _realName = ""; + _tag = ""; + _perm = ""; + _user = ""; + _group = ""; + _mode = ( mode_t )0; + _device = ( dev_t )0; + _links = ( nlink_t )0; + _size = ( off_t )0; + _mtime = ( time_t )0; +} + + +NCFileSelectionTag::NCFileSelectionTag( NCFileInfo * info ) + : YTableCell( " " ) + , fileInfo( info ) +{ + setLabel( fileInfo->_tag ); +} + +NCFileSelectionTag::~NCFileSelectionTag() +{ + if ( fileInfo ) + { + delete fileInfo; + } +} + +NCFileSelection::NCFileSelection( YWidget * parent, + YTableHeader * tableHeader, + NCFileSelectionType type, + const string & iniDir ) + : NCTable( parent, tableHeader ) + , startDir( iniDir ) + , currentDir( iniDir ) + , tableType( type ) +{ + SetSepChar( ' ' ); + + struct stat statInfo; + + if ( !iniDir.empty() ) + { + stat( iniDir.c_str(), &statInfo ); + } + + if ( iniDir.empty() + || !S_ISDIR( statInfo.st_mode ) ) + { + char wDir[PATH_MAX+1]; // + + // start with working directory + + if ( getcwd( wDir, PATH_MAX ) ) + { + startDir = wDir; + currentDir = wDir; + } + else + { + startDir = "/"; + currentDir = "/"; + } + } + + // yuiDebug() << endl; +} + + +NCFileSelection::~NCFileSelection() +{ + // yuiDebug() << endl; +} + + +string NCFileSelection::getCurrentLine() +{ + int index = getCurrentItem(); + + if ( index != -1 ) + { + NCFileInfo * info = getFileInfo( index ); + return info->_name; + } + else + { + return ""; + } +} + + +void NCFileSelection::setCurrentDir() +{ + string selected = getCurrentLine(); + yuiDebug() << "Current directory: " << selected << endl; + + if ( selected != ".." ) + { + if ( startDir != "/" ) + { + currentDir = startDir + "/" + selected; + } + else + { + currentDir = startDir + selected; + } + } + else + { + size_t pos; + + if (( pos = currentDir.find_last_of( "/" ) ) != 0 ) + { + currentDir = currentDir.substr( 0, pos ); + } + else + { + currentDir = "/"; + } + } +} + + +void NCFileSelection::addLine( const vector & elements, + NCFileInfo * info ) +{ + YTableItem *tabItem = new YTableItem(); + + tabItem->addCell( new NCFileSelectionTag( info ) ); + + for ( unsigned i = 1; i < elements.size()+1; ++i ) { + tabItem->addCell( elements[i-1] ); + } + + // use all-at-once insertion mode - DrawPad() is called only after the loop + addItem(tabItem, true); +} + + +void NCFileSelection::deleteAllItems() +{ + return NCTable::deleteAllItems(); +} + + +bool NCFileTable::createListEntry( NCFileInfo * fileInfo ) +{ + vector data; + + switch ( tableType ) + { + case T_Overview: + { + data.reserve( 2 ); + data.push_back( fileInfo->_name ); + break; + } + case T_Detailed: + { + data.reserve( 6 ); + data.push_back( fileInfo->_name ); + char size_buf[50]; + sprintf( size_buf, "%lld", ( long long int ) fileInfo->_size ); + data.push_back( size_buf ); + data.push_back( fileInfo->_perm ); + data.push_back( fileInfo->_user ); + data.push_back( fileInfo->_group ); + break; + } + default: + { + data.reserve( 2 ); + data.push_back( " " ); + data.push_back( " " ); + break; + } + } + + addLine( data, fileInfo ); + + return true; +} + + +bool NCDirectoryTable::createListEntry( NCFileInfo * fileInfo ) +{ + vector data; + + switch ( tableType ) + { + case T_Overview: + { + data.reserve( 2 ); + data.push_back( fileInfo->_name ); + break; + } + case T_Detailed: + { + data.reserve( 4 ); + data.push_back( fileInfo->_name ); + data.push_back( fileInfo->_perm ); + data.push_back( fileInfo->_user ); + data.push_back( fileInfo->_group ); + break; + } + default: + { + data.reserve( 2 ); + data.push_back( " " ); + data.push_back( " " ); + break; + } + } + + addLine( data, fileInfo ); + + return true; +} + + +NCFileInfo * NCFileSelection::getFileInfo( int index ) +{ + // get the tag + NCFileSelectionTag *cc = getTag( index ); + + if ( !cc ) + return 0; + + return cc->getFileInfo(); +} + + +NCFileSelectionTag * NCFileSelection::getTag( int index ) +{ + // get the table line + NCTableLine * cl = myPad()->ModifyLine( index ); + + if ( !cl ) + return 0; + + // get first column (the column containing the status info) + YTableItem *it = dynamic_cast (cl->origItem() ); + YTableCell *tcell = it->cell(0); + NCFileSelectionTag * cc = static_cast( tcell ); + + return cc; +} + + + + + + +NCFileTable::NCFileTable( YWidget * parent, + YTableHeader * tableHeader, + NCFileSelectionType type, + const string & filter, + const string & iniDir ) + : NCFileSelection( parent, tableHeader, type, iniDir ) + , currentFile("") +{ + //fillHeader(); + + string filterStr = filter; + const string delims( " \t" ); + string::size_type begin, end; + + begin = filterStr.find_first_not_of( delims ); + + while ( begin != string::npos ) + { + end = filterStr.find_first_of( delims, begin ); + + if ( end == string::npos ) + end = filterStr.length(); + + pattern.push_back( filterStr.substr( begin, end - begin ) ); + begin = filterStr.find_first_not_of( delims, end ); + } +} + + +/** + * Fill the column headers of the file table + **/ +void NCFileTable::fillHeader() +{ + vector header; + string old_textdomain = textdomain(NULL); + setTextdomain( "ncurses" ); + + switch ( tableType ) + { + case T_Overview: + { + header.reserve( 2 ); + header.push_back( string( " " ) ); + // column header name of the file + header.push_back( string( _( "File name" ) ) ); + break; + } + + case T_Detailed: + { + header.reserve( 6 ); + header.push_back( string( " " ) ); + // column header name of the file + header.push_back( string( _( "File name" ) ) ); + // column header size of the file + header.push_back( string( _( "Size" ) ) ); + // column header file permissions + header.push_back( string( _( "Permissions" ) ) ); + // column header user + header.push_back( string( _( "User" ) ) ); + // column header group + header.push_back( string( _( "Group" ) ) ); + break; + } + + default: + { + header.reserve( 2 ); + header.push_back( string( " " ) ); + header.push_back( string( _( "File name" ) ) ); + break; + } + } + + setHeader( header ); + // restore former text domain + setTextdomain( old_textdomain.c_str() ); +} + + +bool NCFileTable::filterMatch( const string & fileEntry ) +{ + if ( pattern.empty() ) + return true; + + bool match = false; + + list::iterator it = pattern.begin(); + + while ( it != pattern.end() ) + { + if ( fnmatch(( *it ).c_str(), fileEntry.c_str(), FNM_PATHNAME ) == 0 ) + match = true; + + ++it; + } + + return match; +} + + +NCursesEvent NCFileSelection::handleKeyEvents( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + + if ( sendKeyEvents() && + ( key == KEY_LEFT || key == KEY_RIGHT ) ) + { + ret = NCursesEvent::key; + + switch ( key ) + { + case KEY_LEFT: + ret.keySymbol = "CursorLeft"; + break; + + case KEY_RIGHT: + ret.keySymbol = "CursorRight"; + break; + } + } + + return ret; +} + + +NCursesEvent NCFileTable::wHandleInput( wint_t key ) +{ + NCursesEvent ret = handleKeyEvents( key ); + + // return key event + + if ( ret == NCursesEvent::key ) + return ret; + + // call handleInput of NCPad + handleInput( key ); + + currentFile = getCurrentLine(); + + switch ( key ) + { + case KEY_UP: + case KEY_PPAGE: + case KEY_HOME: + case KEY_DOWN: + case KEY_NPAGE: + case KEY_END: + { + ret = NCursesEvent::SelectionChanged; + ret.result = currentFile; + break; + } + + default: + ret = NCursesEvent::none; + } + + // yuiDebug() << "CURRENT_FILE: " << currentFile << endl; + + return ret; +} + + +bool NCFileTable::fillList() +{ + + struct stat statInfo; + struct stat linkInfo; + struct dirent * entry; + list tmpList; + list::iterator it; + + fillHeader(); // create the column headers + + DIR * diskDir = opendir( currentDir.c_str() ); + + if ( diskDir ) + { + deleteAllItems(); + + while (( entry = readdir( diskDir ) ) ) + { + string entryName = entry->d_name; + + if ( entryName != "." + && filterMatch( entryName ) ) + { + tmpList.push_back( entryName ); + } + } + + // sort the list and fill the table widget with file entries + tmpList.sort(); + it = tmpList.begin(); + + while ( it != tmpList.end() ) + { + string fullName = currentDir + "/" + ( *it ); + + if ( lstat( fullName.c_str(), &statInfo ) == 0 ) + { + if ( S_ISREG( statInfo.st_mode ) || S_ISBLK( statInfo.st_mode ) ) + { + if ((( *it ) == ".." && currentDir != "/" ) + || ( *it ) != ".." ) + { + createListEntry( new NCFileInfo(( *it ), &statInfo ) ); + } + } + else if ( S_ISLNK( statInfo.st_mode ) ) + { + if ( stat( fullName.c_str(), &linkInfo ) == 0 ) + { + if ( S_ISREG( linkInfo.st_mode ) || S_ISBLK( linkInfo.st_mode ) ) + { + createListEntry( new NCFileInfo(( *it ), &linkInfo, true ) ); + } + } + } + } + + ++it; + } + + drawList(); // draw the list + + if ( getNumLines() > 0 ) + { + scrollToFirstItem(); + currentFile = getCurrentLine(); + } + else + { + currentFile = ""; + } + + closedir( diskDir ); + } + else + { + yuiError() << "ERROR opening directory: " << currentDir << " errno: " + << strerror( errno ) << endl; + return false; + } + + return true; +} + + +NCDirectoryTable::NCDirectoryTable( YWidget * parent, + YTableHeader * tableHeader, + NCFileSelectionType type, + const string & iniDir ) + : NCFileSelection( parent, tableHeader, type, iniDir ) +{ + //fillHeader(); +} + + +/** + * Fill the column headers of the table + **/ +void NCDirectoryTable::fillHeader() +{ + vector header; + string old_textdomain = textdomain(NULL); + setTextdomain( "ncurses" ); + + switch ( tableType ) + { + case T_Overview: + { + header.reserve( 2 ); + header.push_back( string( " " ) ); + // column header name of diretcory + header.push_back( string( _( "Directory Name" ) ) ); + break; + } + + case T_Detailed: + { + header.reserve( 5 ); + header.push_back( string( " " ) ); + // column header name of diretcory + header.push_back( string( _( "Directory Name" ) ) ); + header.push_back( string( _( "Permissions" ) ) ); + header.push_back( string( _( "User" ) ) ); + header.push_back( string( _( "Group" ) ) ); + break; + } + + default: + { + header.reserve( 2 ); + header.push_back( string( " " ) ); + header.push_back( string( _( "Directory Name" ) ) ); + break; + } + } + + setHeader( header ); + // restore former text domain + setTextdomain( old_textdomain.c_str() ); +} + + +bool NCDirectoryTable::fillList() +{ + struct stat statInfo; + struct stat linkInfo; + struct dirent * entry; + list tmpList; + list::iterator it; + + fillHeader(); // create the column headers + + DIR * diskDir = opendir( currentDir.c_str() ); + + if ( diskDir ) + { + deleteAllItems(); + + while (( entry = readdir( diskDir ) ) ) + { + string entryName = entry->d_name; + + if ( entryName != "." ) + { + tmpList.push_back( entryName ); + } + } + + // sort the list and fill the table widget with directory entries + tmpList.sort(); + + it = tmpList.begin(); + + while ( it != tmpList.end() ) + { + string fullName = currentDir + "/" + ( *it ); + + if ( lstat( fullName.c_str(), &statInfo ) == 0 ) + { + if ( S_ISDIR( statInfo.st_mode ) ) + { + if ((( *it ) == ".." && currentDir != "/" ) + || ( *it ) != ".." ) + { + createListEntry( new NCFileInfo(( *it ), &statInfo ) ); + } + } + else if ( S_ISLNK( statInfo.st_mode ) ) + { + if ( stat( fullName.c_str(), &linkInfo ) == 0 ) + { + if ( S_ISDIR( linkInfo.st_mode ) ) + { + createListEntry( new NCFileInfo(( *it ), &linkInfo, true ) ); + } + } + } + } + + ++it; + } + + drawList(); // draw the list + startDir = currentDir; // set start directory + + if ( getNumLines() > 0 ) + scrollToFirstItem(); + + closedir( diskDir ); + } + else + { + yuiError() << "ERROR opening directory: " << currentDir << " errno: " + << strerror( errno ) << endl; + + return false; + } + + return true; +} + + +NCursesEvent NCDirectoryTable::wHandleInput( wint_t key ) +{ + NCursesEvent ret = handleKeyEvents( key ); + + // return key event + + if ( ret == NCursesEvent::key ) + return ret; + + unsigned old_pos = getCurrentItem(); + + // call handleInput of NCPad + handleInput( key ); + + switch ( key ) + { + case KEY_UP: + case KEY_PPAGE: + case KEY_HOME: + { + if ( old_pos != 0 ) + { + setCurrentDir(); + ret = NCursesEvent::SelectionChanged; + ret.result = currentDir; + } + + break; + } + + case KEY_DOWN: + case KEY_NPAGE: + case KEY_END: + { + setCurrentDir(); + ret = NCursesEvent::SelectionChanged; + ret.result = currentDir; + break; + } + + case KEY_RETURN: + case KEY_SPACE: + { + setCurrentDir(); + ret = NCursesEvent::Activated; + ret.result = currentDir; + break; + } + + default: + ret = NCursesEvent::none; + } + + // yuiDebug() << "CURRENT: " << currentDir << " START DIR: " << startDir << endl; + + return ret; +} + + + diff --git a/deps/libyui/libyui-ncurses/src/NCFileSelection.h b/deps/libyui/libyui-ncurses/src/NCFileSelection.h new file mode 100644 index 0000000000000000000000000000000000000000..5c459d62d4ebe005f9924a98f5b8ae2b06cecbb2 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCFileSelection.h @@ -0,0 +1,279 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCFileSelection.h + + Author: Gabriele Strattner + +/-*/ + +#ifndef NCFileSelection_h +#define NCFileSelection_h + +#include + +#include "NCPadWidget.h" +#include "NCTablePad.h" +#include "NCTable.h" + +#include +#include + +#include +#include +#include +#include +#include + + +struct NCFileInfo +{ + /** + * Constructor from a stat buffer (i.e. based on an lstat() call). + **/ + NCFileInfo( std::string fileName, + struct stat * statInfo, + bool link = false ); + + NCFileInfo(); + + ~NCFileInfo() {}; + + // Data members. + + std::string _name; // the file name (without path!) + std::string _realName; // actual file name + std::string _tag; // short label + std::string _perm; // permission std::string + std::string _user; // user name + std::string _group; // group name + dev_t _device; // device this object resides on + mode_t _mode; // file permissions + object type + nlink_t _links; // number of links + off_t _size; // size in bytes + time_t _mtime; // modification time + + bool isDir() { return (( S_ISDIR( _mode ) ) ? true : false ); } + + bool isLink() { return (( S_ISLNK( _mode ) ) ? true : false ); } + + bool isFile() { return (( S_ISREG( _mode ) ) ? true : false ); } +}; + + +/** + * This class is used for the first column of the file table. + * Contains the file data. + **/ +class NCFileSelectionTag : public YTableCell +{ + +private: + + NCFileInfo * fileInfo; + +public: + + NCFileSelectionTag( NCFileInfo * info ); + + ~NCFileSelectionTag(); + + NCFileInfo * getFileInfo() const { return fileInfo; } +}; + + +/** + * The class which provides methods to handle a std::list of files or directories. + **/ +class NCFileSelection : public NCTable +{ +public: + enum NCFileSelectionType + { + T_Overview, + T_Detailed, + T_Unknown + }; + +private: + + NCFileSelection & operator=( const NCFileSelection & ); + NCFileSelection( const NCFileSelection & ); + + // returns the first column of line with 'index' (the tag) + NCFileSelectionTag * getTag( int index ); + + +protected: + + std::string startDir; + std::string currentDir; + NCFileSelectionType tableType; // T_Overview or T_Detailed + + void setCurrentDir(); + std::string getCurrentLine(); + + NCursesEvent handleKeyEvents( wint_t key ); + +public: + + /** + * Constructor + */ + NCFileSelection( YWidget * parent, + YTableHeader * tableHeader, + NCFileSelectionType type, + const std::string & iniDir ); + + virtual ~NCFileSelection(); + + /** + * Get the file info. + * index: The std::list index + * return: fileInfo Information about the file (directory) + */ + NCFileInfo * getFileInfo( int index ); + + /** + * Set the type of the table widget + * type: Possible values: NCFileSelection::T_Overview, NCFileSelection::T_Detailed + */ + void setTableType( NCFileSelectionType type ) { tableType = type; }; + + virtual void addLine( const std::vector & elements, + NCFileInfo * fileInfo ); + + /** + * Get number of lines ( std::list entries ) + */ + unsigned getNumLines() { return myPad()->Lines(); } + + /** + * Draws the file std::list (has to be called after the loop with + * addLine() calls) + */ + void drawList() { return DrawPad(); } + + /** + * Clears the package std::list + */ + virtual void deleteAllItems(); + + /** + * Fills the header of the table + */ + virtual void fillHeader() = 0; + + /** + * Creates a line in the package table. + */ + virtual bool createListEntry( NCFileInfo * fileInfo ) = 0; + + /** + * Get the current directory + * return: The currently selected directory + */ + std::string getCurrentDir() { return currentDir; } + + /** + * Fill the std::list of diretcories or files + * Returns 'true' on success. + */ + virtual bool fillList() = 0; + + /** + * Set the start directory + */ + void setStartDir( const std::string & start ) + { + currentDir = start; + startDir = start; + } + +}; + + +class NCFileTable : public NCFileSelection +{ +private: + + std::list pattern; // files must match this pattern + std::string currentFile; // currently selected file + +public: + + /** + * Constructor + */ + NCFileTable( YWidget * parent, + YTableHeader * tableHeader, + NCFileSelectionType type, + const std::string & filter, + const std::string & iniDir ); + + virtual ~NCFileTable() {} + + void setCurrentFile( const std::string & file ) + { + currentFile = file; + } + + bool filterMatch( const std::string & fileName ); + + std::string getCurrentFile() { return currentFile; } + + virtual void fillHeader(); + + virtual bool createListEntry( NCFileInfo * fileInfo ); + + /** + * Fill the std::list of files + * Returns 'true' on success. + */ + virtual bool fillList(); + + virtual NCursesEvent wHandleInput( wint_t key ); +}; + + +class NCDirectoryTable : public NCFileSelection +{ +public: + NCDirectoryTable( YWidget * parent, + YTableHeader * tableHeader, + NCFileSelectionType type, + const std::string & iniDir ); + + virtual ~NCDirectoryTable() {} + + virtual void fillHeader(); + + virtual bool createListEntry( NCFileInfo * fileInfo ); + + /** + * Fill the std::list of directories. + * Returns 'true' on success. + */ + virtual bool fillList(); + + virtual NCursesEvent wHandleInput( wint_t key ); +}; + + + +#endif // NCFileSelection_h diff --git a/deps/libyui/libyui-ncurses/src/NCFrame.cc b/deps/libyui/libyui-ncurses/src/NCFrame.cc new file mode 100644 index 0000000000000000000000000000000000000000..cf8a7a91061f86692744448c5e514d4c893645a8 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCFrame.cc @@ -0,0 +1,133 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCFrame.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCFrame.h" + + +NCFrame::NCFrame( YWidget * parent, const std::string & nlabel ) + : YFrame( parent, nlabel ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; + framedim.Pos = wpos( 1 ); + framedim.Sze = wsze( 2 ); + setLabel( YFrame::label() ); + hotlabel = &label; +} + + +NCFrame::~NCFrame() +{ + // yuiDebug() << std::endl; +} + + +int NCFrame::preferredWidth() +{ + defsze.W = hasChildren() ? firstChild()->preferredWidth() : 0; + + if ( label.width() > (unsigned) defsze.W ) + defsze.W = label.width(); + + defsze.W += framedim.Sze.W; + + return defsze.W; +} + + +int NCFrame::preferredHeight() +{ + defsze.H = hasChildren() ? firstChild()->preferredHeight() : 0; + defsze.H += framedim.Sze.H; + + return defsze.H; +} + + +void NCFrame::setSize( int newwidth, int newheight ) +{ + wsze csze( newheight, newwidth ); + wRelocate( wpos( 0 ), csze ); + csze = wsze::max( 0, csze - framedim.Sze ); + + if ( hasChildren() ) + firstChild()->setSize( csze.W, csze.H ); +} + + +void NCFrame::setLabel( const std::string & nlabel ) +{ + YFrame::setLabel( nlabel ); + label = NCstring( YFrame::label() ); + label.stripHotkey(); + Redraw(); +} + + +void NCFrame::setEnabled( bool do_bv ) +{ + // Use setEnabled() from the parent, it should work out (#256707) :-) + NCWidget::setEnabled( do_bv ); + YFrame::setEnabled( do_bv ); +} + + +bool NCFrame::gotBuddy() +{ + if ( !label.hasHotkey() ) + return false; + + for ( tnode * c = this->Next(); + c && c->IsDescendantOf( this ); + c = c->Next() ) + { + if ( c->Value()->GetState() != NC::WSdumb ) + return true; + } + + return false; +} + + +void NCFrame::wRedraw() +{ + if ( !win ) + return; + + chtype bg = wStyle().dumb.text; + win->bkgd( bg ); + win->box(); + + if ( gotBuddy() ) + label.drawAt( *win, widgetStyle(), wpos( 0, 1 ), + wsze( 1, win->width() - 2 ), NC::TOPLEFT, false ); + else + label.drawAt( *win, bg, bg, wpos( 0, 1 ), + wsze( 1, win->width() - 2 ), NC::TOPLEFT, false ); +} + diff --git a/deps/libyui/libyui-ncurses/src/NCFrame.h b/deps/libyui/libyui-ncurses/src/NCFrame.h new file mode 100644 index 0000000000000000000000000000000000000000..50fd527f519515335f811a9faf5dd5d30a878759 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCFrame.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCFrame.h + + Author: Michael Andres + +/-*/ + +#ifndef NCFrame_h +#define NCFrame_h + +#include + +#include +#include "NCWidget.h" + +class NCFrame; + + +class NCFrame : public YFrame, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCFrame & obj ); + + NCFrame & operator=( const NCFrame & ); + NCFrame( const NCFrame & ); + + + NClabel label; + +protected: + + bool gotBuddy(); + + virtual const char * location() const { return "NCFrame"; } + + virtual void wRedraw(); + +public: + + NCFrame( YWidget * parent, const std::string & label ); + virtual ~NCFrame(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCFrame_h diff --git a/deps/libyui/libyui-ncurses/src/NCImage.cc b/deps/libyui/libyui-ncurses/src/NCImage.cc new file mode 100644 index 0000000000000000000000000000000000000000..f01236807d3abd669f4a800d0ad020601df196d2 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCImage.cc @@ -0,0 +1,72 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCImage.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCImage.h" + + +NCImage::NCImage( YWidget * parent, std::string defaulttext, bool animated ) + : YImage( parent, defaulttext, animated ) + , NCWidget( parent ) + , label( defaulttext ) +{ + // yuiDebug() << std::endl; + defsze = 0; + wstate = NC::WSdumb; + skipNoDimWin = true; +} + + +NCImage::~NCImage() +{ + // yuiDebug() << std::endl; +} + + +int NCImage::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCImage::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCImage::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YImage::setEnabled( do_bv ); +} + + + +void NCImage::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCImage.h b/deps/libyui/libyui-ncurses/src/NCImage.h new file mode 100644 index 0000000000000000000000000000000000000000..bd9cb1404eb8a8e3abd49fccf4ebdb5da3a51a33 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCImage.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCImage.h + + Author: Michael Andres + +/-*/ + +#ifndef NCImage_h +#define NCImage_h + +#include + +#include +#include "NCWidget.h" + +class NCImage; + + +class NCImage : public YImage, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCImage & obj ); + + NCImage & operator=( const NCImage & ); + NCImage( const NCImage & ); + + + NClabel label; + +protected: + + virtual const char * location() const { return "NCImage"; } + +public: + + NCImage( YWidget * parent, std::string defaulttext, bool animated = false ); + virtual ~NCImage(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCImage_h diff --git a/deps/libyui/libyui-ncurses/src/NCInputField.cc b/deps/libyui/libyui-ncurses/src/NCInputField.cc new file mode 100644 index 0000000000000000000000000000000000000000..499de98ee33d28274e9ae936e22895e6798dd78e --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCInputField.cc @@ -0,0 +1,641 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCInputField.cc + + Author: Michael Andres + +/-*/ +#include + + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCInputField.h" +#include "YNCursesUI.h" + +#include // iswalnum() + + +NCInputField::NCInputField( YWidget * parent, + const std::string & nlabel, + bool passwordMode, + unsigned maxInput, + unsigned maxFld ) + : YInputField( parent, nlabel, passwordMode ) + , NCWidget( parent ) + , passwd( passwordMode ) + , lwin( 0 ) + , twin( 0 ) + , maxFldLength( maxFld ) + , maxInputLength( maxInput ) + , fldstart( 0 ) + , fldlength( 0 ) + , curpos( 0 ) + , fldtype( PLAIN ) + , returnOnReturn_b( false ) + , InputMaxLength( -1 ) +{ + // yuiDebug() << std::endl; + + if ( maxInputLength && + ( !maxFldLength || maxFldLength > maxInputLength ) ) + { + maxFldLength = maxInputLength; + } + + setLabel( nlabel ); + + hotlabel = &label; + // initial text isn't an argument any longer + //setText( ntext ); +} + + + +NCInputField::~NCInputField() +{ + delete lwin; + delete twin; + // yuiDebug() << std::endl; +} + + + +int NCInputField::preferredWidth() +{ + return wGetDefsze().W; +} + + + +int NCInputField::preferredHeight() +{ + return wGetDefsze().H; +} + + + +void NCInputField::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YInputField::setEnabled( do_bv ); +} + + + +void NCInputField::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + + +void NCInputField::setDefsze() +{ + unsigned defwidth = maxFldLength ? maxFldLength : 5; + + if ( label.width() > defwidth ) + defwidth = label.width(); + + defsze = wsze( label.height() + 1, defwidth ); +} + + + +void NCInputField::wCreate( const wrect & newrect ) +{ + NCWidget::wCreate( newrect ); + + if ( !win ) + return; + + wrect lrect( 0, wsze::min( newrect.Sze, + wsze( label.height(), newrect.Sze.W ) ) ); + + if ( lrect.Sze.H == newrect.Sze.H ) + lrect.Sze.H -= 1; + + wrect trect( 0, wsze( 1, newrect.Sze.W ) ); + + trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; + + lwin = new NCursesWindow( *win, + lrect.Sze.H, lrect.Sze.W, + lrect.Pos.L, lrect.Pos.C, + 'r' ); + + twin = new NCursesWindow( *win, + trect.Sze.H, trect.Sze.W, + trect.Pos.L, trect.Pos.C, + 'r' ); + + if ( maxFldLength && maxFldLength < (unsigned) newrect.Sze.W ) + trect.Sze.W = maxFldLength; + + fldlength = trect.Sze.W; +} + + + +void NCInputField::wDelete() +{ + delete lwin; + delete twin; + lwin = 0; + twin = 0; + NCWidget::wDelete(); +} + + + +void NCInputField::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + YInputField::setLabel( nlabel ); + setDefsze(); + Redraw(); +} + + + +void NCInputField::setValue( const std::string & ntext ) +{ + std::string old_value = value(); + buffer = NCstring( ntext ).str(); + + if ( maxInputLength && buffer.length() > maxInputLength ) + { + buffer = buffer.erase( maxInputLength ); + } + + fldstart = 0; + + curpos = buffer.length(); + tUpdate(); + + if (notify() && old_value != ntext) + { + NCursesEvent event = NCursesEvent::ValueChanged; + event.widget = this; + YNCursesUI::ui()->sendEvent(event); + } +} + + + +std::string NCInputField::value() +{ + NCstring text( buffer ); + + return text.Str(); +} + + + +void NCInputField::setValidChars( const std::string & validchars ) +{ + validChars = NCstring( validchars ); + YInputField::setValidChars( validchars ); +} + + + +bool NCInputField::validKey( wint_t key ) const +{ + // private: NCstring validChars; + const std::wstring vwch( validChars.str() ); + + if ( vwch.empty() ) + return true; + + if ( key < 0 || WCHAR_MAX < key ) + return false; + + return( vwch.find(( wchar_t )key ) != std::wstring::npos ); +} + + + +void NCInputField::wRedraw() +{ + if ( !win ) + return; + + // label + const NCstyle::StWidget & style( widgetStyle( true ) ); + + lwin->bkgd( style.plain ); + + lwin->clear(); + + label.drawAt( *lwin, style ); + + tUpdate(); +} + + + +inline bool NCInputField::bufferFull() const +{ + return( maxInputLength && buffer.length() == maxInputLength ); +} + + + +inline unsigned NCInputField::maxCursor() const +{ + return( bufferFull() ? buffer.length() - 1 : buffer.length() ); +} + + + +void NCInputField::tUpdate() +{ + if ( !win ) + return; + + unsigned maxc = maxCursor(); + + // adjust cursor + if ( curpos > maxc ) + { + curpos = maxc; + } + + // adjust fldstart that cursor is visible + if ( maxc < fldlength ) + { + fldstart = 0; + } + else + { + if ( curpos <= fldstart ) + { + fldstart = curpos ? curpos - 1 : 0; + } + + if ( curpos >= fldstart + fldlength - 1 ) + { + fldstart = curpos + ( curpos == maxc ? 1 : 2 ) - fldlength; + } + } + + const NCstyle::StWidget & style( widgetStyle() ); + + twin->bkgd( widgetStyle( true ).plain ); + + twin->move( 0, 0 ); + + unsigned i = 0; + + unsigned end = fldlength; + + const wchar_t * cp = buffer.data() + fldstart; + + // draw left scrollhint if + if ( *cp && fldstart ) + { + twin->bkgdset( style.scrl ); + twin->addch( ACS_LARROW ); + ++i; + ++cp; + } + + // check for right scrollhint + if ( fldstart + fldlength <= maxc ) + { + --end; + } + + // draw field + twin->bkgdset( style.data ); + + for ( /*adjusted i*/; *cp && i < end; ++i ) + { + if ( passwd ) + { + twin->addwstr( L"*" ); + } + else + { + twin->addwstr( cp, 1 ); + } + + ++cp; + } + + twin->bkgdset( style.plain ); + + for ( /*adjusted i*/; i < end; ++i ) + { + twin->addch( ACS_CKBOARD ); + } + + // draw right scrollhint if + if ( end < fldlength ) + { + twin->bkgdset( style.scrl ); + twin->addch( ACS_RARROW ); + } + + // reverse curpos + if ( GetState() == NC::WSactive ) + { + twin->move( 0, curpos - fldstart ); + twin->bkgdset( wStyle().cursor ); + + if ( curpos < buffer.length() ) + twin->add_attr_char(); + else + twin->addch( ACS_CKBOARD ); + } + + Update(); +} + + + +NCursesEvent NCInputField::wHandleInput( wint_t key ) +{ + NCursesEvent ret = NCursesEvent::none; + bool beep = false; + bool update = true; + + switch ( key ) + { + case '\b': //ctrl-h + case 0x7f: //del + case KEY_BACKSPACE: + + if ( bufferFull() && curpos == maxCursor() ) + { + // if we're on the last char in a full buffer delete this char + // and not the previous one. + buffer.erase( curpos, 1 ); + } + else if ( curpos ) + { + buffer.erase( --curpos, 1 ); + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_DC: + + if ( curpos < buffer.length() ) + { + buffer.erase( curpos, 1 ); + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_SLEFT: + case KEY_HOME: + + if ( curpos ) + { + curpos = 0; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_SRIGHT: + case KEY_END: + + if ( curpos < maxCursor() ) + { + curpos = maxCursor(); + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_LEFT: + + if ( curpos ) + { + --curpos; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_RIGHT: + + if ( curpos < maxCursor() ) + { + ++curpos; + } + else + { + update = false; + beep = true; + } + + break; + + case KEY_RETURN: + update = false; + + if ( notify() || returnOnReturn_b ) + ret = NCursesEvent::Activated; + + break; + + case KEY_HOTKEY: + update = false; + + break; + + default: + bool is_special = false; + + if ( key > 0xFFFF ) + { + is_special = true; + key -= 0xFFFF; + } + + if (( !is_special && KEY_MIN < key && KEY_MAX > key ) + || + !iswprint( key ) + || + // if we are at limit of input + ( InputMaxLength >= 0 && InputMaxLength <= (int) buffer.length() ) ) + { + update = false; + beep = true; + } + else if ( fldtype == NUMBER ) + { + if ( bufferFull() && key != L'+' ) + { + update = false; + beep = true; + } + else + { + switch ( key ) + { + case L'0': + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + + if ( curpos || buffer.empty() || buffer[0] != L'-' ) + { + buffer.insert( std::wstring::size_type( curpos ), 1, key ); + + if ( curpos < maxCursor() ) + ++curpos; + } + else + { + update = false; + beep = true; + } + + break; + + case L'+': + + if ( !buffer.empty() && buffer[0] == L'-' ) + { + buffer.erase( std::wstring::size_type( 0 ), 1 ); + + if ( curpos ) + --curpos; + } + else + { + update = false; + } + + break; + + case L'-': + + if ( buffer.empty() || buffer[0] != L'-' ) + { + buffer.insert( std::wstring::size_type( 0 ), 1, L'-' ); + + if ( curpos < maxCursor() ) + ++curpos; + } + else + { + update = false; + } + + break; + + default: + update = false; + beep = true; + break; + } + } + + } + else // PLAIN + { + + if ( bufferFull() || !validKey( key ) ) + { + update = false; + beep = true; + } + else + { + buffer.insert( std::wstring::size_type( curpos ), 1, key ); + + if ( curpos < maxCursor() ) + ++curpos; + } + + } + + break; + } + + if ( update ) + { + tUpdate(); + + if ( notify() ) + ret = NCursesEvent::ValueChanged; + } + + if ( beep ) + ::beep(); + + return ret; + +} + + +void NCInputField::setInputMaxLength( int numberOfChars ) +{ + int nr = numberOfChars; + + // if there is more text then the maximum number of chars, + // truncate the text and update the buffer + + if ( nr >= 0 && (int) buffer.length() > nr ) + { + buffer.erase( nr, maxCursor() - nr ); + tUpdate(); + curpos = buffer.length(); + } + + InputMaxLength = nr; + + YInputField::setInputMaxLength( numberOfChars ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCInputField.h b/deps/libyui/libyui-ncurses/src/NCInputField.h new file mode 100644 index 0000000000000000000000000000000000000000..2eda1b9600e52936a2d0c772d0bff8593710eb0c --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCInputField.h @@ -0,0 +1,137 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCInputField.h + + Author: Michael Andres + +/-*/ + +#ifndef NCInputField_h +#define NCInputField_h + +#include + +#include +#include "NCWidget.h" + + +class NCInputField : public YInputField, public NCWidget +{ + + friend std::ostream & operator<<( std::ostream & str, const NCInputField & obj ); + + NCInputField & operator=( const NCInputField & ); + NCInputField( const NCInputField & ); + +public: + + enum FTYPE + { + PLAIN, + NUMBER + }; + +private: + + bool passwd; + NClabel label; + std::wstring buffer; + + NCursesWindow * lwin; + NCursesWindow * twin; + + unsigned maxFldLength; + unsigned maxInputLength; + + unsigned fldstart; + unsigned fldlength; + unsigned curpos; + + FTYPE fldtype; + NCstring validChars; + + bool returnOnReturn_b; + + void setDefsze(); + void tUpdate(); + + bool bufferFull() const; + unsigned maxCursor() const; + + // specifies how much characters can be inserted. -1 for unlimited input + int InputMaxLength; + +protected: + + virtual const char * location() const { return "NCInputField"; } + + virtual void wCreate( const wrect & newrect ); + virtual void wDelete(); + + virtual void wRedraw(); + + bool validKey( wint_t key ) const; + +public: + + NCInputField( YWidget * parent, + const std::string & label, + bool passwordMode = false, + unsigned maxInput = 0, + unsigned maxFld = 0 + ); + virtual ~NCInputField(); + + void setFldtype( FTYPE t ) { fldtype = t; } + + void setReturnOnReturn( bool on_br ) { returnOnReturn_b = on_br; } + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setValue( const std::string & ntext ); + virtual std::string value(); + + virtual void setValidChars( const std::string & validchars ); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + // limits the input to numberOfChars characters and truncates the text + // if appropriate + void setInputMaxLength( int numberOfChars ); + + void setCurPos( unsigned pos ) { curpos = pos; } +}; + + +#endif // NCInputField_h diff --git a/deps/libyui/libyui-ncurses/src/NCInputTextBase.cc b/deps/libyui/libyui-ncurses/src/NCInputTextBase.cc new file mode 100644 index 0000000000000000000000000000000000000000..848cd077794845cfaa0385b528b7fb5a7c0d06bf --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCInputTextBase.cc @@ -0,0 +1,296 @@ +/* + Copyright (C) 2014 Angelo Naselli + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCInputText.cc + + Author: Angelo Naselli + +/-*/ +#include + + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCInputTextBase.h" + +#include // iswalnum() + + +NCInputTextBase::NCInputTextBase ( YWidget * parent, + bool passwordMode, + unsigned maxInput, + unsigned maxFld ) + : NCWidget ( parent ) + , passwd ( passwordMode ) + , lwin ( 0 ) + , twin ( 0 ) + , maxFldLength ( maxFld ) + , maxInputLength ( maxInput ) + , fldstart ( 0 ) + , fldlength ( 0 ) + , curpos ( 0 ) + , returnOnReturn_b ( false ) +{ + // yuiDebug() << std::endl; + + if ( maxInputLength && + ( !maxFldLength || maxFldLength > maxInputLength ) ) + { + maxFldLength = maxInputLength; + } + + hotlabel = &_label; +} + + + +NCInputTextBase::~NCInputTextBase() +{ + delete lwin; + delete twin; + // yuiDebug() << std::endl; +} + + + +int NCInputTextBase::preferredWidth() +{ + return wGetDefsze().W; +} + + + +int NCInputTextBase::preferredHeight() +{ + return wGetDefsze().H; +} + + + +void NCInputTextBase::setEnabled ( bool do_bv ) +{ + NCWidget::setEnabled ( do_bv ); +} + + + +void NCInputTextBase::setSize ( int newwidth, int newheight ) +{ + wRelocate ( wpos ( 0 ), wsze ( newheight, newwidth ) ); +} + + + +void NCInputTextBase::setDefsze() +{ + unsigned defwidth = maxFldLength ? maxFldLength : 5; + + if ( _label.width() > defwidth ) + defwidth = _label.width(); + + defsze = wsze ( _label.height() + 1, defwidth ); +} + + + +void NCInputTextBase::wCreate ( const wrect & newrect ) +{ + NCWidget::wCreate ( newrect ); + + if ( !win ) + return; + + wrect lrect ( 0, wsze::min ( newrect.Sze, + wsze ( _label.height(), newrect.Sze.W ) ) ); + + if ( lrect.Sze.H == newrect.Sze.H ) + lrect.Sze.H -= 1; + + wrect trect ( 0, wsze ( 1, newrect.Sze.W ) ); + + trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; + + lwin = new NCursesWindow ( *win, + lrect.Sze.H, lrect.Sze.W, + lrect.Pos.L, lrect.Pos.C, + 'r' ); + + twin = new NCursesWindow ( *win, + trect.Sze.H, trect.Sze.W, + trect.Pos.L, trect.Pos.C, + 'r' ); + + if ( maxFldLength && maxFldLength < (unsigned) newrect.Sze.W ) + trect.Sze.W = maxFldLength; + + fldlength = trect.Sze.W; +} + + + +void NCInputTextBase::wDelete() +{ + delete lwin; + delete twin; + lwin = 0; + twin = 0; + NCWidget::wDelete(); +} + + +void NCInputTextBase::wRedraw() +{ + if ( !win ) + return; + + // label + const NCstyle::StWidget & style ( widgetStyle ( true ) ); + + lwin->bkgd ( style.plain ); + + lwin->clear(); + + _label.drawAt ( *lwin, style ); + + tUpdate(); +} + + + +bool NCInputTextBase::bufferFull() const +{ + return ( maxInputLength && buffer.length() == maxInputLength ); +} + + + +unsigned NCInputTextBase::maxCursor() const +{ + return ( bufferFull() ? buffer.length() - 1 : buffer.length() ); +} + + + +void NCInputTextBase::tUpdate() +{ + if ( !win ) + return; + + unsigned maxc = maxCursor(); + + // adjust cursor + if ( curpos > maxc ) + { + curpos = maxc; + } + + // adjust fldstart that cursor is visible + if ( maxc < fldlength ) + { + fldstart = 0; + } + else + { + if ( curpos <= fldstart ) + { + fldstart = curpos ? curpos - 1 : 0; + } + + if ( curpos >= fldstart + fldlength - 1 ) + { + fldstart = curpos + ( curpos == maxc ? 1 : 2 ) - fldlength; + } + } + + const NCstyle::StWidget & style ( widgetStyle() ); + + twin->bkgd ( widgetStyle ( true ).plain ); + + twin->move ( 0, 0 ); + + unsigned i = 0; + + unsigned end = fldlength; + + const wchar_t * cp = buffer.data() + fldstart; + + // draw left scrollhint if + if ( *cp && fldstart ) + { + twin->bkgdset ( style.scrl ); + twin->addch ( ACS_LARROW ); + ++i; + ++cp; + } + + // check for right scrollhint + if ( fldstart + fldlength <= maxc ) + { + --end; + } + + // draw field + twin->bkgdset ( style.data ); + + for ( /*adjusted i*/; *cp && i < end; ++i ) + { + if ( passwd ) + { + twin->addwstr ( L"*" ); + } + else + { + twin->addwstr ( cp, 1 ); + } + + ++cp; + } + + twin->bkgdset ( style.plain ); + + for ( /*adjusted i*/; i < end; ++i ) + { + twin->addch ( ACS_CKBOARD ); + } + + // draw right scrollhint if + if ( end < fldlength ) + { + twin->bkgdset ( style.scrl ); + twin->addch ( ACS_RARROW ); + } + + // reverse curpos + if ( GetState() == NC::WSactive ) + { + twin->move ( 0, curpos - fldstart ); + twin->bkgdset ( wStyle().cursor ); + + if ( curpos < buffer.length() ) + twin->add_attr_char(); + else + twin->addch ( ACS_CKBOARD ); + } + + Update(); +} + + + diff --git a/deps/libyui/libyui-ncurses/src/NCInputTextBase.h b/deps/libyui/libyui-ncurses/src/NCInputTextBase.h new file mode 100644 index 0000000000000000000000000000000000000000..170dde7efa256bcd7a3c295766101ee3aca5c4b1 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCInputTextBase.h @@ -0,0 +1,105 @@ +/* + Copyright (C) 2014 Angelo Naselli + + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCInputText.h + + Author: Angelo Naselli + +/-*/ +#ifndef NCInputText_h +#define NCInputText_h + +#include + +#include "NCWidget.h" + + +class NCInputTextBase : public NCWidget +{ + + friend std::ostream & operator<< ( std::ostream & str, const NCInputTextBase & obj ); + + NCInputTextBase & operator= ( const NCInputTextBase & ); + NCInputTextBase ( const NCInputTextBase & ); + +protected: + + bool passwd; + NClabel _label; + std::wstring buffer; + + NCursesWindow * lwin; + NCursesWindow * twin; + + unsigned maxFldLength; + unsigned maxInputLength; + + unsigned fldstart; + unsigned fldlength; + unsigned curpos; + + bool returnOnReturn_b; + + virtual void setDefsze(); + virtual void tUpdate(); + + virtual bool bufferFull() const; + virtual unsigned maxCursor() const; + + virtual const char * location() const + { + return "NCInputTextBase"; + } + + virtual void wCreate ( const wrect & newrect ); + virtual void wDelete(); + + virtual void wRedraw(); + + + NCInputTextBase ( YWidget * parent, + bool passwordMode = false, + unsigned maxInput = 0, + unsigned maxFld = 0 + ); + virtual ~NCInputTextBase(); + +public: + + void setReturnOnReturn ( bool on_br ) + { + returnOnReturn_b = on_br; + } + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize ( int newWidth, int newHeight ); + + virtual void setEnabled ( bool do_bv ); + + virtual void setCurPos ( unsigned pos ) + { + curpos = pos; + } + +}; + + +#endif // NCInputText_h diff --git a/deps/libyui/libyui-ncurses/src/NCIntField.cc b/deps/libyui/libyui-ncurses/src/NCIntField.cc new file mode 100644 index 0000000000000000000000000000000000000000..c2b86e85008f3531641e949e2367002ff65a4f95 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCIntField.cc @@ -0,0 +1,365 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCIntField.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCIntField.h" +#include "NCPopupTextEntry.h" +#include "stringutil.h" +#include "stdutil.h" + +using stdutil::numstring; + +const unsigned NCIntField::taglen = 2; // "^v" + + +NCIntField::NCIntField( YWidget * parent, + const std::string & nlabel, + int minV, int maxV, + int initialV ) + : YIntField( parent, nlabel, + minV <= maxV ? minV : maxV, + maxV >= minV ? maxV : minV ) + , NCWidget( parent ) + , lwin( 0 ) + , twin( 0 ) + , cvalue( initialV ) + , vlen( 0 ) + , vstart( 0 ) +{ + // yuiDebug() << std::endl; + vlen = numstring( minValue() ).length(); + unsigned tmpval = numstring( maxValue() ).length(); + + if ( tmpval > vlen ) + vlen = tmpval; + + setLabel( nlabel ); + hotlabel = &label; + setValue( initialV ); +} + + +NCIntField::~NCIntField() +{ + delete lwin; + delete twin; + // yuiDebug() << std::endl; +} + + +int NCIntField::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCIntField::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCIntField::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YIntField::setEnabled( do_bv ); +} + + +void NCIntField::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCIntField::setDefsze() +{ + unsigned cols = vlen + taglen; + defsze = wsze( label.height() + 1, + label.width() < cols ? cols : label.width() ); +} + + +void NCIntField::wCreate( const wrect & newrect ) +{ + NCWidget::wCreate( newrect ); + + if ( !win ) + return; + + wrect lrect( 0, wsze::min( newrect.Sze, + wsze( label.height(), newrect.Sze.W ) ) ); + + wrect trect( 0, wsze( 1, newrect.Sze.W ) ); + + if ( lrect.Sze.H == newrect.Sze.H ) + lrect.Sze.H -= 1; + + trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; + + lwin = new NCursesWindow( *win, + lrect.Sze.H, lrect.Sze.W, + lrect.Pos.L, lrect.Pos.C, + 'r' ); + + twin = new NCursesWindow( *win, + trect.Sze.H, trect.Sze.W, + trect.Pos.L, trect.Pos.C, + 'r' ); + + //vstart = ( vlen + 2 < (unsigned) trect.Sze.W ) ? label.width() - vlen - 2 : 0; + vstart = 0; + // vstart is calculated from label width only if value length (+ tags) is smaller + // than window width AND smaller than label width, otherwise start with 0 + // (bug #488757) + if ( vlen + 2 < (unsigned) trect.Sze.W && vlen + 2 < label.width() ) + { + vstart = label.width() - vlen - 2; + } +} + + +void NCIntField::wDelete() +{ + delete lwin; + delete twin; + lwin = 0; + twin = 0; + NCWidget::wDelete(); + vstart = 0; +} + + +void NCIntField::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + setDefsze(); + YIntField::setLabel( nlabel ); + Redraw(); +} + + +void NCIntField::setValueInternal( int newValue ) +{ + // checking newValue is done by YIntField + // -> no checks required + cvalue = newValue; + tUpdate(); +} + + +bool NCIntField::Increment( bool bigstep ) +{ + unsigned dist = maxValue() - cvalue; + + if ( !dist ) + return false; + + unsigned step = bigstep ? 10 : 1; + + if ( step < dist ) + setValue( cvalue + step ); + else + setValue( maxValue() ); + + return true; +} + + +bool NCIntField::Decrement( bool bigstep ) +{ + unsigned dist = cvalue - minValue(); + + if ( !dist ) + return false; + + unsigned step = bigstep ? 10 : 1; + + if ( step < dist ) + setValue( cvalue - step ); + else + setValue( minValue() ); + + return true; +} + + +void NCIntField::wRedraw() +{ + if ( !win ) + return; + + // label + const NCstyle::StWidget & style( widgetStyle( true ) ); + + lwin->bkgd( style.plain ); + + lwin->clear(); + + label.drawAt( *lwin, style ); + + tUpdate(); +} + + +void NCIntField::tUpdate() +{ + if ( !win ) + return; + + const NCstyle::StWidget & style( widgetStyle() ); + + twin->bkgd( widgetStyle( true ).plain ); + + twin->bkgdset( style.data ); + + twin->printw( 0, vstart, " %*d ", vlen, cvalue ); + + twin->bkgdset( style.scrl ); + + twin->addch( 0, vstart, + ( cvalue != minValue() ? ACS_DARROW : ' ' ) ); + + twin->addch( 0, vstart + vlen + 1, + ( cvalue != maxValue() ? ACS_UARROW : ' ' ) ); +} + + +NCursesEvent NCIntField::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + bool beep = false; + int ovlue = cvalue; + + switch ( key ) + { + case KEY_UP: + beep = !Increment(); + break; + + case KEY_DOWN: + beep = !Decrement(); + break; + + case KEY_PPAGE: + beep = !Increment( true ); + break; + + case KEY_NPAGE: + beep = !Decrement( true ); + break; + + case KEY_HOME: + + if ( cvalue != maxValue() ) + setValue( maxValue() ); + else + beep = true; + break; + + case KEY_END: + if ( cvalue != minValue() ) + setValue( minValue() ); + else + beep = true; + break; + + case L'0': + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + case L'-': + enterPopup( key ); + break; + + case L'+': + enterPopup(); + break; + + case KEY_HOTKEY: + break; + + default: + beep = true; + break; + } + + if ( beep ) + ::beep(); + + if ( notify() && ovlue != cvalue ) + ret = NCursesEvent::ValueChanged; + + return ret; +} + + +int NCIntField::enterPopup( wchar_t first ) +{ + std::wstring wch( &first ); + std::string utf8; + + wpos at( ScreenPos() + wpos( win->maxy() - 1, vstart + 1 ) ); + std::string label( std::string( "[" ) + numstring( minValue() ) + + "," + numstring( maxValue() ) + "]" ); + + std::string text( 1, (char) first ); + NCPopupTextEntry * dialog = new NCPopupTextEntry( at, label, text, vlen, 0, + NCInputField::NUMBER ); + YUI_CHECK_NEW( dialog ); + + while ( dialog->post() != -1 ) + { + int nval = atoi( dialog->value().c_str() ); + + if ( nval < minValue() ) + { + dialog->setValue( numstring( minValue() ) ); + } + else if ( maxValue() < nval ) + { + dialog->setValue( numstring( maxValue() ) ); + } + else + { + setValue( nval ); + break; + } + + ::beep(); + } + + YDialog::deleteTopmostDialog(); + + return 0; +} diff --git a/deps/libyui/libyui-ncurses/src/NCIntField.h b/deps/libyui/libyui-ncurses/src/NCIntField.h new file mode 100644 index 0000000000000000000000000000000000000000..53fb34c26d18241e8df79571b16fe2b68b307672 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCIntField.h @@ -0,0 +1,104 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCIntField.h + + Author: Michael Andres + +/-*/ + +#ifndef NCIntField_h +#define NCIntField_h + +#include + +#include +#include "NCWidget.h" + + +class NCIntField : public YIntField, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCIntField & obj ); + + NCIntField & operator=( const NCIntField & ); + NCIntField( const NCIntField & ); + + + static const unsigned taglen; + + NClabel label; + NCursesWindow * lwin; + NCursesWindow * twin; + + int cvalue; + unsigned vlen; + unsigned vstart; + + void setDefsze(); + void tUpdate(); + +protected: + + virtual const char * location() const { return "NCIntField"; } + + virtual void wCreate( const wrect & newrect ); + virtual void wDelete(); + + virtual void wRedraw(); + + bool Increment( bool bigstep = false ); + bool Decrement( bool bigstep = false ); + + int enterPopup( wchar_t first = L'\0' ); + +public: + + NCIntField( YWidget * parent, + const std::string & label, + int minValue, int maxValue, + int initialValue ); + virtual ~NCIntField(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setValueInternal( int newValue ); + + virtual int value() { return cvalue; } + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCIntField_h diff --git a/deps/libyui/libyui-ncurses/src/NCItemSelector.cc b/deps/libyui/libyui-ncurses/src/NCItemSelector.cc new file mode 100644 index 0000000000000000000000000000000000000000..7b9a31ef5472ad9f5f49d0926146db6aef3eec32 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCItemSelector.cc @@ -0,0 +1,686 @@ +/* + Copyright (C) 2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCItemSelector.cc + + Author: Stefan Hundhammer + +/-*/ + +#include +#include +#include + +#define YUILogComponent "ncurses" +#include +#include "NCItemSelector.h" +#include "YNCursesUI.h" + +using std::string; +using std::vector; + + + +NCItemSelectorBase::NCItemSelectorBase( YWidget * parent, bool enforceSingleSelection ) + : YItemSelector( parent, enforceSingleSelection ) + , NCPadWidget( parent ) + , _prefSize( 50, 5 ) // width, height + , _prefSizeDirty( true ) + , _selectorWidth( string( "|[x] |" ).size() ) +{ + // yuiDebug() << endl; + InitPad(); +} + + +NCItemSelectorBase::NCItemSelectorBase( YWidget * parent, + const YItemCustomStatusVector & customStates ) + : YItemSelector( parent, customStates ) + , NCPadWidget( parent ) + , _prefSize( 50, 5 ) // width, height + , _prefSizeDirty( true ) + , _selectorWidth( 0 ) +{ + // yuiDebug() << endl; + InitPad(); + + // Find the longest text indicator + + for ( int i=0; i < customStatusCount(); ++i ) + { + int len = customStatus( i ).textIndicator().size(); + + if ( _selectorWidth < len ) + _selectorWidth = len; + } + + _selectorWidth += string( "| |" ).size(); +} + + +NCItemSelectorBase::~NCItemSelectorBase() +{ + // yuiDebug() << endl; +} + + +NCPad * NCItemSelectorBase::CreatePad() +{ + wsze psze( defPadSze() ); + NCTablePad * npad = new NCTablePad( psze.H, psze.W, *this ); + npad->bkgd( listStyle().item.plain ); + npad->SetSepChar( ' ' ); + npad->AssertMinCols( 2 ); + npad->SetHotCol( 1 ); + + return npad; +} + + +int NCItemSelectorBase::preferredWidth() +{ + return preferredSize().W; +} + + +int NCItemSelectorBase::preferredHeight() +{ + return preferredSize().H; +} + + +wsze NCItemSelectorBase::preferredSize() +{ + if ( _prefSizeDirty ) + { + const int minHeight = 5; // 2 frame lines + 3 lines for content + const int minWidth = 20; + int visibleItemsCount = std::min( itemsCount(), visibleItems() ); + + _prefSize.W = 0; + _prefSize.H = 0; + + for ( int i=0; i < visibleItemsCount; ++i ) + { + if ( _prefSize.H > i ) // need a separator line? + ++_prefSize.H; // for the separator line + + ++_prefSize.H; // For the item label + + vector lines = descriptionLines( itemAt( i ) ); + _prefSize.H += lines.size(); + + for ( const string & line: lines ) // as wide as the longest line + _prefSize.W = std::max( _prefSize.W, (int) line.size() + _selectorWidth ); + } + + _prefSize.H += 2; // for the frame lines + _prefSize.W = std::max( _prefSize.W, minWidth ); + _prefSize.H = std::max( _prefSize.H, minHeight ); + _prefSizeDirty = false; + } + + return _prefSize; +} + + +void NCItemSelectorBase::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +bool NCItemSelectorBase::setKeyboardFocus() +{ + if ( ! grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; +} + + +void NCItemSelectorBase::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YItemSelector::setEnabled( do_bv ); +} + + +void NCItemSelectorBase::setVisibleItems( int newVal ) +{ + _prefSizeDirty = true; + YItemSelector::setVisibleItems( newVal ); +} + + +YItem * NCItemSelectorBase::currentItem() const +{ + if ( !myPad()->Lines() ) + return 0; + + NCTableTag * tag = tagCell( currentLine() ); + + return tag ? tag->origItem() : 0; +} + + +void NCItemSelectorBase::setCurrentItem( YItem * item ) +{ + int lineNo = findItemLine( item ); + + if ( lineNo >= 0 ) + myPad()->ScrlLine( lineNo ); +} + + +void NCItemSelectorBase::addItem( YItem * item ) +{ + if ( item ) + { + YItemSelector::addItem( item ); + createItemWidget( item ); + } +} + + +void NCItemSelectorBase::createItemWidget( YItem * item ) +{ + if ( item ) + { + vector cells( 2U, 0 ); + + _prefSizeDirty = true; + int lineNo = myPad()->Lines(); + + if ( lineNo > 0 ) + { + // Add a blank line as a separator from the previous item + // + // ...but only if there is any previous item that had a description. + // If there are only items without description, we don't need separator lines. + + cells[0] = new NCTableCol( "", NCTableCol::SEPARATOR ); + cells[1] = new NCTableCol( "", NCTableCol::SEPARATOR ); + myPad()->Append( cells, lineNo ); + ++lineNo; + } + + // yuiDebug() << "Adding new item " << item->label() << " at line #" << lineNo << endl; + + // Add the item label with "[ ]" or "( )" for selection + + cells[0] = createTagCell( item ); + cells[1] = new NCTableCol( item->label() ); + + cells[1]->stripHotkey(); + + NCTableLine * tableLine = new NCTableLine( cells, lineNo ); + myPad()->Append( tableLine ); + + if ( enforceSingleSelection() && item->selected() ) + myPad()->ScrlLine( lineNo ); + + ++lineNo; + + // Add the item description (possible multi-line) + + vector lines = descriptionLines( item ); + + for ( const string & line: lines ) + { + cells[0] = new NCTableCol( "", NCTableCol::PLAIN ); + cells[1] = new NCTableCol( line, NCTableCol::PLAIN ); + myPad()->Append( cells, lineNo ); + ++lineNo; + } + } +} + + +NCTableTag * NCItemSelectorBase::tagCell( int index ) const +{ + NCTableLine * tableLine = myPad()->ModifyLine( index ); + + if ( ! tableLine ) + return 0; + + return dynamic_cast ( tableLine->GetCol( 0 ) ); +} + + +int NCItemSelectorBase::findItemLine( YItem * wantedItem ) const +{ + for ( int lineNo = 0; lineNo < (int) myPad()->Lines(); ++lineNo ) + { + NCTableTag * tag = tagCell( lineNo ); + + if ( tag && tag->origItem() == wantedItem ) + return lineNo; + } + + return -1; +} + + +string NCItemSelectorBase::description( YItem * item ) const +{ + string desc; + + if ( item ) + { + YDescribedItem * descItem = dynamic_cast( item ); + + if ( descItem ) + desc = descItem->description(); + } + + return desc; +} + + +vector +NCItemSelectorBase::descriptionLines( YItem * item ) const +{ + vector lines; + + // This temporary variable is only needed to work around a bug in older boost versions: + // https://github.com/boostorg/algorithm/commit/c6f784cb + + string desc = description( item ); + boost::split( lines, desc, boost::is_any_of( "\n" ) ); + + return lines; +} + + +void NCItemSelectorBase::deleteAllItems() +{ + YItemSelector::deleteAllItems(); + myPad()->ClearTable(); + DrawPad(); +} + + +void NCItemSelectorBase::selectItem( YItem *item, bool selected ) +{ + if ( item ) + { + YItemSelector::selectItem( item, selected ); + + NCTableTag * tag = (NCTableTag *) item->data(); + YUI_CHECK_PTR( tag ); + + tag->SetSelected( selected ); + + DrawPad(); + } +} + + +void NCItemSelectorBase::deselectAllItems() +{ + YItemSelector::deselectAllItems(); + + for ( int i = 0; i < linesCount(); i++ ) + { + NCTableTag * tag = tagCell( i ); + + if ( tag ) + tag->SetSelected( false ); + } + + DrawPad(); +} + + +YItem * +NCItemSelectorBase::scrollDownToNextItem() +{ + YItem * item = 0; + + while ( currentLine() < linesCount() - 1 ) + { + YItem * item = currentItem(); + + if ( item ) + return item; + + // yuiDebug() << "Scrolling down" << endl; + myPad()->ScrlDown(); + } + + if ( ! item ) // That was the last one + item = scrollUpToPreviousItem(); + + return item; +} + + +YItem * +NCItemSelectorBase::scrollUpToPreviousItem() +{ + while ( true ) + { + YItem * item = currentItem(); + + if ( item ) + return item; + + if ( currentLine() == 0 ) + return 0; + + // yuiDebug() << "Scrolling up" << endl; + myPad()->ScrlUp(); + } + + /**NOTREACHED**/ + return 0; +} + + +NCursesEvent +NCItemSelectorBase::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + YItem * changedItem = 0; + YItem * curItem = currentItem(); + + switch ( key ) + { + case KEY_SPACE: + case KEY_RETURN: // Cycle item status and stay on this item + + if ( ! curItem ) + curItem = scrollUpToPreviousItem(); + + if ( curItem ) + { + cycleCurrentItemStatus(); + changedItem = curItem; + } + + break; + + + case '+': // Select this item and go to the next item + + if ( ! curItem ) + curItem = scrollUpToPreviousItem(); + + if ( curItem && + curItem->status() != 1 && + statusChangeAllowed( curItem->status(), 1 ) ) + { + cycleCurrentItemStatus(); + changedItem = curItem; + } + + if ( ! enforceSingleSelection() ) + { + myPad()->ScrlDown(); + curItem = scrollDownToNextItem(); + } + + break; + + + case '-': // Deselect this item and go to the next item + + if ( ! curItem ) + curItem = scrollUpToPreviousItem(); + + if ( curItem && + curItem->status() > 0 && + statusChangeAllowed( curItem->status(), 0 ) ) + { + setItemStatus( curItem, 0 ); + changedItem = curItem; + } + + if ( ! enforceSingleSelection() ) + { + myPad()->ScrlDown(); + curItem = scrollDownToNextItem(); + } + + break; + + // Those keys have different meanings in this widget: + // Scroll up and down by item, not by line. + + case KEY_UP: // Scroll up one item + myPad()->ScrlUp(); + scrollUpToPreviousItem(); + break; + + case KEY_DOWN: // Scroll down one item + myPad()->ScrlDown(); + scrollDownToNextItem(); + break; + + case KEY_END: // Scroll to the last item + myPad()->ScrlToLastLine(); + // We want to be on the last item, not on the last line + scrollUpToPreviousItem(); + break; + + // The Home key (scroll to the first item) is handled in the base + // class: Since the first is on the first line, so we can simply let + // the base class scroll to the first line. + + + // We would have liked to use KEY_SHIFT_UP and KEY_SHIFT_DOWN for + // scrolling up or down by line rather by item, but unfortunately + // NCurses does not support that at all; there are no predefined keys + // for any of that (but oddly enough KEY_SLEFT and KEY_SRIGHT for + // shifted arrow left or right), and there is no way to query the + // status of the modifier keys. + // + // See also /usr/include/ncurses/ncurses.h . + // + // There are lots of articles on StackOverflow etc. about this topic, + // but there is not a single portable solution; not even portable + // between the various terminal emulators (xterm, KDE konsole, + // gnome-terminal, xfce4-terminal) or the Linux console, let alone all + // the various other terminal types out there. + // + // So we have to resort to different keys. Not sure how many users will + // even realize that, but maybe some users actually try to use + // 'vi'-like keys like 'j' or 'k'. + + case 'j': // For 'vi' fans: Scroll down one line + myPad()->ScrlDown(); + break; + + case 'k': // For 'vi' fans: Scroll up one line + myPad()->ScrlUp(); + break; + + case KEY_HOTKEY: + + changedItem = curItem; + curItem = findItemWithHotkey( _hotKey ); + + if ( curItem ) + { + setCurrentItem( curItem ); + + if ( ! changedItem ) + changedItem = curItem; + + cycleCurrentItemStatus(); + } + + break; + + default: + handleInput( key ); // Call base class input handler + break; + } + + if ( notify() && changedItem ) + ret = valueChangedNotify( changedItem ); + + return ret; +} + + +void NCItemSelectorBase::activateItem( YItem * item ) +{ + if ( notify() ) + { + NCursesEvent event = valueChangedNotify( item ); + event.selection = (YMenuItem *) item; + event.widget = this; + + YNCursesUI::ui()->sendEvent( event ); + } +} + + +void NCItemSelectorBase::shortcutChanged() +{ + // Any of the items might have its keyboard shortcut changed, but we don't + // know which one. So let's simply re-create the widgets again. + + myPad()->ClearTable(); + + for ( YItemIterator it = itemsBegin(); it != itemsEnd(); ++it ) + { + createItemWidget( *it ); + } + + DrawPad(); +} + + +bool NCItemSelectorBase::HasHotkey( int key ) +{ + if ( ! findItemWithHotkey( key ) ) + return false; + + _hotKey = key; + + return true; +} + + +// ---------------------------------------------------------------------- + + + +NCItemSelector::NCItemSelector( YWidget * parent, bool enforceSingleSelection ) + : NCItemSelectorBase( parent, enforceSingleSelection ) +{ + // yuiDebug() << endl; +} + + +NCItemSelector::~NCItemSelector() +{ + // yuiDebug() << endl; +} + + +NCTableTag * +NCItemSelector::createTagCell( YItem * item ) +{ + NCTableTag * tag = new NCTableTag( item, item->selected(), enforceSingleSelection() ); + YUI_CHECK_NEW( tag ); + + return tag; +} + + +NCursesEvent +NCItemSelector::valueChangedNotify( YItem * item ) +{ + if ( enforceSingleSelection() && item && item->selected() ) + deselectAllItemsExcept( item ); + + yuiDebug() << "Sending ValueChanged event for " << (YItemSelector* ) this << endl; + + return NCursesEvent::ValueChanged; +} + + +void NCItemSelector::cycleCurrentItemStatus() +{ + YItem *item = currentItem(); + + if ( item ) + { + if ( enforceSingleSelection() ) + { + selectItem( item, true ); + deselectAllItemsExcept( item ); + } + else // Multi-selection + { + selectItem( item, !( item->selected() ) ); + } + } +} + + +bool NCItemSelector::statusChangeAllowed( int fromStatus, int toStatus ) +{ + if ( fromStatus == toStatus ) // No use setting to the same status as before + return false; + + if ( toStatus < 0 || toStatus > 1 ) + return false; + + if ( enforceSingleSelection() ) + return toStatus == 1; // Allow only setting 0 -> 1 + else + return true; +} + + +void NCItemSelector::deselectAllItemsExcept( YItem * exceptItem ) +{ + for ( YItemIterator it = itemsBegin(); it != itemsEnd(); ++it ) + { + if ( *it != exceptItem ) + { + (*it)->setSelected( false ); + NCTableTag * tag = (NCTableTag *) (*it)->data(); + + if ( tag ) + tag->SetSelected( false ); + } + } + + DrawPad(); +} + + +YItem* NCItemSelectorBase::findItemWithHotkey( int key ) const +{ + for ( YItemConstIterator it = itemsBegin(); it != itemsEnd(); it++ ) + { + NClabel label = NCstring( (*it)->label() ); + label.stripHotkey(); + + if ( label.hasHotkey() && tolower( label.hotkey() ) == tolower( key ) ) + return *it; + } + + return nullptr; +} diff --git a/deps/libyui/libyui-ncurses/src/NCItemSelector.h b/deps/libyui/libyui-ncurses/src/NCItemSelector.h new file mode 100644 index 0000000000000000000000000000000000000000..021fb076e345d9b6612c837dfe5303497c75666d --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCItemSelector.h @@ -0,0 +1,360 @@ +/* + Copyright (C) 2019 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCItemSelector.h + + Author: Stefan Hundhammer + +/-*/ + +#ifndef NCItemSelector_h +#define NCItemSelector_h + +#include +#include +#include + +#include +#include "NCPadWidget.h" +#include "NCTablePad.h" + + +class NCItemSelectorBase : public YItemSelector, public NCPadWidget +{ + friend std::ostream & operator<<( std::ostream & str, const NCItemSelectorBase & obj ); + +protected: + + /** + * Standard constructor. + **/ + NCItemSelectorBase( YWidget * parent, bool enforceSingleSelection ); + + /** + * Constructor for custom item status values. + **/ + NCItemSelectorBase( YWidget * parent, + const YItemCustomStatusVector & customStates ); + +public: + + /** + * Destructor. + **/ + virtual ~NCItemSelectorBase(); + + /** + * Handle keyboard input. + **/ + virtual NCursesEvent wHandleInput( wint_t key ); + + /** + * Return the preferred width for this widget. + * Reimplemented from YWidget. + **/ + virtual int preferredWidth(); + + /** + * Return the preferred height for this widget. + * Reimplemented from YWidget. + **/ + virtual int preferredHeight(); + + /** + * Set the size of this widget. + * Reimplemented from YWidget. + **/ + virtual void setSize( int newWidth, int newHeight ); + + /** + * Return the current item, i.e. the item that currently has the keyboard + * focus. Not to be confused with the selected item. + **/ + virtual YItem * currentItem() const; + + /** + * Set the current item, i.e. the item that currently has the keyboard + * focus. + **/ + virtual void setCurrentItem( YItem * item ); + + /** + * Enable or disable this widget. + * Reimplemented from YWidget. + **/ + virtual void setEnabled( bool do_bv ); + + /** + * Set the keyboard focus to this widget. + * Reimplemented from YWidget. + **/ + virtual bool setKeyboardFocus(); + + /** + * Set the number of visible items for this widget. + * Reimplemented from YItemSelector. + **/ + virtual void setVisibleItems( int newVal ); + + /** + * Return the number of lines in this widget. This is different from the + * number of items because each item always has one line for the item + * label, optionally multiple lines for the description, and optionally a + * separator line between it and the next item. + **/ + int linesCount() const { return (int) myPad()->Lines(); } + + /** + * Return number of the current line, i.e. the line that has the keyboard + * focus. + **/ + int currentLine() const { return myPad()->CurPos().L; } + + /** + * Add an item to this widget. + * Reimplemented from YSelectionWidget. + **/ + virtual void addItem( YItem * item ); + + /** + * Delete all items. + * Reimplemented from YSelectionWidget. + **/ + virtual void deleteAllItems(); + + /** + * Select or deselect an item. + * Reimplemented from YSelectionWidget. + **/ + virtual void selectItem( YItem * item, bool selected ); + + /** + * Deselect all items. + **/ + virtual void deselectAllItems(); + + /** + * Return the text line with the specified line number. Notice that this is + * different from the item index (see getNumLines()). + **/ + const NCTableLine * getLine( int lineNo ) { return myPad()->GetLine( lineNo ); } + + + virtual void startMultipleChanges() { startMultidraw(); } + + virtual void doneMultipleChanges() { stopMultidraw(); } + + virtual const char * location() const { return "NCItemSelectorBase"; } + + /** + * Activate selected item. Can be used in tests to simulate user input. + **/ + virtual void activateItem( YItem * item ); + + /** + * Notification that some shortcut was changed. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void shortcutChanged(); + + /** + * Whether any item has the given hot-key . + * Reimplemented from NCWidget. + **/ + virtual bool HasHotkey( int key ) ; + +protected: + + /** + * Create a widget for the given item. + **/ + void createItemWidget( YItem * item ); + + /** + * Create a tag cell for an item. This is the cell with the "[x]" or "(x)" + * selector. It also stores the item pointer so the item can later be + * referenced by this tag. + * + * Derived classes are required to implement this. + **/ + virtual NCTableTag * createTagCell( YItem * item ) = 0; + + /** + * Cycle the status of the current item through its possible values. + * For a plain ItemSelector, this means true -> false -> true. + * + * Derived classes are required to implement this. + **/ + virtual void cycleCurrentItemStatus() = 0; + + /** + * Return 'true' if a status change (by user interaction) from status + * 'fromStatus' to status 'toStatus' is allowed, 'false' if not. + **/ + virtual bool statusChangeAllowed( int fromStatus, int toStatus ) + { return false; } + + /** + * Notification that a status value was just changed in the input handler + * and the 'notify' flag is set. The returned event is used as the return + * value of the input handler (unless it has event type 'none' which is + * also returned by the default constructor of NCursesEvent), i.e. it is + * sent to the application. + * + * Derived classes are required to implement this. + **/ + virtual NCursesEvent valueChangedNotify( YItem * item ) = 0; + + /** + * Return the desription text for an item. The result may contain newlines. + **/ + std::string description( YItem * item ) const; + + /** + * Return the description text for an item as multiple lines. + **/ + std::vector descriptionLines( YItem * item ) const; + + /** + * If the cursor is not on the first line of an item (the line with the + * "[x]" selector), scroll down to the next line that is the first line of + * an item. + **/ + YItem * scrollDownToNextItem(); + + /** + * If the cursor is not on the first line of an item (the line with the + * "[x]" selector), scroll up to the next line that is the first line of + * an item. + **/ + YItem * scrollUpToPreviousItem(); + + /** + * Return the preferred size for this widget. + **/ + virtual wsze preferredSize(); + + /** + * Return the tag cell (the cell with the "[x]" or "(x)" selector) for the + * item with the specified index. + **/ + virtual NCTableTag * tagCell( int index ) const; + + /** + * Return the line number that contains the first line of 'item' + * or -1 if not found. + **/ + int findItemLine( YItem * item ) const; + + /** + * Create the pad for this widget. + **/ + virtual NCPad * CreatePad(); + + /** + * Return the pad for this widget; overloaded to narrow the type. + */ + virtual NCTablePad * myPad() const + { return dynamic_cast( NCPadWidget::myPad() ); } + + virtual void wRecoded() { NCPadWidget::wRecoded(); } + +private: + + // Disable assignment operator and copy constructor + + NCItemSelectorBase & operator=( const NCItemSelectorBase & ); + NCItemSelectorBase( const NCItemSelectorBase & ); + + YItem* findItemWithHotkey( int key ) const; + +protected: + + // Data members + + wsze _prefSize; + bool _prefSizeDirty; + int _selectorWidth; + int _hotKey; + + +}; // class NCItemSelectorBase + + + +class NCItemSelector: public NCItemSelectorBase +{ +public: + /** + * Constructor. + **/ + NCItemSelector( YWidget * parent, bool enforceSingleSelection ); + + /** + * Destructor. + **/ + virtual ~NCItemSelector(); + + virtual const char * location() const { return "NCItemSelector"; } + +protected: + + /** + * Create a tag cell for an item. This is the cell with the "[x]" or "(x)" + * selector. It also stores the item pointer so the item can later be + * referenced by this tag. + **/ + virtual NCTableTag * createTagCell( YItem * item ); + + /** + * Notification that a status value was just changed in the input handler + * and the 'notify' flag is set. + **/ + virtual NCursesEvent valueChangedNotify( YItem * item ); + + /** + * Cycle the status of the current item through its possible values. + * For a plain ItemSelector, this means true -> false -> true. + **/ + virtual void cycleCurrentItemStatus(); + + /** + * Return 'true' if a status change (by user interaction) from status + * 'fromStatus' to status 'toStatus' is allowed, 'false' if not. + **/ + virtual bool statusChangeAllowed( int fromStatus, int toStatus ); + + /** + * Deselect all items except the specified one. This is used for single + * selection. + **/ + void deselectAllItemsExcept( YItem * exceptItem ); + + +private: + + // Disable assignment operator and copy constructor + + NCItemSelector & operator=( const NCItemSelector & ); + NCItemSelector( const NCItemSelector & ); + +}; // class NCItemSelector + + +#endif // NCItemSelector_h diff --git a/deps/libyui/libyui-ncurses/src/NCLabel.cc b/deps/libyui/libyui-ncurses/src/NCLabel.cc new file mode 100644 index 0000000000000000000000000000000000000000..2f9a690e42909230336f5a4f6af59b2d6de830c9 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCLabel.cc @@ -0,0 +1,198 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCLabel.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCLabel.h" + +#define AUTO_WRAP_WIDTH 10 +#define AUTO_WRAP_HEIGHT 1 + +using std::string; + + +NCLabel::NCLabel( YWidget * parent, + const string & nlabel, + bool isHeading, + bool isOutputField ) + : YLabel( parent, nlabel, isHeading, isOutputField ) + , NCWidget( parent ) + , heading( isHeading ) +{ + // yuiDebug() << std::endl; + setText( nlabel ); + hotlabel = &label; + wstate = NC::WSdumb; +} + + +NCLabel::~NCLabel() +{ + // yuiDebug() << std::endl; +} + + +int NCLabel::preferredWidth() +{ + int width; + + if ( autoWrap() ) + { + if ( layoutPass() == 2 ) + { + // Use the width passed down to us from the parent layout manager + // in the last setSize() call. This is the definitive width that + // will be used after taking all other children of the layout into + // consideration, also including making widgets smaller due to size + // restrictions, or redistributing excess space. + // + // Since this widget can auto-wrap its contents, we accept + // basically any width; we just need to adapt the preferred height + // accordingly. + width = wrapper.lineWidth(); + } + else + { + // Use a preliminary width. Typically, this widget should be + // wrapped into a MinSize or MinWidth which hopefully gives us a + // much more useful width than this. + // + // We would also just use 0 here, but that would make debugging + // really hard since the widget might completly disappear. + // + // The real width that will be used will be set in the setSize() + // call following the recursive preferredWidth() / + // preferredHeight() calls in the widget tree. + width = AUTO_WRAP_WIDTH; + } + } + else // ! autoWrap() + { + width = wGetDefsze().W; + } + + return width; +} + + +int NCLabel::preferredHeight() +{ + int height; + + if ( autoWrap() ) + { + if ( layoutPass() == 2 ) + { + // This is where the magic happens: + // + // setSize() in the first layout pass gave us the real width which + // we stored in as the wrapper's lineWidth. We can now let the + // wrapper wrap the text into that width and calculate the height + // (the number of lines of the wrapped text) that is really needed + // based on that width. + height = wrapper.lines(); + label = NCstring( wrapper.wrappedText() ); + } + else + { + height = AUTO_WRAP_HEIGHT; + } + } + else // ! autoWrap() + { + height = wGetDefsze().H; + } + + return height; +} + + +void NCLabel::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YLabel::setEnabled( do_bv ); +} + + +void NCLabel::setSize( int newWidth, int newHeight ) +{ + if ( autoWrap() && layoutPass() == 1 ) + wrapper.setLineWidth( newWidth ); + + wRelocate( wpos( 0 ), wsze( newHeight, newWidth ) ); +} + + +void NCLabel::setText( const string & newLabel ) +{ + label = NCstring( newLabel ); + defsze = label.size(); + YLabel::setText( newLabel ); + Redraw(); +} + + +void NCLabel::wRedraw() +{ + if ( !win ) + return; + + chtype bg = heading ? wStyle().dumb.title + : wStyle().dumb.text; + + win->bkgd( bg ); + win->clear(); + + if ( autoWrap() ) + label = NCstring( wrapper.wrappedText() ); + + label.drawAt( *win, bg, bg ); +} + + +void NCLabel::setAutoWrap( bool autoWrap ) +{ + YLabel::setAutoWrap( autoWrap ); + + if ( autoWrap ) + { + wrapper.setText( NCstring( text() ).str() ); + // Delay setting 'label' until the line width for wrapping is set + } + else + { + // This will probably never happen since the default for autoWrap is + // 'false' and nobody will ever set an auto-wrapping label back to + // non-autowrapping programatically. + // + // But anyway, just in case: Let's revert the values to the initial + // defaults. + + label = NCstring( text() ); + defsze = label.size(); + wrapper.clear(); + } +} + diff --git a/deps/libyui/libyui-ncurses/src/NCLabel.h b/deps/libyui/libyui-ncurses/src/NCLabel.h new file mode 100644 index 0000000000000000000000000000000000000000..f68f1a4738d5634a183d6894305c47c5d0832b23 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCLabel.h @@ -0,0 +1,78 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCLabel.h + + Author: Michael Andres + +/-*/ + +#ifndef NCLabel_h +#define NCLabel_h + +#include + +#include +#include "NCWidget.h" +#include "NCWordWrapper.h" + +class NCLabel; + + +class NCLabel : public YLabel, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCLabel & obj ); + + NCLabel & operator=( const NCLabel & ); + NCLabel( const NCLabel & ); + + + bool heading; + NClabel label; + NCWordWrapper wrapper; + +protected: + + virtual const char * location() const { return "NCLabel"; } + + virtual void wRedraw(); + +public: + + NCLabel( YWidget * parent, + const std::string & text, + bool isHeading = false, + bool isOutputField = false ); + + virtual ~NCLabel(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setText( const std::string & nlabel ); + + virtual void setEnabled( bool do_bv ); + virtual void setAutoWrap( bool autoWrap = true ); +}; + + +#endif // NCLabel_h diff --git a/deps/libyui/libyui-ncurses/src/NCLayoutBox.cc b/deps/libyui/libyui-ncurses/src/NCLayoutBox.cc new file mode 100644 index 0000000000000000000000000000000000000000..98e29afc0243fe7a72dfe1526cc8c6baa5ddedd0 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCLayoutBox.cc @@ -0,0 +1,72 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCLayoutBox.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCLayoutBox.h" + + +NCLayoutBox::NCLayoutBox( YWidget * parent, + YUIDimension dimension ) + : YLayoutBox( parent, dimension ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; +} + + +NCLayoutBox::~NCLayoutBox() +{ + // yuiDebug() << std::endl; +} + + +void NCLayoutBox::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); + YLayoutBox::setSize( newwidth, newheight ); +} + + +void NCLayoutBox::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YLayoutBox::setEnabled( do_bv ); +} + + +void NCLayoutBox::moveChild( YWidget * child, int newx, int newy ) +{ + NCWidget * cw = dynamic_cast( child ); + + if ( !( cw && IsParentOf( *cw ) ) ) + { + yuiError() << DLOC << cw << " is not my child" << std::endl; + return; + } + + wMoveChildTo( *cw, wpos( newy, newx ) ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCLayoutBox.h b/deps/libyui/libyui-ncurses/src/NCLayoutBox.h new file mode 100644 index 0000000000000000000000000000000000000000..7150e73dc090f55375ae694a829e64b8ca4a559d --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCLayoutBox.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCLayoutBox.h + + Author: Michael Andres + +/-*/ + +#ifndef NCLayoutBox_h +#define NCLayoutBox_h + +#include + +#include +#include "NCWidget.h" + +class NCLayoutBox; + + +class NCLayoutBox : public YLayoutBox, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCLayoutBox & obj ); + + NCLayoutBox & operator=( const NCLayoutBox & ); + NCLayoutBox( const NCLayoutBox & ); + + +protected: + + virtual const char * location() const + { + return primary() == YD_HORIZ ? "NC(H)LayoutBox" : "NC(V)LayoutBox" ; + } + +public: + + NCLayoutBox( YWidget * parent, YUIDimension dimension ); + virtual ~NCLayoutBox(); + + virtual int preferredWidth() { return YLayoutBox::preferredWidth(); } + virtual int preferredHeight() { return YLayoutBox::preferredHeight(); } + + virtual void setSize( int newWidth, int newHeight ); + + virtual void moveChild( YWidget * child, int newx, int newy ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCLayoutBox_h diff --git a/deps/libyui/libyui-ncurses/src/NCLogView.cc b/deps/libyui/libyui-ncurses/src/NCLogView.cc new file mode 100644 index 0000000000000000000000000000000000000000..d63bf0a744455999ffd200869b99a9dfad864931 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCLogView.cc @@ -0,0 +1,160 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCLogView.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCLogView.h" + + +NCLogView::NCLogView( YWidget * parent, + const std::string & nlabel, + int visibleLines, + int maxLines ) + : YLogView( parent, nlabel, visibleLines, maxLines ) + , NCPadWidget( parent ) +{ + // yuiDebug() << std::endl; + defsze = wsze( visibleLines, 5 ) + 2; + setLabel( nlabel ); +} + + +NCLogView::~NCLogView() +{ + // yuiDebug() << std::endl; +} + + +int NCLogView::preferredWidth() +{ + defsze.W = ( 5 > labelWidth() ? 5 : labelWidth() ) + 2; + return wGetDefsze().W; +} + + +int NCLogView::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCLogView::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YLogView::setEnabled( do_bv ); +} + + +void NCLogView::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCLogView::setLabel( const std::string & nlabel ) +{ + YLogView::setLabel( nlabel ); + NCPadWidget::setLabel( NCstring( nlabel ) ); +} + + +void NCLogView::displayLogText( const std::string & ntext ) +{ + DelPad(); + text = NCtext( NCstring( ntext ), Columns() ); + Redraw(); +} + + +void NCLogView::wRedraw() +{ + if ( !win ) + return; + + bool initial = ( !myPad() || !myPad()->Destwin() ); + + if ( myPad() ) + myPad()->bkgd( listStyle().item.plain ); + + NCPadWidget::wRedraw(); + + if ( initial ) + myPad()->ScrlTo( wpos( text.Lines(), 0 ) ); +} + + +void NCLogView::wRecoded() +{ + DelPad(); + wRedraw(); +} + + +NCursesEvent NCLogView::wHandleInput( wint_t key ) +{ + handleInput( key ); + return NCursesEvent::none; +} + + +NCPad * NCLogView::CreatePad() +{ + wsze psze( defPadSze() ); + NCPad * npad = new NCPad( psze.H, psze.W, *this ); + npad->bkgd( listStyle().item.plain ); + return npad; +} + + +void NCLogView::DrawPad() +{ + // maximal value for lines is 32000! + unsigned maxLines = 20000; + unsigned skipLines = 0; + unsigned lines = text.Lines(); + unsigned cl = 0; + + if ( lines > maxLines ) + { + skipLines = lines - maxLines; + lines = maxLines; + } + + AdjustPad( wsze( lines, Columns() ) ); + + for ( NCtext::const_iterator line = text.begin(); line != text.end(); ++line ) + { + if ( skipLines == 0 ) + { + myPad()->move( cl++, 0 ); + std::wstring cline = ( *line ).str(); + myPad()->addwstr( cline.c_str() ); + } + else + { + skipLines--; + } + } +} + diff --git a/deps/libyui/libyui-ncurses/src/NCLogView.h b/deps/libyui/libyui-ncurses/src/NCLogView.h new file mode 100644 index 0000000000000000000000000000000000000000..021792f6d2dea3665a9b108f38fa2114df3162b2 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCLogView.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCLogView.h + + Author: Michael Andres + +/-*/ + +#ifndef NCLogView_h +#define NCLogView_h + +#include + +#include +#include "NCPadWidget.h" + + +class NCLogView : public YLogView, public NCPadWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCLogView & obj ); + + NCLogView & operator=( const NCLogView & ); + NCLogView( const NCLogView & ); + + + NCtext text; + +protected: + + virtual const char * location() const { return "NCLogView"; } + + virtual void wRedraw(); + virtual void wRecoded(); + + virtual NCPad * CreatePad(); + virtual void DrawPad(); + +public: + + NCLogView( YWidget * parent, + const std::string & label, + int visibleLines, + int maxLines ); + virtual ~NCLogView(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + virtual void displayLogText( const std::string & ntext ); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } +}; + + +#endif // NCLogView_h diff --git a/deps/libyui/libyui-ncurses/src/NCMenuBar.cc b/deps/libyui/libyui-ncurses/src/NCMenuBar.cc new file mode 100644 index 0000000000000000000000000000000000000000..0f930ee75a6aba8cd1eb0443e3a00426541c7bdc --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMenuBar.cc @@ -0,0 +1,403 @@ +/* + Copyright (C) 2020 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMenuBar.cc + + Author: Jose Iván López + +/-*/ + + +#include + +#define YUILogComponent "ncurses" +#include +#include "NCMenuBar.h" +#include "YNCursesUI.h" +#include "NCPopupMenu.h" + + +// Margin to the left of the first toplevel item +#define LEFT_MARGIN 0 + +// Spacing between toplevel items +#define SPACING 2 + + +// Helper class that represents a top level menu +struct NCMenuBar::Menu +{ + wpos position; + YMenuItem* item; + + + // Whether the menu can be selected + bool isSelectable() const + { + if ( ! item ) + return false; + + return item->isEnabled(); + } + + + // Whether the menu contains the given hot-key + bool hasHotkey( int key ) const + { + NClabel label = NCstring( item->label() ); + label.stripHotkey(); + + if ( ! label.hasHotkey() ) + return false; + + return tolower( key ) == tolower( label.hotkey() ); + } + +}; + + +NCMenuBar::NCMenuBar( YWidget* parent ) : + YMenuBar( parent ), NCWidget( parent ), _menus() +{ + defsze = wsze( 1, 10 ); +} + + +NCMenuBar::~NCMenuBar() +{ + clear(); +} + + +void +NCMenuBar::clear() +{ + for ( Menu* menu : _menus ) + delete menu; + + _menus.clear(); + + defsze = wsze( 1, 10 ); +} + + +void +NCMenuBar::rebuildMenuTree() +{ + clear(); + + int width = LEFT_MARGIN; + + for ( YItemIterator it = itemsBegin(); it != itemsEnd(); ++it ) + { + YMenuItem * item = dynamic_cast(*it); + YUI_CHECK_PTR( item ); + + if ( ! item->isMenu() ) + YUI_THROW( YUIException( "NCMenuBar: Only menus allowed on toplevel. ") ); + + if ( ! item->isVisible() ) + continue; + + Menu * menu = new Menu(); + menu->item = item; + menu->position = wpos( 0, width ); + + _menus.add( menu ); + item->setUiItem( menu ); + + NClabel label( NCstring( menu->item->label() ) ); + label.stripHotkey(); + + width += label.width() + SPACING; + } + + selectNextMenu(); + + defsze = wsze( 1, width ); +} + + +void +NCMenuBar::wRedraw() +{ + if ( !win ) + return; + + for ( const Menu * menu : _menus ) + { + const NCstyle::StWidget & style = menuStyle( menu ); + + win->bkgdset( style.plain ); + + NClabel label( NCstring( menu->item->label() ) ); + label.stripHotkey(); + + label.drawAt( *win, style, menu->position, wsze( -1, label.width() + SPACING ), NC::LEFT ); + } + + if ( defsze.W < win->width() ) { + const NCstyle::StWidget & bkg_style( widgetStyle( true ) ); + + win->move( 0, defsze.W ); + win->bkgdset( bkg_style.plain ); + win->clrtoeol(); + } +} + + +NCursesEvent +NCMenuBar::postMenu() +{ + wpos at(ScreenPos() + wpos( 1, selectedMenu()->position.C) ); + + NCPopupMenu * dialog = new NCPopupMenu( + at, + selectedMenu()->item->childrenBegin(), + selectedMenu()->item->childrenEnd() + ); + + YUI_CHECK_NEW( dialog ); + + NCursesEvent event; + dialog->post( &event ); + + YDialog::deleteTopmostDialog(); + + return handlePostMenu( event ); +} + + +void +NCMenuBar::setItemEnabled( YMenuItem * item, bool enabled ) +{ + YMenuWidget::setItemEnabled( item, enabled ); + rebuildMenuTree(); + wRedraw(); +} + + +void +NCMenuBar::setItemVisible( YMenuItem * item, bool visible ) +{ + YMenuWidget::setItemVisible( item, visible ); + rebuildMenuTree(); + wRedraw(); +} + + +void +NCMenuBar::activateItem( YMenuItem * item ) +{ + if ( item->isMenu() || item->isSeparator() ) + return; + + NCursesEvent event = NCursesEvent::menu; + + event.widget = this; + event.selection = item; + + YNCursesUI::ui()->sendEvent( event ); +} + + +NCursesEvent +NCMenuBar::wHandleInput( wint_t key ) +{ + NCursesEvent event = NCursesEvent::none; + + switch ( key ) + { + case KEY_LEFT: + selectPreviousMenu(); + wRedraw(); + break; + + case KEY_RIGHT: + selectNextMenu(); + wRedraw(); + break; + + case KEY_BACKSPACE: + wRedraw(); + break; + + case KEY_DOWN: + case KEY_SPACE: + case KEY_RETURN: + event = postMenu(); + break; + + default: + event = NCWidget::wHandleInput(key); + break; + } + + return event; +} + + +int +NCMenuBar::preferredWidth() +{ + return defsze.W; +} + + +int +NCMenuBar::preferredHeight() +{ + return 1; +} + + +void +NCMenuBar::setSize( int newWidth, int newHeight ) +{ + wRelocate( wpos( 0 ), wsze( newHeight, newWidth ) ); +} + + +void +NCMenuBar::setEnabled( bool enabled ) +{ + NCWidget::setEnabled( enabled ); + YMenuBar::setEnabled( enabled ); +} + + +bool +NCMenuBar::setKeyboardFocus() +{ + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; +} + + +bool +NCMenuBar::HasHotkey( int key ) +{ + if( key < 0 || UCHAR_MAX < key ) + return false; + + return findMenuWithHotkey( key ) != _menus.end(); +} + + +NCursesEvent +NCMenuBar::wHandleHotkey( wint_t key ) +{ + CyclicContainer::Iterator menu = findMenuWithHotkey( key ); + + if ( menu == _menus.end() ) + return NCursesEvent::none; + + _menus.setCurrent( menu ); + + wRedraw(); + return postMenu(); +} + + +void +NCMenuBar::shortcutChanged() +{ + // Any of the items might have its keyboard shortcut changed, but we don't + // know which one. So let's simply redraw the widget again. + + wRedraw(); +} + + +NCursesEvent +NCMenuBar::handlePostMenu( const NCursesEvent & event ) +{ + NCursesEvent newEvent = NCursesEvent::none; + + if ( event == NCursesEvent::button ) + { + newEvent = NCursesEvent::menu; + newEvent.selection = event.selection; + } + else if ( event == NCursesEvent::key ) + { + if ( event.keySymbol == "CursorLeft" ) + { + wHandleInput( KEY_LEFT ); + newEvent = wHandleInput( KEY_DOWN ); + } + else if ( event.keySymbol == "CursorRight" ) + { + wHandleInput( KEY_RIGHT ); + newEvent = wHandleInput( KEY_DOWN ); + } + else if ( event.keySymbol == "BackSpace" ) + { + newEvent = wHandleInput( KEY_BACKSPACE ); + } + else if ( event.keySymbol == "Hotkey" ) + { + newEvent = wHandleHotkey( event.detail ); + } + } + + return newEvent; +} + + +NCMenuBar::Menu * +NCMenuBar::selectedMenu() +{ + return *_menus.current(); +} + + +void +NCMenuBar::selectNextMenu() +{ + _menus.setCurrent( _menus.next() ); +} + + +void +NCMenuBar::selectPreviousMenu() +{ + _menus.setCurrent( _menus.previous() ); +} + + +CyclicContainer::Iterator +NCMenuBar::findMenuWithHotkey( wint_t key ) +{ + return std::find_if( _menus.begin(), _menus.end(), [key](Menu * menu) { + return menu->hasHotkey( key ); + }); +} + + +const NCstyle::StWidget & +NCMenuBar::menuStyle( const Menu * menu ) +{ + if ( !menu->item->isEnabled() ) + return wStyle().getWidget( NC::WSdisabled ); + + bool non_active = ( menu != selectedMenu() ); + return widgetStyle( non_active ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCMenuBar.h b/deps/libyui/libyui-ncurses/src/NCMenuBar.h new file mode 100644 index 0000000000000000000000000000000000000000..afae37632dba09fd30757586f38bab44686d14c4 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMenuBar.h @@ -0,0 +1,207 @@ +/* + Copyright (C) 2020 SUSE LLC + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMenuBar.h + + Author: Jose Iván López + +/-*/ + + +#ifndef NCMenuBar_h +#define NCMenuBar_h + +#include +#include "NCWidget.h" +#include "CyclicContainer.h" + +class NCMenuBar: public YMenuBar, public NCWidget +{ +public: + /** + * Constructor. + **/ + NCMenuBar( YWidget * parent ); + + /** + * Destructor. + **/ + virtual ~NCMenuBar(); + + /** + * Rebuild the displayed menu tree from the internally stored YMenuItems. + * + * Implemented from YMenuWidget. + **/ + virtual void rebuildMenuTree(); + + /** + * Enable or disable an item. + * + * Reimplemented from YMenuWidget. + **/ + virtual void setItemEnabled( YMenuItem * item, bool enabled ); + + /** + * show or hide an item. + * + * Reimplemented from YMenuWidget. + **/ + virtual void setItemVisible( YMenuItem * item, bool visible ); + + /** + * Support for the Rest API for UI testing: + * + * Activate the item selected in the tree. + * This can be used in tests to simulate user input. + * + * Implemented from YMenuWidget. + **/ + virtual void activateItem( YMenuItem * item ); + + /** + * Handle keyboard input. + * Reimplemented from NCWidget. + **/ + virtual NCursesEvent wHandleInput( wint_t key ); + + /** + * Return the preferred width for this widget. + * Reimplemented from YWidget. + **/ + virtual int preferredWidth(); + + /** + * Return the preferred height for this widget. + * Reimplemented from YWidget. + **/ + virtual int preferredHeight(); + + /** + * Set the size of this widget. + * Reimplemented from YWidget. + **/ + virtual void setSize( int newWidth, int newHeight ); + + /** + * Enable or disable this widget. + * Reimplemented from YWidget. + **/ + virtual void setEnabled( bool enabled ); + + /** + * Set the keyboard focus to this widget. + * Reimplemented from YWidget. + **/ + virtual bool setKeyboardFocus(); + + /** + * Handle keyboard input. + * Reimplemented from NCWidget. + **/ + virtual NCursesEvent wHandleHotkey( wint_t key ); + + /** + * Whether any menu option has the given hot-key . + * Reimplemented from NCWidget. + **/ + virtual bool HasHotkey( int key ) ; + + /** + * Notification that some shortcut was changed. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void shortcutChanged(); + +protected: + + /** + * Clear all content. + **/ + void clear(); + + virtual const char * location() const { return "NCMenuBar"; } + + /** + * Reimplemented from NCWidget. + **/ + virtual void wRedraw(); + + /** + * Open a menu dialog + * @return event from the menu dialog + **/ + NCursesEvent postMenu(); + +private: + + struct Menu; + + friend std::ostream & operator<<( std::ostream & str, + const NCMenuBar & obj ); + + // Disable assignment operator and copy constructor + + NCMenuBar & operator=( const NCMenuBar & ); + NCMenuBar( const NCMenuBar & ); + + /** Helper method to manage the menu dialog event + * @param event event from the menu dialog + * @return a new event + **/ + NCursesEvent handlePostMenu( const NCursesEvent & event ); + + /** Currently selected menu. + * @return selected menu + **/ + Menu * selectedMenu(); + + /** Select the next enabled menu option. + * @note When there is no selected menu, the first enabled one is selected. + **/ + void selectNextMenu(); + + /** Select the previous enabled menu. + * @note When there is no selected menu, the last enabled one is selected. + **/ + void selectPreviousMenu(); + + /** Find the menu with the given hot-key. + * @param key a hot-key + * @return the menu with the given hot-key. + **/ + CyclicContainer::Iterator findMenuWithHotkey( wint_t key ); + + /** Style to apply to the given menu + * The style depends on the status of the menu (enabled or disabled). + * @param menu a menu + * @return style to apply + **/ + const NCstyle::StWidget & menuStyle( const Menu * menu ); + + /** Container of menus + * It allows cyclic navigation between the menus. + * Note that this container holds pointers to menus, but it does not own the pointers. The pointers + * are owned by the NCMenuBar object. + **/ + CyclicContainer _menus; + +}; // NCMenuBar + +#endif // NCMenuBar_h diff --git a/deps/libyui/libyui-ncurses/src/NCMenuButton.cc b/deps/libyui/libyui-ncurses/src/NCMenuButton.cc new file mode 100644 index 0000000000000000000000000000000000000000..6ec81eae82cd99b73c4f8fdd29b6b5e2f1dad03f --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMenuButton.cc @@ -0,0 +1,172 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMenuButton.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCMenuButton.h" +#include "NCPopupMenu.h" +#include "YNCursesUI.h" + + +NCMenuButton::NCMenuButton( YWidget * parent, + std::string nlabel ) + : YMenuButton( parent, nlabel ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + setLabel( nlabel ); + hotlabel = &label; +} + + +NCMenuButton::~NCMenuButton() +{ + // yuiDebug() << std::endl; +} + + +int NCMenuButton::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCMenuButton::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCMenuButton::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YMenuButton::setEnabled( do_bv ); +} + + +void NCMenuButton::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +NCursesEvent NCMenuButton::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + + switch ( key ) + { + case KEY_HOTKEY: + case KEY_SPACE: + case KEY_RETURN: + case KEY_DOWN: + ret = postMenu(); + break; + } + + return ret; +} + + +void NCMenuButton::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + defsze = wsze( label.height(), label.width() + 3 ); + YMenuButton::setLabel( nlabel ); + Redraw(); +} + + +void NCMenuButton::wRedraw() +{ + if ( !win ) + return; + + const NCstyle::StWidget & style( widgetStyle() ); + + win->bkgdset( style.plain ); + + if ( label.height() > 1 ) + { + win->box( wrect( 0, win->size() - wsze( 0, 1 ) ) ); + } + + win->printw( 0, 0, "[" ); + + win->printw( 0, win->maxx(), "]" ); + + label.drawAt( *win, style, wpos( 0, 1 ), wsze( -1, win->width() - 3 ), + NC::CENTER ); + + win->bkgdset( style.scrl ); + win->vline( 0, win->maxx() - 1, win->height(), ' ' ); + haveUtf8() ? + win->add_wch( 0, win->maxx() - 1, WACS_DARROW ) + : win->addch( 0, win->maxx() - 1, ACS_DARROW ); +} + + +void NCMenuButton::rebuildMenuTree() +{ + // NOP +} + + +NCursesEvent NCMenuButton::postMenu() +{ + // Add fixed heigth of 1; + // dont't use win->height() because win might be invalid (bnc#931154) + wpos at( ScreenPos() + wpos( 1, 0 ) ); + + NCPopupMenu * dialog = new NCPopupMenu( at, + itemsBegin(), + itemsEnd() ); + YUI_CHECK_NEW( dialog ); + + NCursesEvent event; + dialog->post( &event ); + + YDialog::deleteTopmostDialog(); + + NCursesEvent newEvent = NCursesEvent::none; + + if ( event == NCursesEvent::button ) + { + newEvent = NCursesEvent::menu; + newEvent.selection = event.selection; + } + + return newEvent; +} + + +void NCMenuButton::activateItem( YMenuItem * item ) +{ + NCursesEvent event = NCursesEvent::menu; + event.widget = this; + event.selection = item; + YNCursesUI::ui()->sendEvent( event ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCMenuButton.h b/deps/libyui/libyui-ncurses/src/NCMenuButton.h new file mode 100644 index 0000000000000000000000000000000000000000..96efcfce54da4b371870df881dc306a63dbc0a72 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMenuButton.h @@ -0,0 +1,93 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMenuButton.h + + Author: Michael Andres + +/-*/ + +#ifndef NCMenuButton_h +#define NCMenuButton_h + +#include + +#include +#include "NCApplication.h" +#include "NCWidget.h" + + +class NCMenuButton : public YMenuButton, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCMenuButton & obj ); + + NCMenuButton & operator=( const NCMenuButton & ); + NCMenuButton( const NCMenuButton & ); + + NClabel label; + bool haveUtf8() { return YUI::app()->hasFullUtf8Support(); } + +protected: + + virtual const char * location() const { return "NCMenuButton"; } + + virtual void wRedraw(); + + NCursesEvent postMenu(); + +public: + + NCMenuButton( YWidget * parent, + std::string label ); + virtual ~NCMenuButton(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void rebuildMenuTree(); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setEnabled( bool do_bv ); + + YMenuItem * findItem( int selection ) { return findMenuItem( selection ); } + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + /** + * Activate the item selected in the tree. Can be used in tests to simulate + * user input. + **/ + virtual void activateItem( YMenuItem * item ); + +}; + + +#endif // NCMenuButton_h diff --git a/deps/libyui/libyui-ncurses/src/NCMultiLineEdit.cc b/deps/libyui/libyui-ncurses/src/NCMultiLineEdit.cc new file mode 100644 index 0000000000000000000000000000000000000000..dbd1f38a9ab00cb90eb6a6a3ba7b3c7518625d05 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMultiLineEdit.cc @@ -0,0 +1,140 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMultiLineEdit.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCMultiLineEdit.h" + + +NCMultiLineEdit::NCMultiLineEdit( YWidget * parent, const std::string & nlabel ) + : YMultiLineEdit( parent, nlabel ) + , NCPadWidget( parent ) +{ + // yuiDebug() << std::endl; + defsze = wsze( 5, 5 ) + wsze( 0, 2 ); + setLabel( nlabel ); +} + + +NCMultiLineEdit::~NCMultiLineEdit() +{ + // yuiDebug() << std::endl; +} + + +int NCMultiLineEdit::preferredWidth() +{ + defsze.W = ( 5 > labelWidth() ? 5 : labelWidth() ) + 2; + return wGetDefsze().W; +} + + +int NCMultiLineEdit::preferredHeight() +{ + return wGetDefsze().H; + //return YMultiLineEdit::defaultVisibleLines(); +} + + +void NCMultiLineEdit::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YMultiLineEdit::setEnabled( do_bv ); +} + + +void NCMultiLineEdit::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCMultiLineEdit::setLabel( const std::string & nlabel ) +{ + YMultiLineEdit::setLabel( nlabel ); + NCPadWidget::setLabel( NCstring( nlabel ) ); +} + + +void NCMultiLineEdit::setValue( const std::string & ntext ) +{ + DelPad(); + ctext = NCstring( ntext ); + Redraw(); +} + + +std::string NCMultiLineEdit::value() +{ + if ( myPad() ) + { + ctext = NCstring( myPad()->getText() ); + } + + return ctext.Str(); +} + + +void NCMultiLineEdit::wRedraw() +{ + if ( !win ) + return; + + NCPadWidget::wRedraw(); +} + + +NCursesEvent NCMultiLineEdit::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + handleInput( key ); + + if ( notify() ) + ret = NCursesEvent::ValueChanged; + + return ret; +} + + +NCPad * NCMultiLineEdit::CreatePad() +{ + wsze psze( defPadSze() ); + NCPad * npad = new NCTextPad( psze.H, psze.W, *this ); + npad->bkgd( listStyle().item.plain ); + + return npad; +} + + +void NCMultiLineEdit::DrawPad() +{ + myPad()->setText( ctext ); +} + + +void NCMultiLineEdit::setInputMaxLength( int numberOfChars ) +{ + myPad()->setInputMaxLength( numberOfChars ); + YMultiLineEdit::setInputMaxLength( numberOfChars ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCMultiLineEdit.h b/deps/libyui/libyui-ncurses/src/NCMultiLineEdit.h new file mode 100644 index 0000000000000000000000000000000000000000..227a95ddcd64963d53fec04449bff4f1aa67d0f6 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMultiLineEdit.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMultiLineEdit.h + + Author: Michael Andres + +/-*/ + +#ifndef NCMultiLineEdit_h +#define NCMultiLineEdit_h + +#include + +#include +#include "NCPadWidget.h" +#include "NCTextPad.h" + + +class NCMultiLineEdit : public YMultiLineEdit, public NCPadWidget +{ +private: + friend std::ostream & operator<<( std::ostream & str, const NCMultiLineEdit & obj ); + + NCMultiLineEdit & operator=( const NCMultiLineEdit & ); + NCMultiLineEdit( const NCMultiLineEdit & ); + + NCstring ctext; + +protected: + + /** + * Overload myPad to narrow the type + */ + virtual NCTextPad * myPad() const + { return dynamic_cast( NCPadWidget::myPad() ); } + +protected: + + virtual const char * location() const { return "NCMultiLineEdit"; } + + virtual void wRedraw(); + + virtual NCPad * CreatePad(); + virtual void DrawPad(); + +public: + + NCMultiLineEdit( YWidget * parent, const std::string & label ); + + virtual ~NCMultiLineEdit(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + virtual void setValue( const std::string & ntext ); + + virtual std::string value(); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + // sets the maximum number of characters of the NCTextPad + void setInputMaxLength( int numberOfChars ); + +}; + + +#endif // NCMultiLineEdit_h diff --git a/deps/libyui/libyui-ncurses/src/NCMultiSelectionBox.cc b/deps/libyui/libyui-ncurses/src/NCMultiSelectionBox.cc new file mode 100644 index 0000000000000000000000000000000000000000..2e6673b7bdd1c10fdf174d0630a629073b8b7e2f --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMultiSelectionBox.cc @@ -0,0 +1,280 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMultiSelectionBox.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCMultiSelectionBox.h" + + +NCMultiSelectionBox::NCMultiSelectionBox( YWidget * parent, + const std::string & nlabel ) + : YMultiSelectionBox( parent, nlabel ) + , NCPadWidget( parent ) +{ + // yuiDebug() << std::endl; + InitPad(); + setLabel( nlabel ); +} + + +NCMultiSelectionBox::~NCMultiSelectionBox() +{ + // yuiDebug() << std::endl; +} + + +int NCMultiSelectionBox::preferredWidth() +{ + wsze sze = wGetDefsze(); + return sze.W > (int) ( labelWidth() + 2 ) ? sze.W : ( labelWidth() + 2 ); +} + + +int NCMultiSelectionBox::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCMultiSelectionBox::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YMultiSelectionBox::setEnabled( do_bv ); +} + + +void NCMultiSelectionBox::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +YItem * NCMultiSelectionBox::currentItem() +{ + if ( !myPad()->Lines() ) + return 0; + + int index = myPad()->CurPos().L; + + return itemAt( index ); +} + + +void NCMultiSelectionBox::setCurrentItem( YItem * item ) +{ + if ( item ) + myPad()->ScrlLine( item->index() ); +} + + +void NCMultiSelectionBox::addItem( YItem * item ) +{ + std::vector cells( 2U, 0 ); + + if ( item ) + { + item->setIndex( itemsCount() ); + YMultiSelectionBox::addItem( item ); + cells[0] = new NCTableTag( item, item->selected() ); + + // Do not set style to NCTableCol::PLAIN here, otherwise the current + // item will not be highlighted if the cursor is not over the widget + + cells[1] = new NCTableCol( item->label() ); + myPad()->Append( cells, item->index() ); + DrawPad(); + } +} + + +/** + * Return pointer to current line tag + * (holds state and yitem pointer) + **/ +NCTableTag * NCMultiSelectionBox::tagCell( int index ) +{ + NCTableLine * cl = myPad()->ModifyLine( index ); + + if ( !cl ) + return 0; + + return static_cast( cl->GetCol( 0 ) ); +} + + +const NCTableTag * NCMultiSelectionBox::tagCell( int index ) const +{ + const NCTableLine * cl = myPad()->GetLine( index ); + + if ( !cl ) + return 0; + + return static_cast( cl->GetCol( 0 ) ); +} + + +void NCMultiSelectionBox::deleteAllItems() +{ + YMultiSelectionBox::deleteAllItems(); + myPad()->ClearTable(); + DrawPad(); +} + + +bool NCMultiSelectionBox::isItemSelected( YItem *item ) +{ + if ( item ) + return item->selected(); + else + return false; +} + + +void NCMultiSelectionBox::selectItem( YItem *yitem, bool selected ) +{ + if ( yitem ) + { + YMultiSelectionBox::selectItem( yitem, selected ); + + // retrieve pointer to the line tag associated with this item + NCTableTag * tag = (NCTableTag *) yitem->data(); + YUI_CHECK_PTR( tag ); + + tag->SetSelected( selected ); + + DrawPad(); + } +} + + +void NCMultiSelectionBox::deselectAllItems() +{ + YMultiSelectionBox::deselectAllItems(); + + for ( unsigned i = 0; i < getNumLines(); i++ ) + { + NCTableTag *t = tagCell( i ); + YUI_CHECK_PTR( t ); + + t->SetSelected( false ); + } + + DrawPad(); +} + + + +/** + * Toggle item from selected -> deselected and vice versa + **/ +void NCMultiSelectionBox::toggleCurrentItem() +{ + YItem *it = currentItem(); + if ( it ) + selectItem( it, !( it->selected() ) ); +} + + +void NCMultiSelectionBox::setLabel( const std::string & nlabel ) +{ + YMultiSelectionBox::setLabel( nlabel ); + NCPadWidget::setLabel( NCstring( nlabel ) ); +} + + +/** + * Create empty MsB pad + **/ +NCPad * NCMultiSelectionBox::CreatePad() +{ + wsze psze( defPadSze() ); + NCTablePad * npad = new NCTablePad( psze.H, psze.W, *this ); + npad->bkgd( listStyle().item.plain ); + npad->SetSepChar( ' ' ); + return npad; +} + + +void NCMultiSelectionBox::wRecoded() +{ + NCPadWidget::wRecoded(); +} + + +NCursesEvent NCMultiSelectionBox::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + bool valueChanged = false; + YItem *oldCurrentItem = currentItem(); + + if ( ! handleInput( key ) ) + { + YItem *citem = currentItem(); + + switch ( key ) + { + case KEY_SPACE: + + case KEY_RETURN: + toggleCurrentItem(); + valueChanged = true; + break; + + case '+': + + if ( !isItemSelected( citem ) ) + { + selectItem( citem, true ); + valueChanged = true; + } + + myPad()->ScrlDown(); + + break; + + case '-': + + if ( isItemSelected( citem ) ) + { + selectItem( citem, false ); + valueChanged = true; + } + + myPad()->ScrlDown(); + + break; + } + } + + if ( notify() ) + { + if ( valueChanged ) + ret = NCursesEvent::ValueChanged; + else if ( oldCurrentItem != currentItem() ) + ret = NCursesEvent::SelectionChanged; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses/src/NCMultiSelectionBox.h b/deps/libyui/libyui-ncurses/src/NCMultiSelectionBox.h new file mode 100644 index 0000000000000000000000000000000000000000..65aba5ee9131463d5ac36471c05d87774f2992e6 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCMultiSelectionBox.h @@ -0,0 +1,115 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCMultiSelectionBox.h + + Author: Michael Andres + +/-*/ + +#ifndef NCMultiSelectionBox_h +#define NCMultiSelectionBox_h + +#include + +#include +#include "NCPadWidget.h" +#include "NCTablePad.h" + + +class NCMultiSelectionBox : public YMultiSelectionBox, public NCPadWidget +{ + + friend std::ostream & operator<<( std::ostream & str, const NCMultiSelectionBox & obj ); + + NCMultiSelectionBox & operator=( const NCMultiSelectionBox & ); + NCMultiSelectionBox( const NCMultiSelectionBox & ); + +protected: + + /** + * Overload myPad to narrow the type + */ + virtual NCTablePad * myPad() const + { return dynamic_cast( NCPadWidget::myPad() ); } + + NCTableTag * tagCell( int index ); + const NCTableTag * tagCell( int index ) const; + + bool isItemSelected( YItem *item ); + + void toggleCurrentItem(); + +public: + + virtual void startMultipleChanges() { startMultidraw(); } + + virtual void doneMultipleChanges() { stopMultidraw(); } + + virtual const char * location() const { return "NCMultiSelectionBox"; } + + virtual void addItem( YItem * item ); + + virtual void deleteAllItems(); + + virtual void selectItem( YItem * item, bool selected ); + + virtual void deselectAllItems(); + +protected: + + virtual NCPad * CreatePad(); + virtual void wRecoded(); + + +public: + + NCMultiSelectionBox( YWidget * parent, const std::string & label ); + virtual ~NCMultiSelectionBox(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual YItem * currentItem(); + virtual void setCurrentItem( YItem * item ); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + unsigned getNumLines() { return myPad()->Lines(); } + + const NCTableLine * getLine( int index ) { return myPad()->GetLine( index ); } + + void clearItems() { return myPad()->ClearTable(); } +}; + + +#endif // NCMultiSelectionBox_h diff --git a/deps/libyui/libyui-ncurses/src/NCOptionalWidgetFactory.cc b/deps/libyui/libyui-ncurses/src/NCOptionalWidgetFactory.cc new file mode 100644 index 0000000000000000000000000000000000000000..af6a236fd45bad9b769806b40989fc88e3f4b37f --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCOptionalWidgetFactory.cc @@ -0,0 +1,88 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCOptionalWidgetFactory.cc + + Author: Gabriele Mohr + +/-*/ + +#include "NCOptionalWidgetFactory.h" +#include +#include "NCTimeField.h" +#include "NCDateField.h" + + +#define THROW_UNSUPPORTED( WIDGET_TYPE ) \ + YUI_THROW( YUIUnsupportedWidgetException( WIDGET_TYPE ) ); \ + return 0 + + +NCOptionalWidgetFactory::NCOptionalWidgetFactory() + : YOptionalWidgetFactory() +{ + // NOP +} + + +NCOptionalWidgetFactory::~NCOptionalWidgetFactory() +{ + // NOP +} + +bool NCOptionalWidgetFactory::hasDumbTab() +{ + return true; +} + +NCDumbTab * +NCOptionalWidgetFactory::createDumbTab( YWidget * parent ) +{ + NCDumbTab * dumbTab = new NCDumbTab( parent ); + YUI_CHECK_NEW( dumbTab ); + + return dumbTab; +} + +bool NCOptionalWidgetFactory::hasTimeField() +{ + return true; +} + +YTimeField* NCOptionalWidgetFactory::createTimeField( YWidget * parent, const std::string & label ) +{ + NCTimeField * timeField = new NCTimeField( parent, label ); + YUI_CHECK_NEW( timeField ); + + return timeField; +} + + +bool NCOptionalWidgetFactory::hasDateField() +{ + return true; +} + +YDateField* NCOptionalWidgetFactory::createDateField( YWidget * parent, const std::string & label ) +{ + NCDateField * dateField = new NCDateField( parent, label ); + YUI_CHECK_NEW( dateField ); + + return dateField; +} + diff --git a/deps/libyui/libyui-ncurses/src/NCOptionalWidgetFactory.h b/deps/libyui/libyui-ncurses/src/NCOptionalWidgetFactory.h new file mode 100644 index 0000000000000000000000000000000000000000..615aa1ca4840d75531c26f1238129e468a308d5f --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCOptionalWidgetFactory.h @@ -0,0 +1,83 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCOptionalWidgetFactory.h + + Author: Gabriele Mohr + +/-*/ + +#ifndef NCOptionalWidgetFactory_h + +#define NCOptionalWidgetFactory_h + +#include +#include "NCDumbTab.h" + +class YTimeField; +class YDateField; + +/** + * Widget factory for optional ("special") widgets. + * + * Remember to always check with the corresponding "has..()" method if the + * current UI actually provides the requested widget. Otherwise the + * "create...()" method will throw an exception. + **/ +class NCOptionalWidgetFactory: public YOptionalWidgetFactory +{ + +public: + + // + // Optional Widgets + // + + // Currently none for this UI + +protected: + + friend class YNCursesUI; + + /** + * Constructor. + * + * Use YUI::optionalWidgetFactory() to get the singleton for this class. + **/ + NCOptionalWidgetFactory(); + + /** + * Destructor. + **/ + virtual ~NCOptionalWidgetFactory(); + + bool hasDumbTab(); + + NCDumbTab *createDumbTab( YWidget * parent ); + + bool hasTimeField(); + YTimeField* createTimeField( YWidget * parent, const std::string & label ); + + bool hasDateField(); + YDateField* createDateField( YWidget * parent, const std::string & label ); + +}; // class NCOptionalWidgetFactory + + + +#endif // NCOptionalWidgetFactory_h diff --git a/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginIf.h b/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginIf.h new file mode 100644 index 0000000000000000000000000000000000000000..d9de6078c21de420a377708766306fc0f9156876 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginIf.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPackageSelectorPluginIf.h + + Author: Katharina Machalkova + + +/-*/ + +#ifndef NCPackageSelectorPluginIf_h +#define NCPackageSelectorPluginIf_h + +#include +#include +#include + +class NCPackageSelectorPluginIf +{ + +public: + + virtual ~NCPackageSelectorPluginIf() {} + + virtual YPackageSelector *createPackageSelector( YWidget *parent, long modeFlags ) = 0 ; + + virtual YEvent *runPkgSelection( YDialog *currentDialog, YWidget *packageSelector ) = 0; + + virtual YWidget *createPkgSpecial( YWidget *parent, const std::string &subwidget ) = 0; +}; + + +#endif diff --git a/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginStub.cc b/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginStub.cc new file mode 100644 index 0000000000000000000000000000000000000000..fe1f3a67a0043b7e9c421f7a2921e006959d8edf --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginStub.cc @@ -0,0 +1,81 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPackageSelectorPluginStub.cc + + Author: Hedgehog Painter + + +/-*/ + +#include "NCPackageSelectorPluginStub.h" + +#define YUILogComponent "ncurses-ui" +#include +#include "NCWidget.h" +#include "NCLabel.h" +#include "NCDialog.h" +#include "NCPackageSelectorPluginIf.h" +#include "YNCursesUI.h" // NCtoY2Event + +#define PLUGIN_BASE_NAME "ncurses-pkg" + + +NCPackageSelectorPluginStub::NCPackageSelectorPluginStub() + : YPackageSelectorPlugin( PLUGIN_BASE_NAME ) +{ + if ( success() ) + { + yuiMilestone() << "Loaded " << PLUGIN_BASE_NAME + << " plugin successfully from " << pluginLibFullPath() + << std::endl; + } + + + impl = ( NCPackageSelectorPluginIf* ) locateSymbol( "PSP" ); + + if ( !impl ) + YUI_THROW( YUIPluginException( PLUGIN_BASE_NAME ) ); + +} + + +NCPackageSelectorPluginStub::~NCPackageSelectorPluginStub() +{ + // NOP +} + + +YPackageSelector * NCPackageSelectorPluginStub::createPackageSelector( YWidget * parent, + long modeFlags ) +{ + return impl->createPackageSelector( parent, modeFlags ); +} + + +YWidget * NCPackageSelectorPluginStub::createPkgSpecial( YWidget *parent, const std::string &subwidget ) +{ + return impl->createPkgSpecial( parent, subwidget ); +} + + +YEvent * NCPackageSelectorPluginStub::runPkgSelection( YDialog * dialog, + YWidget * selector ) +{ + return impl->runPkgSelection( dialog, selector ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginStub.h b/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginStub.h new file mode 100644 index 0000000000000000000000000000000000000000..5b0063ac7acb497cece8acca2f1a3b9634702607 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPackageSelectorPluginStub.h @@ -0,0 +1,81 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPackageSelectorPluginStub.h + + Author: Katharina Machalkova + +/-*/ + +#ifndef NCPackageSelectorPluginStub_h +#define NCPackageSelectorPluginStub_h + +#include +#include +#include + +#include "NCPackageSelectorPluginIf.h" + +/** + * Simplified access to the ncurses UI's package selector plugin. + **/ + +class NCPackageSelectorPluginIf; + +class NCPackageSelectorPluginStub: public YPackageSelectorPlugin +{ +public: + + /** + * Constructor: Load the plugin library for the NCurses package selector. + **/ + NCPackageSelectorPluginStub(); + + /** + * Destructor. Calls dlclose() which will unload the plugin library if it + * is no longer used, i.e. if the reference count dlopen() uses reaches 0. + **/ + virtual ~NCPackageSelectorPluginStub(); + + /** + * Create a package selector. + * Implemented from YPackageSelectorPlugin. + * + * This might return 0 if the plugin lib could not be loaded or if the + * appropriate symbol could not be located in the plugin lib. + **/ + virtual YPackageSelector * createPackageSelector( YWidget * parent, + long modeFlags ); + + /** + * Fills the PackageSelector widget (runs the package selection). + */ + virtual YEvent * runPkgSelection( YDialog *currentDialog, + YWidget * packageSelector ); + + /** + * Create a special widget + */ + virtual YWidget * createPkgSpecial( YWidget *parent, + const std::string &subwidget ); + + NCPackageSelectorPluginIf *impl ; +}; + + +#endif // NCPackageSelectorPluginStub_h diff --git a/deps/libyui/libyui-ncurses/src/NCPad.cc b/deps/libyui/libyui-ncurses/src/NCPad.cc new file mode 100644 index 0000000000000000000000000000000000000000..5808f201b854c1fa77f92b9e19b49c2bb4304ac9 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPad.cc @@ -0,0 +1,217 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPad.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPad.h" + + +// PAD_PAGESIZE needs to be large enough to feed any destwin. We +// get in throuble here if the terminal has more than 1024 lines. +#define PAD_PAGESIZE 1024 + +// Maximum height of the NCursesPad (e.g. in case it can't hold more +// than 32768 lines). Larger pads need to page. +//#define MAX_PAD_HEIGHT 100 +#define MAX_PAD_HEIGHT NCursesWindow::maxcoord() + + +NCPad::NCPad( int lines, int cols, const NCWidget & p ) + : NCursesPad( lines > MAX_PAD_HEIGHT ? PAD_PAGESIZE : lines, cols ) + , _vheight( lines > MAX_PAD_HEIGHT ? lines : 0 ) + , parw( p ) + , destwin ( 0 ) + , maxdpos ( 0 ) + , maxspos ( 0 ) + , dclear ( false ) + , dirty ( false ) +{} + + +void NCPad::Destwin( NCursesWindow * dwin ) +{ + if ( dwin != destwin ) + { + destwin = dwin; + + if ( destwin ) + { + wsze mysze( vheight(), width() ); + + drect = wrect( 0, wsze( destwin->height(), destwin->width() ) ); + srect = wrect( 0, wsze::min( mysze, drect.Sze ) ); + maxdpos = drect.Pos + srect.Sze - 1; + maxspos = mysze - srect.Sze; + + dclear = ( drect.Sze != srect.Sze ); + setpos( CurPos() ); + } + else + { + drect = srect = wrect(); + maxdpos = maxspos = 0; + } + } +} + + +void NCPad::resize( wsze nsze ) +{ + SetPadSize( nsze ); // might be enlarged by NCPadWidget if redirected + + if ( nsze.H != vheight() + || nsze.W != width() ) + { + NCursesWindow * odest = Destwin(); + + if ( odest ) + Destwin( 0 ); + + if ( nsze.H > MAX_PAD_HEIGHT ) + { + // yuiDebug() << "TRUNCATE PAD: " << nsze.H << " > " << MAX_PAD_HEIGHT << std::endl; + NCursesPad::resize( PAD_PAGESIZE, nsze.W ); + _vheight = nsze.H; + } + else + { + NCursesPad::resize( nsze.H, nsze.W ); + _vheight = 0; + } + + // yuiDebug() << "Pageing ?: " << paging() << std::endl; + + if ( odest ) + Destwin( odest ); + } +} + + +void NCPad::updateScrollHint() +{ + NCScrollHint::VSet( srect.Sze.H + maxspos.L, srect.Sze.H, srect.Pos.L ); + NCScrollHint::HSet( srect.Sze.W + maxspos.C, srect.Sze.W, srect.Pos.C ); +} + + +int NCPad::update() +{ + if ( destwin ) + { + if ( dirty ) + { + return dirtyPad(); + } + + if ( dclear ) + destwin->clear(); + + updateScrollHint(); + + if ( ! paging() ) + { + return copywin( *destwin, + srect.Pos.L, srect.Pos.C, + drect.Pos.L, drect.Pos.C, + maxdpos.L, maxdpos.C, + false /* are blanks transparent */); + } + + // Here: Table is paging, so we must prepare the visible lines + // on the Pad before we're copying them to the destwin: + wsze lSze( 1, width() ); + for ( int i = 0; i <= maxdpos.L; ++i ) + { + directDraw( *this, wrect( wpos( i, 0 ), lSze ), srect.Pos.L+i ); + } + return copywin( *destwin, + 0, srect.Pos.C, + drect.Pos.L, drect.Pos.C, + maxdpos.L, maxdpos.C, + false ); + } + return OK; +} + + +int NCPad::setpos( const wpos & newpos ) +{ + srect.Pos = newpos.between( 0, maxspos ); + return update(); +} + + +void NCPad::wRecoded() +{ + // yuiDebug() << "NCPad::wRecoded" << std::endl; +} + + +bool NCPad::handleInput( wint_t key ) +{ + bool handled = true; + + switch ( key ) + { + case KEY_UP: + ScrlUp(); + break; + + case KEY_PPAGE: + ScrlUp( destwin->maxy() ); + break; + + case KEY_HOME: + ScrlUp( vheight() ); + break; + + case KEY_DOWN: + ScrlDown(); + break; + + case KEY_NPAGE: + ScrlDown( destwin->maxy() ); + break; + + case KEY_END: + ScrlDown( vheight() ); + break; + + case KEY_LEFT: + case KEY_SLEFT: + ScrlLeft(); + break; + + case KEY_RIGHT: + case KEY_SRIGHT: + ScrlRight(); + break; + + default: + handled = false; + break; + } + + return handled; +} diff --git a/deps/libyui/libyui-ncurses/src/NCPad.h b/deps/libyui/libyui-ncurses/src/NCPad.h new file mode 100644 index 0000000000000000000000000000000000000000..4372ce5b6764416eab1e0b54ec5eb01df06c2a71 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPad.h @@ -0,0 +1,246 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPad.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPad_h +#define NCPad_h + +#include + +#include "NCurses.h" +#include "NCWidget.h" + + +//! Interface for scroll callbacks +class NCSchrollCB +{ +public: + + virtual ~NCSchrollCB() {} + + /// @param total virtual size + /// @param visible size of the visible part + /// @param start position of the visible part + virtual void HScroll( unsigned total, unsigned visible, unsigned start ) {} + + /// @param total virtual size + /// @param visible size of the visible part + /// @param start position of the visible part + virtual void VScroll( unsigned total, unsigned visible, unsigned start ) {} + + virtual void ScrollHead( NCursesWindow & w, unsigned ccol ) {} + + virtual void AdjustPadSize( wsze & minsze ) {} +}; + +/** + * Forward the scroll callbacks to another object. + * By default it forwards to itself + */ +class NCScrollHint : protected NCSchrollCB +{ +private: + + NCSchrollCB * redirect; + +protected: + + NCScrollHint() : redirect( this ) {} + + virtual ~NCScrollHint() {} + +protected: + + virtual void SetHead( NCursesWindow & w, unsigned ccol ) + { + redirect->ScrollHead( w, ccol ); + } + + void VSet( unsigned total, unsigned visible, unsigned start ) + { + redirect->VScroll( total, visible, start ); + } + + void HSet( unsigned total, unsigned visible, unsigned start ) + { + redirect->HScroll( total, visible, start ); + } + + virtual void SetPadSize( wsze & minsze ) + { + redirect->AdjustPadSize( minsze ); + } + +public: + + //! Set the receiver of callbacks to *dest* + void SendSchrollCB( NCSchrollCB * dest ) { redirect = ( dest ? dest : this ); } + + virtual void SendHead() {} +}; + + +/// A virtual window with a real viewport (which is NCursesWindow) +/// and a scrolling mechanism. +/// +/// In the underlying C ncurses library, a *pad* is a virtual window without a +/// position. Of course that is not very useful without any way to display it +/// so there's a prefresh() function to draw a portion of that pad into a +/// visible "viewport" window. Our NCursesPad fork just directly forwards to +/// prefresh() without remembering the window. Upstream NCursesPad does know a +/// viewport window and so does NCPad (*destwin*). +class NCPad : public NCursesPad, public NCScrollHint +{ +private: + + /** The real height in case the NCursesPad is truncated, otherwise \c 0. + * + * \note Don't use _vheight directly, but \ref vheight. + * + * Up to ncurses5, ncurses uses \c short for window dimensions (can't hold + * more than 32768 lines). If \ref resize truncated the window, the real + * size is in \ref _vheight. Longer lists need to be paged. + * + * \todo Once all NCPad based types are able to page, \a maxPadHeight could be + * std::set to e.g \c 1024 to avoid bigger widgets in memory. Currently just + * \ref NCTablePad supports paging. If paging is \c ON, all content lines are + * written via \ref directDraw. Without paging \ref DoRedraw is reponsible for this. + */ + int _vheight; + +protected: + + const NCWidget & parw; + + NCursesWindow * destwin; ///< Where to draw us (may be nullptr, not owned) + ///< Destination rectangle: (Pos is always 0, 0) + wrect drect; + wrect srect; ///< Source rectangle: the visible part of this pad + wpos maxdpos; + wpos maxspos; + + bool dclear; ///< should destwin be cleared before contents is copied there + bool dirty; + + /** The (virtual) height of the Pad (even if truncated). */ + int vheight() const { return _vheight ? _vheight : height(); } + + /** Whether the Pad is truncated (we're paging). */ + bool paging() const { return _vheight; } + + virtual int dirtyPad() { dirty = false; return setpos( CurPos() ); } + + /// Set the visible position to *newpos* (but clamp by *maxspos*), then \ref update. + virtual int setpos( const wpos & newpos ); + + /// Adjust CurPos relatively by *offset* + int adjpos( const wpos & offset ) + { + return setpos( CurPos() + offset ); + } + + virtual void updateScrollHint(); + + /** Directly draw a table item at a specific location. + * + * \ref update usually copies the visible table content from the + * \ref NCursesPad to \ref destwin. In case the \ref NCursesPad + * is truncated, the visible lines are prepared immediately before + * they are written to \ref destwin + * . + * \see \ref _vheight. + */ + virtual void directDraw( NCursesWindow & w, const wrect at, unsigned lineno ) {} + +public: + + /// @param p (used just for styling info, NOT sizing) + NCPad( int lines, int cols, const NCWidget & p ); + virtual ~NCPad() {} + +public: + + NCursesWindow * Destwin() { return destwin; } + + /// @param dwin (not owned) + virtual void Destwin( NCursesWindow * dwin ); + + virtual void resize( wsze nsze ); + // OMFG this little overload does something completely different than + // the one above + virtual int resize( int lines, int columns ) { return NCursesWindow::resize(lines, columns );} + virtual void wRecoded(); + virtual void setDirty() { dirty = true; } + + int update(); + virtual int setpos() { return setpos( CurPos() ); } + + virtual wpos CurPos() const { return srect.Pos; } + + int ScrlTo( const wpos & newpos ) + { + return setpos( newpos ); + } + + /// Scroll to a line, keeping the column + int ScrlLine( int line ) + { + return setpos( wpos( line, srect.Pos.C ) ); + } + + /// Scroll to a column, keeping the line + int ScrlCol( int col ) + { + return setpos( wpos( srect.Pos.L, col ) ); + } + + int ScrlDown( int lines = 1 ) + { + return adjpos( wpos( lines, 0 ) ); + } + + int ScrlUp( int lines = 1 ) + { + return adjpos( wpos( -lines, 0 ) ); + } + + int ScrlRight( int cols = 1 ) + { + return adjpos( wpos( 0, cols ) ); + } + + int ScrlLeft( int cols = 1 ) + { + return adjpos( wpos( 0, -cols ) ); + } + + int ScrlToLastLine() + { + return ScrlDown( vheight() ); + } + + virtual bool handleInput( wint_t key ); +}; + + +#endif // NCPad_h diff --git a/deps/libyui/libyui-ncurses/src/NCPadWidget.cc b/deps/libyui/libyui-ncurses/src/NCPadWidget.cc new file mode 100644 index 0000000000000000000000000000000000000000..90b2ff0aaa550efd4b7e92e18ac8489d06e74acf --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPadWidget.cc @@ -0,0 +1,559 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPadWidget.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPadWidget.h" + +/** + * Scrollbar indicator. + * + * It's a dumb indicator: it does not react to keyboard events (class FIXME + * does it instead) + * + * Appearance details: + * + * Suppose we have a horizontal scrollbar 10 cells wide: ~~===~~~~~ + * The visible part of the scrolled contents is indicated by the BAR, + * here 3 cells wide. (The bar is also known as "slider", "puck", "elevator") + * + * Unlike in GUIs we have no arrows at the ends of the scrollbar because we + * can't read the mouse clicks anyway. + * + * If the scrollbar gets shrunk to size 1 or 2, it is drawn with arrows + * meaning there is something in the pointed direction. + * + */ +class NCScrollbar +{ +public: + + enum orientation { HORZ, VERT }; + +private: + + chtype ch_forward; //!< draw an arrow pointing down/right + chtype ch_backward; //!< draw an arrow pointing up/left + chtype ch_barbeg; //!< draw the top/left end of the bar (elevator) + chtype ch_barend; //!< draw the bottom/right end of the bar (elavator) + chtype ch_barone; //!< draw a bar (elevator) that has the smallest visible length of 1 + + const NCWidget & parw; //!< parent widget + NCursesWindow * win; //!< where this indicator draws itself + orientation type; //!< horizontal or vertical + unsigned len; //!< the length of this indicator in cells + + unsigned total; //!< 0 to total is the virtual size + unsigned visible; //!< size of the visible part + unsigned at; //!< position of the visible part + +private: + + // Clamp *visible* and *at* so that visible <= visible + at <= total + void adjust() + { + if ( visible > total ) + { + // yuiDebug() << "adjust visible " << visible << " > total " << total << std::endl; + visible = total; + } + + if ( at + visible > total ) + { + // yuiDebug() << "adjust at " << at << " + visible " << visible << " > total " << total << std::endl; + at = total - visible; + } + } + + // line starting at *p*, length *l* + void draw_line( unsigned p, unsigned l, chtype ch = 0 ) + { + if ( !l ) + return; + + if ( type == HORZ ) + win->hline( 0, p, l, ch ); + else + win->vline( p, 0, l, ch ); + } + + void draw_bar( unsigned p, unsigned l ) + { + if ( !l ) + return; + + if ( l == 1 ) + { + if ( type == HORZ ) + win->addch( 0, p, ch_barone ); + else + win->addch( p, 0, ch_barone ); + + return; + } + + unsigned e = p + l - 1; // barend + + l -= 2; // inner bar + + if ( type == HORZ ) + { + win->addch( 0, p, ch_barbeg ); + win->addch( 0, e, ch_barend ); + + if ( l ) + win->hline( 0, p + 1, l ); + } + else + { + win->addch( p, 0, ch_barbeg ); + win->addch( e, 0, ch_barend ); + + if ( l ) + win->vline( p + 1, 0, l ); + } + } + + void draw() + { + if ( !win ) + return; + + bool topvis = ( at == 0 ); + + bool botvis = ( at + visible == total ); + + const NCstyle::StWidget & style( parw.frameStyle() ); + + win->bkgdset( style.plain ); + + draw_line( 0, len ); + + if ( topvis && botvis ) + { + // no scroll at all + return; + } + + switch ( len ) + { + case 1: + win->bkgdset( style.scrl ); + + if ( topvis == botvis ) + { + // both == false; otherwise handled above + win->addch( 0, 0, ch_barone ); + } + else + { + win->addch( 0, 0, ( topvis ? ch_forward : ch_backward ) ); + } + + break; + + case 2: + win->bkgdset( style.scrl ); + + if ( !topvis ) + win->addch( 0, 0, ch_backward ); + + if ( !botvis ) + win->addch( win->maxy(), win->maxx(), ch_forward ); + + break; + + default: + + case 3: + { + unsigned blen; + unsigned bat; + + if ( visible + 1 == total ) + { + // just one invisible line + blen = len - 1; + bat = at ? 1 : 0; + } + else + { + blen = ( visible * ( len - 2 ) / total ) + 1; + + if ( topvis == botvis ) + { + // both == false; otherwise handled above + bat = ( at * ( len - 2 ) / total ) + 1; + } + else + { + bat = ( topvis ? 0 : len - blen ); + } + } + + win->bkgdset( style.plain ); + + draw_line( 0, len ); + win->bkgdset( style.scrl ); + draw_bar( bat, blen ); + } + + break; + } + } + +public: + + /// @param parwid parent widget + /// @param par window of parent widget + /// @param p position relative to parent window + /// @param l length of self (width if horizontal, height if vertical) + /// @param orient horizontal or vertical + NCScrollbar( const NCWidget & parwid, NCursesWindow & par, wpos p, unsigned l, orientation orient ) + : ch_forward( orient == HORZ ? ACS_RARROW : ACS_DARROW ) + , ch_backward( orient == HORZ ? ACS_LARROW : ACS_UARROW ) + , ch_barbeg( orient == HORZ ? ACS_LTEE : ACS_TTEE ) + , ch_barend( orient == HORZ ? ACS_RTEE : ACS_BTEE ) + , ch_barone( orient == HORZ ? ACS_VLINE : ACS_HLINE ) + , parw( parwid ) + , win( 0 ) + , type( orient ) + , len( l ? l : 1 ) + , total( 0 ) + , visible( 0 ) + , at( 0 ) + { + try + { + win = new NCursesWindow( par, + ( type == HORZ ? 1 : len ), // height + ( type == VERT ? 1 : len ), // width + p.L, p.C, + 'r' ); + } + catch ( NCursesException & err ) + { + // yuiDebug() << "NCScrollbar: " << err.message + // << ": at " << p << " len " << len << " in " << par << std::endl; + return; + } + } + + virtual ~NCScrollbar() + { + delete win; + } + +public: + + /// Set the indicator. The arguments use the same units, + /// independent of the indicator's screen size. + /// + /// @param tot total virtual size + /// @param vis size of the visible part + /// @param start position of the visible part + void set( unsigned tot, unsigned vis, unsigned start ) + { + total = tot; + visible = vis; + at = start; + adjust(); + draw(); + } + +}; + + + + +NCPadWidget::NCPadWidget( NCWidget * myparent ) + : NCWidget( myparent ) + , padwin( 0 ) + , hsb( 0 ) + , vsb( 0 ) + , multidraw( false ) + , pad( 0 ) + , hasHeadline( false ) + , activeLabelOnly( false ) +{ + // yuiDebug() << std::endl; + hotlabel = &label; + defsze = wsze( 3, 10 ) + 2; +} + + +NCPadWidget::NCPadWidget( YWidget * myparent ) + : NCWidget( myparent ) + , padwin( 0 ) + , hsb( 0 ) + , vsb( 0 ) + , multidraw( false ) + , pad( 0 ) + , hasHeadline( false ) + , activeLabelOnly( false ) +{ + // yuiDebug() << std::endl; + hotlabel = &label; + defsze = wsze( 3, 10 ) + 2; +} + + +NCPadWidget::~NCPadWidget() +{ + delete pad; + + if ( padwin != win ) + delete padwin; + + // yuiDebug() << std::endl; +} + + +void NCPadWidget::wCreate( const wrect & newrect ) +{ + const int bsize = 2; // space allocated for the pad border + + NCWidget::wCreate( newrect ); + + if ( win ) + { + wrect padrect( newrect.inside() ); + + if ( hasHeadline ) + { + if ( padrect.Sze.H > 1 ) + { + padrect.Pos.L += 1; + padrect.Sze.H -= 1; + } + else + hasHeadline = false; + } + + padwin = new NCursesWindow( *win, + padrect.Sze.H, padrect.Sze.W, + padrect.Pos.L, padrect.Pos.C, + 'r' ); + + // The scrollbar has to be at least one character large otherwise ncurses window + // for the scrollbar will fail to create and we end with an exception which + // crashes the whole UI consequently. + // + // The scrollbar size is lowered by -2 because there is an overhead for frames etc. + if (win->width() - bsize) + { + hsb = new NCScrollbar( *this, *win, wpos( win->maxy(), 1 ), win->width() - bsize, NCScrollbar::HORZ ); + } + else + { + // no space -> no scrollbar, scrolling still works using arrows + hsb = nullptr; + } + + if (win->height() - bsize) + { + // we have enough space for a vertical scrollbar + vsb = new NCScrollbar( *this, *win, wpos( 1, win->maxx() ), win->height() - bsize, NCScrollbar::VERT ); + } + else + { + // no space -> no scrollbar, scrolling still works using arrows + vsb = nullptr; + } + } + else + { + padwin = 0; + hsb = 0; + vsb = 0; + } +} + + +void NCPadWidget::wDelete() +{ + if ( pad ) + { + pad->Destwin( 0 ); + } + + if ( padwin ) + { + if ( padwin != win ) + { + delete padwin; + } + + padwin = 0; + } + + delete hsb; + + hsb = 0; + delete vsb; + vsb = 0; + NCWidget::wDelete(); +} + + +void NCPadWidget::InitPad() +{ + if ( pad ) + return; + + pad = CreatePad(); + pad->SendSchrollCB( this ); + AdjustPad( wsze( pad->height(), pad->width() ) ); + DrawPad(); +} + + +void NCPadWidget::AdjustPadSize( wsze & minsze ) +{ + minPadSze = minsze; + minsze = wsze::max( minsze, defPadSze() ); +} + + +void NCPadWidget::AdjustPad( wsze nsze ) +{ + if ( !pad ) + return; + + pad->resize( nsze ); +} + + +void NCPadWidget::DelPad() +{ + delete pad; + pad = 0; +} + + +void NCPadWidget::setLabel( const NClabel & nlabel ) +{ + label = nlabel; + label.stripHotkey(); + Redraw(); +} + + +void NCPadWidget::wRedraw() +{ + if ( !win ) + return; + + // yuiDebug() << "wRedraw called for: " << win << std::endl; + + const NCstyle::StWidget & style( frameStyle() ); + + win->bkgdset( style.plain ); + + win->box(); + + if ( !activeLabelOnly || GetState() == NC::WSactive ) + label.drawAt( *win, style, wpos( 0, 1 ), + wsze( 1, win->width() - 2 ), NC::TOPLEFT, false ); + + InitPad(); + + if ( !pad->Destwin() ) + { + AdjustPad( minPadSze ); + pad->Destwin( padwin ); + } + else + { + pad->setDirty(); + pad->setpos(); + pad->SendHead(); + } +} + + +void NCPadWidget::wRecoded() +{ + if ( pad ) + pad->wRecoded(); + + wRedraw(); +} + + +void NCPadWidget::HScroll( unsigned total, unsigned visible, unsigned start ) +{ + // horizontal scroll bar might got disabled because of lack of space. See + // NCPadWidget::wCreate + if (hsb) + { + hsb->set( total, visible, start ); + } +} + + +void NCPadWidget::VScroll( unsigned total, unsigned visible, unsigned start ) +{ + // vertical scroll bar might got disabled because of lack of space. See + // NCPadWidget::wCreate + if (vsb) + { + vsb->set( total, visible, start ); + } +} + + +void NCPadWidget::ScrollHead( NCursesWindow & w, unsigned ccol ) +{ + if ( hasHeadline && win ) + { + w.copywin( *win, 0, ccol, 1, 1, 1, win->width() - 2, false ); + } +} + + +NCPad * NCPadWidget::CreatePad() +{ + wsze psze( defPadSze() ); + NCPad * npad = new NCPad( psze.H, psze.W, *this ); + npad->bkgd( wStyle().list.item.plain ); + + return npad; +} + + +void NCPadWidget::DrawPad() +{ + if ( pad && !inMultidraw() ) + { + pad->update(); + Redraw(); + } +} + + +bool NCPadWidget::handleInput( wint_t key ) +{ + return pad->handleInput( key ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCPadWidget.h b/deps/libyui/libyui-ncurses/src/NCPadWidget.h new file mode 100644 index 0000000000000000000000000000000000000000..787173de3c00b3f46d5892de10534d98eb6375a9 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPadWidget.h @@ -0,0 +1,129 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPadWidget.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPadWidget_h +#define NCPadWidget_h + +#include + +#include "NCWidget.h" +#include "NCPad.h" + +class NCPadWidget; +class NCScrollbar; + +/** + * Base class for widgets with scrollable contents + */ +class NCPadWidget : public NCWidget, protected NCSchrollCB +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCPadWidget & obj ); + + NCPadWidget & operator=( const NCPadWidget & ); + NCPadWidget( const NCPadWidget & ); + + + NClabel label; + NCursesWindow * padwin; ///< (owned IFF different from NCWidget::*win*) + NCScrollbar * hsb; ///< (owned) + NCScrollbar * vsb; ///< (owned) + + wsze minPadSze; + bool multidraw; + NCPad * pad; ///< (owned) + +protected: + + /** + * Return the current pad. Make it virtual so descendant classes + * can narrow the return type. + */ + virtual NCPad * myPad() const { return pad; } + + bool hasHeadline; + bool activeLabelOnly; + + void startMultidraw() { multidraw = true; } + + void stopMultidraw() { multidraw = false; DrawPad(); } + + bool inMultidraw() const { return multidraw; } + +protected: + + virtual const char * location() const { return "NCPadWidget"; } + + // widget stuff + unsigned labelWidth() const { return label.width(); } + + virtual void wCreate( const wrect & newrect ); + virtual void wDelete(); + virtual void wRedraw(); + virtual void wRecoded(); + + // pad stuff + wsze defPadSze() const + { + if ( !padwin ) + return 0; + + return wsze( padwin->height(), padwin->width() ); + } + + virtual NCPad * CreatePad(); + virtual void DrawPad(); + + void InitPad(); + void AdjustPad( wsze nsze ); + void DelPad(); + + // scroll hints + virtual void HScroll( unsigned total, unsigned visible, unsigned start ); + virtual void VScroll( unsigned total, unsigned visible, unsigned start ); + virtual void ScrollHead( NCursesWindow & w, unsigned ccol ); + + // resize hints + virtual void AdjustPadSize( wsze & minsze ); + + // input + virtual bool handleInput( wint_t key ); + +public: + + NCPadWidget( NCWidget * myparent = 0 ); + NCPadWidget( YWidget * parent ); + + virtual ~NCPadWidget(); + + size_t Columns() { return minPadSze.W; } + + void setLabel( const NClabel & nlabel ); + + virtual void setEnabled( bool do_bv ) { NCWidget::setEnabled( do_bv ); } +}; + + +#endif // NCPadWidget_h diff --git a/deps/libyui/libyui-ncurses/src/NCPopup.cc b/deps/libyui/libyui-ncurses/src/NCPopup.cc new file mode 100644 index 0000000000000000000000000000000000000000..bf438015f9c7b255929622a316766554a86b0725 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopup.cc @@ -0,0 +1,87 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopup.h + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPopup.h" + + +NCPopup::NCPopup( const wpos & at, bool boxed ) + : NCDialog( YPopupDialog, at, boxed ) +{ +} + + +NCPopup::~NCPopup() +{ +} + + +void NCPopup::popupDialog() +{ + initDialog(); + showDialog(); + activate( true ); + + while ( !( postevent = userInput() ) ) + ; + + activate( false ); +} + + +void NCPopup::popdownDialog() +{ + closeDialog(); +} + + +NCursesEvent NCPopup::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + return NCDialog::wHandleInput( ch ); +} + + +int NCPopup::post( NCursesEvent * returnevent ) +{ + postevent = NCursesEvent(); + + do + { + popupDialog(); + } + while ( postAgain() ); + + popdownDialog(); + + if ( returnevent ) + *returnevent = postevent; + + // yuiDebug() << "Return event.detail: " << postevent.detail << std::endl; + + return postevent.detail; +} diff --git a/deps/libyui/libyui-ncurses/src/NCPopup.h b/deps/libyui/libyui-ncurses/src/NCPopup.h new file mode 100644 index 0000000000000000000000000000000000000000..c010fac6eac780013591d498cd9f5c4db90b8927 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopup.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopup.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPopup_h +#define NCPopup_h + +#include + +#include "NCDialog.h" + + +class NCPopup : public NCDialog +{ + + NCPopup & operator=( const NCPopup & ); + NCPopup( const NCPopup & ); + +protected: + + NCursesEvent postevent; + + void popupDialog(); + void popdownDialog(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + + NCPopup( const wpos & at, bool boxed = true ); + virtual ~NCPopup(); + + virtual bool postAgain() + { + if ( postevent != NCursesEvent::cancel ) + postevent.detail = 0; + + return false; + } + +public: + + int post( NCursesEvent * returnevent = 0 ); + +}; + + +#endif // NCPopup_h + + diff --git a/deps/libyui/libyui-ncurses/src/NCPopupInfo.cc b/deps/libyui/libyui-ncurses/src/NCPopupInfo.cc new file mode 100644 index 0000000000000000000000000000000000000000..e5e10fa799a11494739d85b2d3f36f41b4be53f6 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupInfo.cc @@ -0,0 +1,215 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupInfo.cc + + Author: Gabriele Strattner + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPopupInfo.h" + +#include "NCTree.h" +#include +#include +#include "NCLayoutBox.h" +#include "NCSpacing.h" + + +namespace +{ + const std::string idOk( "ok" ); + const std::string idCancel( "cancel" ); +} + + +NCPopupInfo::NCPopupInfo( const wpos & at, + const std::string & headline, + const std::string & text, + std::string okButtonLabel, + std::string cancelButtonLabel ) + : NCPopup( at, false ) + , helpText( 0 ) + , okButton( 0 ) + , cancelButton( 0 ) + , hDim( 50 ) + , vDim( 20 ) + , visible( false ) +{ + createLayout( headline, text, okButtonLabel, cancelButtonLabel ); +} + + +NCPopupInfo::~NCPopupInfo() +{ +} + + +void NCPopupInfo::createLayout( const std::string & headline, + const std::string & text, + std::string okButtonLabel, + std::string cancelButtonLabel ) +{ + std::string old_textdomain = textdomain( NULL ); + setTextdomain( "ncurses" ); + + // the vertical split is the (only) child of the dialog + NCLayoutBox * split = new NCLayoutBox( this, YD_VERT ); + + // add the headline + new NCLabel( split, headline, true, false ); // isHeading = true + + // add the rich text widget + helpText = new NCRichText( split, text ); + + NCLayoutBox * hSplit = new NCLayoutBox( split, YD_HORIZ ); + + if ( okButtonLabel != "" && cancelButtonLabel != "" ) + { + new NCSpacing( hSplit, YD_HORIZ, true, 0.4 ); // stretchable = true + } + + if ( okButtonLabel != "" ) + { + // add the OK button + okButton = new NCPushButton( hSplit, okButtonLabel ); + okButton->setFunctionKey( 10 ); + } + + if ( cancelButtonLabel != "" ) + { + new NCSpacing( hSplit, YD_HORIZ, true, 0.4 ); + + // add the Cancel button + cancelButton = new NCPushButton( hSplit, cancelButtonLabel ); + cancelButton->setFunctionKey( 9 ); + + new NCSpacing( hSplit, YD_HORIZ, true, 0.4 ); + } + + //If we don't have cancel button and have single ok button instead + //let's focus it by default (#397393) + if ( cancelButtonLabel == "" && okButton ) + focusOkButton(); + + //the same with missing ok button and single cancel button + if ( okButtonLabel == "" && cancelButton ) + focusCancelButton(); + + // restore former text domain + setTextdomain( old_textdomain.c_str() ); +} + + +NCursesEvent & NCPopupInfo::showInfoPopup() +{ + postevent = NCursesEvent(); + + do + { + popupDialog(); + } + while ( postAgain() ); + + popdownDialog(); + + return postevent; +} + + +void NCPopupInfo::popup() +{ + initDialog(); + showDialog(); + activate( true ); + visible = true; +} + + +void NCPopupInfo::popdown() +{ + activate( false ); + closeDialog(); + visible = false; +} + + +int NCPopupInfo::preferredWidth() +{ + int horDim = hDim; + + if ( hDim >= NCurses::cols() ) + horDim = NCurses::cols() - 10; + + return horDim; +} + + +int NCPopupInfo::preferredHeight() +{ + int vertDim = vDim; + + if ( vDim >= NCurses::lines() ) + vertDim = NCurses::lines() - 5; + + return vertDim; +} + + +NCursesEvent +NCPopupInfo::wHandleInput( wint_t ch ) +{ + if ( ch == 27 ) // ESC + return NCursesEvent::cancel; + + if ( ch == KEY_RETURN ) + return NCursesEvent::button; + + return NCDialog::wHandleInput( ch ); +} + + +bool NCPopupInfo::postAgain() +{ + if ( ! postevent.widget ) + return false; + + if ( okButton && cancelButton ) + { + if ( postevent.widget == cancelButton ) + { + yuiMilestone() << "Cancel button pressed" << std::endl; + // close the dialog + postevent = NCursesEvent::cancel; + } + + // else - nothing to do (postevent is already set) + } + + if ( postevent == NCursesEvent::button || postevent == NCursesEvent::cancel ) + { + // return false means: close the popup dialog + return false; + } + + return true; +} + + diff --git a/deps/libyui/libyui-ncurses/src/NCPopupInfo.h b/deps/libyui/libyui-ncurses/src/NCPopupInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..f6212ff2de1a57232550d976b5d7db3fcbb18537 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupInfo.h @@ -0,0 +1,107 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupInfo.h + + Author: Gabriele Strattner + +/-*/ + +#ifndef NCPopupInfo_h +#define NCPopupInfo_h + +#include + +#include +#include + +#include "NCPopup.h" +#include "NCComboBox.h" +#include "NCLabel.h" +#include "NCRichText.h" +#include "NCCheckBox.h" +#include "NCPushButton.h" +#include "NCi18n.h" + + +/* + Textdomain "ncurses" + */ + + + +class NCPopupInfo : public NCPopup +{ +private: + + NCPopupInfo & operator=( const NCPopupInfo & ); + NCPopupInfo( const NCPopupInfo & ); + + + NCRichText * helpText; + NCPushButton * okButton; + NCPushButton * cancelButton; + + int hDim; + int vDim; + bool visible; + +protected: + + virtual bool postAgain(); + + virtual NCursesEvent wHandleInput( wint_t ch ); + +public: + + NCPopupInfo( const wpos & at, + const std::string & headline, + const std::string & text, + // the label of an OK button + std::string okButtonLabel = _( "&OK" ), + std::string cancelButtonLabel = "" ); + + virtual ~NCPopupInfo(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + void createLayout( const std::string & headline, + const std::string & text, + std::string okButtonLabel, + std::string cancelButtonLabel ); + + NCursesEvent & showInfoPopup(); + + void popup(); + + void popdown(); + + bool isVisible() { return visible; } + + void setPreferredSize( int horiz, int vert ) { hDim = horiz; vDim = vert; } + + void focusOkButton() { okButton->setKeyboardFocus(); } + + void focusCancelButton() { cancelButton->setKeyboardFocus(); } + +}; + + + +#endif // NCPopupInfo_h diff --git a/deps/libyui/libyui-ncurses/src/NCPopupList.cc b/deps/libyui/libyui-ncurses/src/NCPopupList.cc new file mode 100644 index 0000000000000000000000000000000000000000..632668516b88e14ae13952f8c5e6d8476b2d8af0 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupList.cc @@ -0,0 +1,66 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupList.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPopupList.h" +#include + + +NCPopupList::NCPopupList( const wpos & at, + const std::string & label, + const std::list & deflist, + int index ) + : NCPopupTable( at ) +{ + createEntries( deflist, index ); +} + + +NCPopupList::~NCPopupList() +{ + +} + + +void NCPopupList::createEntries( const std::list & deflist, int index ) +{ + std::vector row( 1 ); + createList( row ); + + for ( std::list::const_iterator entry = deflist.begin(); + entry != deflist.end(); ++entry ) + { + YItem *item = new YTableItem(( *entry ) ); + addItem( item ); + } + + setCurrentItem( index ); +} + + +bool NCPopupList::postAgain() +{ + return NCPopupTable::postAgain(); +} diff --git a/deps/libyui/libyui-ncurses/src/NCPopupList.h b/deps/libyui/libyui-ncurses/src/NCPopupList.h new file mode 100644 index 0000000000000000000000000000000000000000..44d49d6fde78fef58d28e72aa10650d12b76c0b7 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupList.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupList.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPopupList_h +#define NCPopupList_h + +#include +#include + +#include "NCPopupTable.h" + + +class NCPopupList : public NCPopupTable +{ + + NCPopupList & operator=( const NCPopupList & ); + NCPopupList( const NCPopupList & ); + +protected: + + virtual bool postAgain(); + +public: + + NCPopupList( const wpos & at, + const std::string & label, + const std::list & deflist, + int index = 0 ); + + virtual ~NCPopupList(); + + void createEntries( const std::list & deflist, int index ); +}; + + + +#endif // NCPopupList_h diff --git a/deps/libyui/libyui-ncurses/src/NCPopupMenu.cc b/deps/libyui/libyui-ncurses/src/NCPopupMenu.cc new file mode 100644 index 0000000000000000000000000000000000000000..abb11b44c6225c2a830459b424a40eecaf1b2d5e --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupMenu.cc @@ -0,0 +1,279 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupMenu.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPopupMenu.h" +#include "NCTable.h" + + +// Helper class that represents a menu item +struct NCPopupMenu::Item +{ + YTableItem * tableItem; + YMenuItem * menuItem; + + + // Whether the item can be selected + bool isSelectable() const + { + if ( ! menuItem ) + return false; + + return menuItem->isEnabled() && !menuItem->isSeparator(); + } + +}; + + +NCPopupMenu::NCPopupMenu( const wpos & at, YItemIterator begin, YItemIterator end ) + : NCPopupTable( at ) + , _items() +{ + std::vector row( 2 ); + createList( row ); + + for ( YItemIterator it = begin; it != end; ++it ) + { + YMenuItem * menuItem = dynamic_cast( *it ); + YUI_CHECK_PTR( menuItem ); + + if ( ! menuItem->isVisible() ) + continue; + + row[0] = menuItem->label(); + row[1] = menuItem->hasChildren() ? "..." : ""; + + YTableItem *tableItem = new YTableItem( row[0], row[1] ); + // yuiDebug() << "Add to std::map: TableItem: " << tableItem << " Menu item: " << item << std::endl; + + NCTableLine::STATE state = menuItem->isEnabled() ? NCTableLine::S_NORMAL : NCTableLine::S_DISABLED; + + addItem( tableItem, state ); + + Item * item = new Item(); + item->tableItem = tableItem; + item->menuItem = menuItem; + + _items.add( item ); + } + + selectNextItem(); + + stripHotkeys(); +} + + +NCPopupMenu::~NCPopupMenu() +{ + for (Item * item : _items) + delete item; +} + + +NCursesEvent NCPopupMenu::wHandleInput( wint_t ch ) +{ + NCursesEvent event; + + switch ( ch ) + { + case KEY_RIGHT: + { + Item * item = selectedItem(); + + if ( item ) + { + if ( item->menuItem->hasChildren() ) + event = NCursesEvent::button; + else + { + event = NCursesEvent::key; + event.keySymbol = "CursorRight"; + } + } + + break; + } + + case KEY_LEFT: + event = NCursesEvent::key; + + event.keySymbol = "CursorLeft"; + event.detail = NCursesEvent::CONTINUE; + + break; + + case KEY_DOWN: + selectNextItem(); + break; + + case KEY_UP: + selectPreviousItem(); + break; + + case KEY_BACKSPACE: + event = NCursesEvent::key; + event.keySymbol = "BackSpace"; + break; + + case KEY_SPACE: + case KEY_RETURN: + { + Item * item = selectedItem(); + + if ( item && ! item->menuItem->hasChildren() ) + { + event = NCursesEvent::SelectionChanged; + event.detail = item->tableItem->index(); + } + else + { + event = NCPopup::wHandleInput( ch ); + } + } + break; + + default: + event = wHandleHotkey( ch ); + + if ( event == NCursesEvent::none ) + event = NCPopup::wHandleInput( ch ); + + break; + } + + return event; +} + + +NCursesEvent NCPopupMenu::wHandleHotkey( wint_t key ) +{ + NCursesEvent event = NCPopupTable::wHandleHotkey( key ); + + if ( event == NCursesEvent::none ) + { + event = NCursesEvent::key; + event.keySymbol = "Hotkey"; + event.detail = key; + } + + return event; +} + + +bool NCPopupMenu::postAgain() +{ + // dont mess up postevent.detail here + bool again = false; + int selection = ( postevent == NCursesEvent::button ) ? getCurrentItem() : -1; + + Item * item = selectedItem(); + + if ( ! item ) + return false; + + yuiDebug() << "Menu item: " << item->menuItem->label() << std::endl; + + if ( selection != -1 ) + { + if ( item->menuItem->hasChildren() ) + { + // post submenu + wpos at( ScreenPos() + wpos( selection, inparent.Sze.W - 1 ) ); + NCPopupMenu * dialog = new NCPopupMenu( at, + item->menuItem->childrenBegin(), + item->menuItem->childrenEnd() ); + YUI_CHECK_NEW( dialog ); + + again = ( dialog->post( &postevent ) == NCursesEvent::CONTINUE ); + + YDialog::deleteTopmostDialog(); + } + else + { + // store selection + postevent.selection = item->menuItem; + } + } + + return again; +} + + +NCPopupMenu::Item * NCPopupMenu::selectedItem() +{ + updateSelectedItem(); + + return *_items.current(); +} + + +void NCPopupMenu::selectNextItem() +{ + selectItem( _items.next() ); +} + + +void NCPopupMenu::selectPreviousItem() +{ + selectItem( _items.previous() ); +} + + +void NCPopupMenu::updateSelectedItem() +{ + YTableItem * tableItem = dynamic_cast ( getCurrentItemPointer() ); + + if ( ! tableItem ) + return; + + CyclicContainer::Iterator newCurrent = findItem( tableItem); + + if ( newCurrent == _items.end() ) + return; + + if ( _items.current() != newCurrent ) + selectItem( newCurrent ); +} + + +CyclicContainer::Iterator NCPopupMenu::findItem( YTableItem * tableItem ) +{ + return find_if( _items.begin(), _items.end(), [tableItem](Item * item) { + return item->tableItem == tableItem; + }); +} + + +void NCPopupMenu::selectItem( CyclicContainer::Iterator item ) +{ + _items.setCurrent( item ); + + if ( item != _items.end() ) + { + int index = std::distance(_items.begin(), item); + + setCurrentItem(index); + } +} diff --git a/deps/libyui/libyui-ncurses/src/NCPopupMenu.h b/deps/libyui/libyui-ncurses/src/NCPopupMenu.h new file mode 100644 index 0000000000000000000000000000000000000000..f195f56d0005fe639c5199940cd705495d990a06 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupMenu.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupMenu.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPopupMenu_h +#define NCPopupMenu_h + +#include "NCPopupTable.h" +#include "CyclicContainer.h" + + +class NCPopupMenu : public NCPopupTable +{ +private: + + struct Item; + + NCPopupMenu & operator=( const NCPopupMenu & ); + NCPopupMenu( const NCPopupMenu & ); + + Item * selectedItem(); + + void selectNextItem(); + void selectPreviousItem(); + void updateSelectedItem(); + + CyclicContainer::Iterator findItem( YTableItem * tableItem ); + + void selectItem( CyclicContainer::Iterator item ); + + /** + * Container of menu items. + * It allows cyclic navigation between the items. + * + * Note that this container holds pointers to items, but it does not own + * the pointers. The pointers are owned by the NCPopupMenu object. + **/ + CyclicContainer _items; + +protected: + + virtual NCursesEvent wHandleInput( wint_t ch ); + virtual NCursesEvent wHandleHotkey( wint_t key ); + + virtual bool postAgain(); + +public: + + NCPopupMenu( const wpos & at, + YItemIterator begin, + YItemIterator end ); + + virtual ~NCPopupMenu(); + +}; + +#endif // NCPopupMenu_h diff --git a/deps/libyui/libyui-ncurses/src/NCPopupTable.cc b/deps/libyui/libyui-ncurses/src/NCPopupTable.cc new file mode 100644 index 0000000000000000000000000000000000000000..eebdf1455a40654e90947efd8da7c54a63eb62d7 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupTable.cc @@ -0,0 +1,133 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupTable.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPopupTable.h" + +#include "NCTable.h" +#include + + +NCPopupTable::NCPopupTable( const wpos & at ) + : NCPopup( at, false ) + , sellist( 0 ) +{ +} + + +NCPopupTable::~NCPopupTable() +{ +} + + +void NCPopupTable::createList( std::vector & row ) +{ + if ( sellist ) + return ; + + YTableHeader * tableHeader = new YTableHeader(); + + // sellist = new NCTable( this, row.size() ); + sellist = new NCTable( this, tableHeader ); + + YUI_CHECK_NEW( sellist ); + + sellist->setBigList( true ); + sellist->SetSepChar( ' ' ); + sellist->SetSepWidth( 0 ); + sellist->SetHotCol( 0 ); + sellist->setNotify( true ); +} + + +void NCPopupTable::addItem( YItem *yitem, NCTableLine::STATE state ) +{ + if ( !yitem ) + return; + + sellist->addItem( yitem, state ); + + // Calling sellist->addItem() resets the hotcol because + // NCTableStyle's constructor sets hotcol to -1. + // Set hotcol again: + sellist->SetHotCol( 0 ); +} + + +void NCPopupTable::setCurrentItem( int index ) +{ + if ( !sellist ) + return; + + sellist->setCurrentItem( index ); +} + + +int NCPopupTable::getCurrentItem() const +{ + if ( !sellist ) + return -1; + + return sellist->getCurrentItem(); +} + + +YItem * NCPopupTable::getCurrentItemPointer() const +{ + if ( !sellist ) + return 0; + + return sellist->getCurrentItemPointer(); +} + + +NCursesEvent NCPopupTable::wHandleHotkey( wint_t key ) +{ + if ( key >= 0 && sellist->setItemByKey( key ) ) + return wHandleInput( KEY_RETURN ); + + return NCursesEvent::none; +} + + +bool NCPopupTable::postAgain() +{ + if ( sellist ) + { + postevent.detail = ( postevent == NCursesEvent::button ) ? + sellist->getCurrentItem() : NCursesEvent::NODETAIL; + } + + return false; +} + + +void NCPopupTable::stripHotkeys() +{ + if ( sellist ) + { + sellist->stripHotkeys(); + } +} diff --git a/deps/libyui/libyui-ncurses/src/NCPopupTable.h b/deps/libyui/libyui-ncurses/src/NCPopupTable.h new file mode 100644 index 0000000000000000000000000000000000000000..c4297e9eb895b19d6ec9ea9338a41c0d5ddefefc --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupTable.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupTable.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPopupTable_h +#define NCPopupTable_h + +#include + +#include +#include + +#include "NCPopup.h" +#include "NCTableItem.h" +#include + +class NCTable; + + +class NCPopupTable : public NCPopup +{ +private: + + NCPopupTable & operator=( const NCPopupTable & ); + NCPopupTable( const NCPopupTable & ); + + NCTable * sellist; + +protected: + + void createList( std::vector & row ); + + void addItem( YItem *yitem, NCTableLine::STATE state = NCTableLine::S_NORMAL ); + + void setCurrentItem( int index ); + int getCurrentItem() const; + YItem * getCurrentItemPointer() const; + + virtual NCursesEvent wHandleHotkey( wint_t ch ); + + NCPopupTable( const wpos & at ); + virtual ~NCPopupTable(); + + virtual bool postAgain(); + +public: + void stripHotkeys(); +}; + + + +#endif // NCPopupTable_h diff --git a/deps/libyui/libyui-ncurses/src/NCPopupTextEntry.cc b/deps/libyui/libyui-ncurses/src/NCPopupTextEntry.cc new file mode 100644 index 0000000000000000000000000000000000000000..957d07a5839ca8275e03325adf8d8cd5796af21b --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupTextEntry.cc @@ -0,0 +1,85 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupTextEntry.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCPopupTextEntry.h" +#include "NCInputField.h" + + +NCPopupTextEntry::NCPopupTextEntry( const wpos & at, + const std::string & label, + const std::string & text, + unsigned maxInput, + unsigned maxFld, + NCInputField::FTYPE t ) + : NCPopup( at ) + , wtext( 0 ) +{ + wtext = new NCInputField( this, + label, + false, // passwordMode = false + maxInput, + maxFld + ); + YUI_CHECK_NEW( wtext ); + + wtext->setValue( text ); + wtext->setFldtype( t ); + wtext->setReturnOnReturn( true ); + +} + + +NCPopupTextEntry::~NCPopupTextEntry() +{ +} + + +bool NCPopupTextEntry::postAgain() +{ + if ( postevent == NCursesEvent::button ) + postevent.detail = 0; + + return false; +} + + +std::string NCPopupTextEntry::askForText( const wpos & at, + const std::string & label, + const std::string & text, + unsigned maxInput, + unsigned maxFld ) +{ + NCPopupTextEntry * dialog = new NCPopupTextEntry( at, label, text, maxInput, maxFld, + NCInputField::PLAIN); + YUI_CHECK_NEW( dialog ); + std::string result; + + dialog->post(); + result = dialog->value(); + YDialog::deleteTopmostDialog(); + + return result; +} diff --git a/deps/libyui/libyui-ncurses/src/NCPopupTextEntry.h b/deps/libyui/libyui-ncurses/src/NCPopupTextEntry.h new file mode 100644 index 0000000000000000000000000000000000000000..65eae6a81eb79e58c3bcf05adb74dbfe19192f26 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPopupTextEntry.h @@ -0,0 +1,71 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPopupTextEntry.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPopupTextEntry_h +#define NCPopupTextEntry_h + +#include + +#include "NCPopup.h" +#include "NCInputField.h" + + + +class NCPopupTextEntry : public NCPopup +{ +private: + + NCPopupTextEntry & operator=( const NCPopupTextEntry & ); + NCPopupTextEntry( const NCPopupTextEntry & ); + + + NCInputField * wtext; + + virtual bool postAgain(); + +public: + + NCPopupTextEntry( const wpos & at, + const std::string & label, + const std::string & text, + unsigned maxInput = 0, + unsigned maxFld = 0, + NCInputField::FTYPE t = NCInputField::PLAIN ); + + virtual ~NCPopupTextEntry(); + + void setValue( const std::string & ntext ) { wtext->setValue( ntext ); } + + std::string value() { return wtext->value(); } + + static std::string askForText( const wpos & at, + const std::string & label, + const std::string & text = "", + unsigned maxInput = 0, + unsigned maxFld = 0 ); +}; + + + +#endif // NCPopupTextEntry_h diff --git a/deps/libyui/libyui-ncurses/src/NCProgressBar.cc b/deps/libyui/libyui-ncurses/src/NCProgressBar.cc new file mode 100644 index 0000000000000000000000000000000000000000..44f6fee6a476bcc964b002cf3c523a2cdf7127f0 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCProgressBar.cc @@ -0,0 +1,224 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCProgressBar.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCProgressBar.h" + + +NCProgressBar::NCProgressBar( YWidget * parent, + const std::string & nlabel, + int maxValue ) + : YProgressBar( parent, nlabel, maxValue ) + , NCWidget( parent ) + , label( nlabel ) + , maxval( maxValue ) + , cval( 0 ) + , lwin( 0 ) + , twin( 0 ) +{ + // yuiDebug() << std::endl; + + if ( maxval <= 0 ) + maxval = 1; + + hotlabel = &label; + + setLabel( nlabel ); + + // initial progress isn't an argument any longer + //setProgress( progress ); + wstate = NC::WSdumb; +} + + +NCProgressBar::~NCProgressBar() +{ + delete lwin; + delete twin; + // yuiDebug() << std::endl; +} + + +int NCProgressBar::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCProgressBar::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCProgressBar::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YProgressBar::setEnabled( do_bv ); +} + + +void NCProgressBar::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCProgressBar::setDefsze() +{ + defsze = wsze( label.height() + 1, + label.width() < 5 ? 5 : label.width() ); +} + + +void NCProgressBar::wCreate( const wrect & newrect ) +{ + NCWidget::wCreate( newrect ); + + if ( !win ) + return; + + wrect lrect( 0, wsze::min( newrect.Sze, + wsze( label.height(), newrect.Sze.W ) ) ); + + wrect trect( 0, wsze( 1, newrect.Sze.W ) ); + + if ( lrect.Sze.H == newrect.Sze.H ) + lrect.Sze.H -= 1; + + trect.Pos.L = lrect.Sze.H > 0 ? lrect.Sze.H : 0; + + lwin = new NCursesWindow( *win, + lrect.Sze.H, lrect.Sze.W, + lrect.Pos.L, lrect.Pos.C, + 'r' ); + + twin = new NCursesWindow( *win, + trect.Sze.H, trect.Sze.W, + trect.Pos.L, trect.Pos.C, + 'r' ); +} + + +void NCProgressBar::wDelete() +{ + delete lwin; + delete twin; + lwin = 0; + twin = 0; + NCWidget::wDelete(); +} + + +void NCProgressBar::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + setDefsze(); + YProgressBar::setLabel( nlabel ); + Redraw(); +} + + +void NCProgressBar::setValue( int newValue ) +{ + cval = newValue; + + if ( cval < 0 ) + cval = 0; + else if ( cval > maxval ) + cval = maxval; + + Redraw(); + + YProgressBar::setValue( newValue ); +} + + +void NCProgressBar::wRedraw() +{ + if ( !win ) + return; + + // label + chtype bg = wStyle().dumb.text; + + lwin->bkgdset( bg ); + + lwin->clear(); + + label.drawAt( *lwin, bg, bg ); + + tUpdate(); +} + + +void NCProgressBar::tUpdate() +{ + if ( !win ) + return; + + double split = double( twin->maxx() + 1 ) * cval / maxval; + + int cp = int( split ); + + if ( cp == 0 && split > 0.0 ) + cp = 1; + + const NCstyle::StProgbar & style( wStyle().progbar ); + + twin->bkgdset( style.bar.chattr ); + + twin->clear(); + + if ( cp <= twin->maxx() ) + { + twin->bkgdset( NCattribute::getNonChar( style.nonbar.chattr ) ); + twin->move( 0, cp ); + + for ( int i = 0; i < twin->width() - cp; ++i ) + { + twin->addch( NCattribute::getChar( style.nonbar.chattr ) ); + } + } + + if ( twin->maxx() >= 6 ) + { + Value_t pc = 100 * cval / maxval; + Value_t off = twin->maxx() / 2 - ( pc == 100 ? 2 + : pc >= 10 ? 1 + : 0 ); + char buf[5]; + sprintf( buf, "%lld%%", pc ); + twin->move( 0, off ); + + for ( char * ch = buf; *ch; ++ch ) + { + chtype a = twin->inch(); + NCattribute::setChar( a, *ch ); + twin->addch( a ); + } + } +} diff --git a/deps/libyui/libyui-ncurses/src/NCProgressBar.h b/deps/libyui/libyui-ncurses/src/NCProgressBar.h new file mode 100644 index 0000000000000000000000000000000000000000..c92f3a61068f91439fb5a0bf9f05d4361744c463 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCProgressBar.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCProgressBar.h + + Author: Michael Andres + +/-*/ + +#ifndef NCProgressBar_h +#define NCProgressBar_h + +#include + +#include +#include "NCWidget.h" + +class NCProgressBar; + + +class NCProgressBar : public YProgressBar, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCProgressBar & obj ); + + NCProgressBar & operator=( const NCProgressBar & ); + NCProgressBar( const NCProgressBar & ); + + + typedef long long Value_t; + + NClabel label; + Value_t maxval; + Value_t cval; + NCursesWindow * lwin; + NCursesWindow * twin; + + void setDefsze(); + void tUpdate(); + +protected: + + virtual const char * location() const { return "NCProgressBar"; } + + virtual void wCreate( const wrect & newrect ); + virtual void wDelete(); + + virtual void wRedraw(); + +public: + + NCProgressBar( YWidget * parent, + const std::string & label, + int maxValue = 100 ); + virtual ~NCProgressBar(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setValue( int newValue ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCProgressBar_h diff --git a/deps/libyui/libyui-ncurses/src/NCPushButton.cc b/deps/libyui/libyui-ncurses/src/NCPushButton.cc new file mode 100644 index 0000000000000000000000000000000000000000..97cebe0c8af340bf1829f8855b0744016603a72b --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPushButton.cc @@ -0,0 +1,134 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPushButton.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include +#include "NCDialog.h" +#include "NCurses.h" +#include "NCPushButton.h" +#include "YNCursesUI.h" + + +NCPushButton::NCPushButton( YWidget * parent, const std::string & nlabel ) + : YPushButton( parent, nlabel ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + setLabel( nlabel ); + hotlabel = &label; +} + + +NCPushButton::~NCPushButton() +{ + // yuiDebug() << std::endl; +} + + +int NCPushButton::preferredWidth() +{ + wsze defsize = wGetDefsze(); + return wGetDefsze().W; +} + + +int NCPushButton::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCPushButton::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YPushButton::setEnabled( do_bv ); +} + + +void NCPushButton::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +NCursesEvent NCPushButton::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + + switch ( key ) + { + case KEY_HOTKEY: + case KEY_RETURN: + ret = NCursesEvent::Activated; + break; + } + + return ret; +} + + +void NCPushButton::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + defsze = wsze( label.height(), label.width() + 2 ); + YPushButton::setLabel( nlabel ); + Redraw(); +} + + +void NCPushButton::wRedraw() +{ + if ( !win ) + return; + + const NCstyle::StWidget & style( widgetStyle() ); + + win->bkgd( style.plain ); + + win->clear(); + + if ( label.height() <= 1 ) + { + win->printw( 0, 0, "[" ); + win->printw( 0, win->maxx(), "]" ); + } + else + { + win->box(); + } + + label.drawAt( *win, style, wpos( 0, 1 ), wsze( -1, win->width() - 2 ), + NC::CENTER ); +} + +// pressing the button +void NCPushButton::activate() +{ + // send an activation event for this widget + NCursesEvent event = NCursesEvent::Activated; + event.widget = this; + YNCursesUI::ui()->sendEvent(event); +} diff --git a/deps/libyui/libyui-ncurses/src/NCPushButton.h b/deps/libyui/libyui-ncurses/src/NCPushButton.h new file mode 100644 index 0000000000000000000000000000000000000000..967e0058c55af935ab4c395736f17653e849f89d --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCPushButton.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCPushButton.h + + Author: Michael Andres + +/-*/ + +#ifndef NCPushButton_h +#define NCPushButton_h + +#include + +#include +#include "NCWidget.h" + + +class NCPushButton : public YPushButton, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCPushButton & obj ); + + NCPushButton & operator=( const NCPushButton & ); + NCPushButton( const NCPushButton & ); + + + NClabel label; + +protected: + + virtual const char * location() const { return "NCPushButton"; } + + virtual void wRedraw(); + +public: + + NCPushButton( YWidget * parent, const std::string & label ); + virtual ~NCPushButton(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } + + /** + * Activate the button. Can be used in tests to simulate user input. + * + * Derived classes are required to implement this. + **/ + virtual void activate(); + +}; + + +#endif // NCPushButton_h diff --git a/deps/libyui/libyui-ncurses/src/NCRadioButton.cc b/deps/libyui/libyui-ncurses/src/NCRadioButton.cc new file mode 100644 index 0000000000000000000000000000000000000000..bfb40dcd4fd182746e1158d940cb90396ccaefd3 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCRadioButton.cc @@ -0,0 +1,167 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCRadioButton.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCRadioButton.h" +#include "NCRadioButtonGroup.h" +#include "YNCursesUI.h" + + +NCRadioButton::NCRadioButton( YWidget * parent, + const std::string & nlabel, + bool check ) + : YRadioButton( parent, nlabel ) + , NCWidget( parent ) + , checked( false ) +{ + // yuiDebug() << std::endl; + setLabel( nlabel ); + hotlabel = &label; + setValue( check ); +} + + +NCRadioButton::~NCRadioButton() +{ + // yuiDebug() << std::endl; +} + + +int NCRadioButton::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCRadioButton::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCRadioButton::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YRadioButton::setEnabled( do_bv ); +} + + +void NCRadioButton::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCRadioButton::setLabel( const std::string & nlabel ) +{ + label = NCstring( nlabel ); + label.stripHotkey(); + defsze = wsze( label.height(), label.width() + 4 ); + YRadioButton::setLabel( nlabel ); + Redraw(); +} + + +void NCRadioButton::setValue( bool newval ) +{ + if ( newval != checked ) + { + checked = newval; + + if ( checked && buttonGroup() ) + { + buttonGroup()->uncheckOtherButtons( this ); + } + + Redraw(); + + if (notify()) + { + NCursesEvent event = NCursesEvent::ValueChanged; + event.widget = this; + YNCursesUI::ui()->sendEvent(event); + } + } +} + + +void NCRadioButton::wRedraw() +{ + if ( !win ) + return; + + const NCstyle::StWidget & style( widgetStyle() ); + + win->bkgdset( style.plain ); + + win->printw( 0, 0, "( ) " ); + + label.drawAt( *win, style, wpos( 0, 4 ) ); + + win->bkgdset( style.data ); + + win->printw( 0, 1, "%c", ( checked ? 'x' : ' ' ) ); +} + + +NCursesEvent NCRadioButton::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + bool oldChecked = checked; + NCRadioButtonGroup * group; + + switch ( key ) + { + case KEY_HOTKEY: + case KEY_SPACE: + case KEY_RETURN: + setValue( true ); + + if ( notify() && oldChecked != checked ) + ret = NCursesEvent::ValueChanged; + + break; + + case KEY_UP: + group = dynamic_cast( buttonGroup() ); + + if ( group ) + group->focusPrevButton(); + + break; + + case KEY_DOWN: + group = dynamic_cast( buttonGroup() ); + + if ( group ) + group->focusNextButton(); + + break; + } + + return ret; +} + diff --git a/deps/libyui/libyui-ncurses/src/NCRadioButton.h b/deps/libyui/libyui-ncurses/src/NCRadioButton.h new file mode 100644 index 0000000000000000000000000000000000000000..42a39f2159537c6ff5ad76c462523ba9e7411005 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCRadioButton.h @@ -0,0 +1,86 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCRadioButton.h + + Author: Michael Andres + +/-*/ + +#ifndef NCRadioButton_h +#define NCRadioButton_h + +#include + +#include +#include "NCWidget.h" + +class NCRadioButton; + + +class NCRadioButton : public YRadioButton, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCRadioButton & obj ); + + NCRadioButton & operator=( const NCRadioButton & ); + NCRadioButton( const NCRadioButton & ); + + bool checked; + NClabel label; + +protected: + + virtual const char * location() const { return "NCRadioButton"; } + + virtual void wRedraw(); + +public: + + NCRadioButton( YWidget * parent, + const std::string & label, + bool checked ); + + virtual ~NCRadioButton(); + + virtual int preferredWidth(); + virtual int preferredHeight(); + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setLabel( const std::string & nlabel ); + + virtual void setValue( bool newval ); + virtual bool value() { return checked; } + + virtual NCursesEvent wHandleInput( wint_t key ); + + virtual void setEnabled( bool do_bv ); + + virtual bool setKeyboardFocus() + { + if ( !grabFocus() ) + return YWidget::setKeyboardFocus(); + + return true; + } +}; + + +#endif // NCRadioButton_h diff --git a/deps/libyui/libyui-ncurses/src/NCRadioButtonGroup.cc b/deps/libyui/libyui-ncurses/src/NCRadioButtonGroup.cc new file mode 100644 index 0000000000000000000000000000000000000000..1128a60409014335e8b668f3c4a075b628747041 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCRadioButtonGroup.cc @@ -0,0 +1,129 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCRadioButtonGroup.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCRadioButtonGroup.h" + + +NCRadioButtonGroup::NCRadioButtonGroup( YWidget * parent ) + : YRadioButtonGroup( parent ) + , NCWidget( parent ) + , focusId( 1 ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; +} + + +NCRadioButtonGroup::~NCRadioButtonGroup() +{ + // yuiDebug() << std::endl; +} + + +void NCRadioButtonGroup::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); + YRadioButtonGroup::setSize( newwidth, newheight ); +} + + +void NCRadioButtonGroup::addRadioButton( YRadioButton *button ) +{ + YRadioButtonGroup::addRadioButton( button ); +} + + +void NCRadioButtonGroup::removeRadioButton( YRadioButton *button ) +{ + YRadioButtonGroup::removeRadioButton( button ); +} + + +void NCRadioButtonGroup::focusNextButton() +{ + int n = 0; + + if ( focusId < radioButtonsCount() ) + focusId++; + else if ( focusId == radioButtonsCount() ) + focusId = 0; + + for ( YRadioButtonListConstIterator it = radioButtonsBegin(); + it != radioButtonsEnd(); + ++it ) + { + if ( ++n == focusId ) + { + NCRadioButton * radioButton = dynamic_cast( *it ); + + if ( radioButton ) + radioButton->setKeyboardFocus(); + } + } +} + + +void NCRadioButtonGroup::focusPrevButton() +{ + int n = 0; + + if ( focusId > 0 ) + focusId--; + else if ( focusId == 0 ) + focusId = radioButtonsCount() - 1; + + for ( YRadioButtonListConstIterator it = radioButtonsBegin(); + it != radioButtonsEnd(); + ++it ) + { + n++; + + if ( n == focusId ) + { + NCRadioButton * radioButton = dynamic_cast( *it ); + + if ( radioButton ) + radioButton->setKeyboardFocus(); + } + } +} + + +void NCRadioButtonGroup::setEnabled( bool do_bv ) +{ + for ( YRadioButtonListConstIterator it = radioButtonsBegin(); + it != radioButtonsEnd(); + ++it ) + { + NCRadioButton * radioButton = dynamic_cast( *it ); + + if ( radioButton ) + radioButton->setEnabled( do_bv ); + } + + YRadioButtonGroup::setEnabled( do_bv ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCRadioButtonGroup.h b/deps/libyui/libyui-ncurses/src/NCRadioButtonGroup.h new file mode 100644 index 0000000000000000000000000000000000000000..a38facba6100880418fd6f66a8897a8de2cddd31 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCRadioButtonGroup.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCRadioButtonGroup.h + + Author: Michael Andres + +/-*/ + +#ifndef NCRadioButtonGroup_h +#define NCRadioButtonGroup_h + +#include + +#include +#include "NCRadioButton.h" +#include "NCWidget.h" + +class NCRadioButtonGroup; + + +class NCRadioButtonGroup : public YRadioButtonGroup, public NCWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCRadioButtonGroup & obj ); + + NCRadioButtonGroup & operator=( const NCRadioButtonGroup & ); + NCRadioButtonGroup( const NCRadioButtonGroup & ); + + int focusId; + +protected: + + virtual const char * location() const { return "NCRadioButtonGroup"; } + +public: + + NCRadioButtonGroup( YWidget * parent ); + virtual ~NCRadioButtonGroup(); + + virtual int preferredWidth() { return YRadioButtonGroup::preferredWidth(); } + virtual int preferredHeight() { return YRadioButtonGroup::preferredHeight(); } + + virtual void setSize( int newWidth, int newHeight ); + + virtual void addRadioButton( YRadioButton *button ); + virtual void removeRadioButton( YRadioButton *button ); + + virtual void setEnabled( bool do_bv ); + + void focusNextButton(); + void focusPrevButton(); + +}; + + +#endif // NCRadioButtonGroup_h diff --git a/deps/libyui/libyui-ncurses/src/NCReplacePoint.cc b/deps/libyui/libyui-ncurses/src/NCReplacePoint.cc new file mode 100644 index 0000000000000000000000000000000000000000..b462fcaf0ce1e48668e23e383c7de3be343b7890 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCReplacePoint.cc @@ -0,0 +1,57 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCReplacePoint.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCurses.h" +#include "NCReplacePoint.h" + + +NCReplacePoint::NCReplacePoint( YWidget * parent ) + : YReplacePoint( parent ) + , NCWidget( parent ) +{ + // yuiDebug() << std::endl; + wstate = NC::WSdumb; +} + + +NCReplacePoint::~NCReplacePoint() +{ + // yuiDebug() << std::endl; +} + + +void NCReplacePoint::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); + YReplacePoint::setSize( newwidth, newheight ); +} + + +void NCReplacePoint::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YReplacePoint::setEnabled( do_bv ); +} diff --git a/deps/libyui/libyui-ncurses/src/NCReplacePoint.h b/deps/libyui/libyui-ncurses/src/NCReplacePoint.h new file mode 100644 index 0000000000000000000000000000000000000000..3b37f57ebbe9ead77695d7067f81d795ed0e7f5f --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCReplacePoint.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCReplacePoint.h + + Author: Michael Andres + +/-*/ + +#ifndef NCReplacePoint_h +#define NCReplacePoint_h + +#include + +#include +#include "NCWidget.h" + +class NCReplacePoint; + + +class NCReplacePoint : public YReplacePoint, public NCWidget +{ + + friend std::ostream & operator<<( std::ostream & str, const NCReplacePoint & obj ); + + NCReplacePoint & operator=( const NCReplacePoint & ); + NCReplacePoint( const NCReplacePoint & ); + +protected: + + virtual const char * location() const { return "NCReplacePoint"; } + +public: + + NCReplacePoint( YWidget * parent ); + virtual ~NCReplacePoint(); + + virtual int preferredWidth() { return YReplacePoint::preferredWidth(); } + virtual int preferredHeight() { return YReplacePoint::preferredHeight(); } + + virtual void setSize( int newWidth, int newHeight ); + + virtual void setEnabled( bool do_bv ); +}; + + +#endif // NCReplacePoint_h diff --git a/deps/libyui/libyui-ncurses/src/NCRichText.cc b/deps/libyui/libyui-ncurses/src/NCRichText.cc new file mode 100644 index 0000000000000000000000000000000000000000..94536f44bbf09a1695c9a2f5f171b73889703a81 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCRichText.cc @@ -0,0 +1,1368 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCRichText.cc + + Author: Michael Andres + +/-*/ + +#define YUILogComponent "ncurses" +#include +#include "NCRichText.h" +#include "YNCursesUI.h" +#include "stringutil.h" +#include "stdutil.h" +#include +#include + +#include +#include + +using stdutil::form; + + +const unsigned NCRichText::listindent = 4; +const std::wstring NCRichText::listleveltags( L"@*+o#-%$&" );// + +const bool NCRichText::showLinkTarget = false; + +std::map NCRichText::_charentity; + + + +const std::wstring NCRichText::entityLookup( const std::wstring & val_r ) +{ + //strip leading '#', if any + std::wstring::size_type hash = val_r.find( L"#", 0 ); + std::wstring ascii = L""; + + if ( hash != std::wstring::npos ) + { + std::wstring s = val_r.substr( hash + 1 ); + wchar_t *endptr; + //and try to convert to int (wcstol only knows "0x" for hex) + boost::replace_all( s, "x", "0x" ); + + long int c = std::wcstol( s.c_str(), &endptr, 0 ); + + //conversion succeeded + + if ( s.c_str() != endptr ) + { + std::wostringstream ws; + ws << char( c ); + ascii = ws.str(); + } + } + +#define REP(l,r) _charentity[l] = r + if ( _charentity.empty() ) + { + // initialize replacement for character entities. A value of NULL + // means do not replace. + std::wstring product; + NCstring::RecodeToWchar( YUI::app()->productName(), "UTF-8", &product ); + + REP( L"amp", L"&" ); + REP( L"gt", L">" ); + REP( L"lt", L"<" ); + REP( L"nbsp", L" " ); + REP( L"quot", L"\"" ); + REP( L"product", product ); + } + + std::map::const_iterator it = _charentity.find( val_r ); + + if ( it != _charentity.end() ) + { + //known entity - already in the map + return it->second; + } + else + { + if ( !ascii.empty() ) + { + //replace ascii code by character - e.g. #42 -> '*' + //and insert into map to remember it + REP( val_r, ascii ); + } + } + + return ascii; + +#undef REP +} + + + +/** + * Filter out the known &...; entities and return the text with entities + * replaced + **/ +const std::wstring NCRichText::filterEntities( const std::wstring & text ) +{ + std::wstring txt = text; + // filter known '&..;' + + for ( std::wstring::size_type special = txt.find( L"&" ); + special != std::wstring::npos; + special = txt.find( L"&", special + 1 ) ) + { + std::wstring::size_type colon = txt.find( L";", special + 1 ); + + if ( colon == std::wstring::npos ) + break; // no ';' -> no need to continue + + const std::wstring repl = entityLookup( txt.substr( special + 1, colon - special - 1 ) ); + + if ( !repl.empty() + || txt.substr( special + 1, colon - special - 1 ) == L"product" ) // always replace &product; + { + txt.replace( special, colon - special + 1, repl ); + } + else + yuiDebug() << "porn.bat" << std::endl; + } + + return txt; +} + + +void NCRichText::Anchor::draw( NCPad & pad, const chtype attr, int color ) +{ + unsigned l = sline; + unsigned c = scol; + + while ( l < eline ) + { + pad.move( l, c ); + pad.chgat( -1, attr, color ); + ++l; + c = 0; + } + + pad.move( l, c ); + + pad.chgat( ecol - c, attr, color ); +} + + +NCRichText::NCRichText( YWidget * parent, const std::string & ntext, + bool plainTextMode ) + : YRichText( parent, ntext, plainTextMode ) + , NCPadWidget( parent ) + , text( ntext ) + , plainText( plainTextMode ) + , textwidth( 0 ) + , cl( 0 ) + , cc( 0 ) + , cindent( 0 ) + , atbol( true ) + , preTag( false ) + , Tattr( 0 ) +{ + // yuiDebug() << std::endl; + activeLabelOnly = true; + setValue( ntext ); +} + + +NCRichText::~NCRichText() +{ + // yuiDebug() << std::endl; +} + + +int NCRichText::preferredWidth() +{ + return wGetDefsze().W; +} + + +int NCRichText::preferredHeight() +{ + return wGetDefsze().H; +} + + +void NCRichText::setEnabled( bool do_bv ) +{ + NCWidget::setEnabled( do_bv ); + YRichText::setEnabled( do_bv ); +} + + +void NCRichText::setSize( int newwidth, int newheight ) +{ + wRelocate( wpos( 0 ), wsze( newheight, newwidth ) ); +} + + +void NCRichText::setLabel( const std::string & nlabel ) +{ + // not implemented: YRichText::setLabel( nlabel ); + NCPadWidget::setLabel( NCstring( nlabel ) ); +} + + +void NCRichText::setValue( const std::string & ntext ) +{ + DelPad(); + text = NCstring( ntext ); + YRichText::setValue( ntext ); + Redraw(); +} + + +void NCRichText::wRedraw() +{ + if ( !win ) + return; + + bool initial = ( !myPad() || !myPad()->Destwin() ); + + if ( !( plainText || anchors.empty() ) ) + arm( armed ); + + NCPadWidget::wRedraw(); + + if ( initial && autoScrollDown() ) + { + myPad()->ScrlTo( wpos( myPad()->maxy(), 0 ) ); + } + + return; +} + + +void NCRichText::wRecoded() +{ + DelPad(); + wRedraw(); +} + + +void NCRichText::activateLink( const std::string & url ) +{ + NCursesEvent event = NCursesEvent::menu; + event.result = url; + event.widget = this; + YNCursesUI::ui()->sendEvent( event ); +} + + +NCursesEvent NCRichText::wHandleInput( wint_t key ) +{ + NCursesEvent ret; + handleInput( key ); + + if ( !( plainText || anchors.empty() ) ) + { + switch ( key ) + { + case KEY_SPACE: + case KEY_RETURN: + + if ( armed != Anchor::unset ) + { + ret = NCursesEvent::menu; + std::string str; + NCstring::RecodeFromWchar( anchors[armed].target, "UTF-8", &str ); + yuiMilestone() << "LINK: " << str << std::endl; + ret.result = str; + ret.selection = NULL; + } + + break; + } + } + return ret; +} + + +NCPad * NCRichText::CreatePad() +{ + wsze psze( defPadSze() ); + textwidth = psze.W; + NCPad * npad = new NCPad( psze.H, textwidth, *this ); + return npad; +} + + +void NCRichText::DrawPad() +{ +#if 0 + yuiDebug() << "Start: plain mode " << plainText << std::endl + << " padsize " << myPad()->size() << std::endl + << " text length " << text.str().size() << std::endl; +#endif + + myPad()->bkgdset( wStyle().richtext.plain ); + myPad()->clear(); + + if ( plainText ) + DrawPlainPad(); + else + DrawHTMLPad(); + + // yuiDebug() << "Done" << std::endl; +} + + +void NCRichText::DrawPlainPad() +{ + NCtext ftext( text ); + // yuiDebug() << "ftext is " << wsze( ftext.Lines(), ftext.Columns() ) << std::endl; + + AdjustPad( wsze( ftext.Lines(), ftext.Columns() ) ); + + cl = 0; + + for ( NCtext::const_iterator line = ftext.begin(); + line != ftext.end(); ++line, ++cl ) + { + myPad()->addwstr( cl, 0, ( *line ).str().c_str() ); + } +} + +void NCRichText::PadPreTXT( const wchar_t * osch, const unsigned olen ) +{ + std::wstring wtxt( osch, olen ); + + // resolve the entities even in PRE (#71718) + wtxt = filterEntities( wtxt ); + + NCstring nctxt( wtxt ); + NCtext ftext( nctxt ); + + // insert the text + const wchar_t * sch = wtxt.data(); + + while ( *sch ) + { + myPad()->addwstr( sch, 1 ); // add one wide chararacter + + ++sch; + } +} + +// +// DrawHTMLPad tools +// + +inline void SkipToken( const wchar_t *& wch ) +{ + do + { + ++wch; + } + while ( *wch && *wch != L'>' ); + + if ( *wch ) + ++wch; +} + + +static std::wstring WStoken( L" \n\t\v\r\f" ); + + +inline void SkipWS( const wchar_t *& wch ) +{ + do + { + ++wch; + } + while ( *wch && WStoken.find( *wch ) != std::wstring::npos ); +} + + +static std::wstring WDtoken( L" <\n\t\v\r\f" ); // WS + TokenStart '<' + + +inline void SkipWord( const wchar_t *& wch ) +{ + do + { + ++wch; + } + while ( *wch && WDtoken.find( *wch ) == std::wstring::npos ); +} + +static std::wstring PREtoken( L"<\n\v\r\f" ); // line manipulations + TokenStart '<' + + +inline void SkipPreTXT( const wchar_t *& wch ) +{ + do + { + ++wch; + } + while ( *wch && PREtoken.find( *wch ) == std::wstring::npos ); +} + + +// +// Calculate longest line of text in
 
tags +// and adjust the pad accordingly +// +void NCRichText::AdjustPrePad( const wchar_t *osch ) +{ + const wchar_t * wch = osch; + std::wstring wstr( wch, 6 ); + + do + { + ++wch; + wstr.assign( wch, 6 ); + } + while ( *wch && wstr != L"
" ); + + std::wstring wtxt( osch, wch - osch ); + + // resolve the entities to get correct length for calculation of longest line + wtxt = filterEntities( wtxt ); + + // replace
by \n to get appropriate lines in NCtext + boost::replace_all( wtxt, L"
", L"\n" ); + boost::replace_all( wtxt, L"
", L"\n" ); + + // yuiDebug() << "Text: " << wtxt << " initial length: " << wch - osch << std::endl; + + NCstring nctxt( wtxt ); + NCtext ftext( nctxt ); + + std::list::const_iterator line; + size_t llen = 0; // longest line + + // iterate through NCtext + for ( line = ftext.Text().begin(); line != ftext.Text().end(); ++line ) + { + size_t tmp_len = 0; + + tmp_len = textWidth( (*line).str() ); + + if ( tmp_len > llen ) + llen = tmp_len; + } + // yuiDebug() << "Longest line: " << llen << std::endl; + + if ( llen > textwidth ) + { + textwidth = llen; + AdjustPad( wsze( cl + ftext.Lines(), llen ) ); // adjust pad to longest line + } + +} + +void NCRichText::DrawHTMLPad() +{ + // yuiDebug() << "Start:" << std::endl; + + liststack = std::stack(); + canchor = Anchor(); + anchors.clear(); + armed = Anchor::unset; + + cl = 0; + cc = 0; + cindent = 0; + myPad()->move( cl, cc ); + atbol = true; + + const wchar_t * wch = ( wchar_t * )text.str().data(); + const wchar_t * swch = 0; + + while ( *wch ) + { + switch ( *wch ) + { + case L' ': + case L'\t': + case L'\n': + case L'\v': + case L'\r': + case L'\f': + if ( ! preTag ) + { + SkipWS( wch ); + PadWS(); + } + else + { + switch ( *wch ) + { + case L' ': // add white space + case L'\t': + myPad()->addwstr( wch, 1 ); + break; + + case L'\n': + case L'\f': + PadNL(); // add new line + break; + + default: + yuiDebug() << "Ignoring " << *wch << std::endl; + } + ++wch; + } + + break; + + case L'<': + swch = wch; + SkipToken( wch ); + + if ( PadTOKEN( swch, wch ) ) + break; // strip token + else + wch = swch; // reset and fall through + + default: + swch = wch; + + if ( !preTag ) + { + SkipWord( wch ); + PadTXT( swch, wch - swch ); + } + else + { + SkipPreTXT( wch ); + PadPreTXT( swch, wch - swch ); + } + + break; + } + } + + PadBOL(); + AdjustPad( wsze( cl, textwidth ) ); + +#if 0 + yuiDebug() << "Anchors: " << anchors.size() << std::endl; + + for ( unsigned i = 0; i < anchors.size(); ++i ) + { + yuiDebug() << form( " %2d: [%2d,%2d] -> [%2d,%2d]", + i, + anchors[i].sline, anchors[i].scol, + anchors[i].eline, anchors[i].ecol ) << std::endl; + } +#endif +} + + +inline void NCRichText::PadNL() +{ + cc = cindent; + + if ( ++cl == (unsigned) myPad()->height() ) + { + AdjustPad( wsze( myPad()->height() + defPadSze().H, textwidth ) ); + } + + myPad()->move( cl, cc ); + + atbol = true; +} + + +inline void NCRichText::PadBOL() +{ + if ( !atbol ) + PadNL(); +} + + +inline void NCRichText::PadWS( bool tab ) +{ + if ( atbol ) + return; // no WS at beginning of line + + if ( cc == textwidth ) + { + PadNL(); + } + else + { + myPad()->addwstr( L" " ); + ++cc; + } +} + + +inline void NCRichText::PadTXT( const wchar_t * osch, const unsigned olen ) +{ + std::wstring txt( osch, olen ); + + txt = filterEntities( txt ); + + size_t len = textWidth( txt ); + + if ( !atbol && cc + len > textwidth ) + PadNL(); + + // insert the text + const wchar_t * sch = txt.data(); + + while ( *sch ) + { + myPad()->addwstr( sch, 1 ); // add one wide chararacter + cc += wcwidth( *sch ); + atbol = false; // at begin of line = false + + if ( cc >= textwidth ) + { + PadNL(); // add a new line + } + + sch++; + } +} + +/** + * Get the number of columns needed to print a 'std::wstring'. Only printable characters + * are taken into account because otherwise 'wcwidth' would return -1 (e.g. for '\n'). + * Tabs are calculated with tabsize(). + * Attention: only use textWidth() to calculate space, not for iterating through a text + * or to get the length of a text (real text length includes new lines). + */ +size_t NCRichText::textWidth( std::wstring wstr ) +{ + size_t len = 0; + std::wstring::const_iterator wstr_it; // iterator for std::wstring + + for ( wstr_it = wstr.begin(); wstr_it != wstr.end() ; ++wstr_it ) + { + // check whether char is printable + if ( iswprint( *wstr_it ) ) + { + len += wcwidth( *wstr_it ); + } + else if ( *wstr_it == '\t' ) + { + len += myPad()->tabsize(); + } + } + + return len; +} + + +/** + * Set character attributes (e.g. color, font face...) + **/ +inline void NCRichText::PadSetAttr() +{ + const NCstyle::StRichtext & style( wStyle().richtext ); + chtype nbg = style.plain; + + if ( Tattr & T_ANC ) + { + nbg = style.link; + } + else if ( Tattr & T_HEAD ) + { + nbg = style.title; + } + else + { + switch ( Tattr & Tfontmask ) + { + case T_BOLD: + nbg = style.B; + break; + + case T_IT: + nbg = style.I; + break; + + case T_TT: + nbg = style.T; + break; + + case T_BOLD|T_IT: + nbg = style.BI; + break; + + case T_BOLD|T_TT: + nbg = style.BT; + break; + + case T_IT|T_TT: + nbg = style.IT; + break; + + case T_BOLD|T_IT|T_TT: + nbg = style.BIT; + break; + } + } + + myPad()->bkgdset( nbg ); +} + + +void NCRichText::PadSetLevel() +{ + cindent = listindent * liststack.size(); + + if ( cindent > textwidth / 2 ) + cindent = textwidth / 2; + + if ( atbol ) + { + cc = cindent; + myPad()->move( cl, cc ); + } +} + + +void NCRichText::PadChangeLevel( bool down, int tag ) +{ + if ( down ) + { + if ( liststack.size() ) + liststack.pop(); + } + else + { + liststack.push( tag ); + } + + PadSetLevel(); +} + + +void NCRichText::openAnchor( std::wstring args ) +{ + canchor.open( cl, cc ); + + const wchar_t * ch = ( wchar_t * )args.data(); + const wchar_t * lookupstr = L"href = "; + const wchar_t * lookup = lookupstr; + + for ( ; *ch && *lookup; ++ch ) + { + wchar_t c = towlower( *ch ); + + switch ( c ) + { + case L'\t': + case L' ': + + if ( *lookup != L' ' ) + lookup = lookupstr; + + break; + + default: + if ( *lookup == L' ' ) + { + ++lookup; + + if ( !*lookup ) + { + // ch is the 1st char after lookupstr + --ch; // end of loop will ++ch + break; + } + } + + if ( c == *lookup ) + ++lookup; + else + lookup = lookupstr; + + break; + } + } + + if ( !*lookup ) + { + const wchar_t * delim = ( *ch == L'"' ) ? L"\"" : L" \t"; + args = ( *ch == L'"' ) ? ++ch : ch; + + std::wstring::size_type end = args.find_first_of( delim ); + + if ( end != std::wstring::npos ) + args.erase( end ); + + canchor.target = args; + } + else + { + yuiError() << "No value for 'HREF=' in anchor '" << args << "'" << std::endl; + } +} + + +void NCRichText::closeAnchor() +{ + canchor.close( cl, cc ); + + if ( canchor.valid() ) + anchors.push_back( canchor ); + + canchor = Anchor(); +} + + +// expect "<[/]value>" +bool NCRichText::PadTOKEN( const wchar_t * sch, const wchar_t *& ech ) +{ + // "<[/]value>" + if ( *sch++ != L'<' || *( ech - 1 ) != L'>' ) + return false; + + // "[/]value>" + bool endtag = ( *sch == L'/' ); + + if ( endtag ) + ++sch; + + // "value>" + if ( ech - sch <= 1 ) + return false; + + std::wstring value( sch, ech - 1 - sch ); + + std::wstring args; + + std::wstring::size_type argstart = value.find_first_of( L" \t\n" ); + + if ( argstart != std::wstring::npos ) + { + args = value.substr( argstart ); + value.erase( argstart ); + } + + for ( unsigned i = 0; i < value.length(); ++i ) + { + if ( isupper( value[i] ) ) + { + value[i] = static_cast( tolower( value[i] ) ); + } + } + + int leveltag = 0; + + int headinglevel = 0; + + TOKEN token = T_UNKNOWN; + + switch ( value.length() ) + { + case 1: + + if ( value[0] == 'b' ) token = T_BOLD; + else if ( value[0] == 'i' ) token = T_IT; + else if ( value[0] == 'p' ) token = T_PAR; + else if ( value[0] == 'a' ) token = T_ANC; + else if ( value[0] == 'u' ) token = T_BOLD; + + break; + + case 2: + if ( value == L"br" ) token = T_BR; + else if ( value == L"em" ) token = T_IT; + else if ( value == L"h1" ) { token = T_HEAD; headinglevel = 1; } + else if ( value == L"h2" ) { token = T_HEAD; headinglevel = 2; } + else if ( value == L"h3" ) { token = T_HEAD; headinglevel = 3; } + else if ( value == L"hr" ) token = T_IGNORE; + else if ( value == L"li" ) token = T_LI; + else if ( value == L"ol" ) { token = T_LEVEL; leveltag = 1; } + else if ( value == L"qt" ) token = T_IGNORE; + else if ( value == L"tt" ) token = T_TT; + else if ( value == L"ul" ) { token = T_LEVEL; leveltag = 0; } + + break; + + case 3: + + if ( value == L"big" ) token = T_IGNORE; + else if ( value == L"pre" ) token = T_PLAIN; + //
and
are the only non-pair tags currently supported. + // We treat bellow these two special cases in order to work as + // users expect. This issue was described at + // https://github.com/libyui/libyui-ncurses/issues/33 + else if ( value == L"br/" ) token = T_BR; + else if ( value == L"hr/" ) token = T_IGNORE; + + break; + + case 4: + if ( value == L"bold" ) token = T_BOLD; + else if ( value == L"code" ) token = T_TT; + else if ( value == L"font" ) token = T_IGNORE; + + break; + + case 5: + if ( value == L"large" ) token = T_IGNORE; + else if ( value == L"small" ) token = T_IGNORE; + + break; + + case 6: + if ( value == L"center" ) token = T_PAR; + else if ( value == L"strong" ) token = T_BOLD; + + break; + + case 10: + if ( value == L"blockquote" ) token = T_PAR; + + break; + + default: + token = T_UNKNOWN; + + break; + } + + if ( token == T_UNKNOWN ) + { + yuiDebug() << "T_UNKNOWN :" << value << ":" << args << ":" << std::endl; + // see bug #67319 + // return false; + return true; + } + + if ( token == T_IGNORE ) + return true; + + switch ( token ) + { + case T_LEVEL: + PadChangeLevel( endtag, leveltag ); + PadBOL(); + // add new line after end of the list + // (only at the very end) + if ( endtag && !cindent ) + PadNL(); + + break; + + case T_BR: + PadNL(); + + break; + + case T_HEAD: + if ( endtag ) + Tattr &= ~token; + else + Tattr |= token; + + PadSetAttr(); + PadBOL(); + + if ( headinglevel && endtag ) + PadNL(); + + break; + + case T_PAR: + PadBOL(); + + if ( !cindent ) + { + if ( endtag ) + // add new line after closing tag (FaTE 3124) + PadNL(); + } + + break; + + case T_LI: + PadSetLevel(); + PadBOL(); + + if ( !endtag ) + { + std::wstring tag; + + if ( liststack.empty() ) + { + tag = std::wstring( listindent, L' ' ); + } + else + { + wchar_t buf[16]; + + if ( liststack.top() ) + { + swprintf( buf, 15, L"%2ld. ", liststack.top()++ ); + } + else + { + swprintf( buf, 15, L" %lc ", listleveltags[liststack.size()%listleveltags.size()] ); + } + + tag = buf; + } + + // outsent list tag: + cc = ( tag.size() < cc ? cc - tag.size() : 0 ); + + myPad()->move( cl, cc ); + + PadTXT( tag.c_str(), tag.size() ); + + atbol = true; + } + + break; + + case T_PLAIN: + + if ( !endtag ) + { + preTag = true; // display text preserving newlines and spaces + AdjustPrePad( ech ); + } + else + { + preTag = false; + PadNL(); // add new line (text may continue after
) + } + + break; + + case T_ANC: + + if ( endtag ) + { + closeAnchor(); + } + else + { + openAnchor( args ); + } + + // fall through + + case T_BOLD: + case T_IT: + case T_TT: + if ( endtag ) + Tattr &= ~token; + else + Tattr |= token; + + PadSetAttr(); + + break; + + case T_IGNORE: + case T_UNKNOWN: + break; + } + + return true; +} + + +void NCRichText::arm( unsigned i ) +{ + if ( !myPad() ) + { + armed = i; + return; + } + + // yuiDebug() << i << " (" << armed << ")" << std::endl; + + if ( i == armed ) + { + if ( armed != Anchor::unset ) + { + // just redraw + anchors[armed].draw( *myPad(), wStyle().richtext.getArmed( GetState() ), 0 ); + myPad()->update(); + } + + return; + } + + if ( armed != Anchor::unset ) + { + anchors[armed].draw( *myPad(), wStyle().richtext.link, (int) wStyle().richtext.visitedlink ); + armed = Anchor::unset; + } + + if ( i != Anchor::unset ) + { + armed = i; + anchors[armed].draw( *myPad(), wStyle().richtext.getArmed( GetState() ), 0 ); + } + + if ( showLinkTarget ) + { + if ( armed != Anchor::unset ) + NCPadWidget::setLabel( NCstring( anchors[armed].target ) ); + else + NCPadWidget::setLabel( NCstring() ); + } + else + { + myPad()->update(); + } +} + + +void NCRichText::HScroll( unsigned total, unsigned visible, unsigned start ) +{ + NCPadWidget::HScroll( total, visible, start ); + // no hyperlink handling needed, because Richtext does not HScroll +} + + +void NCRichText::VScroll( unsigned total, unsigned visible, unsigned start ) +{ + NCPadWidget::VScroll( total, visible, start ); + + if ( plainText || anchors.empty() ) + return; // <-- no links to check + + // Take care of hyperlinks: Check whether an armed link is visible. + // If not arm the first visible link on page or none. + vScrollFirstvisible = start; + + vScrollNextinvisible = start + visible; + + if ( armed != Anchor::unset ) + { + if ( anchors[armed].within( vScrollFirstvisible, vScrollNextinvisible ) ) + return; // <-- armed link is vissble + else + disarm(); + } + + for ( unsigned i = 0; i < anchors.size(); ++i ) + { + if ( anchors[i].within( vScrollFirstvisible, vScrollNextinvisible ) ) + { + arm( i ); + break; + } + } +} + + +bool NCRichText::handleInput( wint_t key ) +{ + if ( plainText || anchors.empty() ) + { + return NCPadWidget::handleInput( key ); + } + + // take care of hyperlinks + bool handled = true; + + switch ( key ) + { + case KEY_LEFT: + // jump to previous link; scroll up if none + { + unsigned newarmed = Anchor::unset; + + if ( armed == Anchor::unset ) + { + // look for an anchor above current page + for ( unsigned i = anchors.size(); i; ) + { + --i; + + if ( anchors[i].eline < vScrollFirstvisible ) + { + newarmed = i; + break; + } + } + } + else if ( armed > 0 ) + { + newarmed = armed - 1; + } + + if ( newarmed == Anchor::unset ) + { + handled = NCPadWidget::handleInput( KEY_UP ); + } + else + { + if ( !anchors[newarmed].within( vScrollFirstvisible, vScrollNextinvisible ) ) + myPad()->ScrlLine( anchors[newarmed].sline ); + + arm( newarmed ); + } + } + + break; + + case KEY_RIGHT: + // jump to next link; scroll down if none + { + unsigned newarmed = Anchor::unset; + + if ( armed == Anchor::unset ) + { + // look for an anchor below current page + for ( unsigned i = 0; i < anchors.size(); ++i ) + { + if ( anchors[i].sline >= vScrollNextinvisible ) + { + newarmed = i; + break; + } + } + } + else if ( armed + 1 < anchors.size() ) + { + newarmed = armed + 1; + } + + if ( newarmed == Anchor::unset ) + { + handled = NCPadWidget::handleInput( KEY_DOWN ); + } + else + { + if ( !anchors[newarmed].within( vScrollFirstvisible, vScrollNextinvisible ) ) + myPad()->ScrlLine( anchors[newarmed].sline ); + + arm( newarmed ); + } + } + + break; + + case KEY_UP: + // arm previous visible link; scroll up if none + + if ( armed != Anchor::unset + && armed > 0 + && anchors[armed-1].within( vScrollFirstvisible, vScrollNextinvisible ) ) + { + arm( armed - 1 ); + } + else + { + handled = NCPadWidget::handleInput( key ); + } + + break; + + case KEY_DOWN: + // arm next visible link; scroll down if none + + if ( armed != Anchor::unset + && armed + 1 < anchors.size() + && anchors[armed+1].within( vScrollFirstvisible, vScrollNextinvisible ) ) + { + arm( armed + 1 ); + } + else + { + handled = NCPadWidget::handleInput( key ); + } + + break; + + default: + handled = NCPadWidget::handleInput( key ); + }; + + return handled; +} + + +std::string NCRichText::vScrollValue() const +{ + const NCPad* mypad = myPad(); + + if ( !mypad ) + return ""; + + return std::to_string( mypad->CurPos().L ); +} + + +void NCRichText::setVScrollValue( const std::string & newValue ) +{ + NCPad* mypad = myPad(); + + if ( !mypad || newValue.empty() ) + return; + + if ( newValue == "minimum" ) + mypad->ScrlLine( 0 ); + else if ( newValue == "maximum" ) + mypad->ScrlLine( mypad->maxy() ); + else + { + try + { + mypad->ScrlLine( std::stoi( newValue ) ); + } + catch (...) + { + yuiError() << "failed to set vertical scroll value '" << newValue << "'" << endl; + } + } +} + + +std::string NCRichText::hScrollValue() const +{ + const NCPad* mypad = myPad(); + + if ( !mypad ) + return ""; + + return std::to_string( mypad->CurPos().C ); +} + + +void NCRichText::setHScrollValue( const std::string & newValue ) +{ + NCPad* mypad = myPad(); + + if ( !mypad || newValue.empty() ) + return; + + if ( newValue == "minimum" ) + mypad->ScrlCol( 0 ); + else if ( newValue == "maximum" ) + mypad->ScrlCol( mypad->maxx() ); + else + { + try + { + mypad->ScrlCol( std::stoi( newValue ) ); + } + catch (...) + { + yuiError() << "failed to set horizontal scroll value '" << newValue << "'" << endl; + } + } +} diff --git a/deps/libyui/libyui-ncurses/src/NCRichText.h b/deps/libyui/libyui-ncurses/src/NCRichText.h new file mode 100644 index 0000000000000000000000000000000000000000..68f86ac908a730355730acc53e0a2fc0041ab023 --- /dev/null +++ b/deps/libyui/libyui-ncurses/src/NCRichText.h @@ -0,0 +1,258 @@ +/* + Copyright (C) 2000-2012 Novell, Inc + This library 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.1 of the + License, or (at your option) version 3.0 of the License. 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 Lesser General Public + License for more details. You should have received a copy of the GNU + Lesser General Public License along with this library; if not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + Floor, Boston, MA 02110-1301 USA +*/ + + +/*-/ + + File: NCRichText.h + + Author: Michael Andres + +/-*/ + +#ifndef NCRichText_h +#define NCRichText_h + +#include +#include + +#include +#include "NCPadWidget.h" + + +class NCRichText : public YRichText, public NCPadWidget +{ +private: + + friend std::ostream & operator<<( std::ostream & str, const NCRichText & obj ); + + NCRichText & operator=( const NCRichText & ); + NCRichText( const NCRichText & ); + + /** + * Lookup std::map for character entities (e.g. '>'). Initialized + * and used by entityLookup. + **/ + static std::map _charentity; + + /** + * Lookup and return replacement for a character entity. Expects + * the leading '&' and trailing ';'<.code> to + * be stripped from val_r. Returns NULL, + * if the character entity should not be replaced. + **/ + static const std::wstring entityLookup( const std::wstring & val_r ); + + /** + * Lookup and replace all replacements for a character entity. + **/ + static const std::wstring filterEntities( const std::wstring & text ); + +private: + + NCstring text; + + bool plainText; + + unsigned textwidth; + unsigned cl; + unsigned cc; + unsigned cindent; + bool atbol; + + bool preTag; //
 tag
+
+    unsigned Tattr;
+
+    static const unsigned Tfontmask = 0xff00;
+    enum TOKEN
+    {
+	T_UNKNOWN = 0x0000,
+	T_IGNORE  = 0x0001,
+	T_BR	  = 0x0002,
+	T_PAR	  = 0x0004,
+	T_LEVEL   = 0x0008,
+	T_LI	  = 0x0010,
+	T_PLAIN	= 0x0012,
+	// font
+	T_BOLD	  = 0x0100,
+	T_IT	  = 0x0200,
+	T_TT	  = 0x0400,
+	T_ANC	  = 0x0800,
+	T_HEAD	  = 0x1000
+    };
+
+private:
+
+    static const unsigned listindent;
+    static const std::wstring   listleveltags;
+
+    std::stack liststack;
+
+    void PadChangeLevel( bool down, int tag );
+    void PadSetLevel();
+    size_t textWidth( std::wstring wstr );
+
+private:
+
+    class Anchor
+    {
+
+    public:
+
+	static const unsigned unset = (unsigned) - 1;
+
+	unsigned sline;
+	unsigned scol;
+	unsigned eline;
+	unsigned ecol;
+
+	std::wstring target;
+
+	Anchor()
+	{
+	    sline = scol = eline = ecol = unset;
+	}
+
+	Anchor( int sl, int sc )
+	{
+	    open( sl, sc );
+	}
+
+	void open( int sl, int sc )
+	{
+	    sline = sl;
+	    scol  = sc;
+	    eline = ecol = unset;
+	    target = L"";
+	}
+
+	void close( int el, int ec )
+	{
+	    eline = el;
+	    ecol  = ec;
+	}
+
+	bool valid()
+	{
+	    if ( sline == unset || scol == unset
+		 || eline == unset || ecol == unset )
+		return false;
+
+	    if (( eline == sline && ecol <= scol )
+		|| eline < sline )
+		return false;
+
+	    return true;
+	}
+
+	bool within( unsigned firstvisible, unsigned nextinvisible )
+	{
+	    return sline < nextinvisible && eline >= firstvisible;
+	}
+
+	void draw( NCPad & pad, const chtype attr, int color );
+    };
+
+    static const bool showLinkTarget;
+
+    Anchor		canchor;
+    std::vector	anchors;
+    unsigned		armed;
+
+    unsigned vScrollFirstvisible;
+    unsigned vScrollNextinvisible;
+
+    void openAnchor( std::wstring args );
+    void closeAnchor();
+
+    void arm( unsigned i );
+    void disarm() { arm( Anchor::unset ); }
+
+private:
+
+    void PadSetAttr();
+
+    void DrawPlainPad();
+    void DrawHTMLPad();
+
+    void PadNL();
+    void PadBOL();
+    void PadWS( bool tab = false );
+    void PadTXT( const wchar_t * sch, const unsigned len );
+    void PadPreTXT( const wchar_t * sch, const unsigned len );
+    void AdjustPrePad( const wchar_t * sch );
+    bool PadTOKEN( const wchar_t * sch, const wchar_t *& ech );
+
+protected:
+
+    virtual const char * location() const { return "NCRichText"; }
+
+    virtual void wRedraw();
+    virtual void wRecoded();
+
+    virtual NCPad * CreatePad();
+    virtual void    DrawPad();
+
+    virtual void HScroll( unsigned total, unsigned visible, unsigned start ) override;
+    virtual void VScroll( unsigned total, unsigned visible, unsigned start ) override;
+
+    virtual bool handleInput( wint_t key );
+
+public:
+
+    NCRichText( YWidget * parent, const std::string & text,
+		bool plainTextMode = false );
+    virtual ~NCRichText();
+
+    virtual int preferredWidth();
+    virtual int preferredHeight();
+
+    virtual void setSize( int newWidth, int newHeight );
+
+    virtual void setLabel( const std::string & nlabel );
+
+    virtual NCursesEvent wHandleInput( wint_t key );
+
+    virtual void setValue( const std::string & ntext ) override;
+
+    virtual void setEnabled( bool do_bv );
+
+    virtual bool setKeyboardFocus()
+    {
+	if ( !grabFocus() )
+	    return YWidget::setKeyboardFocus();
+
+	return true;
+    }
+
+    virtual std::string vScrollValue() const override;
+
+    virtual void setVScrollValue( const std::string & newValue ) override;
+
+    virtual std::string hScrollValue() const override;
+
+    virtual void setHScrollValue( const std::string & newValue ) override;
+
+    /**
+     * Derived classes should implement this, method is used to trigger event
+     * like user has pressed the link in the RichText
+     **/
+    virtual void activateLink( const std::string & url );
+
+};
+
+
+#endif // NCRichText_h
diff --git a/deps/libyui/libyui-ncurses/src/NCSelectionBox.cc b/deps/libyui/libyui-ncurses/src/NCSelectionBox.cc
new file mode 100644
index 0000000000000000000000000000000000000000..83a962072bb6385ab1cd982d0a8446d5e3108d2c
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCSelectionBox.cc
@@ -0,0 +1,254 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCSelectionBox.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCSelectionBox.h"
+
+
+
+NCSelectionBox::NCSelectionBox( YWidget * parent, const std::string & nlabel )
+	: YSelectionBox( parent, nlabel )
+	, NCPadWidget( parent )
+	, biglist( false )
+{
+    // yuiDebug() << std::endl;
+    InitPad();
+    setLabel( nlabel );
+}
+
+
+NCSelectionBox::~NCSelectionBox()
+{
+    // yuiDebug() << std::endl;
+}
+
+
+int NCSelectionBox::preferredWidth()
+{
+    wsze sze = biglist ? myPad()->tableSize() + 2 : wGetDefsze();
+    return sze.W > (int)( labelWidth() + 2 ) ? sze.W : ( labelWidth() + 2 );
+}
+
+
+int NCSelectionBox::preferredHeight()
+{
+    wsze sze = biglist ? myPad()->tableSize() + 2 : wGetDefsze();
+    return sze.H;
+}
+
+
+void NCSelectionBox::setSize( int newwidth, int newheight )
+{
+    wRelocate( wpos( 0 ), wsze( newheight, newwidth ) );
+}
+
+
+void NCSelectionBox::setEnabled( bool do_bv )
+{
+    NCWidget::setEnabled( do_bv );
+    YSelectionBox::setEnabled( do_bv );
+}
+
+
+int NCSelectionBox::getCurrentItem() const
+{
+    if ( !myPad()->Lines() )
+	return -1;
+
+    // yuiDebug() << "Current pos: " << myPad()->CurPos().L << std::endl;
+
+    return myPad()->CurPos().L;
+}
+
+
+std::string NCSelectionBox::getLine( int index )
+{
+    NCTableLine * line = const_cast( myPad()->GetLine( index ) );
+    NCTableCol * value;
+    std::string val;
+
+    if ( line->Cols() == 1 )
+    {
+	value = line->GetItems()[0];
+	const NClabel label = value->Label();
+	const std::list text = label.getText();
+	std::list::const_iterator it = text.begin();
+
+	while ( it != text.end() )
+	{
+	    val += ( *it ).Str();
+	    ++it;
+	}
+    }
+
+    return val;
+}
+
+
+void NCSelectionBox::setCurrentItem( int index )
+{
+    myPad()->ScrlLine( index );
+}
+
+
+void NCSelectionBox::selectItem( YItem *item, bool selected )
+{
+    YSelectionBox::selectItem( item, selected );
+
+    myPad()->ScrlLine( selected ? item->index() : -1 );
+}
+
+
+void NCSelectionBox::selectItem( int index )
+{
+    YSelectionBox::deselectAllItems();
+
+    if ( hasItems() && index >= 0 )
+    {
+	YItem * item = YSelectionBox::itemAt( index );
+
+	if ( item )
+	{
+	    // yuiDebug() << "selectItem:	" << item->label().c_str() << std::endl;
+	    item->setSelected( true );
+	}
+	else
+	    YUI_THROW( YUIException( "Can't find selected item" ) );
+    }
+}
+
+
+void NCSelectionBox::addItem( YItem * item )
+{
+    std::vector cells( 1U, 0 );
+
+    if ( item )
+    {
+        item->setIndex( itemsCount() );
+	YSelectionBox::addItem( item );
+	cells[0] = new NCTableCol( item->label() );
+	myPad()->Append( cells, item->index() );
+	DrawPad();
+
+	if ( item->selected() )
+	    myPad()->ScrlLine( myPad()->Lines() );
+    }
+}
+
+
+void NCSelectionBox::addItem( const std::string & description, bool selected )
+{
+    YSelectionWidget::addItem( description, selected );
+}
+
+
+void NCSelectionBox::setLabel( const std::string & nlabel )
+{
+    YSelectionBox::setLabel( nlabel );
+    NCPadWidget::setLabel( NCstring( nlabel ) );
+}
+
+
+NCPad * NCSelectionBox::CreatePad()
+{
+    wsze    psze( defPadSze() );
+    NCPad * npad = new NCTablePad( psze.H, psze.W, *this );
+    npad->bkgd( listStyle().item.plain );
+
+    return npad;
+}
+
+
+void NCSelectionBox::wRecoded()
+{
+    NCPadWidget::wRecoded();
+}
+
+
+NCursesEvent NCSelectionBox::wHandleInput( wint_t key )
+{
+    NCursesEvent ret = NCursesEvent::none;
+
+    int oldItem = getCurrentItem();
+
+    // handle key event first
+
+    if ( sendKeyEvents() &&
+	 ( key == KEY_LEFT || key == KEY_RIGHT ) )
+    {
+	ret = NCursesEvent::key;
+
+	switch ( key )
+	{
+	    case KEY_LEFT:
+		ret.keySymbol = "CursorLeft";
+		break;
+
+	    case KEY_RIGHT:
+		ret.keySymbol = "CursorRight";
+		break;
+	}
+
+	return ret;
+    }
+
+    // call handleInput of NCPad
+    handleInput( key );
+
+    int citem = getCurrentItem();
+
+    selectItem( citem );
+
+    switch ( key )
+    {
+	case KEY_SPACE:
+	case KEY_RETURN:
+
+	    if ( notify() && citem != -1 )
+	    {
+		return NCursesEvent::Activated;
+	    }
+
+	    break;
+    }
+
+    if ( notify() && immediateMode() && oldItem != citem )
+    {
+	ret = NCursesEvent::SelectionChanged;
+    }
+
+    return ret;
+}
+
+
+/**
+ * Clear the table and the lists holding the values
+ **/
+void NCSelectionBox::deleteAllItems()
+{
+    YSelectionBox::deleteAllItems();
+    clearTable();
+    DrawPad();
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCSelectionBox.h b/deps/libyui/libyui-ncurses/src/NCSelectionBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..c452e9c908e745d6f2576b23d38b0918db0507c8
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCSelectionBox.h
@@ -0,0 +1,104 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCSelectionBox.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCSelectionBox_h
+#define NCSelectionBox_h
+
+#include 
+
+#include 
+#include "NCPadWidget.h"
+#include "NCTablePad.h"
+
+
+class NCSelectionBox : public YSelectionBox, public NCPadWidget
+{
+
+    friend std::ostream & operator<<( std::ostream & str, const NCSelectionBox & obj );
+
+    NCSelectionBox & operator=( const NCSelectionBox & );
+    NCSelectionBox( const NCSelectionBox & );
+
+protected:
+
+    /**
+     * Overload myPad to narrow the type
+     */
+    virtual NCTablePad * myPad() const
+    { return dynamic_cast( NCPadWidget::myPad() ); }
+
+    bool	  biglist;
+
+protected:
+
+    virtual const char * location() const { return "NCSelectionBox"; }
+
+    virtual NCPad * CreatePad();
+    virtual void    wRecoded();
+
+public:
+
+    NCSelectionBox( YWidget * parent, const std::string & label );
+    virtual ~NCSelectionBox();
+
+    bool bigList() const { return biglist; }
+
+    void setBigList( bool big ) { biglist = big; }
+
+    virtual void addItem( YItem *item );
+    virtual void addItem( const std::string & itemLabel, bool selected = false );
+
+    virtual int preferredWidth();
+    virtual int preferredHeight();
+
+    virtual void setSize( int newWidth, int newHeight );
+
+    virtual void setLabel( const std::string & nlabel );
+
+    virtual int getCurrentItem() const;
+    virtual void setCurrentItem( int index );
+
+    virtual void selectItem( YItem *item, bool selected );
+    virtual void selectItem( int index );
+
+    virtual NCursesEvent wHandleInput( wint_t key );
+
+    virtual void setEnabled( bool do_bv );
+
+    virtual bool setKeyboardFocus()
+    {
+	if ( !grabFocus() )
+	    return YWidget::setKeyboardFocus();
+
+	return true;
+    }
+
+    std::string getLine( int index );
+    void clearTable() { myPad()->ClearTable(); };
+
+    void deleteAllItems();
+};
+
+
+#endif // NCSelectionBox_h
diff --git a/deps/libyui/libyui-ncurses/src/NCSpacing.cc b/deps/libyui/libyui-ncurses/src/NCSpacing.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c1cac87f4ecde090b2dd3d7738f70f9180c2ae31
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCSpacing.cc
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCSpacing.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCurses.h"
+#include "NCSpacing.h"
+
+
+
+NCSpacing::NCSpacing( YWidget * parent,
+		      YUIDimension dim,
+		      bool stretchable,
+		      YLayoutSize_t layoutUnits )
+	: YSpacing( parent, dim, stretchable, layoutUnits )
+	, NCWidget( parent )
+{
+    // yuiDebug() << std::endl;
+
+    if      ( dim == YD_VERT  )	l = "NC(V)Spacing";
+    else if ( dim == YD_HORIZ )	l = "NC(H)Spacing";
+    else	                l = "NC(N)Spacing";
+
+    wstate = NC::WSdumb;
+    skipNoDimWin = true;
+}
+
+
+NCSpacing::~NCSpacing()
+{
+    // yuiDebug() << std::endl;
+}
+
+
+void NCSpacing::setSize( int newwidth, int newheight )
+{
+    wRelocate( wpos( 0 ), wsze( newheight, newwidth ) );
+}
+
+
+void NCSpacing::setEnabled( bool do_bv )
+{
+    NCWidget::setEnabled( do_bv );
+    YSpacing::setEnabled( do_bv );
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCSpacing.h b/deps/libyui/libyui-ncurses/src/NCSpacing.h
new file mode 100644
index 0000000000000000000000000000000000000000..8669eded136f6cd1d7ada2556f3698837fcff75e
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCSpacing.h
@@ -0,0 +1,68 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCSpacing.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCSpacing_h
+#define NCSpacing_h
+
+#include 
+
+#include 
+#include 
+#include 
+#include "NCWidget.h"
+
+
+class NCSpacing : public YSpacing, public NCWidget
+{
+
+    friend std::ostream & operator<<( std::ostream & str, const NCSpacing & obj );
+
+    NCSpacing & operator=( const NCSpacing & );
+    NCSpacing( const NCSpacing & );
+
+    const char * l;
+
+protected:
+
+    virtual const char * location() const { return l; }
+
+public:
+
+    NCSpacing( YWidget * parent,
+	       YUIDimension dim,
+	       bool stretchable = false,
+	       YLayoutSize_t layoutUnits = 0.0 );
+
+    virtual ~NCSpacing();
+
+    virtual int preferredWidth()  { return YSpacing::preferredWidth(); }
+    virtual int preferredHeight() { return YSpacing::preferredHeight(); }
+
+    virtual void setSize( int newWidth, int newHeight );
+
+    virtual void setEnabled( bool do_bv );
+};
+
+
+#endif // NCSpacing_h
diff --git a/deps/libyui/libyui-ncurses/src/NCSquash.cc b/deps/libyui/libyui-ncurses/src/NCSquash.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7f90b9f0c5b28db1c4d3c97b6be29c2b8073e6a5
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCSquash.cc
@@ -0,0 +1,59 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCSquash.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCurses.h"
+#include "NCSquash.h"
+
+
+
+NCSquash::NCSquash( YWidget * parent,
+		    bool hsquash, bool vsquash )
+	: YSquash( parent, hsquash, vsquash )
+	, NCWidget( parent )
+{
+    // yuiDebug() << std::endl;
+    wstate = NC::WSdumb;
+}
+
+
+NCSquash::~NCSquash()
+{
+    // yuiDebug() << std::endl;
+}
+
+
+void NCSquash::setSize( int newwidth, int newheight )
+{
+    wRelocate( wpos( 0 ), wsze( newheight, newwidth ) );
+    YSquash::setSize( newwidth, newheight );
+}
+
+
+void NCSquash::setEnabled( bool do_bv )
+{
+    NCWidget::setEnabled( do_bv );
+    YSquash::setEnabled( do_bv );
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCSquash.h b/deps/libyui/libyui-ncurses/src/NCSquash.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd7ee077255c43638f2460d006e429a6df820be7
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCSquash.h
@@ -0,0 +1,62 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCSquash.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCSquash_h
+#define NCSquash_h
+
+#include 
+
+#include 
+#include "NCWidget.h"
+
+
+class NCSquash : public YSquash, public NCWidget
+{
+
+    friend std::ostream & operator<<( std::ostream & str, const NCSquash & obj );
+
+private:
+
+    NCSquash & operator=( const NCSquash & );
+    NCSquash( const NCSquash & );
+
+protected:
+
+    virtual const char * location() const { return "NCSquash"; }
+
+public:
+
+    NCSquash( YWidget * parent, bool hsquash, bool vsquash );
+    virtual ~NCSquash();
+
+    virtual int preferredWidth() { return YSquash::preferredWidth(); }
+    virtual int preferredHeight() { return YSquash::preferredHeight(); }
+
+    virtual void setSize( int newWidth, int newHeight );
+
+    virtual void setEnabled( bool do_bv );
+};
+
+
+#endif // NCSquash_h
diff --git a/deps/libyui/libyui-ncurses/src/NCStyleDef.cc b/deps/libyui/libyui-ncurses/src/NCStyleDef.cc
new file mode 100644
index 0000000000000000000000000000000000000000..47e05978a85fb45b714a32f026b12b9103e69494
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCStyleDef.cc
@@ -0,0 +1,1840 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCStyleDef.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#include 
+#include 
+#include 
+#include 
+
+
+#define	 YUILogComponent "ncurses"
+#include 
+#include "NCurses.h"
+#include "NCstyle.h"
+
+
+class NCStyleDef
+{
+
+public:
+
+    // Self reference
+    static NCStyleDef * NCStyleDef_p;
+
+    // Reference to class NCstyle
+    NCstyle & NCstyle_C;
+
+    // Master panel
+    NCursesPanel p;
+
+    // draw panel frame in move mode or plain
+    void pbox( bool on = false );
+
+    // move panel interactive or determined by key
+    int	 movePad( int key = -1 );
+
+    static const NCursesPanel & pad()			{ return NCStyleDef_p->p; }
+
+    static void			refresh()		{ NCStyleDef_p->p.refresh(); }
+
+    static int			movepad( int key = -1 ) { return NCStyleDef_p->movePad( key ); }
+
+
+    // Example popup is somwhat special. It's handmade, so we habe to
+    // keep it in sync when attributes change.
+
+    enum ExMode { EX_OFF, EX_ON, EX_TOGGLE, EX_UPDATE };
+
+    static void showex( ExMode mode );
+
+    // Advise NCstyle to fake attributes, i.e. always return the set we currently process
+    static void fakestyle( NCstyle::StyleSet style )
+    {
+	NCStyleDef_p->NCstyle_C.fakestyle( style );
+
+	if ( style != NCstyle::MaxStyleSet )
+	{
+	    NCStyleDef_p->doshowset( NCStyleDef_p->wSet.cset, true );
+	    showex( EX_UPDATE );
+	}
+	else
+	{
+	    showex( EX_OFF );
+	}
+    }
+
+    // to be called to reflect changed attributes on screen
+    static void attrchanged()
+    {
+	NCurses::Redraw();
+	showex( EX_UPDATE );
+    }
+
+    // SetTypes handled by struct Wset.
+
+    enum SetType
+    {
+	Global = 0,
+	DialogBorder,
+	DialogBorderActive,
+	DialogText,
+	Widget,
+	WidgetActive,
+	FrameWidget,
+	FrameWidgetActive,
+	List,
+	ListActive,
+	RichText,
+	ProgressBar,
+	// last entry
+	MaxSetType
+    };
+
+    static std::string dumpName( SetType a )
+    {
+#define PRT(t) case t: return #t;
+
+	switch ( a )
+	{
+	    PRT( Global );
+	    PRT( DialogBorder );
+	    PRT( DialogBorderActive );
+	    PRT( DialogText );
+	    PRT( Widget );
+	    PRT( WidgetActive );
+	    PRT( FrameWidget );
+	    PRT( FrameWidgetActive );
+	    PRT( List );
+	    PRT( ListActive );
+	    PRT( RichText );
+	    PRT( ProgressBar );
+
+	    case MaxSetType:
+		break;
+	}
+
+	return "unknown";
+
+#undef PRT
+    }
+
+    // Aset serves as menu entry for struct Wchattr.
+    // Any modification of the associated chtype is handled here.
+
+    struct Aset
+    {
+
+private:
+	chtype * attr_p;
+
+public:
+	std::string	 label;
+	Aset( chtype & ch, const std::string & l ) : attr_p( &ch ), label( l )
+	{}
+
+	chtype attr()	  const { return *attr_p; }
+
+	chtype textattr() const { return attr() &  ~NCattribute::char_mask; }
+
+	void setBg( bool prev ) { NCattribute::setBg( *attr_p, NCattribute::getBg( *attr_p ) + ( prev ? -1 : 1 ) ); }
+
+	void setFg( bool prev ) { NCattribute::setFg( *attr_p, NCattribute::getFg( *attr_p ) + ( prev ? -1 : 1 ) ); }
+
+	void toggleStyle( chtype sty ) { NCattribute::toggleStyle( *attr_p, sty ); }
+
+	void setStyle( chtype sty )    { NCattribute::setStyle( *attr_p, sty ); }
+
+	void setChar( chtype sty )     { NCattribute::setChar( *attr_p, sty ); }
+    };
+
+    // Retrieve appropriate chtype from NCstyle
+    const chtype & attr( NCstyle::STglobal a )
+    {
+	return NCstyle_C.getStyle( NCstyle_C.fakestyle_e ).attr( a );
+    }
+
+    const chtype & attr( NCstyle::STlocal a )
+    {
+	return NCstyle_C.getStyle( NCstyle_C.fakestyle_e ).attr( a );
+    }
+
+    // Build the Aset std::vector associated with a SetType and assing it to struct Wchattr.
+    void doshowset( SetType a, bool reset = false );
+
+    static void showset( SetType a )
+    {
+	NCStyleDef_p->doshowset( a );
+    }
+
+    // queryCharEnt serves as menu entry for the ACS char popoup in queryChar()
+    // queryChar(). Used in struct Wchattr.
+
+    struct queryCharEnt
+    {
+	std::string l;
+	chtype c;
+	queryCharEnt( std::string L, chtype C ) { l = L; c = C; }
+    };
+
+    static chtype queryChar( int column = 0, chtype selbg = A_REVERSE );
+
+    // Show details of Wchattr's current item (fg/bg and attributes)
+
+    void doshowstat( const Aset & a ) { wChstat.stat( a ); }
+
+    static void showstat( const Aset & a )
+    {
+	NCStyleDef_p->doshowstat( a );
+    }
+
+    static const char * dumpColor( short c )
+    {
+	switch ( c )
+	{
+	    case -1:
+		return "-1";
+		break;
+
+	    case COLOR_BLACK:
+		return "bk";
+		break;
+
+	    case COLOR_RED:
+		return "re";
+		break;
+
+	    case COLOR_GREEN:
+		return "gr";
+		break;
+
+	    case COLOR_YELLOW:
+		return "ye";
+		break;
+
+	    case COLOR_BLUE:
+		return "bl";
+		break;
+
+	    case COLOR_MAGENTA:
+		return "ma";
+		break;
+
+	    case COLOR_CYAN:
+		return "cy";
+		break;
+
+	    case COLOR_WHITE:
+		return "wh";
+		break;
+	}
+
+	return "??";
+    }
+
+
+    /**
+     * SubWin: base class for the windows used
+     **/
+    struct SubWin
+    {
+	static const int taglen = 7;
+	NCursesWindow w;
+	std::string	tag;
+	chtype		changestyle;
+	SubWin( std::string T, NCursesWindow & P, int H, int W, int L, int C )
+		: w( P, H, W, L, C, 'r' )
+		, tag( std::string( "<" ) + T + ">" )
+	{
+	    changestyle = A_NORMAL;
+	}
+
+	virtual ~SubWin() {}
+
+	virtual void draw( bool immediate = false )
+	{
+	    w.syncup();
+
+	    if ( immediate )
+		refresh();
+	}
+
+	virtual int dtag()
+	{
+	    if ( tag.size() > 2 )
+	    {
+		w.printw( 0, 0, "%-*.*s", taglen, taglen, tag.c_str() );
+		return w.width() - taglen;
+	    }
+
+	    w.move( 0, 0 );
+
+	    return w.width();
+	}
+
+	virtual int change()
+	{
+	    enterchange();
+	    bool continue_bi = true;
+	    int	 in	     = -1;
+
+	    do
+	    {
+		switch (( in = getch() ) )
+		{
+		    case -1:
+		    case KEY_ESC:
+		    case KEY_TAB:
+		    case KEY_RETURN:
+			in = -1; // no reconsume
+
+		    case KEY_F( 1 ):
+		    case KEY_F( 2 ):
+		    case KEY_F( 3 ):
+		    case KEY_F( 4 ):
+		    case KEY_F( 5 ):
+		    case KEY_F( 6 ):
+		    case KEY_F( 7 ):
+		    case KEY_F( 8 ):
+		    case KEY_F( 9 ):
+		    case KEY_F( 10 ):
+			continue_bi = false;
+			break;
+
+		    default:
+			handle( in );
+			break;
+		}
+	    }
+	    while ( continue_bi );
+
+	    leavechange();
+
+	    return in;
+	}
+
+	virtual void enterchange()
+	{
+	    changestyle = A_REVERSE;
+	    w.bkgd( changestyle );
+	    draw( true );
+	}
+
+	virtual void leavechange()
+	{
+	    changestyle = A_NORMAL;
+	    w.bkgd( changestyle );
+	    draw( true );
+	}
+
+	virtual void handle( int in )
+	{
+	}
+    };
+
+
+    /**
+     * Wstyle: Selection of the current NCstyle::StyleSet to process
+     **/
+    struct Wstyle : public SubWin
+    {
+	NCstyle::StyleSet cset;
+	Wstyle( std::string T, NCursesWindow & P, int H, int W, int L, int C )
+		: SubWin( T, P, H, W, L, C )
+	{
+	    cset = ( NCstyle::StyleSet )( 0 );
+	}
+
+	virtual void draw( bool immediate = false )
+	{
+	    int len = dtag();
+	    w.printw( "%-*.*s", len, len, NCstyle::dumpName( cset ).c_str() );
+
+	    if ( cset == 0 )
+		w.addch( 0, 2, '-' );
+
+	    if ( cset ==  NCstyle::MaxStyleSet - 1 )
+		w.addch( 0, 4, '-' );
+
+	    SubWin::draw( immediate );
+	}
+
+	virtual void handle( int in )
+	{
+	    switch ( in )
+	    {
+		case KEY_UP:
+
+		    if ( cset > 0 )
+		    {
+			cset = ( NCstyle::StyleSet )( cset - 1 );
+			draw( true );
+			fakestyle( cset );
+		    }
+		    break;
+
+		case KEY_DOWN:
+
+		    if ( cset + 1 < NCstyle::MaxStyleSet )
+		    {
+			cset = ( NCstyle::StyleSet )( cset + 1 );
+			draw( true );
+			fakestyle( cset );
+		    }
+		    break;
+	    }
+	}
+    };
+
+
+    /**
+     * Wset: Selection of the current attribute std::set to process
+     **/
+    struct Wset : public SubWin
+    {
+	SetType cset;
+	Wset( std::string T, NCursesWindow & P, int H, int W, int L, int C )
+		: SubWin( T, P, H, W, L, C )
+	{
+	    cset = ( SetType )( 0 );
+	}
+
+	virtual void draw( bool immediate = false )
+	{
+	    int len = dtag();
+	    w.printw( "%-*.*s", len, len, dumpName( cset ).c_str() );
+
+	    if ( cset == 0 )
+		w.addch( 0, 2, '-' );
+
+	    if ( cset ==  MaxSetType - 1 )
+		w.addch( 0, 4, '-' );
+
+	    SubWin::draw( immediate );
+	}
+
+	virtual void handle( int in )
+	{
+	    switch ( in )
+	    {
+		case KEY_UP:
+
+		    if ( cset > 0 )
+		    {
+			cset = ( SetType )( cset - 1 );
+			draw( true );
+			showset( cset );
+		    }
+
+		    break;
+
+		case KEY_DOWN:
+
+		    if ( cset + 1 < MaxSetType )
+		    {
+			cset = ( SetType )( cset + 1 );
+			draw( true );
+			showset( cset );
+		    }
+
+		    break;
+	    }
+	}
+    };
+
+
+    /**
+     * Wchattr: handle modification of the current attribute std::set.
+     **/
+    struct Wchattr : public SubWin
+    {
+	std::vector aset;
+	unsigned     fitem;
+	unsigned     citem;
+	Wchattr( std::string T, NCursesWindow & P, int H, int W, int L, int C )
+		: SubWin( T, P, H, W, L, C )
+	{
+	    fitem = citem = 0;
+	}
+
+	virtual void draw( bool immediate = false )
+	{
+	    w.box();
+	    dtag();
+	    drawTable( immediate );
+	}
+
+	virtual void handle( int in )
+	{
+	    if ( !aset.size() )
+		return;
+
+	    bool redraw	   = true;
+
+	    bool redrawall = true;
+
+	    switch ( in )
+	    {
+		case KEY_UP:
+
+		    if ( citem )
+		    {
+			--citem;
+			redrawall = false;
+		    }
+
+		    break;
+
+		case KEY_DOWN:
+
+		    if ( citem + 1 < aset.size() )
+		    {
+			++citem;
+			redrawall = false;
+		    }
+
+		    break;
+
+		case KEY_LEFT:
+		case KEY_RIGHT:
+		    movepad( in );
+		    break;
+
+		case KEY_PPAGE:
+		    aset[citem].setBg( true );
+		    break;
+
+		case KEY_NPAGE:
+		    aset[citem].setBg( false );
+		    break;
+
+		case KEY_HOME:
+		    aset[citem].setFg( true );
+		    break;
+
+		case KEY_END:
+		    aset[citem].setFg( false );
+		    break;
+
+		case KEY_IC:
+		case 'b':
+		    aset[citem].toggleStyle( A_BOLD );
+		    break;
+
+		case KEY_DC:
+		case 'n':
+		    aset[citem].setStyle( A_NORMAL );
+		    break;
+
+		case 'l':
+		    aset[citem].toggleStyle( A_BLINK );
+		    break;
+
+		case 's':
+		    aset[citem].toggleStyle( A_STANDOUT );
+		    break;
+
+		case 'u':
+		    aset[citem].toggleStyle( A_UNDERLINE );
+		    break;
+
+		case 'r':
+		    aset[citem].toggleStyle( A_REVERSE );
+		    break;
+
+		case 'd':
+		    aset[citem].toggleStyle( A_DIM );
+		    break;
+
+		case 'i':
+		    aset[citem].toggleStyle( A_INVIS );
+		    break;
+
+		case 'a':
+		    {
+			chtype ach = queryChar( pad().begx() + 5, aset[citem].textattr() );
+
+			if ( ach != ( chtype ) - 1 )
+			    aset[citem].setChar( ach );
+		    }
+
+		    break;
+
+		default:
+		    redraw = redrawall = false;
+		    break;
+	    }
+
+	    if ( redraw )
+		drawTable( true );
+
+	    if ( redrawall )
+		attrchanged();
+	}
+
+	void set( std::vector & nset, bool reset = false )
+	{
+	    aset.swap( nset );
+	    draw( true );
+	}
+
+	void drawTable( bool immediate = false )
+	{
+	    unsigned t	  = w.height() - 1;
+	    unsigned high = ( t - 1 );
+	    unsigned spot = high / 2;
+	    unsigned l = 1;
+
+	    if ( !aset.size() )
+		citem = 0;
+	    else if ( citem >= aset.size() )
+		citem = aset.size() - 1;
+
+	    if ( high >= aset.size() || citem <= spot )
+	    {
+		fitem = 0;
+	    }
+	    else
+	    {
+		fitem = citem - spot;
+
+		if ( fitem + high >= aset.size() )
+		    fitem = aset.size() - high;
+	    }
+
+	    for ( unsigned i = fitem; l < t; ++i, ++l )
+	    {
+		drawItemAt( l, i );
+	    }
+
+	    if ( !aset.size() )
+	    {
+		int len = w.width() - 2;
+		w.bkgdset( changestyle );
+		w.printw( 1, 1, "%-*.*s", len, len, "" );
+	    }
+
+	    w.bkgdset( changestyle );
+
+	    SubWin::draw( immediate );
+	}
+
+	void drawItemAt( unsigned line, unsigned num )
+	{
+	    int len = w.width() - 4;
+
+	    if ( num < aset.size() )
+	    {
+		w.bkgdset( changestyle );
+
+		if ( num == citem )
+		{
+		    w.addstr( line, 1, "->" );
+		    showstat( aset[num] );
+		}
+		else
+		{
+		    w.addstr( line, 1, "  " );
+		}
+
+		w.bkgdset( aset[num].attr() );
+
+		w.printw( line, 3, "%-*.*s", len, len, "" );
+		w.bkgdset( aset[num].textattr() );
+		w.addstr( line, 3, aset[num].label.c_str(), len );
+	    }
+	    else
+	    {
+		w.bkgdset( changestyle );
+		w.printw( line, 1, "%-*.*s", len + 2, len + 2, "" );
+	    }
+	}
+    };
+
+
+    /**
+     * Wchstat: show current attributes definition
+     **/
+    struct Wchstat : public SubWin
+    {
+	Wchstat( std::string T, NCursesWindow & P, int H, int W, int L, int C )
+		: SubWin( T, P, H, W, L, C )
+	{
+	}
+
+	virtual int change() { return -1; }
+
+	virtual void draw( bool immediate = false )
+	{
+	    w.bkgdset( A_NORMAL );
+	    w.clear();
+	    SubWin::draw( immediate );
+	}
+
+	void stat( const Aset & a )
+	{
+	    static char buf[1024];
+	    int len = w.width() - 2;
+	    chtype ch = a.attr();
+	    w.bkgdset( a.attr() );
+	    w.clear();
+	    w.bkgdset( a.textattr() );
+	    w.box();
+	    w.addstr( 0, 1, a.label.c_str(), len );
+	    sprintf( buf, "%s/%s %c%c%c%c%c%c%c %c%3u",
+		     dumpColor( NCattribute::fg_color_of( ch ) ),
+		     dumpColor( NCattribute::bg_color_of( ch ) ),
+		     ( ch&A_INVIS ?	 'i' : '.' ),
+		     ( ch&A_BOLD ?	 'b' : '.' ),
+		     ( ch&A_DIM ?	 'd' : '.' ),
+		     ( ch&A_BLINK ?	 'l' : '.' ),
+		     ( ch&A_REVERSE ?	 'r' : '.' ),
+		     ( ch&A_UNDERLINE ?	 'u' : '.' ),
+		     ( ch&A_STANDOUT ?	 's' : '.' ),
+		     ( ch&A_ALTCHARSET ? 'A' : '.' ),
+		     (unsigned) ( ch&A_CHARTEXT )
+		   );
+	    w.addstr( 1, 1, buf, len );
+	    SubWin::draw( true );
+	}
+    };
+
+
+    /**
+     * Wex: popup and down the example Dialog
+     **/
+    struct Wex : public SubWin
+    {
+	SetType cset;
+	Wex( std::string T, NCursesWindow & P, int H, int W, int L, int C )
+		: SubWin( T, P, H, W, L, C )
+	{
+	    showex( EX_OFF );
+	}
+
+	virtual void draw( bool immediate = false )
+	{
+	    int len = dtag();
+	    w.printw( "%-*.*s", len, len, "Example Dialog" );
+	    SubWin::draw( immediate );
+	}
+
+	virtual int change()
+	{
+	    showex( EX_TOGGLE );
+	    return -1;
+	}
+    };
+
+
+    //
+    // Construct the panel and widgets
+    //
+
+    Wstyle  wStyle;
+    Wset    wSet;
+    Wchstat wChstat;
+    Wchattr wChattr;
+    Wex	    wEx;
+
+    NCStyleDef( NCstyle & style )
+	    : NCstyle_C( style )
+	    , p( 19, 30, NCurses::lines() - 19, 1 )
+	    , wStyle( "F1/2", p,  1, 28,  1, 1 )
+	    , wSet( "F3/4", p,	1, 28,	2, 1 )
+	    , wChstat( "",     p,  3, 28,  3, 1 )
+	    , wChattr( "",     p, 11, 28,  6, 1 )
+	    , wEx( "F6",   p,  1, 28, 17, 1 )
+    {
+	NCStyleDef_p = this;
+	pbox();
+	wStyle.draw();
+	wSet.draw();
+	wChstat.draw();
+	wChattr.draw();
+	wEx.draw();
+    }
+
+    ~NCStyleDef() { NCStyleDef_p = 0; }
+
+    void changeStyle();
+
+    void saveStyle();
+
+    // that's the way the chtype is saved to file
+    std::ostream & dumpChtype( std::ostream & str, const chtype & ch )
+    {
+	static chtype mask = A_STANDOUT | A_UNDERLINE | A_REVERSE | A_BLINK | A_DIM | A_BOLD | A_INVIS;
+	chtype base  = ch & ~mask;
+	chtype style = ch & mask;
+#define PRTIF(S) if ( style & S ) str << "|" << #S
+	str << base;
+	PRTIF( A_STANDOUT );
+	PRTIF( A_UNDERLINE );
+	PRTIF( A_REVERSE );
+	PRTIF( A_BLINK );
+	PRTIF( A_DIM );
+	PRTIF( A_BOLD );
+	PRTIF( A_INVIS );
+#undef PRTIF
+	return str;
+    }
+
+    void restoreStyle();
+
+
+    /**
+     * helper struct to std::map strings to NCstyle enum values
+     **/
+    struct lookupIdx
+    {
+	NCstyle::STglobal glob;
+	NCstyle::STlocal  loc;
+	lookupIdx()			 { glob = NCstyle::MaxSTglobal; loc = NCstyle::MaxSTlocal; }
+
+	lookupIdx( NCstyle::STglobal g ) { glob = g; loc = NCstyle::MaxSTlocal; }
+
+	lookupIdx( NCstyle::STlocal  l ) { glob = NCstyle::MaxSTglobal; loc = l; }
+
+	bool isLoc()	 const { return glob == NCstyle::MaxSTglobal && loc != NCstyle::MaxSTlocal; }
+
+	bool isGlob()	 const { return glob != NCstyle::MaxSTglobal && loc == NCstyle::MaxSTlocal; }
+
+	bool isUnknown() const { return glob == NCstyle::MaxSTglobal && loc == NCstyle::MaxSTlocal; }
+
+	unsigned     uindex() const { if ( isLoc() ) return loc; return isGlob() ? glob : (unsigned) - 1; }
+
+	const char * stat()   const { if ( isLoc() ) return "L"; return isGlob() ? "G"	: "?"; }
+    };
+
+    void showHelp();
+};
+
+
+NCStyleDef * NCStyleDef::NCStyleDef_p = 0;
+
+
+
+void NCStyleDef::doshowset( SetType a, bool reset )
+{
+    std::vector aset;
+
+    switch ( a )
+    {
+#define PRT(T) aset.push_back( Aset( const_cast( attr( NCstyle::T ) ), #T ) )
+
+	case Global:
+	    PRT( AppTitle );
+	    PRT( AppText );
+	    break;
+
+	case DialogBorder:
+	    PRT( DialogBorder );
+	    PRT( DialogTitle );
+	    break;
+
+	case DialogBorderActive:
+	    PRT( DialogActiveBorder );
+	    PRT( DialogActiveTitle );
+	    break;
+
+	case DialogText:
+	    PRT( DialogText );
+	    PRT( DialogHeadline );
+	    PRT( DialogDisabled );
+	    break;
+
+	case Widget:
+	    PRT( DialogPlain );
+	    PRT( DialogLabel );
+	    PRT( DialogData );
+	    PRT( DialogHint );
+	    PRT( DialogScrl );
+	    break;
+
+	case WidgetActive:
+	    PRT( DialogActivePlain );
+	    PRT( DialogActiveLabel );
+	    PRT( DialogActiveData );
+	    PRT( DialogActiveHint );
+	    PRT( DialogActiveScrl );
+	    break;
+
+	case FrameWidget:
+	    PRT( DialogFramePlain );
+	    PRT( DialogFrameLabel );
+	    PRT( DialogFrameData );
+	    PRT( DialogFrameHint );
+	    PRT( DialogFrameScrl );
+	    break;
+
+	case FrameWidgetActive:
+	    PRT( DialogActiveFramePlain );
+	    PRT( DialogActiveFrameLabel );
+	    PRT( DialogActiveFrameData );
+	    PRT( DialogActiveFrameHint );
+	    PRT( DialogActiveFrameScrl );
+	    break;
+
+	case List:
+	    PRT( ListTitle );
+	    PRT( ListPlain );
+	    PRT( ListLabel );
+	    PRT( ListData );
+	    PRT( ListHint );
+	    PRT( ListSelPlain );
+	    PRT( ListSelLabel );
+	    PRT( ListSelData );
+	    PRT( ListSelHint );
+	    break;
+
+	case ListActive:
+	    PRT( ListActiveTitle );
+	    PRT( ListActivePlain );
+	    PRT( ListActiveLabel );
+	    PRT( ListActiveData );
+	    PRT( ListActiveHint );
+	    PRT( ListActiveSelPlain );
+	    PRT( ListActiveSelLabel );
+	    PRT( ListActiveSelData );
+	    PRT( ListActiveSelHint );
+	    break;
+
+	case RichText:
+	    PRT( RichTextPlain );
+	    PRT( RichTextTitle );
+	    PRT( RichTextLink );
+	    PRT( RichTextArmedlink );
+	    PRT( RichTextActiveArmedlink );
+	    PRT( RichTextVisitedLink );
+	    PRT( RichTextB );
+	    PRT( RichTextI );
+	    PRT( RichTextT );
+	    PRT( RichTextBI );
+	    PRT( RichTextBT );
+	    PRT( RichTextIT );
+	    PRT( RichTextBIT );
+	    break;
+
+	case ProgressBar:
+	    PRT( ProgbarCh );
+	    PRT( ProgbarBgch );
+	    PRT( TextCursor );
+	    break;
+
+	case MaxSetType:
+	    break;
+#undef PRT
+    }
+
+    wChattr.set( aset, reset );
+}
+
+
+
+void NCStyleDef::pbox( bool on )
+{
+    p.bkgdset( A_NORMAL );
+    p.box();
+
+    if ( on )
+    {
+	p.bkgdset( A_REVERSE );
+	p.addstr( 0, 1, " done " );
+    }
+    else
+	p.addstr( 0, 1, " move pad " );
+
+    p.bkgdset( A_NORMAL );
+}
+
+
+
+int NCStyleDef::movePad( int key )
+{
+    pbox( true );
+    p.show();
+
+    bool continue_bi = true;
+    int in = -1;
+
+    do
+    {
+	refresh();
+
+	if ( key == -1 )
+	    in = getch();
+	else
+	    in = key;
+
+	switch ( in )
+	{
+	    case KEY_UP:
+
+		if ( p.begy() > 0 )
+		{
+		    p.mvwin( p.begy() - 1, p.begx() );
+		}
+		break;
+
+	    case KEY_DOWN:
+
+		if ( p.begy() + p.height() < NCurses::lines() )
+		{
+		    p.mvwin( p.begy() + 1, p.begx() );
+		}
+		break;
+
+	    case KEY_LEFT:
+
+		if ( p.begx() > 0 )
+		{
+		    p.mvwin( p.begy(), p.begx() - 1 );
+		}
+		break;
+
+	    case KEY_RIGHT:
+
+		if ( p.begx() + p.width() < NCurses::cols() )
+		{
+		    p.mvwin( p.begy(), p.begx() + 1 );
+		}
+		break;
+
+	    case -1:
+	    case KEY_ESC:
+	    case KEY_TAB:
+	    case KEY_RETURN:
+	    case KEY_F( 1 ):
+	    case KEY_F( 2 ):
+	    case KEY_F( 3 ):
+	    case KEY_F( 4 ):
+	    case KEY_F( 5 ):
+	    case KEY_F( 6 ):
+	    case KEY_F( 7 ):
+	    case KEY_F( 8 ):
+	    case KEY_F( 9 ):
+	    case KEY_F( 10 ):
+		continue_bi = false;
+		break;
+	}
+
+    }
+    while ( continue_bi && key == -1 );
+
+    pbox( false );
+
+    if ( key != -1 )
+	in = -1;
+
+    return in;
+}
+
+
+
+void NCStyleDef::changeStyle()
+{
+    fakestyle( wStyle.cset );
+    p.show();
+
+    bool continue_bi = true;
+    int in   = -1;
+    int rein =	1;
+
+    do
+    {
+	refresh();
+
+	if ( rein != -2 )
+	{
+	    in = rein;
+	    rein = -1;
+	}
+	else
+	{
+	    in = getch();
+	}
+
+	switch ( in )
+	{
+	    case KEY_F( 1 ):
+		wStyle.handle( KEY_UP );
+		break;
+
+	    case KEY_F( 2 ):
+		wStyle.handle( KEY_DOWN );
+		break;
+
+	    case KEY_F( 3 ):
+		wSet.handle( KEY_UP );
+		break;
+
+	    case KEY_F( 4 ):
+		wSet.handle( KEY_DOWN );
+		break;
+
+	    case KEY_F( 5 ):
+		rein = movePad();
+		break;
+
+	    case KEY_F( 6 ):
+		rein = wEx.change();
+		break;
+
+	    case KEY_F( 8 ):
+		restoreStyle();
+		break;
+
+	    case KEY_F( 9 ):
+		saveStyle();
+		break;
+
+	    case KEY_ESC:
+	    case KEY_F( 10 ):
+		continue_bi = false;
+		break;
+
+	    default:
+		rein = wChattr.change();
+		break;
+	}
+    }
+    while ( continue_bi );
+
+    p.hide();
+
+    p.refresh();
+
+    fakestyle( NCstyle::MaxStyleSet );
+}
+
+
+
+// query popup for ACS chars
+chtype NCStyleDef::queryChar( int column, chtype selbg )
+{
+    std::vector men;
+    men.push_back( queryCharEnt( "NO CHAR", ' ' ) );
+    men.push_back( queryCharEnt( "BLANK", ' ' ) );
+#define PUT(a) men.push_back( queryCharEnt( #a, a ) );
+    PUT( ACS_CKBOARD );
+    PUT( ACS_BOARD );
+    PUT( ACS_BLOCK );
+    PUT( ACS_DIAMOND );
+    PUT( ACS_BULLET );
+    PUT( ACS_DEGREE );
+    PUT( ACS_PLMINUS );
+    PUT( ACS_LEQUAL );
+    PUT( ACS_GEQUAL );
+    PUT( ACS_NEQUAL );
+    PUT( ACS_S1 );
+    PUT( ACS_S3 );
+    PUT( ACS_S7 );
+    PUT( ACS_S9 );
+    PUT( ACS_PI );
+    PUT( ACS_LANTERN );
+    PUT( ACS_STERLING );
+    PUT( ACS_LARROW );
+    PUT( ACS_RARROW );
+    PUT( ACS_DARROW );
+    PUT( ACS_UARROW );
+    PUT( ACS_ULCORNER );
+    PUT( ACS_URCORNER );
+    PUT( ACS_LLCORNER );
+    PUT( ACS_LRCORNER );
+    PUT( ACS_VLINE );
+    PUT( ACS_LTEE );
+    PUT( ACS_RTEE );
+    PUT( ACS_BTEE );
+    PUT( ACS_TTEE );
+    PUT( ACS_HLINE );
+    PUT( ACS_PLUS );
+#undef PUT
+
+    chtype defbg = A_NORMAL;
+    unsigned lrow = men.size() - men.size() / 2;
+
+    NCursesPanel popup( lrow + 2, 39, 1, 1 );
+    popup.bkgd( defbg );
+    popup.box();
+
+    popup.show();
+    chtype   ret = ( chtype ) - 1;
+    unsigned idx = 0;
+    int	     in	 = -1;
+
+    do
+    {
+	int l = 1;
+	int c = 1;
+	int len = 13;
+
+	for ( unsigned i = 0; i < men.size(); ++i, ++l )
+	{
+	    if ( i == lrow )
+	    {
+		c += len + 6;
+		l = 1;
+	    }
+
+	    popup.bkgdset( defbg );
+
+	    popup.addstr( l, c, ( i == idx ? "->" : "  " ) );
+	    popup.bkgdset( i == idx ? selbg : defbg );
+	    popup.addch( ' ' );
+	    popup.addch( men[i].c );
+	    popup.printw( " %-*.*s", len, len, men[i].l.c_str() );
+	}
+
+	popup.refresh();
+
+	switch ( ( in = getch() ) )
+	{
+
+	    case KEY_UP:
+
+		if ( idx )
+		    --idx;
+		break;
+
+	    case KEY_DOWN:
+
+		if ( idx + 1 < men.size() )
+		    ++idx;
+		break;
+
+	    case KEY_RETURN:
+		ret = idx ? men[idx].c : 0;
+
+	    case KEY_ESC:
+		in = -1;
+
+		break;
+	}
+    }
+    while ( in != -1 );
+
+    popup.hide();
+    popup.refresh();
+
+    return ret;
+}
+
+
+#define BGSET(a) W.bkgdset( st.a )
+
+static int hi = 4;
+static int wi = 15;
+
+
+inline void frame( NCursesWindow & w, int l, int c, int H = 0, int W = 0 )
+{
+    if ( !H )
+	H = hi;
+
+    if ( !W )
+	W = wi;
+
+    w.vline( l, c, H );
+    w.vline( l, c + W, H );
+    w.hline( l, c, W );
+    w.hline( l + H, c, W );
+
+    w.addch( l, c, ACS_ULCORNER );
+    w.addch( l + H, c, ACS_LLCORNER );
+    w.addch( l, c + W, ACS_URCORNER );
+    w.addch( l + H, c + W, ACS_LRCORNER );
+}
+
+
+inline void laex( NCursesWindow & W, const char * T, NCstyle::StItem st )
+{
+    BGSET( hint );
+    W.addch( *T );
+    BGSET( label );
+    W.addstr( T + 1 );
+}
+
+
+inline void itex( NCursesWindow & W, const char * T, NCstyle::StItem st )
+{
+    BGSET( plain );
+    W.addstr( "(" );
+    BGSET( data );
+    W.addstr( "X" );
+    BGSET( plain );
+    W.addstr( ") " );
+    laex( W, T, st );
+}
+
+
+inline void butex( NCursesWindow & W, int L, int C, const char * T, NCstyle::StWidget st )
+{
+    W.move( L, C );
+    itex( W, T, st );
+    BGSET( scrl );
+    W.addch( ACS_DARROW );
+}
+
+
+inline void frameex( NCursesWindow & W, int L, int C, const char * T, NCstyle::StWidget st )
+{
+    BGSET( plain );
+    frame( W, L, C );
+    W.move( L, C + 1 );
+    laex( W, T, st );
+    BGSET( scrl );
+    W.addch( L + hi, C + 1, ACS_LTEE );
+    W.addch( ACS_HLINE );
+    W.addch( ACS_RTEE );
+    W.addch( L + 1, C + wi, ACS_TTEE );
+    W.addch( L + 2, C + wi, ACS_BTEE );
+}
+
+
+inline void listex( NCursesWindow & W, int L, int C, NCstyle::StList st )
+{
+    BGSET( title );
+    W.printw( L, C, "%-*s", wi - 1, "Title" );
+    ++L;
+    BGSET( item.plain );
+    W.printw( L, C, "%-*s", wi - 1, "" );
+    W.move( L, C );
+    itex( W, "Item", st.item );
+    ++L;
+    BGSET( selected.plain );
+    W.printw( L, C, "%-*s", wi - 1, "" );
+    W.move( L, C );
+    itex( W, "Selected", st.selected );
+}
+
+
+inline void widex( NCursesWindow & W, int L, int C, const char * T,
+		   NCstyle::StWidget w, NCstyle::StWidget f, NCstyle::StList l )
+{
+    butex( W, L, C, T, w );
+    L += 2;
+    frameex( W, L, C, T, f );
+    L += 1;
+    listex( W, L, C + 1, l );
+}
+
+
+
+void NCStyleDef::showex( ExMode mode )
+{
+    static NCursesPanel W( 14, NCurses::cols(), 0, 0 );
+
+    if ( mode == EX_TOGGLE )
+	mode = W.hidden() ? EX_ON : EX_OFF;
+
+    if ( mode == EX_OFF )
+    {
+	if ( !W.hidden() )
+	{
+	    W.hide();
+	    W.refresh();
+	}
+
+	return;
+    }
+
+    if ( mode == EX_ON && W.hidden() )
+    {
+	W.show();
+    }
+
+    if ( W.hidden() )
+	return;
+
+    const NCstyle::Style & st( NCStyleDef_p->NCstyle_C.getStyle( NCStyleDef_p->NCstyle_C.fakestyle_e ) );
+
+    BGSET( dumb.text );
+    W.clear();
+    BGSET( border.text );
+    W.box();
+    BGSET( border.title );
+    W.addstr( 0, 1, "normal dialog" );
+    int l = 1;
+    int c = 1;
+    BGSET( activeBorder.text );
+    frame( W, l, c, W.height() - 2, W.width() - 2 );
+    BGSET( activeBorder.title );
+    W.addstr( l, c + 1, "active dialog" );
+    l = 3;
+    c = 3;
+    BGSET( dumb.title );
+    W.addstr( l, c, "Heading" );
+    BGSET( dumb.text );
+    frame( W, l + 2, c );
+    W.addstr( l + 2, c + 1, "Frame" );
+    W.addstr( l + 4, c + 1, "Some text" );
+    c += 20;
+    widex( W, l, c, "Disabled", st.disabled, st.disabled, st.disabledList );
+    c += 20;
+    widex( W, l, c, "Normal", st.normal, st.frame, st.list );
+    c += 20;
+    widex( W, l, c, "Active", st.active, st.activeFrame, st.activeList );
+    l += hi + 4;
+    c = 3;
+    BGSET( progbar.bar.chattr );
+    W.addstr( l, c, "	   " );
+    BGSET( progbar.bar.getNonChar() );
+    W.addstr( "50" );
+    BGSET( progbar.nonbar.getNonChar() );
+    W.addstr( "%" );
+    BGSET( progbar.nonbar.chattr );
+    W.addstr( "	      " );
+    W.refresh();
+}
+
+
+void NCStyleDef::saveStyle()
+{
+    std::string fname( "NCstyle." + NCstyle_C.styleName + ".h" );
+    std::string hname( "NCstyle_" + NCstyle_C.styleName + "_h" );
+    std::string fpath( "/tmp/" );
+    fpath += fname;
+
+    std::ofstream out( fpath.c_str(), std::ios::out );
+    NCursesPanel  p( 5, NCurses::cols() - 4, ( NCurses::lines() - 5 ) / 2, 2 );
+    int pl = p.height() / 2;
+    p.box();
+
+    if ( !out.good() )
+    {
+	p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
+	p.printw( pl, 2, "Can't open output file \"%s\"!", fpath.c_str() );
+	p.show();
+	p.refresh();
+	getch();
+	p.hide();
+	p.refresh();
+	return;
+    }
+
+    p.bkgd( NCattribute::color_pair( COLOR_CYAN, COLOR_BLACK ) );
+
+    p.printw( pl, 2, "Saving style \"%s\" in \"%s\" ...", NCstyle_C.styleName.c_str(), fpath.c_str() );
+    p.show();
+    p.refresh();
+
+    out << "/*" << std::endl;
+    out << "  Copyright (C) 2000-2012 Novell, Inc" << std::endl;
+    out << "  This library is free software; you can redistribute it and/or modify" << std::endl;
+    out << "  it under the terms of the GNU Lesser General Public License as" << std::endl;
+    out << "  published by the Free Software Foundation; either version 2.1 of the" << std::endl;
+    out << "  License, or (at your option) version 3.0 of the License. This library" << std::endl;
+    out << "  is distributed in the hope that it will be useful, but WITHOUT ANY" << std::endl;
+    out << "  WARRANTY; without even the implied warranty of MERCHANTABILITY or" << std::endl;
+    out << "  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public" << std::endl;
+    out << "  License for more details. You should have received a copy of the GNU" << std::endl;
+    out << "  Lesser General Public License along with this library; if not, write" << std::endl;
+    out << "  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth" << std::endl;
+    out << "  Floor, Boston, MA 02110-1301 USA" << std::endl;
+    out << "*/" << std::endl;
+    out << std::endl;
+    out << std::endl;
+    out << "/*-/" << std::endl;
+    out << std::endl;
+    out << "   File:       " << fname << std::endl;
+    out << std::endl;
+    out << "   Author:     Generated by class NCstyle" << std::endl;
+    out << std::endl;
+    out << "/-*/" << std::endl;
+    out << "#ifndef " << hname << std::endl;
+    out << "#define " << hname << std::endl;
+    out << "" << std::endl;
+    out << "#include \"NCstyle.h\"" << std::endl;
+    out << "" << std::endl;
+    out << "inline void NCstyleInit_" << NCstyle_C.styleName << "( std::vector & styleSet )" << std::endl;
+    out << "{" << std::endl;
+
+    out << "  //=================================================================" << std::endl;
+    out << "  // init global attributes" << std::endl;
+    out << "  //=================================================================" << std::endl;
+    out << "  NCattrset * attrset( &styleSet[NCstyle::" << NCstyle::dumpName( NCstyle::DefaultStyle ) << "].getAttrGlobal() );" << std::endl;
+
+    for ( NCstyle::STglobal a = ( NCstyle::STglobal )0; a < NCstyle::MaxSTglobal; a = ( NCstyle::STglobal )( a + 1 ) )
+    {
+	out << "  attrset->setAttr( NCstyle::"
+	<< NCstyle::dumpName( a )
+	<< ", ";
+	dumpChtype( out, NCstyle_C( a ) )
+	<< " );" << std::endl;
+    }
+
+    out << "  //=================================================================" << std::endl;
+    out << "  // init local attributes" << std::endl;
+    out << "  //=================================================================" << std::endl;
+
+    for ( NCstyle::StyleSet sts = ( NCstyle::StyleSet )0; sts < NCstyle::MaxStyleSet; sts = ( NCstyle::StyleSet )( sts + 1 ) )
+    {
+	out << "  // " << NCstyle::dumpName( sts ) << std::endl;
+	out << "  attrset = &styleSet[NCstyle::" << NCstyle::dumpName( sts ) << "].getAttrLocal();"  << std::endl;
+
+	for ( NCstyle::STlocal a = ( NCstyle::STlocal )0; a < NCstyle::MaxSTlocal; a = ( NCstyle::STlocal )( a + 1 ) )
+	{
+	    out << "  attrset->setAttr( NCstyle::"
+	    << NCstyle::dumpName( a )
+	    << ", ";
+	    dumpChtype( out, NCstyle_C.styleSet[sts]( a ) )
+	    << " );" << std::endl;
+	}
+    }
+
+    out << "}" << std::endl;
+    out << "#endif // " << hname << std::endl;
+    out.close();
+
+    if ( ! out.good() )
+    {
+	p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
+	p.printw( " FAILED!" );
+    }
+    else
+    {
+	p.printw( " DONE!" );
+
+    }
+
+    p.show();
+
+    p.refresh();
+    getch();
+    p.hide();
+    p.refresh();
+}
+
+
+void NCStyleDef::restoreStyle()
+{
+    std::string fname( "NCstyle." + NCstyle_C.styleName + ".h" );
+    std::string fpath( "/tmp/" );
+    fpath += fname;
+
+    std::ifstream inp( fpath.c_str(), std::ios::in );
+    int ph = 5;
+    NCursesPanel  p( ph, NCurses::cols() - 4, ( NCurses::lines() - ph ) / 2, 2 );
+    int pl = 2;
+    p.box();
+
+    if ( !inp.good() )
+    {
+	p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
+	p.printw( pl, 2, "Can't open input file \"%s\"!", fpath.c_str() );
+	p.show();
+	p.refresh();
+	getch();
+	p.hide();
+	p.refresh();
+	return;
+    }
+
+    p.bkgd( NCattribute::color_pair( COLOR_CYAN, COLOR_BLACK ) );
+
+    p.printw( pl, 2, "Reding style \"%s\" from \"%s\" ...", NCstyle_C.styleName.c_str(), fpath.c_str() );
+    p.show();
+    p.refresh();
+
+    std::list data_vec[NCstyle::MaxStyleSet+1];
+    NCstyle::StyleSet cvec = NCstyle::MaxStyleSet;
+
+    std::string initfnc_ti( "inline void NCstyleInit_" );
+    initfnc_ti += NCstyle_C.styleName + "(";
+    std::string attrdef( "  attrset->setAttr( NCstyle::" );
+    std::string stydef( "  attrset = &styleSet[NCstyle::" );
+
+    enum STATE { PRE, ONFNC, IN, POST, ERROR };
+    STATE psaw = PRE;
+
+    std::string	line( "" );
+    unsigned	lineno = 0;
+
+    while ( inp.good() && psaw != POST && psaw != ERROR )
+    {
+	char c;
+	line = "";
+
+	while ( inp.get( c ), inp.good() && c != '\n' )
+	    line += c;
+
+	{
+	    ++lineno;
+	    // consume
+
+	    switch ( psaw )
+	    {
+		case PRE:
+
+		    if ( line.find( initfnc_ti ) == 0 )
+			psaw = ONFNC;
+
+		    break;
+
+		case ONFNC:
+		    if ( line == "{" || line.find( "  //" ) == 0 )
+			break;
+
+		    if ( line == "  NCattrset * attrset( &styleSet[NCstyle::DefaultStyle].getAttrGlobal() );" )
+		    {
+			psaw = IN;
+			cvec = NCstyle::MaxStyleSet;
+			//p.printw( "[GLOBAL]" );
+			//p.show();
+			//p.refresh();
+		    }
+		    else
+			psaw = ERROR;
+
+		    break;
+
+		case IN:
+		    if ( line == "}" )
+		    {
+			psaw = POST;
+			break;
+		    }
+
+		    if ( line.find( "  //" ) == 0 )
+			break;
+
+		    if ( line.find( attrdef ) == 0 )
+		    {
+			data_vec[cvec].push_back( line.substr( attrdef.size() ) );
+			//p.printw( "." );
+		    }
+		    else if ( line.find( stydef ) == 0 )
+		    {
+			line.erase( 0, stydef.size() );
+
+			if ( line.find( "DefaultStyle]" ) == 0 )
+			{
+			    cvec = NCstyle::DefaultStyle;
+			    //p.printw( "[DefaultStyle]" );
+			}
+			else if ( line.find( "InfoStyle]" ) == 0 )
+			{
+			    cvec = NCstyle::InfoStyle;
+			    //p.printw( "[InfoStyle]" );
+			}
+			else if ( line.find( "WarnStyle]" ) == 0 )
+			{
+			    cvec = NCstyle::WarnStyle;
+			    //p.printw( "[WarnStyle]" );
+			}
+			else if ( line.find( "PopupStyle]" ) == 0 )
+			{
+			    cvec = NCstyle::PopupStyle;
+			    //p.printw( "[PopupStyle]" );
+			}
+			else
+			{
+			    psaw = ERROR;
+			}
+
+			p.show();
+
+			p.refresh();
+		    }
+		    else
+		    {
+			psaw = ERROR;
+		    }
+
+		    break;
+
+		case ERROR:
+
+		case POST:
+		    break;
+	    }
+	}
+    }
+
+    if ( psaw != POST )
+    {
+	p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
+	p.printw( " FAILED stage %d!\n[%d]>>%s<<", psaw, lineno, line.c_str() );
+	p.show();
+	p.refresh();
+	getch();
+	p.hide();
+	p.refresh();
+	return;
+    }
+
+    inp.close();
+
+    // parse data
+
+    std::vector attr_vec;
+
+    for ( cvec = ( NCstyle::StyleSet )0; cvec <= NCstyle::MaxStyleSet; cvec = ( NCstyle::StyleSet )( cvec + 1 ) )
+    {
+	attr_vec.push_back( cvec == NCstyle::MaxStyleSet ? NCattrset( NCstyle::MaxSTglobal ) : NCattrset( NCstyle::MaxSTlocal ) );
+    }
+
+    std::map lookupmap;
+
+    for ( NCstyle::STglobal a = ( NCstyle::STglobal )0; a < NCstyle::MaxSTglobal; a = ( NCstyle::STglobal )( a + 1 ) )
+    {
+	std::map::value_type v( NCstyle::dumpName( a ), lookupIdx( a ) );
+	lookupmap.insert( v );
+    }
+
+    for ( NCstyle::STlocal a = ( NCstyle::STlocal )0; a < NCstyle::MaxSTlocal; a = ( NCstyle::STlocal )( a + 1 ) )
+    {
+	std::map::value_type v( NCstyle::dumpName( a ), lookupIdx( a ) );
+	lookupmap.insert( v );
+    }
+
+    //p.printw( "\n[PARSE]" );
+    //p.show();
+    //p.refresh();
+
+    // globals first
+    for ( cvec = ( NCstyle::StyleSet )( NCstyle::MaxStyleSet + 1 ); cvec > 0; )
+    {
+	cvec = ( NCstyle::StyleSet )( cvec - 1 );
+	//p.printw( "[%s]", NCstyle::dumpName( cvec ).c_str() );
+	//p.show();
+	//p.refresh();
+
+	for ( std::list::iterator i = data_vec[cvec].begin(); i != data_vec[cvec].end(); ++i )
+	{
+	    std::string::size_type sep = i->find( ", " );
+
+	    if ( sep != std::string::npos )
+	    {
+		std::string id( i->substr( 0, sep ) );
+		std::string val( i->substr( sep + 2 ) );
+		sep = val.find( " " );
+
+		if ( sep != std::string::npos )
+		{
+		    val.erase( sep );
+		}
+
+		std::map::const_iterator ldat = lookupmap.find( id );
+
+		if ( ldat == lookupmap.end() || ldat->second.isUnknown() )
+		{
+		    p.printw( "{UNKNOWN:%s=%s}", id.c_str(), val.c_str() );
+		    p.show();
+		    p.refresh();
+		}
+		else
+		{
+		    chtype ch = atoi( val.c_str() );
+		    sep = val.find( "|" );
+
+		    if ( sep != std::string::npos )
+		    {
+			val.erase( 0, sep + 1 );
+
+			while ( val.size() )
+			{
+			    sep = val.find( "|" );
+			    std::string tt = val.substr( 0, sep );
+#define IFASSIGN(T) if ( tt == #T ) ch |= T
+			    IFASSIGN( A_STANDOUT );
+			    else IFASSIGN( A_UNDERLINE );
+			    else IFASSIGN( A_REVERSE );
+			    else IFASSIGN( A_BLINK );
+			    else IFASSIGN( A_DIM );
+			    else IFASSIGN( A_BOLD );
+			    else IFASSIGN( A_INVIS );
+
+#undef IFASSIGN
+			    val.erase( 0, ( sep != std::string::npos ) ? sep + 1 : sep );
+			}
+		    }
+
+		    // ready to assign
+		    if ( ldat->second.isLoc() )
+		    {
+			// actual value is local
+			if ( cvec == NCstyle::MaxStyleSet )
+			{
+			    // global data parsed
+			    for ( unsigned ii = 0; ii < NCstyle::MaxStyleSet; ++ii )
+			    {
+				attr_vec[ii].setAttr( ldat->second.uindex(), ch );
+			    }
+			}
+			else
+			{
+			    // local data parsed
+			    attr_vec[cvec].setAttr( ldat->second.uindex(), ch );
+			}
+
+			attr_vec[cvec].setAttr( ldat->second.uindex(), ch );
+		    }
+		    else if ( ldat->second.isGlob() )
+		    {
+			// actual value is global
+			attr_vec[NCstyle::MaxStyleSet].setAttr( ldat->second.uindex(), ch );
+		    }
+		}
+
+		//p.printw( "." );
+		//p.show();
+		//p.refresh();
+	    }
+	    else
+	    {
+		p.printw( "{NOVAL:%s}", i->c_str() );
+		p.show();
+		p.refresh();
+	    }
+	}
+    }
+
+    // apply
+    cvec = ( NCstyle::StyleSet )0;
+
+    NCstyle_C.getStyle( cvec ).getAttrGlobal() = attr_vec[NCstyle::MaxStyleSet];
+
+    for ( ; cvec < NCstyle::MaxStyleSet; cvec = ( NCstyle::StyleSet )( cvec + 1 ) )
+    {
+	NCstyle_C.getStyle( cvec ).getAttrLocal() = attr_vec[cvec];
+    }
+
+    attrchanged();
+
+    // finish
+    p.printw( " DONE!" );
+    p.show();
+    p.refresh();
+    getch();
+    p.hide();
+    p.refresh();
+}
+
+
+void NCDefineStyle( NCstyle & style )
+{
+    static NCStyleDef cstyle( style );
+    cstyle.changeStyle();
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCStyleDef.h b/deps/libyui/libyui-ncurses/src/NCStyleDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..3487f522610b5200332f516c77a77906a2c7850c
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCStyleDef.h
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCStyleDef.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCStyleDef_h
+#define NCStyleDef_h
+
+extern void NCDefineStyle( NCstyle & style );
+
+#endif // NCStyleDef_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTable.cc b/deps/libyui/libyui-ncurses/src/NCTable.cc
new file mode 100644
index 0000000000000000000000000000000000000000..179564c39a15c70b927b6a38b8120118d73d35b5
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTable.cc
@@ -0,0 +1,762 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTable.cc
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCTable.h"
+#include "NCPopupMenu.h"
+
+#include 
+#include 
+
+using std::string;
+using std::vector;
+using std::endl;
+
+
+/*
+ * Some remarks about single/multi selection:
+ *
+ * A table in single selection mode has only one line/item selected which is
+ * equal to the current item (means the highlighted line). Querying CurrentItem
+ * in YCP looks for selectedItem()
+ * (see YCPPropertyHandler::tryGetSelectionWidgetValue).
+ *
+ * In multi selection mode there can be several items selected (here is means
+ * checked/marked with [x]) and the value is also got from selectedItem() when
+ * asking for :SelectedItems
+ * (see YCPPropertyHandler::tryGetSelectionWidgetValue).
+ *
+ * This means for multi selection mode: at the moment there isn't a possibility
+ * to get the CurrentItem. To get the current item (which line of the list is
+ * currently highlighted), a virtual function currentItem() like available for
+ * the MultiSelectionBox has to be provided to allow NCTable to specify the
+ * line number itself (getCurrentItem).
+ */
+NCTable::NCTable( YWidget *      parent,
+                  YTableHeader * tableHeader,
+                  bool           multiSelection )
+    : YTable( parent, tableHeader, multiSelection )
+    , NCPadWidget( parent )
+    , _prefixCols( 0 )
+    , _nestedItems( false )
+    , _bigList( false )
+    , _multiSelect( multiSelection )
+    , _lastSortCol( 0 )
+    , _sortReverse( false )
+    , _sortStrategy( new NCTableSortDefault() )
+{
+    // yuiDebug() << endl;
+
+    InitPad();
+    rebuildHeaderLine();
+}
+
+
+NCTable::~NCTable()
+{
+    if ( _sortStrategy )
+        delete _sortStrategy;
+}
+
+
+void NCTable::rebuildHeaderLine()
+{
+    _prefixCols = 0;
+
+    if ( _multiSelect )
+        ++_prefixCols;
+
+    vector headers;
+    headers.resize( _prefixCols + columns() );
+
+    for ( int i = 0; i < columns(); i++ )
+    {
+        int col = i + _prefixCols;
+
+        if ( hasColumn( i ) )
+        {
+            NCstring hdr( alignmentStr( i ) );
+            hdr += header( i );
+            // yuiDebug() << "hdr[" << col << "]: \"" << hdr << "\"" << endl;
+            headers[ col ] = hdr;
+        }
+    }
+
+    hasHeadline = myPad()->SetHeadline( headers );
+}
+
+
+NCstring NCTable::alignmentStr( int col )
+{
+    switch ( alignment( col ) )
+    {
+	case YAlignUnchanged:   return "L";
+	case YAlignBegin:       return "L";
+	case YAlignCenter:      return "C";
+	case YAlignEnd:         return "R";
+
+        // No 'default' branch: Let the compiler complain if there is an unhandled enum value.
+    }
+
+    return "L";
+}
+
+
+void NCTable::setCell( int index, int col, const string & newtext )
+{
+    NCTableLine * currentLine = myPad()->ModifyLine( index );
+
+    if ( !currentLine )
+    {
+	yuiWarning() << "No such line: " << wpos( index, col ) << newtext << endl;
+    }
+    else
+    {
+	NCTableCol * currentCol = currentLine->GetCol( col );
+
+	if ( !currentCol )
+	{
+	    yuiWarning() << "No such col: " << wpos( index, col ) << newtext << endl;
+	}
+	else
+	{
+	    // use NCtring to enforce recoding from UTF-8
+	    currentCol->SetLabel( NCstring( newtext ) );
+	    DrawPad();
+	}
+    }
+}
+
+
+void NCTable::cellChanged( const YTableCell * changedCell )
+{
+    YUI_CHECK_PTR( changedCell );
+
+    YTableItem * ytableItem = changedCell->parent();
+    YUI_CHECK_PTR( ytableItem );
+
+    NCTableLine * tableLine = (NCTableLine *) ytableItem->data();
+    YUI_CHECK_PTR( tableLine );
+
+    NCTableCol * tableCol = tableLine->GetCol( changedCell->column() );
+
+    if ( tableCol )
+    {
+        tableCol->SetLabel( changedCell->label() );
+        DrawPad();
+    }
+    else
+    {
+        yuiError() << "No column #" << changedCell->column()
+                   << " in item " << ytableItem
+                   << endl;
+    }
+}
+
+
+void NCTable::setHeader( const vector & headers )
+{
+    YTableHeader * tableHeader = new YTableHeader();
+
+    for ( unsigned i = 0; i < headers.size(); i++ )
+    {
+	tableHeader->addColumn( headers[ i ] );
+    }
+
+    YTable::setTableHeader( tableHeader );
+    rebuildHeaderLine();
+}
+
+
+vector
+NCTable::getHeader() const
+{
+    vector headers;
+    headers.resize( columns() );
+
+    for ( int col = 0; col < columns(); col++ )
+    {
+        headers[ col ] = header( col );
+    }
+
+    return headers;
+}
+
+
+void NCTable::addItems( const YItemCollection & itemCollection )
+{
+    myPad()->ClearTable();
+    YTable::addItems( itemCollection );
+
+    if ( keepSorting() )
+    {
+        rebuildPadLines();
+    }
+    else
+    {
+        sortItems( _lastSortCol, _sortReverse );
+        // this includes rebuildPadLInes()
+    }
+
+    if ( !_multiSelect )
+        selectCurrentItem();
+
+    DrawPad();
+}
+
+
+void NCTable::addItem( YItem *            yitem,
+                       NCTableLine::STATE state )
+{
+    if ( ! yitem->parent() )            // Only for toplevel items:
+        YTable::addItem( yitem );       // Notify the YTable base class
+
+    addPadLine( 0,      // parentLine
+                yitem,
+                false,  // preventRedraw
+                state );
+}
+
+
+void NCTable::addItem( YItem *            yitem,
+                       bool               preventRedraw,
+                       NCTableLine::STATE state )
+{
+    if ( ! yitem->parent() )            // Only for toplevel items:
+        YTable::addItem( yitem );       // Notify the YTable base class
+
+    addPadLine( 0,      // parentLine
+                yitem,
+                preventRedraw,
+                state );
+}
+
+
+void NCTable::addPadLine( NCTableLine *      parentLine,
+                          YItem *            yitem,
+                          bool               preventRedraw,
+                          NCTableLine::STATE state )
+{
+    YTableItem *item = dynamic_cast( yitem );
+    YUI_CHECK_PTR( item );
+
+    // Ideally, _nestedItems should be updated by iterating over ALL items
+    // before the first NCTableLine is created (i.e. before the first
+    // addPadLine() call) so they all get the proper prefix placeholder for
+    // reserving some screen space for the tree line graphics.
+    //
+    // This additional check is just a second line of defence.
+
+    if ( parentLine || item->hasChildren() )
+        _nestedItems = true;
+
+    vector cells;
+
+    if ( _multiSelect )
+    {
+        // Add a table tag to hold the "[ ]" / "[x]" marker.
+        cells.push_back( new NCTableTag( yitem, yitem->selected() ) );
+    }
+
+    // Add all the cells
+    for ( YTableCellIterator it = item->cellsBegin(); it != item->cellsEnd(); ++it )
+        cells.push_back( new NCTableCol( NCstring(( *it )->label() ) ) );
+
+    int index = myPad()->Lines();
+    item->setIndex( index );
+
+    // yuiMilestone() << "Adding pad line for " << item << " index: " << item->index() << endl;
+
+
+    // Create the line itself
+    NCTableLine *line = new NCTableLine( parentLine,
+                                         item,
+                                         cells,
+                                         index,
+                                         _nestedItems,
+                                         state );
+    YUI_CHECK_NEW( line );
+    myPad()->Append( line );
+
+    if ( item->selected() )
+	setCurrentItem( item->index() ) ;
+
+    // Recurse over children (if there are any)
+
+    for ( YItemIterator it = item->childrenBegin(); it != item->childrenEnd(); ++it )
+    {
+        addPadLine( line, *it, preventRedraw, state );
+    }
+
+    if ( ! preventRedraw )
+	DrawPad();
+}
+
+
+void NCTable::rebuildPadLines()
+{
+    myPad()->ClearTable();
+    _nestedItems = hasNestedItems( itemsBegin(), itemsEnd() );
+
+    for ( YItemConstIterator it = itemsBegin(); it != itemsEnd(); ++it )
+    {
+        addPadLine( 0,      // parentLine
+                    *it,
+                    true ); // preventRedraw
+    }
+}
+
+
+bool NCTable::hasNestedItems( const YItemCollection & itemCollection ) const
+{
+    return hasNestedItems( itemCollection.begin(), itemCollection.end() );
+}
+
+
+bool NCTable::hasNestedItems( YItemConstIterator begin,
+                              YItemConstIterator end ) const
+{
+    for ( YItemConstIterator it = begin; it != end; ++it )
+    {
+        if ( (*it)->hasChildren() )
+            return true;
+    }
+
+    return false;
+}
+
+
+void NCTable::deleteAllItems()
+{
+    myPad()->ClearTable();
+    YTable::deleteAllItems();
+    DrawPad();
+
+    _nestedItems   = false;
+    _lastSortCol   = 0;
+    _sortReverse   = false;
+}
+
+
+int NCTable::getCurrentItem() const
+{
+    if ( myPad()->empty() )
+	return -1;
+
+    // The intent of this condition is to return the original index, before
+    // sorting. But the condition was accidentally inverted in 2007 and now it
+    // always returns the index after sorting.
+    // Should we fix it? Depends on whether the current users rely on the
+    // current behavior.
+
+    return keepSorting() ? getCurrentIndex() : myPad()->CurPos().L;
+}
+
+
+YItem * NCTable::getCurrentItemPointer()
+{
+    const NCTableLine * currentLine = myPad()->GetCurrentLine();
+
+    if ( currentLine )
+	return currentLine->origItem();
+    else
+	return 0;
+}
+
+
+int NCTable::getCurrentIndex() const
+{
+    const NCTableLine * currentLine = myPad()->GetCurrentLine();
+
+    return currentLine ? currentLine->index() : -1;
+}
+
+
+void NCTable::scrollToFirstItem()
+{
+    if ( myPad()->empty() )
+        myPad()->ScrlLine( 0 );
+}
+
+
+void NCTable::setCurrentItem( int index )
+{
+    myPad()->ScrlLine( index );
+}
+
+
+void NCTable::selectItem( YItem *yitem, bool selected )
+{
+    if ( ! yitem )
+	return;
+
+    YTableItem *item = dynamic_cast( yitem );
+    YUI_CHECK_PTR( item );
+
+    NCTableLine *line = (NCTableLine *) item->data();
+    YUI_CHECK_PTR( line );
+
+    const NCTableLine *current_line = myPad()->GetLine( myPad()->CurPos().L );
+    YUI_CHECK_PTR( current_line );
+
+    if ( !_multiSelect )
+    {
+	if ( !selected && ( line == current_line ) )
+	{
+	    deselectAllItems();
+	}
+	else
+	{
+	    // first highlight only, then select
+	    setCurrentItem( line->index() );
+	    YTable::selectItem( item, selected );
+	}
+    }
+    else // multiSelect
+    {
+	YTable::selectItem( item, selected );
+
+	// yuiDebug() << item->label() << " is selected: " << std::boolalpha << selected <<  endl;
+
+        // The NCTableTag holds the "[ ]" / "[x]" selection marker
+	NCTableTag * tagCell =  line->tagCell();
+
+        if ( tagCell )
+            tagCell->SetSelected( selected );
+    }
+
+    DrawPad();
+}
+
+
+
+/**
+ * Mark the currently highlighted table item as selected.
+ *
+ * Yes, it is really already highlighted, so no need to selectItem() and
+ * setCurrentItem() here again. (bsc#493884)
+ **/
+void NCTable::selectCurrentItem()
+{
+    const NCTableLine * currentLine = myPad()->GetCurrentLine();
+
+    if ( currentLine )
+	YTable::selectItem( currentLine->origItem(), true );
+}
+
+
+void NCTable::deselectAllItems()
+{
+    if ( !_multiSelect )
+    {
+        setCurrentItem( -1 );
+        YTable::deselectAllItems();
+    }
+    else
+    {
+        YItemCollection itemCollection = YTable::selectedItems();
+        // This will return nested selected items as well
+
+        for ( YItemConstIterator it = itemCollection.begin();
+              it != itemCollection.end();
+              ++it )
+        {
+            // Clear the item's internal selected status flag
+            // and update the "[x]" marker on the screen to "[ ]"
+            // in the corresponding NCTableTag
+
+            selectItem( *it, false );
+        }
+    }
+
+    DrawPad();
+}
+
+
+int NCTable::preferredWidth()
+{
+    wsze sze = _bigList ? myPad()->tableSize() + 2 : wGetDefsze();
+    return sze.W;
+}
+
+
+int NCTable::preferredHeight()
+{
+    wsze sze = _bigList ? myPad()->tableSize() + 2 : wGetDefsze();
+    return sze.H;
+}
+
+
+void NCTable::setSize( int newwidth, int newheight )
+{
+    wRelocate( wpos( 0 ), wsze( newheight, newwidth ) );
+}
+
+
+void NCTable::setLabel( const string & nlabel )
+{
+    // not implemented: YTable::setLabel( nlabel );
+    NCPadWidget::setLabel( NCstring( nlabel ) );
+}
+
+
+void NCTable::setEnabled( bool do_bv )
+{
+    NCWidget::setEnabled( do_bv );
+    YTable::setEnabled( do_bv );
+}
+
+
+bool NCTable::setItemByKey( int key )
+{
+    return myPad()->setItemByKey( key );
+}
+
+
+NCPad * NCTable::CreatePad()
+{
+    wsze    psze( defPadSze() );
+    NCPad * npad = new NCTablePad( psze.H, psze.W, *this );
+    npad->bkgd( listStyle().item.plain );
+
+    return npad;
+}
+
+
+/**
+ * NCurses widget keyboard handler.
+ *
+ * This is the starting point for handling key events. From here, key events
+ * are propagated to the pad and to the items.
+ **/
+NCursesEvent NCTable::wHandleInput( wint_t key )
+{
+    NCursesEvent ret  = NCursesEvent::none;
+    int  currentIndex = getCurrentItem();
+
+    // Call the pad's input handler via NCPadWidget::handleInput()
+    // which calls its pad class's input handler
+    // which may call the current item's input handler.
+    //
+    // Notice that most keys are handled on the level of the pad or the item,
+    // not here. See
+    //
+    // - NCTablePad::handleInput()
+    // - NCTablePadBase::handleInput()
+    // - NCTableLine::handleInput()
+
+    bool handled = handleInput( key ); // NCTablePad::handleInput()
+
+    switch ( key )
+    {
+        case CTRL( 'o' ):       // Table sorting (Ordering)
+            if ( ! handled )
+            {
+                if ( ! keepSorting() )
+                {
+                    interactiveSort();
+                    return NCursesEvent::none;
+                }
+            }
+            break;
+
+
+        case KEY_SPACE:
+            
+            if ( ! handled ) // NCTableLine::handleInput() handles opening/closing branches
+            {
+                if ( _multiSelect )
+                {
+                    toggleCurrentItem();
+
+                    if ( notify() )
+                        return NCursesEvent::ValueChanged;
+                }
+            }
+            break;
+            
+        // Even if the event was already handled:
+        // Take care about sending UI events to the caller.
+
+        case KEY_RETURN:
+
+            if ( _multiSelect )
+            {
+                toggleCurrentItem();
+
+                if ( notify() )
+                    return NCursesEvent::ValueChanged;
+            }
+            else // !_multiSelect
+            {
+                if ( notify() && currentIndex != -1 )
+                    return NCursesEvent::Activated;
+            }
+            break;
+    }
+
+    if (  currentIndex != getCurrentItem() )
+    {
+	if ( notify() && immediateMode() )
+	    ret = NCursesEvent::SelectionChanged;
+
+	if ( !_multiSelect )
+	    selectCurrentItem();
+    }
+
+    return ret;
+}
+
+
+void NCTable::toggleCurrentItem()
+{
+    YTableItem * item =  dynamic_cast( getCurrentItemPointer() );
+
+    if ( item )
+	selectItem( item, !( item->selected() ) );
+}
+
+
+void NCTable::interactiveSort()
+{
+    //
+    // Collect the non-empty column headers
+    //
+
+    YItemCollection menuItems;
+    menuItems.reserve( columns() );
+
+    for ( int col = 0; col < columns(); col++ )
+    {
+        string hdr = header( col );
+
+        if ( ! hdr.empty() )
+        {
+            YMenuItem *item = new YMenuItem( header( col ) ) ;
+
+            // need to set the index explicitly, YMenuItem inherits from YTreeItem
+            // and these don't have indexes set
+            item->setIndex( col );
+            menuItems.push_back( item );
+        }
+    }
+
+    if ( ! menuItems.empty() )
+    {
+        //
+        // Post a popup with the column headers
+        //
+
+        // Get the column; show the popup in the table's upper left corner
+        wpos pos( ScreenPos() + wpos( 2, 1 ) );
+
+        NCPopupMenu *dialog = new NCPopupMenu( pos, menuItems.begin(), menuItems.end() );
+        int sortCol = dialog->post();
+
+        // close the popup
+        YDialog::deleteTopmostDialog();
+
+        if ( sortCol != -1 && hasColumn( sortCol ) )
+        {
+            //
+            // Do the sorting
+            //
+
+            yuiDebug() << "Manually sorting by column #"
+                       << sortCol << ": " << header( sortCol )
+                       << endl;
+
+            _sortReverse = sortCol == _lastSortCol ?
+                ! _sortReverse : false;
+
+            sortItems( sortCol, _sortReverse );
+
+            if ( !_multiSelect )
+                selectCurrentItem();
+
+            DrawPad();
+        }
+    }
+}
+
+
+void NCTable::sortItems( int sortCol, bool reverse )
+{
+    myPad()->ClearTable();
+
+    // Sort the YItems.
+    //
+    // This may feel a little weird since those YItems are owned by the
+    // YSelectionWidget parent class. But we are only changing their sort
+    // order, not invalidating any item pointers; and the internal sort order
+    // is not anything that any calling application code may rely on.
+    //
+    // Since the NCTable now supports nested items, we can no longer simply
+    // sort the NCTableLines to keep this whole sorting localized: In the pad,
+    // they are just a flat list, and the hierarchy is not that easy to find
+    // out.  But we need the hierarchy to sort each tree level separately in
+    // each branch.
+    //
+    // It is much simpler and less error-prone to just clear the pad (and thus
+    // get rid of any existing NCTableLines), sort the YItems and rebuild all
+    // the NCTableLines from the newly sorted YItems.
+
+    _sortStrategy->setSortCol( sortCol );
+    _sortStrategy->setReverse( reverse );
+    _lastSortCol = sortCol;
+
+    sortYItems( itemsBegin(), itemsEnd() );
+
+    rebuildPadLines();
+}
+
+
+void NCTable::sortYItems( YItemIterator begin,
+                          YItemIterator end )
+{
+    // Sort the children first as long as the iterators are
+    // guaranteed to be valid
+
+    for ( YItemIterator it = begin; it != end; ++it )
+    {
+        if ( (*it)->hasChildren() )
+            sortYItems( (*it)->childrenBegin(), (*it)->childrenEnd() );
+    }
+
+    // Sort this level. This may make the iterators invalid.
+    _sortStrategy->sort( begin, end );
+}
+
+
+void NCTable::setSortStrategy( NCTableSortStrategyBase * newStrategy )
+{
+    if ( _sortStrategy )
+        delete _sortStrategy;
+
+    _sortStrategy = newStrategy;
+}
+
diff --git a/deps/libyui/libyui-ncurses/src/NCTable.h b/deps/libyui/libyui-ncurses/src/NCTable.h
new file mode 100644
index 0000000000000000000000000000000000000000..b733a5ed1bbd74a18d2553ef5ee6b5558c17379e
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTable.h
@@ -0,0 +1,463 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTable.h
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#ifndef NCTable_h
+#define NCTable_h
+
+#include 
+#include "NCPadWidget.h"
+#include "NCTablePad.h"
+#include "NCTableSort.h"
+
+
+/**
+ * A table with rows and columns. Items may be nested.
+ *
+ * See also
+ * https://github.com/libyui/libyui-ncurses/blob/master/doc/nctable-and-nctree.md
+ */
+class NCTable : public YTable, public NCPadWidget
+{
+    friend std::ostream & operator<<( std::ostream & str, const NCTable & obj );
+
+public:
+
+    NCTable( YWidget *      parent,
+             YTableHeader * tableHeader,
+             bool           multiSelection = false );
+
+    virtual ~NCTable();
+
+    /**
+     * Set the table header (the first line inside the table) as strings.
+     **/
+    void setHeader( const std::vector& head );
+
+    /**
+     * Get the table headers (the first line inside the table) as strings.
+     * Alignment flags are removed.
+     **/
+    std::vector getHeader() const;
+
+    /**
+     * Add items.
+     *
+     * Reimplemented from YSelectionWidget to optimize sorting.
+     **/
+    virtual void addItems( const YItemCollection & itemCollection );
+
+    /**
+     * Add one item.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void addItem( YItem *yitem )
+        { addItem( yitem, NCTableLine::S_NORMAL ); }
+
+    /**
+     * Add one item with the specified state and redraw the table.
+     *
+     * This overloaded version is first defined here and also used in
+     * NCPopupTable. Notice that this does not have a default value for the
+     * 'state' parameter to avoid clashing with the addItem( YItem * ) version
+     * inherited from YSelectionWidget which might be used from C++
+     * applications using libyui.
+     **/
+    virtual void addItem( YItem *            yitem,
+                          NCTableLine::STATE state );
+
+    /**
+     * Delete all items and clear the pad.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void deleteAllItems();
+
+    /**
+     * Get the index of the current item (the item under the cursor)
+     * or -1 if there is none.
+     **/
+    virtual int getCurrentIndex() const;
+
+    /**
+     * Get the index of the current item (the item under the cursor)
+     * or -1 if there is none, i.e. the table is empty.
+     *
+     * FIXME: This is a misnomer of epic proportions. This should be named
+     * getCurrentIndex(). A method called getCurrentItem() should return the
+     * item (i.e. a pointer or a reference), not an index! But since this is
+     * all over the place in derived classes and in libyui-ncurses-pkg as well,
+     * this is not a trivial thing to fix.
+     **/
+    virtual int getCurrentItem() const;
+
+    /**
+     * Return a pointer to the current item (the item under the cursor)
+     * or 0 if there is none, i.e. the table is empty.
+     *
+     * FIXME: This is what getCurrentItem() should really be.
+     **/
+    YItem * getCurrentItemPointer();
+
+    /**
+     * Set the current item to the specified index.
+     **/
+    virtual void setCurrentItem( int index );
+
+    /**
+     * Scroll to the first item.
+     **/
+    virtual void scrollToFirstItem();
+
+    /**
+     * Select or deselect an item.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void selectItem( YItem *yitem, bool selected );
+
+    /**
+     * Select the current item (the item under the cursor).
+     **/
+    void selectCurrentItem();
+
+    /**
+     * Deselect all items.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void deselectAllItems();
+
+    /**
+     * Keyboard input handler.
+     *
+     * This is the starting point for handling key events. From here, key
+     * events are propagated to the pad and to the items.
+     *
+     * Implemented from NCWidget.
+     **/
+    virtual NCursesEvent wHandleInput( wint_t key );
+
+    /**
+     * libyui geometry management:
+     * Return the preferred width for this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual int preferredWidth();
+
+    /**
+     * libyui geometry management:
+     * Return the preferred height for this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual int preferredHeight();
+
+    /**
+     * libyui geometry management:
+     * Apply the width and height assigned from the parent layout widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void setSize( int newWidth, int newHeight );
+
+    /**
+     * Set the label (the caption) above the table.
+     *
+     * YTable does not specify a label because a table has a whole row of
+     * headers.
+     **/
+    virtual void setLabel( const std::string & nlabel );
+
+    /**
+     * Enable or disable this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void setEnabled( bool do_bv );
+
+    /**
+     * Set the keyboard focus to this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual bool setKeyboardFocus()
+    {
+	if ( !grabFocus() )
+	    return YWidget::setKeyboardFocus();
+
+	return true;
+    }
+
+    /**
+     * Select an item by its hotkey.
+     * Used only in NCPopupTable::wHandleHotkey().
+     **/
+    bool setItemByKey( int key );
+
+    /**
+     * Set the column separator character.
+     * Used only in NCPopupTable and in NCFileSelection.
+     **/
+    void SetSepChar( const chtype colSepchar )
+        { myPad()->SetSepChar( colSepchar ); }
+
+    /**
+     * Set the separator width.
+     * Used only in NCPopupTable.
+     **/
+    void SetSepWidth( const unsigned sepwidth )
+        { myPad()->SetSepWidth( sepwidth ); }
+
+    /**
+     * Set the hotkey column (?).
+     * Used only in NCPopupTable.
+     **/
+    void SetHotCol( int hcol )
+        { myPad()->SetHotCol( hcol ); }
+
+    /**
+     * Flag: Is this a big list?
+     **/
+    bool bigList() const { return _bigList; }
+
+    /**
+     * Set the "big list" flag.
+     **/
+    void setBigList( bool big ) { _bigList = big; }
+
+    /**
+     * Remove all hotkeys from the pad.
+     **/
+    void stripHotkeys() { myPad()->stripHotkeys(); }
+
+    /**
+     * Set a sorting strategy. This class takes ownership.
+     **/
+    void setSortStrategy( NCTableSortStrategyBase * newStrategy );
+
+    /**
+     * Return the current sorting strategy.
+     **/
+    NCTableSortStrategyBase * sortStrategy() const { return _sortStrategy; }
+
+
+protected:
+
+    /**
+     * Code location for logging.
+     *
+     * Implemented from NCWidget.
+     **/
+    virtual const char * location() const { return "NCTable"; }
+
+    /**
+     * Create an empty pad and set its background.
+     **/
+    virtual NCPad * CreatePad();
+
+    /**
+     * Return the TreePad that belongs to this widget.
+     *
+     * Overloaded from NCPadWidget to narrow the type to the actual one used in
+     * this widget.
+     **/
+    virtual NCTablePad * myPad() const
+	{ return dynamic_cast( NCPadWidget::myPad() ); }
+
+    /**
+     * Internal overloaded version of addItem().
+     *
+     * This creates a visual representation of the new table line consisting of
+     * individual cells. If 'preventRedraw' is 'false', the table is redrawn;
+     * otherwise, it is up to the caller to redraw the table.
+     *
+     * This is used in addItem( yitem ) and addItems( itemCollection ) in this
+     * class, but also in the derived NCFileSelection and NCPkgTable classes.
+     **/
+    virtual void addItem( YItem *            yitem,
+                          bool               preventRedraw,
+                          NCTableLine::STATE state = NCTableLine::S_NORMAL );
+
+    /**
+     * Add a pad line (an NCTableLine) for 'yitem' and recurse into any of its
+     * children (and grandchildren etc.).
+     *
+     * Make sure to update _nestedItems (by iterating over all the YItems)
+     * before the first one is added so they will reserve some screen space for
+     * the tree hierarchy line graphics (using the prefix placeholder).
+     *
+     * This can realistically only be done when bulk-adding all YItems at
+     * once. If they are added one by one, the first few may not have any
+     * children, so their corresponding pad lines will not reserve screen space
+     * for the prefix, leading to ugly results.
+     *
+     * If there is no item nesting at all, this does not matter, of course.
+     **/
+    virtual void addPadLine( NCTableLine *      parentLine,
+                             YItem *            yitem,
+                             bool               preventRedraw,
+                             NCTableLine::STATE state = NCTableLine::S_NORMAL );
+
+
+    /**
+     * Build or rebuild the pad lines: Clear the pad, iterate over all YItems
+     * and add a corresponding NCTableLine to the pad. This recurses into any
+     * child YItems.
+     *
+     * This does not redraw the pad. Do that from the outside.
+     **/
+    void rebuildPadLines();
+
+    /**
+     * Rebuild the table header line.
+     **/
+    void rebuildHeaderLine();
+
+    /**
+     * Return the NCurses alignment string for the alignment of the
+     * specified column: One of "L", "C", "R" (Left, Center, Right).
+     **/
+    NCstring alignmentStr( int col );
+
+    /**
+     * Return 'true' if any item in the item collection has any children,
+     * 'false' otherwise.
+     **/
+    bool hasNestedItems( const YItemCollection & itemCollection ) const;
+
+    bool hasNestedItems( YItemConstIterator begin,
+                         YItemConstIterator end ) const;
+
+    /**
+     * Optimization for NCurses from libyui:
+     * Notification that multiple changes are about to come.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void startMultipleChanges() { startMultidraw(); }
+
+    /**
+     * Optimization for NCurses from libyui:
+     * Notification that multiple changes are now finished.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void doneMultipleChanges()	{ stopMultidraw(); }
+
+    /**
+     * Toggle the current item between selected and not selected.
+     **/
+    void toggleCurrentItem();
+
+    /**
+     * Notification that a cell has now changed content:
+     * Set that cell's content also in the corresponding table line.
+     **/
+    void cellChanged( const YTableCell * cell );
+
+    /**
+     * Change the cell with item index 'index' and column no. 'col' to 'newText'.
+     **/
+    void setCell( int index, int col, const std::string & newText );
+
+    /**
+     * Recursively iterate over items and assign each one a unique item index.
+     *
+     * As long as the items don't have any child items, each one simply gets
+     * its initial position in the item collection. When there are children,
+     * however, there will be gaps between the index of one toplevel item and
+     * the next.
+     *
+     * It is generally unsafe to make assumptions about the indices except that
+     * they are unique within one table, and an item will keep its initial
+     * index, no matter how the table is sorted.
+     *
+     * The indices restart from 0 after the table has been cleared, i.e. after
+     * deleteAllItems() or at the start of setItems().
+     **/
+    void assignIndex( YItemConstIterator begin,
+                      YItemConstIterator end );
+
+    /**
+     * Assign an item a unique index.
+     **/
+    void assignIndex( YItem * item );
+
+    /**
+     * Interactive sorting by a user-selected column:
+     *
+     * Open a popup with the (non-empty) column headers and let the user choose
+     * one for sorting.
+     **/
+    void interactiveSort();
+
+    /**
+     * Sort the items by column no. 'sortCol' with the current sort strategy.
+     *
+     * This sorts the YItems and recreates all NCTableLines.
+     * All YItem pointers remain valid, but the NCTableLines do not.
+     **/
+    void sortItems( int sortCol, bool reverse = false );
+
+    /**
+     * Sort the YItems between 'begin' and 'end' using the current sort
+     * strategy.
+     **/
+    void sortYItems( YItemIterator begin,
+                     YItemIterator end   );
+
+private:
+
+    // Disable unwanted assignment opearator and copy constructor
+
+    NCTable & operator=( const NCTable & );
+    NCTable( const NCTable & );
+
+
+    //
+    // Data members
+    //
+
+    // Number of non-data prefix columns for things like the multi-selection
+    // indicator ("[ ]" / "[x]")
+    int  _prefixCols;
+
+    bool _nestedItems;
+    bool _bigList;
+    bool _multiSelect;
+
+    int  _lastSortCol;
+    bool _sortReverse;
+    NCTableSortStrategyBase * _sortStrategy;    //< owned
+};
+
+
+std::ostream & operator<<( std::ostream & stream, const YItem * item );
+
+
+#endif // NCTable_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTableItem.cc b/deps/libyui/libyui-ncurses/src/NCTableItem.cc
new file mode 100644
index 0000000000000000000000000000000000000000..daf41e9ebc0013d2bccdeda104be0ad16d4ca354
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTableItem.cc
@@ -0,0 +1,859 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTableItem.cc
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCTableItem.h"
+#include "NCTable.h"
+#include "stringutil.h"
+#include "stdutil.h"
+
+using stdutil::form;
+using std::string;
+using std::wstring;
+using std::endl;
+
+
+NCTableLine::NCTableLine( std::vector & cells,
+                          int                        index,
+                          bool                       nested,
+                          unsigned                   state )
+    : _cells( cells )
+    , _state( state )
+    , _index( index )
+    , _yitem( 0 )
+    , _nested( nested )
+    , _treeLevel( 0 )
+    , _parent( 0 )
+    , _nextSibling( 0 )
+    , _firstChild( 0 )
+    , _vstate( S_HIDDEN )
+    , _prefix( 0 )
+{
+    initPrefixPlaceholder();
+}
+
+
+NCTableLine::NCTableLine( NCTableLine *              parentLine,
+                          YItem *                    yitem,
+                          std::vector & cells,
+                          int                        index,
+                          bool                       nested,
+                          unsigned                   state )
+    : _cells( cells )
+    , _state( state )
+    , _index( index )
+    , _yitem( yitem )
+    , _nested( nested )
+    , _treeLevel( 0 )
+    , _parent( parentLine )
+    , _nextSibling( 0 )
+    , _firstChild( 0 )
+    , _vstate( S_HIDDEN )
+    , _prefix( 0 )
+{
+    setYItem( yitem );
+    treeInit( parentLine, yitem );
+    initPrefixPlaceholder(); // This needs to be done AFTER treeInit()!
+
+    if ( ! cells.empty() && nested )
+        cells[0]->setPrefix( _prefixPlaceholder );
+}
+
+
+NCTableLine::NCTableLine( unsigned colCount,
+                          int      index,
+                          bool     nested,
+                          unsigned state )
+    : _cells( colCount, (NCTableCol *) 0 )
+    , _state( state )
+    , _index( index )
+    , _yitem( 0 )
+    , _nested( nested )
+    , _treeLevel( 0 )
+    , _parent( 0 )
+    , _nextSibling( 0 )
+    , _firstChild( 0 )
+    , _vstate( S_HIDDEN )
+    , _prefix( 0 )
+{
+    initPrefixPlaceholder();
+}
+
+
+NCTableLine::NCTableLine( NCTableLine * parentLine,
+                          YItem *       yitem,
+                          unsigned      colCount,
+                          int           index,
+                          bool          nested,
+                          unsigned      state )
+    : _cells( colCount, (NCTableCol *) 0 )
+    , _state( state )
+    , _index( index )
+    , _yitem( yitem )
+    , _nested( nested )
+    , _treeLevel( 0 )
+    , _parent( parentLine )
+    , _nextSibling( 0 )
+    , _firstChild( 0 )
+    , _vstate( S_HIDDEN )
+    , _prefix( 0 )
+{
+    setYItem( yitem );
+    treeInit( parentLine, yitem );
+    initPrefixPlaceholder(); // This needs to be done AFTER treeInit()!
+}
+
+
+NCTableLine::~NCTableLine()
+{
+    ClearLine();
+    delete [] _prefix;
+}
+
+
+void NCTableLine::treeInit( NCTableLine * parentLine,
+                            YItem *       yitem      )
+{
+    _parent = parentLine;
+
+    if ( _parent )
+    {
+        addToTree( _parent );
+        _treeLevel = _parent->treeLevel() + 1;
+        _nested    = true;
+
+        if ( ! isOpen( parentLine->yitem() ) )
+            SetState( S_HIDDEN );
+    }
+    else
+    {
+        _firstChild  = 0;
+        _nextSibling = 0;
+        _treeLevel   = 0;
+    }
+}
+
+
+void NCTableLine::initPrefixPlaceholder()
+{
+    // Notice that this needs to be done AFTER treeInit() because prefixLen()
+    // depends on treeLevel() which is only known after the parent is set.
+
+    // Just reserve enough space with blanks. They will be overwritten later in
+    // DrawAt() with real line graphics.
+
+    _prefixPlaceholder = indentationStr();
+}
+
+
+string NCTableLine::indentationStr() const
+{
+    return _nested ? string( prefixLen(), ' ' ) : "";
+}
+
+
+void NCTableLine::addToTree( NCTableLine * parent )
+{
+    if ( parent )
+    {
+        if ( parent->firstChild() ) // The parent already has children
+        {
+            // Find the last child of the parent
+
+            NCTableLine * lastChild = parent->firstChild();
+
+            while ( lastChild->nextSibling() )
+                lastChild = lastChild->nextSibling();
+
+            lastChild->setNextSibling( this );
+        }
+        else // The parent does not have any children yet
+        {
+            parent->setFirstChild( this );
+        }
+    }
+}
+
+
+bool NCTableLine::isOpen( YItem * yitem ) const
+{
+    if ( ! yitem )
+        return false;
+
+    YTreeItem * treeItem = dynamic_cast( yitem );
+
+    if ( treeItem )
+        return treeItem->isOpen();
+
+    // No need to dynamic_cast to YTableItem as well:
+    // YTableItem now (as of 8/2020) inherits YTreeItem.
+
+    return false;
+}
+
+
+void NCTableLine::setOrigItem( YTableItem * yitem )
+{
+    setYItem( yitem );
+}
+
+
+void NCTableLine::setYItem( YItem * yitem )
+{
+    _yitem = yitem;
+
+    if ( _yitem )
+        _yitem->setData( this ) ;
+}
+
+
+void NCTableLine::assertCol( unsigned idx )
+{
+    if ( idx >= Cols() )
+	SetCols( idx + 1 );
+}
+
+
+void NCTableLine::SetCols( unsigned idx )
+{
+    if ( idx == Cols() )
+	return;
+
+    if ( idx < Cols() )
+    {
+	for ( unsigned i = idx; i < Cols(); ++i )
+	{
+	    delete _cells[i];
+	}
+    }
+
+    _cells.resize( idx, 0 );
+}
+
+
+void NCTableLine::stripHotkeys()
+{
+    for ( unsigned i = 0; i < Cols(); ++i )
+    {
+	if ( _cells[i] )
+	    _cells[i]->stripHotkey();
+    }
+}
+
+
+void NCTableLine::SetCols( std::vector & newCells )
+{
+    SetCols( 0 );
+    _cells = newCells;
+}
+
+
+void NCTableLine::AddCol( unsigned idx, NCTableCol * cell )
+{
+    assertCol( idx );
+    delete _cells[idx];
+    _cells[idx] = cell;
+}
+
+
+void NCTableLine::DelCol( unsigned idx )
+{
+    if ( idx < Cols() )
+    {
+	delete _cells[idx];
+	_cells[idx] = 0;
+    }
+}
+
+
+NCTableCol * NCTableLine::GetCol( unsigned idx )
+{
+    if ( idx < Cols() )
+	return _cells[idx];
+
+    return 0;
+}
+
+
+void NCTableLine::UpdateFormat( NCTableStyle & tableStyle )
+{
+    tableStyle.AssertMinCols( Cols() );
+
+    for ( unsigned col = 0; col < Cols(); ++col )
+    {
+	if ( !_cells[ col ] )
+	    continue;
+
+	tableStyle.MinColWidth( col, _cells[ col ]->Size().W );
+    }
+
+    if ( _nested && ! _prefix )
+        updatePrefix(); // Put together line graphics for the tree hierarchy
+}
+
+
+void NCTableLine::DrawAt( NCursesWindow & w,
+                          const wrect     at,
+			  NCTableStyle &  tableStyle,
+			  bool            active ) const
+{
+    _vstate = S_HIDDEN;
+
+    if ( isVisible() )
+    {
+	if ( isDisabled() )
+	    _vstate = S_DISABLED;
+	else
+	    _vstate = active ? S_ACTIVE : S_NORMAL;
+    }
+
+    w.bkgdset( tableStyle.getBG( _vstate ) );
+
+    for ( int i = 0; i < at.Sze.H; ++i )
+    {
+	w.move( at.Pos.L + i, at.Pos.C );
+	w.clrtoeol();
+    }
+
+    DrawItems( w, at, tableStyle, active );
+}
+
+
+void NCTableLine::DrawItems( NCursesWindow & w,
+                             const wrect     at,
+			     NCTableStyle &  tableStyle,
+			     bool            active ) const
+{
+    if ( !( at.Sze > wsze( 0 ) ) )
+	return;
+
+    wrect    lRect( at );
+    unsigned destWidth;
+
+    for ( unsigned col = 0; col < Cols(); ++col )
+    {
+	if ( col > 0 && tableStyle.ColSepWidth() )
+	{
+	    // draw centered
+	    destWidth = tableStyle.ColSepWidth() / 2;
+
+	    if ( destWidth < (unsigned) lRect.Sze.W )
+	    {
+		w.bkgdset( tableStyle.getBG( _vstate, NCTableCol::SEPARATOR ) );
+		w.vline( lRect.Pos.L, lRect.Pos.C + destWidth,
+			 lRect.Sze.H, tableStyle.ColSepChar() );
+		// skip over
+		destWidth = tableStyle.ColSepWidth();
+
+		if ( (unsigned) lRect.Sze.W <= destWidth )
+		    break;
+
+		lRect.Pos.C += destWidth;
+		lRect.Sze.W -= destWidth;
+	    }
+	}
+
+	destWidth = tableStyle.ColWidth( col );
+
+	wrect cRect( lRect );
+
+	// Adjust drawing rectangle for the screen space we just used
+	lRect.Pos.C += destWidth;
+	lRect.Sze.W -= destWidth;
+
+	if ( lRect.Sze.W < 0 )
+	    cRect.Sze.W = destWidth + lRect.Sze.W;
+	else
+	    cRect.Sze.W = destWidth;
+
+	if ( _cells[ col ] )
+	{
+            // Draw item
+	    _cells[ col ]->DrawAt( w, cRect, tableStyle, _vstate, col );
+
+            // Draw tree hierarchy line graphics over the prefix placeholder
+
+            if ( col == 0 && _prefix )
+                drawPrefix( w, cRect, tableStyle );
+	}
+    }
+}
+
+
+void NCTableLine::updatePrefix()
+{
+    if ( _prefix )
+        delete[] _prefix;
+
+    // Build from right to left: Start with the line for this (deepest) level
+
+    _prefix = new chtype[ prefixLen() ];
+    chtype * tagend = &_prefix[ prefixLen()-1 ];
+    *tagend-- = ACS_HLINE;
+    *tagend-- = firstChild() ? ACS_TTEE : ACS_HLINE;
+
+    if ( _parent )
+    {
+        // Draw vertical connector for the siblings on this level
+
+        *tagend-- = nextSibling() ? ACS_LTEE : ACS_LLCORNER;
+
+
+        // From right to left, for each higher level, draw a vertical line
+        // or a blank if this is the last branch on that level
+
+        for ( NCTableLine * p = parent(); p; p = p->parent() )
+        {
+            *tagend-- = p->nextSibling() ? ACS_VLINE : ( ' '&A_CHARTEXT );
+        }
+    }
+    else // This is a toplevel item
+    {
+        *tagend-- = ACS_HLINE; // One more horizontal line to the left
+    }
+}
+
+
+void NCTableLine::drawPrefix( NCursesWindow & w,
+                              const wrect     at,
+                              NCTableStyle  & tableStyle ) const
+{
+    if ( ! _prefix )
+        return;
+
+    w.move( at.Pos.L, at.Pos.C );
+
+    for ( int i = 0; i < prefixLen(); ++i )
+        w.addch( _prefix[i] );
+
+
+    // Draw the "+" indicator if this branch can be opened
+
+    w.move( at.Pos.L, at.Pos.C + prefixLen() - 2 );
+
+    if ( firstChild() && !isSpecial() )
+    {
+        w.bkgdset( tableStyle.highlightBG( _vstate,
+                                           NCTableCol::HINT,
+                                           NCTableCol::SEPARATOR ) );
+    }
+
+    if ( firstChild() && !firstChild()->isVisible() )
+        w.addch( '+' );
+    else
+        w.addch( _prefix[ prefixLen() - 2 ] );
+}
+
+
+bool NCTableLine::handleInput( wint_t key )
+{
+    bool handled = false;
+
+    switch ( key )
+    {
+        case '?':
+            yuiMilestone() << _yitem << ": index: " << index() << endl;
+            break;
+
+        case KEY_IC:    // "Insert" key ("Insert Character")
+        case '+':
+            openBranch();
+            handled = true;
+            break;
+
+        case KEY_DC:    // "Delete" key ("Delete Character")
+        case '-':
+            closeBranch();
+            handled = true;
+            break;
+
+        case KEY_RETURN:
+            // Propagate up to the pad; see bsc#67350
+            break;
+
+        case KEY_SPACE: // Toggle open/closed state of this branch
+
+            if ( _nested )
+            {
+                toggleOpenClosedState();
+                handled = true;
+            }
+            // else
+            //   cascade the event up to NCTable::wHandleInput()
+            //   to let it toggle the selection status in multiSelection mode
+            break;
+    }
+
+    return handled;
+}
+
+
+void NCTableLine::openBranch()
+{
+    if ( firstChild() && ! firstChild()->isVisible() )
+    {
+        // YTableItem inherits YTreeItem which inherits YItem,
+        // so we need to cast the YItem to YTreeItem which has the _isOpen flag.
+        YTreeItem * treeItem = dynamic_cast( _yitem );
+
+        if ( treeItem )
+        {
+            treeItem->setOpen( true );
+            yuiDebug() << "Opening item " << treeItem->label() << endl;
+
+            for ( NCTableLine * child = firstChild(); child; child = child->nextSibling() )
+                child->ClearState( S_HIDDEN );
+        }
+    }
+}
+
+
+void NCTableLine::closeBranch()
+{
+    if ( firstChild() && firstChild()->isVisible() )
+    {
+        // YTableItem inherits YTreeItem which inherits YItem,
+        // so we need to cast the YItem to YTreeItem which has the _isOpen flag.
+        YTreeItem * treeItem = dynamic_cast( _yitem );
+
+        if ( treeItem )
+        {
+            treeItem->setOpen( false );
+            yuiDebug() << "Closing item " << treeItem->label() << endl;
+
+            for ( NCTableLine * child = firstChild(); child; child = child->nextSibling() )
+                child->SetState( S_HIDDEN );
+        }
+    }
+}
+
+
+void NCTableLine::toggleOpenClosedState()
+{
+    if ( firstChild() )
+    {
+        if ( firstChild()->isVisible() )
+            closeBranch();
+        else
+            openBranch();
+    }
+}
+
+
+bool NCTableLine::isVisible() const
+{
+    return ! parent() || ( !isHidden() && parent()->isVisible() );
+}
+
+
+
+NCTableTag * NCTableLine::tagCell() const
+{
+    NCTableTag * ret = 0;
+
+    if ( ! _cells.empty() )
+        ret = dynamic_cast( _cells[0] );
+
+    return ret;
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCTableLine & obj )
+{
+    str << "Line: cols " << obj.Cols() << endl;
+
+    for ( unsigned idx = 0; idx < obj.Cols(); ++idx )
+    {
+	str << "  " << idx << " ";
+	const NCTableCol * cell = obj.GetCol( idx );
+
+	if ( cell )
+	    str << *cell;
+	else
+	    str << "NO_ITEM";
+
+	str << endl;
+    }
+
+    return str;
+}
+
+
+
+//
+//----------------------------------------------------------------------
+//
+
+
+NCTableCol::NCTableCol( const NCstring & label, STYLE style )
+    : _label( label )
+    , _style( style )
+{
+}
+
+
+NCTableCol::~NCTableCol()
+{
+}
+
+
+chtype NCTableCol::setBkgd( NCursesWindow &    w,
+			    NCTableStyle &     tableStyle,
+			    NCTableLine::STATE linestate,
+			    STYLE              colstyle ) const
+{
+    chtype bkgdstyle = tableStyle.getBG( linestate, colstyle );
+
+    if ( bkgdstyle != NCTableStyle::currentBG )
+	w.bkgdset( bkgdstyle );
+    else
+	bkgdstyle = w.getbkgd();
+
+    return bkgdstyle;
+}
+
+
+wrect NCTableCol::prefixAdjusted( const wrect origRect ) const
+{
+    wrect newRect = origRect;
+
+    if ( _prefix.width() > 0 )
+    {
+        newRect.Pos.C += _prefix.width();
+        newRect.Sze.W -= _prefix.width();
+    }
+
+    return newRect;
+}
+
+
+void NCTableCol::DrawAt( NCursesWindow &    w,
+                         const wrect        at,
+			 NCTableStyle &     tableStyle,
+			 NCTableLine::STATE linestate,
+			 unsigned           colidx ) const
+{
+    chtype bg       = setBkgd( w, tableStyle, linestate, _style );
+    chtype hbg      = tableStyle.hotBG( linestate, colidx );
+
+    if ( hbg == NCTableStyle::currentBG )
+	hbg = bg;
+
+    if ( _prefix.width() > 0 )
+        _prefix.drawAt( w, bg, hbg, at );
+
+    _label.drawAt( w, bg, hbg,
+                   prefixAdjusted( at ),
+                   tableStyle.ColAdjust( colidx ) );
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCTableCol & obj )
+{
+    return str << obj._label;
+}
+
+
+//
+//----------------------------------------------------------------------
+//
+
+
+void NCTableHead::DrawAt( NCursesWindow & w,
+                          const wrect     at,
+			  NCTableStyle &  tableStyle,
+			  bool            active ) const
+{
+    _vstate = S_HEADLINE;
+    w.bkgdset( tableStyle.getBG( _vstate ) );
+
+    for ( int i = 0; i < at.Sze.H; ++i )
+    {
+	w.move( at.Pos.L + i, at.Pos.C );
+	w.clrtoeol();
+    }
+
+    DrawItems( w, at, tableStyle, active );
+}
+
+
+//
+//----------------------------------------------------------------------
+//
+
+
+NCTableStyle::NCTableStyle( const NCWidget & parentWidget )
+    : _parentWidget( parentWidget )
+    , _headline( 0 )
+    , _colWidth( 0 )
+    , _colAdjust( 0 )
+    , _colSepWidth( 1 )
+    , _colSepChar( ACS_VLINE )
+    , _hotCol( (unsigned) - 1 )
+{
+}
+
+
+bool NCTableStyle::SetStyleFrom( const std::vector & head )
+{
+    unsigned ncols = head.size();
+
+    _headline.ClearLine();
+    _headline.SetCols( ncols );
+
+    _colWidth.clear();
+    _colAdjust.clear();
+    AssertMinCols( ncols );
+
+    bool hasContent = false;
+
+    for ( unsigned i = 0; i < head.size(); ++i )
+    {
+	const wstring & entry( head[i].str() );
+	bool strip = false;
+
+	if ( entry.length() )
+	{
+	    switch ( entry[0] )
+	    {
+		case 'R':
+		    strip = true;
+		    _colAdjust[i] = NC::RIGHT;
+		    break;
+
+		case 'C':
+		    strip = true;
+		    _colAdjust[i] = NC::CENTER;
+		    break;
+
+		case 'L':
+		    strip = true;
+		    _colAdjust[i] = NC::LEFT;
+		    break;
+
+		default:
+		    yuiWarning() << "No style char [LRC] at beginning of '" << entry << "'" << std::endl;
+		    break;
+	    }
+	}
+
+	NCstring coltxt = strip ? entry.substr( 1 ) : entry;
+	_headline.AddCol( i, new NCTableCol( coltxt ) );
+
+	if ( ! hasContent && coltxt.str().length() )
+	    hasContent = true;
+    }
+
+    return hasContent;
+}
+
+
+chtype NCTableStyle::highlightBG( const NCTableLine::STATE lstate,
+				  const NCTableCol::STYLE  cstyle,
+				  const NCTableCol::STYLE  dstyle ) const
+{
+    return getBG( lstate, cstyle );
+}
+
+
+chtype NCTableStyle::getBG( const NCTableLine::STATE lstate,
+			    const NCTableCol::STYLE  cstyle ) const
+{
+    switch ( lstate )
+    {
+	case NCTableLine::S_NORMAL:
+
+	    switch ( cstyle )
+	    {
+		case NCTableCol::PLAIN:         return listStyle().item.plain;
+		case NCTableCol::DATA:          return listStyle().item.data;
+		case NCTableCol::ACTIVEDATA:    return listStyle().item.plain;
+		case NCTableCol::HINT:          return listStyle().item.hint;
+		case NCTableCol::SEPARATOR:     return listStyle().item.plain;
+		case NCTableCol::NONE:          return currentBG;
+	    }
+	    break;
+
+
+	case NCTableLine::S_ACTIVE:
+
+	    switch ( cstyle )
+	    {
+		case NCTableCol::PLAIN:         return listStyle().selected.plain;
+		case NCTableCol::DATA:          return listStyle().selected.data;
+		case NCTableCol::ACTIVEDATA:    return listStyle().selected.data;
+		case NCTableCol::HINT:          return listStyle().selected.hint;
+		case NCTableCol::SEPARATOR:     return listStyle().selected.plain;
+		case NCTableCol::NONE:          return currentBG;
+	    }
+	    break;
+
+	case NCTableLine::S_DISABLED:
+
+	    switch ( cstyle )
+	    {
+		case NCTableCol::PLAIN:         return _parentWidget.wStyle().disabledList.item.plain;
+		case NCTableCol::DATA:          return _parentWidget.wStyle().disabledList.item.data;
+		case NCTableCol::ACTIVEDATA:    return _parentWidget.wStyle().disabledList.item.plain;
+		case NCTableCol::HINT:          return _parentWidget.wStyle().disabledList.item.hint;
+		case NCTableCol::SEPARATOR:     return listStyle().item.plain;
+		case NCTableCol::NONE:          return currentBG;
+	    }
+	    break;
+
+
+	case NCTableLine::S_HEADLINE:
+	    return listStyle().title;
+	    break;
+
+	case NCTableLine::S_HIDDEN:
+	    return currentBG;
+	    break;
+    }
+
+    return currentBG;
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCTableStyle & obj )
+{
+    str << form( "cols %d, sep %d (%lx)\n",
+                 obj.Cols(), obj.ColSepWidth(), (unsigned long)obj.ColSepChar() );
+
+    for ( unsigned i = 0; i < obj.Cols(); ++i )
+    {
+	str << form( "%2d %d(%3d) ", i, obj.ColAdjust( i ), obj.ColWidth( i ) );
+
+	if ( obj.Headline().GetCol( i ) )
+	    str << obj.Headline().GetCol( i )->Label();
+
+	str << std::endl;
+    }
+
+    return str;
+}
+
diff --git a/deps/libyui/libyui-ncurses/src/NCTableItem.h b/deps/libyui/libyui-ncurses/src/NCTableItem.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e718779089345ce6c80ef1cebb9cb58c11e2790
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTableItem.h
@@ -0,0 +1,707 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTableItem.h
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#ifndef NCTableItem_h
+#define NCTableItem_h
+
+#include 
+#include 
+
+#include "position.h"
+#include "NCWidget.h"
+#include 
+
+class NCTableCol;
+class NCTableStyle;
+class NCTableTag;
+
+
+/**
+ * One line in a NCTable with multiple cells and an optional tree hierarchy.
+ * Each line corresponds to a YItem subclass (YTableItem or YTreeItem).
+ *
+ * This class is also the base class for NCTreeLine; it provides most its
+ * functionlity.
+ *
+ * Notice that on the libyui level, the inheritance hierarchy is
+ *
+ *     YTableItem < YTreeItem < YItem
+ *
+ * whereas on the libyui-ncurses level, it is
+ *
+ *     NCTreeLine < NCTableLine
+ *
+ * i.e. it's just the other way round. This is why it is safer to do dynamic
+ * casts of the internal _yitem to YTreeItem rather than to YTableItem: If
+ * used from an NCTree (i.e. YTree) widget, the items will all be YTreeItems; a
+ * dynamic cast to YTableItem will fail.
+ *
+ * NOTE: "col", "column", here refer to only one cell, not the entire table column.
+ *
+ * See also
+ * https://github.com/libyui/libyui-ncurses/blob/master/doc/nctable-and-nctree.md
+ **/
+class NCTableLine
+{
+public:
+
+    enum STATE
+    {
+	S_NORMAL    = 0x00,
+	S_ACTIVE    = 0x01,
+	S_DISABLED  = 0x10,
+	S_HIDDEN    = 0x20,
+	S_HEADLINE  = 0x40
+    };
+
+
+    /**
+     * Constructor: Create an NCTableLine and fill it with 'cells'. This object
+     * takes over ownership of those cells and will delete it when appropriate.
+     *
+     * 'index' is a unique number with which to identify this line.
+     *
+     * 'nested' specifies whether any item in the table has any child items,
+     * i.e. whether line graphics to visualize the tree structure should be drawn.
+     *
+     * 'state' is an OR'ed combination of the STATE enum.
+     **/
+    NCTableLine( std::vector & cells,
+                 int                        index  = -1,
+                 bool                       nested = false,
+                 unsigned                   state  = S_NORMAL );
+
+    NCTableLine( NCTableLine *              parentLine,
+                 YItem *                    yitem,
+                 std::vector & cells,
+                 int                        index  = -1,
+                 bool                       nested = false,
+                 unsigned                   state  = S_NORMAL );
+
+    /**
+     * Constructor with a number of empty cells.
+     **/
+    NCTableLine( unsigned      colCount,
+                 int           index     = -1,
+                 bool          nested    = false,
+                 unsigned      state     = S_NORMAL );
+
+    NCTableLine( NCTableLine * parentLine,
+                 YItem *       yitem,
+                 unsigned      colCount,
+                 int           index     = -1,
+                 bool          nested    = false,
+                 unsigned      state     = S_NORMAL );
+
+    /**
+     * Destructor.
+     **/
+    virtual ~NCTableLine();
+
+    /**
+     * Return the YItem this line corresponds to.
+     **/
+    YTableItem * origItem() const { return dynamic_cast( _yitem ); }
+
+    /**
+     * Set the YItem this line corresponds to.
+     **/
+    void setOrigItem( YTableItem *yitem );
+
+    /**
+     * Return the unique index by which this line can be identified.
+     **/
+    int index() const { return _index; }
+
+    /**
+     * Return the number of columns (cells) in this line.
+     **/
+    unsigned Cols() const { return _cells.size(); }
+
+    /**
+     * Set a number of (empty) columns (cells).
+     **/
+    void SetCols( unsigned idx );
+
+    /**
+     * Set the columns (cells).
+     **/
+    void SetCols( std::vector & newCells );
+
+    /**
+     * Delete all content.
+     **/
+    void ClearLine()  { SetCols( 0 ); }
+
+    /**
+     * Return all columns (cells).
+     * Ownership of the cells remains with this line; do not delete them!
+     **/
+    std::vector GetItems() const { return _cells; }
+
+    /**
+     * Append one cell. Ownership is transferred to this line.
+     **/
+    void Append( NCTableCol * cell ) { AddCol( Cols(), cell ); }
+
+    void AddCol( unsigned idx, NCTableCol * item );
+    void DelCol( unsigned idx );
+
+    /**
+     * Return a non-const pointer for read/write operations to the column (the
+     * cell) with the specified index or 0 if there is no such cell.
+     *
+     * This is the table cell counterpart to NCTablePad::ModifyLine(). This
+     * does not set any 'dirty' flag.
+     **/
+    NCTableCol * GetCol( unsigned idx );
+
+    /**
+     * Return a const pointer for read-only operatoins to the column (the cell)
+     * with the specified index or 0 if there is no such cell.
+     *
+     * This is the table cell counterpart to NCTablePad::GetLine().
+     **/
+    const NCTableCol * GetCol( unsigned idx ) const
+    {
+	return const_cast( this )->GetCol( idx );
+    }
+
+    void  SetState  ( const STATE s ) { _state |= s; }
+    void  ClearState( const STATE s ) { _state &= ~s; }
+
+    bool  isHidden() const    { return ( _state & S_HIDDEN ); }
+    bool  isDisabled() const  { return ( _state & S_DISABLED ); }
+    bool  isSpecial() const   { return ( _state & ( S_HIDDEN | S_DISABLED ) ); }
+    bool  isActive() const    { return ( _state & S_ACTIVE ); }
+
+    virtual bool isVisible() const;
+
+    virtual bool isEnabled() const { return isVisible() && !isDisabled(); }
+
+    /**
+     * Return 'true' if this should be displayed as nested items, i.e.
+     * with line graphics connecting tree items and their children.
+     * This needs to be set from the outside.
+     **/
+    virtual bool isNested() const { return _nested; }
+
+    /**
+     * Set the 'nested' status.
+     **/
+    virtual void setNested( bool val ) { _nested = val; }
+
+    /**
+     * Open this tree branch
+     **/
+    void openBranch();
+
+    /**
+     * Close this tree branch
+     **/
+    void closeBranch();
+
+    /**
+     * Toggle the open/closed state of this branch
+     **/
+    void toggleOpenClosedState();
+
+    /**
+     * Handle keyboard input. Return 'true' if the key event is handled,
+     * 'false' to propagate it up to the pad.
+     **/
+    virtual bool handleInput( wint_t key );
+
+    /**
+     * Change a line that may have been invisible until now to be visible.
+     *
+     * Return 'true' if there was a status change, i.e. if it was invisible
+     * before, 'false' otherwise.
+     *
+     * This default implementation does nothing and always returns 'false'.
+     * Derived classes that can handle invisible items may want to overwrite
+     * this.
+     **/
+    virtual bool ChangeToVisible() { return false; }
+
+    virtual unsigned Hotspot( unsigned & at ) const { at = 0; return 0; }
+
+    /**
+     * Update TableStyle so that this line fits in
+     **/
+    virtual void UpdateFormat( NCTableStyle & tableStyle );
+
+    /**
+     * Create the real tree hierarchy line graphics prefix and store it in
+     * _prefix
+     **/
+    virtual void updatePrefix();
+
+
+    /// @param active is the table cursor here
+    virtual void DrawAt( NCursesWindow & w,
+                         const wrect     at,
+			 NCTableStyle &  tableStyle,
+			 bool            active ) const;
+
+    void stripHotkeys();
+
+    //
+    // Tree operations
+    //
+
+    virtual NCTableLine * parent()      const { return _parent;      }
+    virtual NCTableLine * firstChild()  const { return _firstChild;  }
+    virtual NCTableLine * nextSibling() const { return _nextSibling; }
+
+    void setParent     ( NCTableLine * newVal ) { _parent      = newVal; }
+    void setFirstChild ( NCTableLine * newVal ) { _firstChild  = newVal; }
+    void setNextSibling( NCTableLine * newVal ) { _nextSibling = newVal; }
+
+    /**
+     * Return the nesting level in the tree (toplevel is 0).
+     **/
+    int treeLevel() const { return _treeLevel; }
+
+    /**
+     * Set the tree nesting level.
+     **/
+    void setTreeLevel( int newVal ) { _treeLevel = newVal; }
+
+    /**
+     * Return the length of the prefix for tree hierarchy line graphics.
+     **/
+    int prefixLen() const { return _nested ? treeLevel() + 3 : 0; }
+
+    /**
+     * Return the tag cell or 0 if there is none.
+     **/
+    NCTableTag * tagCell() const;
+
+    /**
+     * Return a string of a number of blanks suitable for the indentation of
+     * this tree level.
+     **/
+    std::string indentationStr() const;
+
+protected:
+
+    /**
+     * Common init for tree-related things in the constructors that have a
+     * 'parentLine' and a 'yitem' parameter.
+     **/
+    void treeInit( NCTableLine * parentLine, YItem * yitem );
+
+    /**
+     * Initialize _prefixPlaceholder, the placeholder for tree hierarchy line graphics.
+     **/
+    void initPrefixPlaceholder();
+
+    /**
+     * Add this line to the parent's tree hierarchy.
+     **/
+    void addToTree( NCTableLine * parent );
+
+    /**
+     * Return 'true' if yitem inherits YTreeItem or YTableItem and has its
+     * 'open' flag set to 'true'.
+     **/
+    bool isOpen( YItem * yitem ) const;
+
+    /**
+     * Return the YItem this line corresponds to as its base class.
+     **/
+    YItem * yitem() const { return _yitem; }
+
+    /**
+     * Set the YItem this line corresponds to.
+     **/
+    void setYItem( YItem * yitem );
+
+    virtual void DrawItems( NCursesWindow & w,
+                            const wrect     at,
+			    NCTableStyle &  tableStyle,
+			    bool            active ) const;
+
+    void assertCol( unsigned idx );
+
+    /**
+     * Return a placeholder for the prefix string for this line consisting of
+     * enough blanks for the tree hierarchy line graphics.
+     *
+     * The real line graphics will be drawn over this in DrawAt().
+     **/
+    const std::string & prefixPlaceholder() const { return _prefixPlaceholder; }
+
+    /**
+     * Draw the tree hierarchy line graphics prefix in _prefix in window 'w'
+     * into rectangle 'at' with style 'tableStyle'.
+     **/
+    void drawPrefix( NCursesWindow & w,
+                     const wrect     at,
+                     NCTableStyle  & tableStyle ) const;
+
+private:
+
+    friend std::ostream & operator<<( std::ostream & str, const NCTableLine & obj );
+
+    // Disable unwanted assignment operator and copy constructor
+
+    NCTableLine & operator=( const NCTableLine & );
+    NCTableLine( const NCTableLine & );
+
+
+    //
+    // Data members
+    //
+
+protected:
+
+    std::vector _cells; ///< owned
+
+    unsigned      _state;        ///< Or'ed STATE flags
+    int           _index;        ///< unique index to identify this line
+    YItem *       _yitem;        ///< not owned
+    bool          _nested;       ///< using nested (tree-like) items?
+
+    // Tree-related
+
+    int           _treeLevel;
+    NCTableLine * _parent;
+    NCTableLine * _nextSibling;
+    NCTableLine * _firstChild;
+
+    // This should have been an argument for DrawItems.
+    //
+    // It needs to be mutable because some methods that change it promise to be
+    // const, but they break that promise with this variable.
+    mutable STATE _vstate;
+
+    // Tree hierarchy line graphics for this line.
+    //
+    // chtype is a very basic NCurses type to store one character with its
+    // attributes (bg/fg color).
+    chtype *         _prefix;
+    std::string      _prefixPlaceholder;
+};
+
+
+/**
+ * One cell in an NCTableLine with a label and a cell-specific style.
+ *
+ * 'Col' in this context means just this one cell, not the entire column in the
+ * table.
+ *
+ * The style (NCTableCol::STYLE) is just color information,
+ * don't confuse with table sizing+alignment info, NCTableStyle.
+ **/
+class NCTableCol
+{
+
+    friend std::ostream & operator<<( std::ostream & str, const NCTableCol & obj );
+
+public:
+
+    enum STYLE
+    {
+	NONE = 0,    // use current bg
+	PLAIN,	     // plain text
+	DATA,	     // data style
+	ACTIVEDATA,  // data style if line active, else plain
+	HINT,	     // hint
+	SEPARATOR    // separator
+    };
+
+
+    NCTableCol( const NCstring & label = "", STYLE st = ACTIVEDATA );
+
+    virtual ~NCTableCol();
+
+    const NClabel & Label() const { return _label; }
+    virtual void SetLabel( const NClabel & newVal ) { _label = newVal; }
+    virtual void SetLabel( const std::string & newVal ) { _label = NCstring( newVal ); }
+
+    /**
+     * Return the prefix that is drawn (without delimiter) before the label.
+     * This can be used for an empty placeholder for tree hierarchy graphics.
+     **/
+    const NClabel & prefix() const { return _prefix; }
+
+    virtual void setPrefix( const NClabel & newVal ) { _prefix = newVal; }
+    virtual void setPrefix( const std::string & newVal ) { _prefix = NCstring( newVal); }
+    int prefixWidth() const { return _prefix.width(); }
+
+    /**
+     * Return a wrect that is adjusted for the size of the prefix, i.e. a
+     * little to the right and a little narrower.
+     **/
+    wrect prefixAdjusted( const wrect origRect ) const;
+
+    virtual wsze Size() const { return wsze( 1, _prefix.width() + _label.width() ); }
+
+    virtual void DrawAt( NCursesWindow &    w,
+                         const wrect        at,
+			 NCTableStyle &     tableStyle,
+			 NCTableLine::STATE linestate,
+			 unsigned           colidx ) const;
+
+    void stripHotkey() { _label.stripHotkey(); }
+
+    bool	  hasHotkey() const { return _label.hasHotkey(); }
+    unsigned char hotkey()    const { return _label.hotkey(); }
+
+protected:
+
+    chtype setBkgd( NCursesWindow &    w,
+		    NCTableStyle &     tableStyle,
+		    NCTableLine::STATE linestate,
+		    STYLE              colstyle ) const ;
+
+private:
+
+    NClabel _prefix;
+    NClabel _label;
+    STYLE   _style;
+};
+
+
+/**
+ * The header line of an NCTable.
+ **/
+class NCTableHead : public NCTableLine
+{
+
+public:
+
+    NCTableHead( unsigned cols )
+        : NCTableLine( cols )
+        {}
+
+    NCTableHead( std::vector & headCells )
+        : NCTableLine( headCells )
+        {}
+
+    virtual ~NCTableHead()
+        {}
+
+    /**
+     * Draw the header line with special attributes. That is the whole reason
+     * of having a separate class for this.
+     **/
+    virtual void DrawAt( NCursesWindow & w,
+                         const wrect     at,
+			 NCTableStyle &  tableStyle,
+			 bool            active ) const;
+};
+
+
+/// Styling for a NCTable: column widths, alignment and colors.
+class NCTableStyle
+{
+
+    friend std::ostream & operator<<( std::ostream & str, const NCTableStyle & obj );
+
+public:
+
+    static const chtype currentBG = (chtype) - 1;
+
+    NCTableStyle( const NCWidget & parentWidget );
+    ~NCTableStyle() {}
+
+    /// Reset columns, setting their alignment and optionally titles.
+    /// Column widths are zeroed.
+    /// @param head List of strings where their first character
+    ///   is the alignment (L, R, C) and the optional rest is the column heading
+    /// @return do we have a column heading
+    bool SetStyleFrom( const std::vector & head );
+
+    void SetSepChar( const chtype sepChar )	{ _colSepChar = sepChar; }
+
+    /// total width of space between adjacent columns, including the separator character
+    void SetSepWidth( const unsigned sepWidth ) { _colSepWidth = sepWidth; }
+
+    void SetHotCol( int hcol )
+    {
+	_hotCol = ( hcol < 0 || Cols() <= (unsigned) hcol ) ? -1 : hcol;
+    }
+
+    /// Forget sizing based on table content, resize according to headline only
+    void ResetToMinCols()
+    {
+	_colWidth.clear();
+	AssertMinCols( _headline.Cols() );
+	_headline.UpdateFormat( *this );
+    }
+
+    /// Ensure we know width and alignment for at least *num* columns.
+    void AssertMinCols( unsigned num )
+    {
+	if ( _colWidth.size() < num )
+	{
+	    _colWidth.resize( num, 0 );
+	    _colAdjust.resize( _colWidth.size(), NC::LEFT );
+	}
+    }
+
+    /// Update colWidth[num] to be at least *val*.
+    /// @param num column number (may be bigger than previously)
+    /// @param val width of that column for some line
+    void MinColWidth( unsigned num, unsigned val )
+    {
+	AssertMinCols( num );
+
+	if ( val > _colWidth[num] )
+	    _colWidth[ num ] = val;
+    }
+
+    NC::ADJUST ColAdjust( unsigned num ) const { return _colAdjust[num]; }
+
+    unsigned Cols()		         const { return _colWidth.size(); }
+
+    unsigned ColWidth( unsigned num )    const { return _colWidth[num]; }
+
+    unsigned ColSepWidth()	         const { return _colSepWidth; }
+
+    chtype   ColSepChar()	         const { return _colSepChar; }
+
+    unsigned HotCol()		         const { return _hotCol; }
+
+    const NCstyle::StList & listStyle()  const { return _parentWidget.listStyle(); }
+
+    chtype getBG() const { return listStyle().item.plain; }
+
+    chtype getBG( const NCTableLine::STATE lstate,
+		  const NCTableCol::STYLE  cstyle = NCTableCol::PLAIN ) const;
+
+    chtype highlightBG( const NCTableLine::STATE lstate,
+			const NCTableCol::STYLE  cstyle,
+			const NCTableCol::STYLE  dstyle = NCTableCol::PLAIN ) const ;
+
+    chtype hotBG( const NCTableLine::STATE lstate, unsigned colidx ) const
+    {
+	return ( colidx == _hotCol ) ?
+            getBG( lstate, NCTableCol::HINT ) : currentBG;
+    }
+
+    const NCTableLine & Headline() const { return _headline; }
+
+    /// Add up the widths of columns with the separators
+    unsigned TableWidth() const
+    {
+	unsigned twidth = 0;
+
+	for ( unsigned i = 0; i < Cols(); ++i )
+	    twidth += _colWidth[i];
+
+	if ( Cols() > 1 )
+	    twidth += _colSepWidth * ( Cols() - 1 );
+
+	return twidth;
+    }
+
+
+private:
+
+    const NCWidget &            _parentWidget;
+    NCTableHead                 _headline;
+    std::vector	_colWidth;  ///< column widths
+    std::vector	_colAdjust; ///< column alignment
+
+
+    /// total width of space between adjacent columns, including the separator character
+    unsigned _colSepWidth;
+
+    chtype   _colSepChar;	///< column separator character
+    unsigned _hotCol;		///< which column is "hot"
+};
+
+
+/**
+ * A column (one cell) used as a selection marker:
+ * '[ ]'/'[x]' or '( )'/'(x)'.
+ **/
+class NCTableTag : public NCTableCol
+{
+public:
+
+    /**
+     * Constructor.
+     *
+     * @param item (must not be nullptr, not owned)
+     * @param sel currently selected, draw an 'x' inside
+     * @param singleSel if true  draw this in a radio-button style '(x)';
+     *                  if false draw this in a checkbox style     '[x]'
+     **/
+    NCTableTag( YItem *item, bool sel = false, bool singleSel = false )
+        : NCTableCol( NCstring( singleSel ? "( )" : "[ ]" ), SEPARATOR )
+        , _yitem( item )
+        , _selected( sel )
+        , _singleSelection( singleSel )
+    {
+	// store pointer to this tag in Yitem data
+	_yitem->setData( this );
+    }
+
+    virtual ~NCTableTag() {}
+
+    virtual void SetLabel( const NClabel & ) { /*NOOP*/; }
+
+    virtual void DrawAt( NCursesWindow &    w,
+                         const wrect        at,
+			 NCTableStyle &     tableStyle,
+			 NCTableLine::STATE linestate,
+			 unsigned           colidx ) const
+    {
+        // Use parent DrawAt to draw the static part: "[ ]"
+	NCTableCol::DrawAt( w, at, tableStyle, linestate, colidx );
+
+	if ( _selected )
+	{
+            // Draw the "x" inside the "[ ]" with different attributes
+
+	    setBkgd( w, tableStyle, linestate, DATA );
+            wrect drawRect = prefixAdjusted( at );
+	    w.addch( drawRect.Pos.L, drawRect.Pos.C + 1, 'x' );
+	}
+    }
+
+    virtual bool Selected() const        { return _selected; }
+
+    virtual void SetSelected( bool sel ) { _selected = sel; }
+
+    virtual bool SingleSelection() const { return _singleSelection; }
+
+    YItem *origItem() const              { return _yitem; }
+
+private:
+
+    YItem * _yitem; ///< (not owned, never nullptr, should have been a reference)
+    bool    _selected;
+    bool    _singleSelection;
+};
+
+
+#endif // NCTableItem_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTablePad.cc b/deps/libyui/libyui-ncurses/src/NCTablePad.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0755575076c3b6b7c0e5c2b9be8e0984686e3a1f
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTablePad.cc
@@ -0,0 +1,167 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTablePad.cc
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCTablePad.h"
+
+
+
+NCTablePad::NCTablePad( int lines, int cols, const NCWidget & p )
+    : NCTablePadBase( lines, cols, p )
+{
+}
+
+
+NCTablePad::~NCTablePad()
+{
+}
+
+
+int NCTablePad::DoRedraw()
+{
+    if ( !Destwin() )
+    {
+	dirty = true;
+	return OK;
+    }
+
+    prepareRedraw();
+
+    if ( ! paging() )
+        drawContentLines();
+    // else
+    //   item drawing requested via directDraw()
+
+    drawHeader();
+
+    dirty = false;
+
+    return update();
+}
+
+
+void NCTablePad::directDraw( NCursesWindow & w, const wrect at, unsigned lineNo )
+{
+    if ( lineNo < Lines() )
+    {
+        _visibleItems[ lineNo ]->DrawAt( w,
+                                         at,
+                                         _itemStyle,
+                                         ( (unsigned) currentLineNo() == lineNo) );
+    }
+    else
+        yuiWarning() << "Illegal Line no " << lineNo << " (" << Lines() << ")" << std::endl;
+}
+
+
+bool NCTablePad::handleInput( wint_t key )
+{
+    bool handled = false;
+
+    switch ( key )
+    {
+        // At this time, there are no more special keys to handle on this
+        // level. This method is a stub for future extension if any more keys
+        // need to be handled.
+        //
+        // Add 'case KEY_XXX' branches here if there should be any
+        // and don't forget to set 'handled' to 'true'.
+#if 0
+        case KEY_SOMETHING:     // Sample
+            doSomething();
+            handled = true;
+            break;
+#endif
+
+        default: // Call parent class input handler
+
+            // This also calls currentItemHandleInput() as the first thing it
+            // does to forward key presses to the item at the current cursor
+            // position. Many operations such as opening, closing or selecting
+            // an item are done on that level.
+            handled = NCTablePadBase::handleInput( key );
+            break;
+    }
+
+    return handled;
+}
+
+
+bool NCTablePad::setItemByKey( int key )
+{
+    if ( HotCol() >= Cols() )
+	return false;
+
+    if ( key < 0 || UCHAR_MAX < key )
+	return false;
+
+    unsigned hcol = HotCol();
+    unsigned hkey = tolower( key );
+
+    for ( unsigned i = 0; i < visibleLines(); ++i )
+    {
+	if ( _items[i]->GetCol( hcol )->hasHotkey()
+	     && (unsigned) tolower( _items[i]->GetCol( hcol )->hotkey() ) == hkey )
+	{
+	    ScrlLine( i );
+	    return true;
+	}
+    }
+
+    return false;
+}
+
+
+void NCTablePad::stripHotkeys()
+{
+    for ( unsigned i = 0; i < Lines(); ++i )
+    {
+	if ( _items[i] )
+	{
+	    _items[i]->stripHotkeys();
+	}
+    }
+}
+
+
+typedef std::vector::const_iterator NCTableLineIterator;
+
+int NCTablePad::findIndexById( int id ) const
+{
+    NCTableLineIterator begin = _items.begin();
+    NCTableLineIterator end   = _items.end();
+    NCTableLineIterator found = find_if( begin, end,
+                                         [id](NCTableLine * line)
+                                             {
+                                                 return line->index() == id;
+                                             });
+
+    if ( found == end )
+	return -1;
+    else
+	return found - begin;
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCTablePad.h b/deps/libyui/libyui-ncurses/src/NCTablePad.h
new file mode 100644
index 0000000000000000000000000000000000000000..b8cede43a48618f2a43a95868a64749fc3e4eafc
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTablePad.h
@@ -0,0 +1,142 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTablePad.h
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#ifndef NCTablePad_h
+#define NCTablePad_h
+
+#include 
+#include 
+
+#include "NCTablePadBase.h"
+#include "NCTableItem.h"
+#include "NCstring.h"
+
+
+/**
+ * An NCPad for an NCTable.
+ *
+ * Most of its former functionality is now handled in the NCTablePadBase base
+ * class.
+ *
+ * See also
+ * https://github.com/libyui/libyui-ncurses/blob/master/doc/nctable-and-nctree.md
+ *
+ * Notice that this class is heavily used in other selection widgets like
+ *
+ * - NCFileSelection
+ * - NCItemSelector
+ * - NCMultiSelectionBox
+ * - NCSelectionBox
+ *
+ * And the table classes from libyui-ncurses-pkg:
+ * - NCPkgTable
+ * - NCPkgLocaleTable
+ * - NCPkgRepoTable
+ *
+ * So if you change anything here, make sure to test all those classes.
+ **/
+class NCTablePad : public NCTablePadBase
+{
+public:
+
+    NCTablePad( int lines, int cols, const NCWidget & p );
+    virtual ~NCTablePad();
+
+public:
+
+    /**
+     * Handle a keyboard input event. Return 'true' if the event is now
+     * handled, 'false' if it should be propagated to the parent widget.
+     *
+     * Most of the keys are now handled in the NCTablePadBase base class or in
+     * the individual items' handlers (NCTreeLine, NCTableLine). This method
+     * is mostly here as a stub for future extensions.
+     *
+     * Reimplemented from NCTablePadBase and NCPad.
+     **/
+    virtual bool handleInput( wint_t key );
+
+    bool setItemByKey( int key );
+
+    void AssertMinCols( unsigned num )
+    {
+	_itemStyle.AssertMinCols( num );
+    }
+
+    void SetSepChar( const chtype colSepchar )
+    {
+	_itemStyle.SetSepChar( colSepchar );
+    }
+
+    void SetSepWidth( const unsigned sepwidth )
+    {
+	_itemStyle.SetSepWidth( sepwidth );
+    }
+
+    unsigned HotCol() const
+    {
+        return _itemStyle.HotCol();
+    }
+
+    void SetHotCol( int hcol )
+    {
+	_itemStyle.SetHotCol( hcol );
+    }
+
+    /**
+     * Find the item index in a sorted table.
+     * Return -1 if not found.
+     * An item/line remembers its insertion index.
+     *
+     * @param id the index before sorting
+     **/
+    int findIndexById( int id ) const;
+
+    void stripHotkeys();
+
+
+protected:
+
+    /**
+     * Redraw the pad.
+     *
+     * Reimplemented from NCTablePadBase and NCPad.
+     **/
+    virtual int  DoRedraw();
+
+    virtual void directDraw( NCursesWindow & w, const wrect at, unsigned lineno );
+
+
+private:
+
+    // Disable unwanted assignment operator and copy constructor
+
+    NCTablePad & operator=( const NCTablePad & );
+    NCTablePad( const NCTablePad & );
+};
+
+
+#endif // NCTablePad_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTablePadBase.cc b/deps/libyui/libyui-ncurses/src/NCTablePadBase.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ac8eccfd17a30389031ab2133a5c96c0a01f61b5
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTablePadBase.cc
@@ -0,0 +1,466 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTablePadBase.cc
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCTablePadBase.h"
+
+using std::vector;
+
+
+NCTablePadBase::NCTablePadBase( int lines, int cols, const NCWidget & p )
+    : NCPad( lines, cols, p )
+    , _items( 0 )
+    , _headpad( 1, 1 )
+    , _dirtyHead( false )
+    , _dirtyFormat( false )
+    , _itemStyle( p )
+    , _citem( 0 )
+{
+}
+
+
+NCTablePadBase::~NCTablePadBase()
+{
+    ClearTable();
+}
+
+
+void NCTablePadBase::ClearTable()
+{
+    for ( unsigned i = 0; i < Lines(); ++i )
+        delete _items[i];
+
+    _items.clear();
+    _visibleItems.clear();
+    setFormatDirty();
+}
+
+
+NCTableLine * NCTablePadBase::getLineWithIndex( unsigned idx ) const
+{
+    NCTableLine * line = 0;
+
+    if ( idx < Lines() )
+	line = _items[ idx ];
+
+    if ( (unsigned) line->index() == idx )
+        return line;
+
+    int pos = findIndex( idx );
+
+    if ( pos >= 0 )
+    {
+        yuiWarning() << "Found item with index " << idx << " at pos " << pos << endl;
+
+        return _items[ pos ];
+    }
+
+    yuiError() << "Can't find item with index " << idx << endl;
+
+    return 0;
+}
+
+
+const NCTableLine * NCTablePadBase::GetLine( unsigned idx ) const
+{
+    return getLineWithIndex( idx );
+}
+
+
+NCTableLine * NCTablePadBase::ModifyLine( unsigned idx )
+{
+    setFormatDirty();
+    return getLineWithIndex( idx );
+}
+
+
+int NCTablePadBase::findIndex( unsigned idx ) const
+{
+    for ( unsigned i=0; i < Lines(); i++ )
+    {
+        if ( (unsigned) _items[ i ]->index() == idx )
+            return i;
+    }
+
+    return -1;
+}
+
+
+void NCTablePadBase::SetLines( unsigned idx )
+{
+    if ( idx == Lines() )
+	return;
+
+    unsigned olines = Lines();
+
+    if ( idx < Lines() )
+    {
+	for ( unsigned i = idx; i < Lines(); ++i )
+	{
+	    delete _items[i];
+	}
+    }
+
+    _items.resize( idx, 0 );
+
+    for ( unsigned i = olines; i < Lines(); ++i )
+    {
+	if ( !_items[i] )
+	    _items[i] = new NCTableLine( 0 );
+    }
+
+    setFormatDirty();
+}
+
+
+void NCTablePadBase::SetLines( std::vector & newItems )
+{
+    SetLines( 0 );
+    _items = newItems;
+
+    for ( unsigned i = 0; i < Lines(); ++i )
+    {
+	if ( !_items[i] )
+	    _items[i] = new NCTableLine( 0 );
+    }
+
+    setFormatDirty();
+}
+
+
+void NCTablePadBase::AddLine( unsigned idx, NCTableLine * item )
+{
+    assertLine( idx );
+    delete _items[idx];
+    _items[idx] = item ? item : new NCTableLine( 0 );
+
+    setFormatDirty();
+}
+
+
+void NCTablePadBase::assertLine( unsigned idx )
+{
+    if ( idx >= Lines() )
+	SetLines( idx + 1 );
+}
+
+
+bool NCTablePadBase::SetHeadline( const vector & head )
+{
+    bool hascontent = _itemStyle.SetStyleFrom( head );
+    setFormatDirty();
+    update();
+
+    return hascontent;
+}
+
+
+void NCTablePadBase::wRecoded()
+{
+    setFormatDirty();
+    update();
+}
+
+
+wpos NCTablePadBase::CurPos() const
+{
+    _citem.C = srect.Pos.C;
+    return _citem;
+}
+
+
+wsze NCTablePadBase::tableSize()
+{
+    if ( _dirtyFormat )
+        UpdateFormat();
+
+    return wsze( Lines(), _itemStyle.TableWidth() );
+}
+
+
+wsze NCTablePadBase::UpdateFormat()
+{
+    dirty = true;
+    _itemStyle.ResetToMinCols();
+
+    for ( unsigned i = 0; i < Lines(); ++i )
+	_items[i]->UpdateFormat( _itemStyle );
+
+    _dirtyFormat = false;
+    updateVisibleItems();
+
+    maxspos.L = visibleLines() > (unsigned) srect.Sze.H ? visibleLines() - srect.Sze.H : 0;
+
+    wsze size( visibleLines(), _itemStyle.TableWidth() );
+    resize( size );
+
+    return size;
+}
+
+
+// Update the internal _visibleItems() vector.
+// This does NOT do a screen update of the visible items!
+
+void NCTablePadBase::updateVisibleItems()
+{
+    _visibleItems.clear();
+
+    for ( unsigned i = 0; i < Lines(); ++i )
+    {
+	if ( _items[ i ]->isVisible() )
+	    _visibleItems.push_back( _items[ i ] );
+    }
+}
+
+
+int NCTablePadBase::DoRedraw()
+{
+    // Notice that this is only a fallback implementation of this method.
+    // Derived classes usually overwrite this with subtle changes.
+    // See NCTreePad::DoRedraw() or NCTablePad::DoRedraw().
+
+    if ( !Destwin() )
+    {
+	dirty = true;
+	return OK;
+    }
+
+    prepareRedraw();
+    drawContentLines();
+    drawHeader();
+
+    dirty = false;
+
+    return update();
+}
+
+
+void NCTablePadBase::prepareRedraw()
+{
+    if ( _dirtyFormat )
+	UpdateFormat();
+
+    bkgdset( _itemStyle.getBG() );
+    clear();
+}
+
+
+void NCTablePadBase::drawContentLines()
+{
+    wsze lineSize( 1, width() );
+
+    for ( unsigned lineNo = 0; lineNo < visibleLines(); ++lineNo )
+    {
+	_visibleItems[ lineNo ]->DrawAt( *this,
+                                         wrect( wpos( lineNo, 0 ), lineSize ),
+                                         _itemStyle,
+                                         ( lineNo == (unsigned) currentLineNo() ) );
+    }
+}
+
+
+void NCTablePadBase::drawHeader()
+{
+    wsze lineSize( 1, width() );
+
+    if ( _headpad.width() != width() )
+	_headpad.resize( 1, width() );
+
+    _headpad.clear();
+    _itemStyle.Headline().DrawAt( _headpad,
+                                  wrect( wpos( 0, 0 ), lineSize ),
+                                  _itemStyle,
+                                  false );
+    SendHead();
+}
+
+
+int NCTablePadBase::setpos( const wpos & newpos )
+{
+    if ( !Lines() )
+    {
+	if ( dirty || _dirtyFormat )
+	    return DoRedraw();
+
+	return OK;
+    }
+
+    if ( _dirtyFormat )
+	UpdateFormat();
+
+    // Save old values
+    int oldLineNo = currentLineNo();
+    int oldPos    = srect.Pos.C;
+
+    // Calc new values
+    setCurrentLineNo( newpos.L < 0 ? 0 : newpos.L );
+
+    // Prevent scrolling out of the visible lines
+    if ( (unsigned) currentLineNo() >= visibleLines() )
+	setCurrentLineNo( visibleLines() - 1 );
+
+    srect.Pos = wpos( currentLineNo() - ( drect.Sze.H - 1 ) / 2, newpos.C ).between( 0, maxspos );
+
+    if ( currentLineNo() != oldLineNo )
+    {
+	unsigned at  = 0;
+	unsigned len = 0;
+
+	if ( currentLineNo() >= 0 && _visibleItems[ currentLineNo() ] )
+        {
+	    len = _visibleItems[ currentLineNo() ]->Hotspot( at );
+        }
+	else
+        {
+	    return ERR;
+        }
+
+	if ( len )
+	{
+	    if ( (int) at < srect.Pos.C )
+	    {
+		srect.Pos.C = at;
+	    }
+	    else if ( (int) ( at + len - srect.Pos.C ) > drect.Sze.W )
+	    {
+		srect.Pos.C = (int) at < maxspos.C ? at : maxspos.C;
+	    }
+	}
+    }
+
+    if ( dirty )
+	return DoRedraw();
+
+    if ( ! paging() )
+    {
+        // adjust only
+
+    if ( currentLineNo() != oldLineNo )
+    {
+	_visibleItems[ oldLineNo ]->DrawAt( *this,
+                                            wrect( wpos( oldLineNo, 0 ),
+                                                   wsze( 1, width() ) ),
+                                            _itemStyle,
+                                            false );
+    }
+
+    _visibleItems[ currentLineNo() ]->DrawAt( *this,
+                                              wrect( wpos( currentLineNo(), 0 ),
+                                                     wsze( 1, width() ) ),
+                                              _itemStyle,
+                                              true );
+    }
+    // else
+    //   item drawing requested via directDraw()
+
+    if ( srect.Pos.C != oldPos )
+	SendHead();
+
+    return update();
+}
+
+
+bool NCTablePadBase::handleInput( wint_t key )
+{
+    // First, give the current item (the item at the cursor position) a chance
+    // to handle item-specific keys. The item handles opening and closing
+    // branches and item selection.
+
+    bool handled = currentItemHandleInput( key );
+
+    if ( ! handled )
+    {
+        switch ( key )
+        {
+            // At this time, there are no more special keys to handle on this
+            // level. This switch is a stub for future extension if any more
+            // keys need to be handled.
+            //
+            // Add 'case KEY_XXX' branches here if there should be any
+            // and don't forget to set 'handled' to 'true'.
+#if 0
+            case KEY_SOMETHING:     // Sample
+                doSomething();
+                handled = true;
+                break;
+#endif
+
+            default: // Call parent class input handler
+
+                // The NCPad handles scrolling with the cursor keys, PgDn,
+                // PgUp, Home, End.
+                handled = NCPad::handleInput( key );
+                break;
+        }
+    }
+
+    return handled;
+}
+
+
+bool NCTablePadBase::currentItemHandleInput( wint_t key )
+{
+    bool handled = false;
+    NCTableLine * currentLine = GetCurrentLine();
+
+    if ( currentLine )
+    {
+        handled = currentLine->handleInput( key );
+
+        if ( handled )
+        {
+            UpdateFormat();
+            setpos( wpos( currentLineNo(), srect.Pos.C ) );
+        }
+    }
+
+    return handled;
+}
+
+
+NCTableLine * NCTablePadBase::GetCurrentLine() const
+{
+    if ( currentLineNo() >= 0 && (unsigned) currentLineNo() < visibleLines() )
+	return _visibleItems[ currentLineNo() ];
+
+    return 0;
+}
+
+
+//----------------------------------------------------------------------
+
+
+std::ostream & operator<<( std::ostream & str, const NCTablePadBase & obj )
+{
+    str << "TablePadBase: lines " << obj.Lines() << std::endl;
+
+    for ( unsigned idx = 0; idx < obj.Lines(); ++idx )
+    {
+	str << idx << " " << *obj.GetLine( idx );
+    }
+
+    return str;
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCTablePadBase.h b/deps/libyui/libyui-ncurses/src/NCTablePadBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ee0755f0251cfc44e31a5aca92d66005c5fa6b7
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTablePadBase.h
@@ -0,0 +1,299 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTablePadBase.h
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#ifndef NCTablePadBase_h
+#define NCTablePadBase_h
+
+#include 
+#include "NCPad.h"
+#include "NCTableItem.h"
+
+class NCTableCol;
+
+
+/**
+ * An NCPad for an NCTable or an NCTree.
+ *
+ * This is an abstract base class for NCTablePad and NCTreePad.
+ *
+ * See also
+ * https://github.com/libyui/libyui-ncurses/blob/master/doc/nctable-and-nctree.md
+ *
+ * Notice that this class is heavily used in other selection widgets like
+ *
+ * - NCFileSelection
+ * - NCItemSelector
+ * - NCMultiSelectionBox
+ * - NCSelectionBox
+ *
+ * And the table classes from libyui-ncurses-pkg:
+ * - NCPkgTable
+ * - NCPkgLocaleTable
+ * - NCPkgRepoTable
+ *
+ * So if you change anything here, make sure to test all those classes.
+ **/
+class NCTablePadBase : public NCPad
+{
+    friend std::ostream & operator<<( std::ostream & str, const NCTablePadBase & obj );
+
+protected:
+    /**
+     * Constructor. This is protected because this is an abstract base class,
+     * not meant to be instantiated on this level.
+     **/
+    NCTablePadBase( int lines, int cols, const NCWidget & p );
+
+public:
+
+    virtual ~NCTablePadBase();
+
+    /**
+     * Clear all content.
+     **/
+    void ClearTable();
+
+    virtual void wRecoded();
+
+    /// CurPos().L is the index of the selected item
+    virtual wpos CurPos() const;
+
+    wsze tableSize();
+
+    /**
+     * Return the number of lines that are currently visible.
+     * This is updated in UpdateFormat().
+     **/
+    unsigned visibleLines() const { return _visibleItems.size(); }
+
+    bool SetHeadline( const std::vector & head );
+
+    virtual void SendHead()
+    {
+	SetHead( _headpad, srect.Pos.C );
+	_dirtyHead = false;
+    }
+
+    void SetSepChar( const chtype colSepchar )
+    {
+	_itemStyle.SetSepChar( colSepchar );
+    }
+
+    void SetSepWidth( const unsigned sepwidth )
+    {
+	_itemStyle.SetSepWidth( sepwidth );
+    }
+
+    void SetHotCol( int hcol )
+    {
+	_itemStyle.SetHotCol( hcol );
+    }
+
+    /**
+     * Return the number of table columns (logical, not screen)
+     */
+    unsigned Cols()   const { return _itemStyle.Cols(); }
+
+    /**
+     * Return the number of table lines (logical, not screen)
+     **/
+    unsigned Lines()  const { return _items.size(); }
+
+    bool empty() const { return _items.empty(); }
+
+    unsigned HotCol() const { return _itemStyle.HotCol(); }
+
+    /**
+     * Expand or shrink to have exactly *count* logical lines
+     **/
+    void SetLines( unsigned count );
+
+    void SetLines( std::vector & newItems );
+
+    /**
+     * Add *item* at position *idx*, expanding if needed
+     * @param item we take ownership
+     *
+     * @deprecated Used only by Append; undefined behaviour if used after
+     * sorting
+     **/
+    void AddLine( unsigned idx, NCTableLine * item );
+
+    /**
+     * Add one item to the end of _items.
+     **/
+    void Append( NCTableLine * item ) { AddLine( Lines(), item ); }
+
+    /**
+     * Create a new item from 'cells' and add it to the end of _items.
+     **/
+    void Append( std::vector & cells, int index )
+        { AddLine( Lines(), new NCTableLine( cells, index ) ); }
+
+    /**
+     * Return the line at *idx* for read-only operations.
+     **/
+    const NCTableLine * GetLine( unsigned idx ) const;
+
+    /**
+     * Return line at *idx* for read-write operations and mark it as modified.
+     **/
+    NCTableLine * ModifyLine( unsigned idx );
+
+    /**
+     * Find the item with index 'idx' in the items and return its position.
+     * Return -1 if not found.
+     **/
+    int findIndex( unsigned idx ) const;
+
+    /**
+     * Return the current line (the line at the cursor position) or 0 if there
+     * is none.
+     **/
+    NCTableLine * GetCurrentLine() const;
+
+    /**
+     * Handle a keyboard input event. Return 'true' if the event is now
+     * handled, 'false' if it should be propagated to the parent widget.
+     *
+     * Most of the keys are now handled in the individual items' handlers
+     * (NCTreeLine, NCTableLine). This method is mostly here as a stub for
+     * future extensions.
+     *
+     * Reimplemented from NCPad.
+     **/
+    virtual bool handleInput( wint_t key );
+
+
+private:
+
+    // Disable unwanted assignment operator and copy constructor
+
+    NCTablePadBase & operator=( const NCTablePadBase & );
+    NCTablePadBase( const NCTablePadBase & );
+
+    /**
+     * Return the line with index 'idx' or 0 if not found.
+     **/
+    NCTableLine * getLineWithIndex( unsigned idx ) const;
+
+
+protected:
+
+    virtual wsze UpdateFormat();
+
+    /**
+     * Call the current item's handleInput() method and return 'true' if the
+     * event is now handled, 'false' if not.
+     **/
+    virtual bool currentItemHandleInput( wint_t key );
+
+    /**
+     * Update the internal _visibleItems vector with the items that are
+     * currently visible: Clear the old contents of the vector, iterate over
+     * all lines and check which ones are currently visible.
+     *
+     * This does NOT do a screen update of the visible items!
+     **/
+    void updateVisibleItems();
+
+    void setFormatDirty() { dirty = _dirtyFormat = true; }
+
+    virtual int dirtyPad() { return setpos( CurPos() ); }
+
+    /**
+     * Redraw the pad.
+     *
+     * Reimplemented from NCPad.
+     **/
+    virtual int DoRedraw();
+
+    /**
+     * Prepare a redraw: Update the format if needed, set the background, clear
+     * the old content.
+     **/
+    virtual void prepareRedraw();
+
+    /**
+     * Redraw the (visible) content lines one by one.
+     **/
+    virtual void drawContentLines();
+
+    /**
+     * Redraw the table header.
+     **/
+    virtual void drawHeader();
+
+    /**
+     * Base function for scrolling: Move the cursor position to 'newPos' and
+     * redraw the old and the new current item with suitable attributes: The
+     * new current item is highlighted, the old one is not.
+     *
+     * Reimplemented from NCPad.
+     **/
+    virtual int setpos( const wpos & newPos );
+
+    /**
+     * Return the current line number (the cursor position).
+     **/
+    int currentLineNo() const { return _citem.L; }
+
+    /**
+     * Set the current line number (the cursor position).
+     **/
+    void setCurrentLineNo( int newVal ) { _citem.L = newVal; }
+
+    /**
+     * Return the current column number (the cursor position).
+     **/
+    int currentColNo() const { return _citem.C; }
+
+    /**
+     * Set the current column number (the cursor position).
+     **/
+    void setCurrentColNo( int newVal ) { _citem.C = newVal; }
+
+    /**
+     * Ensure that a line with the specified index exists.
+     * Enlarge or shrink if necessary.
+     **/
+    void assertLine( unsigned index );
+
+
+    //
+    // Data members
+    //
+
+    std::vector _items;        ///< (owned)
+    std::vector _visibleItems; ///< not owned
+    NCursesPad	              _headpad;
+    bool	              _dirtyHead;
+    bool	              _dirtyFormat;  ///< does table format (size) need recalculating?
+    NCTableStyle	      _itemStyle;
+    wpos		      _citem;        ///< current/cursor position
+};
+
+
+#endif  // NCTablePadBase_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTableSort.cc b/deps/libyui/libyui-ncurses/src/NCTableSort.cc
new file mode 100644
index 0000000000000000000000000000000000000000..604d8c96cdfbdf10af2576c18f2b73662126dea7
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTableSort.cc
@@ -0,0 +1,122 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+#define  YUILogComponent "ncurses"
+#include 
+#include 
+
+#include "NCTableSort.h"
+#include "NCTable.h"
+
+
+/**
+ * Support classes for sorting by column in a table for use in an NCTablePad
+ **/
+
+void
+NCTableSortDefault::sort( YItemIterator begin, YItemIterator end )
+{
+    // yuiMilestone() << "Sorting by col #" << sortCol()
+    //                << " reverse: " << std::boolalpha << reverse() << endl;
+
+    std::stable_sort( begin, end,
+                      Compare( sortCol(), reverse() ) );
+}
+
+
+bool
+NCTableSortDefault::Compare::operator() ( YItem * item1,
+					  YItem * item2 ) const
+{
+    std::wstring w1 = smartSortKey( item1 );
+    std::wstring w2 = smartSortKey( item2 );
+
+    bool ok1, ok2;
+    long long number1 = toNumber( w1, &ok1 );
+    long long number2 = toNumber( w2, &ok2 );
+
+    if ( ok1 && ok2 )
+    {
+	// Both are numbers
+	return !_reverse ? number1 < number2 : number1 > number2;
+    }
+    else if ( ok1 && !ok2 )
+    {
+	// int < string
+	return true;
+    }
+    else if ( !ok1 && ok2 )
+    {
+	// string > int
+	return false;
+    }
+    else
+    {
+	// compare strings using collating information
+	int result = std::wcscoll( w1.c_str(), w2.c_str() );
+
+	return !_reverse ? result < 0 : result > 0;
+    }
+}
+
+
+long long
+NCTableSortDefault::Compare::toNumber( const std::wstring & str, bool * ok ) const
+{
+    try
+    {
+	size_t sz;
+	long long val = std::stoll( str, &sz );
+	*ok = sz == str.size();
+
+	return val;
+    }
+    catch (...)
+    {
+	*ok = false;
+	return 0;
+    }
+}
+
+
+std::wstring
+NCTableSortDefault::Compare::smartSortKey( YItem * item ) const
+{
+    std::wstring empty;
+
+    if ( ! item )
+        return empty;
+
+    YTableItem * tableItem = dynamic_cast( item );
+
+    if ( ! tableItem )
+        return empty;
+
+    YTableCell * tableCell = tableItem->cell( _sortCol );
+
+    if ( ! tableCell )
+        return empty;
+
+    NCstring result;
+
+    if ( tableCell->hasSortKey() )
+        result = NCstring( tableCell->sortKey() );
+    else
+        result = NCstring( tableCell->label() );
+
+    return result.str();
+}
+
diff --git a/deps/libyui/libyui-ncurses/src/NCTableSort.h b/deps/libyui/libyui-ncurses/src/NCTableSort.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff062b8c773d393e7d9f22d6f9d26dfbf5b08abd
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTableSort.h
@@ -0,0 +1,124 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+#ifndef NCTableSort_h
+#define NCTableSort_h
+
+#include 
+#include 
+#include 
+
+class NCTableLine;
+
+
+/**
+ * Support classes for sorting by column in a table for use in an NCTablePad
+ **/
+
+
+/**
+ * Abstract base class for sorting strategies.
+ **/
+class NCTableSortStrategyBase
+{
+public:
+
+    NCTableSortStrategyBase( int sortCol = 0, bool reverse = false )
+        : _sortCol( sortCol )
+        , _reverse( reverse )
+        {}
+
+    virtual ~NCTableSortStrategyBase()
+        {}
+
+    /**
+     * Sort items between 'begin' and 'end' in place.
+     *
+     * Derived classes are required to implement this.
+     **/
+    virtual void sort( YItemIterator begin, YItemIterator end ) = 0;
+
+
+    int  sortCol() const                { return _sortCol;    }
+    void setSortCol( int col )          { _sortCol = col;     }
+
+    bool reverse() const		{ return _reverse;    }
+    void setReverse( bool reverse )	{ _reverse = reverse; }
+
+
+private:
+
+    int  _sortCol;
+    bool _reverse;
+};
+
+
+/**
+ * Default sort strategy
+ **/
+class NCTableSortDefault: public NCTableSortStrategyBase
+{
+public:
+    virtual void sort( YItemIterator begin, YItemIterator end ) override;
+
+protected:
+
+    /**
+     * Comparison functor.
+     *
+     * This uses the sort key of the cell if it has one, the label if not.
+     *
+     * It also tries to convert strings to numbers to do a numeric comparison
+     * if possible.
+     **/
+    class Compare
+    {
+    public:
+	Compare( int sortCol, bool reverse )
+	    : _sortCol( sortCol )
+            , _reverse( reverse )
+	    {}
+
+        /**
+         * The comparison itself: Return the result of  item1 < item2
+         **/
+	bool operator() ( YItem * item1, YItem * item2 ) const;
+
+    protected:
+
+        /**
+         * Return the sort key of column no. _sortCol for an item or, if it
+         * doesn't have one, its label in that column.
+         **/
+	std::wstring smartSortKey( YItem * item ) const;
+
+        /**
+         * Try to convert a string to a number. Return the number and set the
+         * 'ok' flag to 'true' on success, to 'false' on failure.
+         **/
+	long long toNumber( const std::wstring& str, bool * ok ) const;
+
+
+        // Data members
+
+	const int  _sortCol;
+	const bool _reverse;
+    };
+
+};
+
+
+#endif  // NCTableSort_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTextPad.cc b/deps/libyui/libyui-ncurses/src/NCTextPad.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a012b96a2bc793ce0e2ae23fac5e86b3d79812fd
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTextPad.cc
@@ -0,0 +1,612 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTextPad.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCTextPad.h"
+
+#include 
+
+using std::endl;
+
+// FLAW: if notification is enabled the dialog gets disabled and reenabled
+// when procesing the event. This causes noticable flicker if the enabled/disabled
+// attriutes differ. That's why 'nonactive' style is used.
+#define MY_TEXT_STYLE ( parw.widgetStyle( /*nonactive*/true ).data )
+
+NCTextPad::NCTextPad( int l, int c, const NCWidget & p )
+	: NCPad( l, c, p )
+	, lines( 1U, 0 )
+	, cline( lines.begin() )
+	, curson( false )
+	, InputMaxLength( -1 )
+{
+    bkgd( MY_TEXT_STYLE );
+}
+
+
+
+NCTextPad::~NCTextPad()
+{
+}
+
+
+
+void NCTextPad::resize( wsze nsze )
+{
+    SetPadSize( nsze ); // might be enlarged by NCPadWidget if redirected
+
+    if ( nsze.H != height()
+	 || nsze.W != width() )
+    {
+	NCursesWindow * odest = Destwin();
+
+	if ( odest )
+	    Destwin( 0 );
+
+	NCursesPad::resize( nsze.H, nsze.W );
+
+	if ( odest )
+	    Destwin( odest );
+    }
+}
+
+
+
+void NCTextPad::assertSze( wsze minsze )
+{
+    if ( minsze.W > width()
+	 || minsze.H > height() )
+	resize( minsze );
+}
+
+
+
+void NCTextPad::assertWidth( unsigned minw )
+{
+    if ( minw >= (unsigned) width() ) // == for the '\n'
+	resize( wsze( height(), minw + 10 ) );
+}
+
+
+
+void NCTextPad::assertHeight( unsigned minh )
+{
+    if ( minh > (unsigned) height() )
+	resize( wsze( minh + 10, width() ) );
+}
+
+
+
+wpos NCTextPad::CurPos() const
+{
+    return curs;
+}
+
+
+
+void NCTextPad::cursor( bool on )
+{
+    if ( on != curson )
+    {
+	if (( curson = on ) )
+	{
+	    bkgdset( parw.wStyle().cursor );
+	    add_attr_char( curs.L, curs.C );
+	    bkgdset( MY_TEXT_STYLE );
+	}
+	else
+	{
+	    add_attr_char( curs.L, curs.C );
+	}
+    }
+}
+
+
+
+int NCTextPad::setpos()
+{
+    // BUG?: bkgd does not change the color attibute of nonwhite characters
+    // on the pad so we repaint them in the new color in case it changed.
+    chtype oldbkgd = NCattribute::getColor( getbkgd() );
+    bkgd( MY_TEXT_STYLE );
+
+    if ( NCattribute::getColor( getbkgd() ) != oldbkgd )
+    {
+      // repaint text
+      for ( int l = 0; l < height(); ++l )
+	for ( int c = 0; c < width(); ++ c )
+	{
+	  add_attr_char( l, c );
+	}
+    }
+    cursor( parw.GetState() == NC::WSactive );
+    return setpos( CurPos() );
+}
+
+
+
+int NCTextPad::setpos( const wpos & newpos )
+{
+    wpos npos( newpos.between( 0, wpos( maxy(), maxx() ) ) );
+
+    if ( (unsigned) npos.L >= lines.size() )
+    {
+	npos.L = lines.size() - 1;
+	cline = lines.end();
+	--cline;
+    }
+    else if ( npos.L != curs.L )
+    {
+	advance( cline, npos.L - curs.L );
+    }
+
+    if ( (unsigned) npos.C > *cline )
+    {
+	npos.C = *cline;
+    }
+
+    bool ocurs = curson;
+
+    if ( ocurs )
+        cursorOff();
+
+    curs = npos;
+
+    if ( ocurs )
+        cursorOn();
+
+    wpos padpos( curs );
+
+    if ( drect.Sze > wsze( 0 ) )
+    {
+	padpos = ( padpos / drect.Sze ) * drect.Sze;
+    }
+
+    return NCPad::setpos( padpos );
+}
+
+
+
+bool NCTextPad::handleInput( wint_t key )
+{
+    bool handled = true;
+    bool beep	 = false;
+    bool update  = true;
+
+    cursorOff();
+
+    switch ( key )
+    {
+	case KEY_LEFT:
+
+	    if ( curs.C )
+	    {
+		--curs.C;
+	    }
+	    else if ( curs.L )
+	    {
+		--cline;
+		--curs.L;
+		curs.C = ( *cline );
+	    }
+	    else
+	    {
+		beep = true;
+		update = false;
+	    }
+	    break;
+
+
+	case KEY_UP:
+
+	    if ( curs.L )
+	    {
+		--cline;
+		--curs.L;
+	    }
+	    else
+	    {
+		beep = true;
+		update = false;
+	    }
+	    break;
+
+
+	case KEY_RIGHT:
+
+	    if ( (unsigned) curs.C < ( *cline ) )
+	    {
+		++curs.C;
+	    }
+	    else if ( (unsigned) curs.L + 1 < lines.size() )
+	    {
+		++cline;
+		++curs.L;
+		curs.C = 0;
+	    }
+	    else
+	    {
+		beep = true;
+		update = false;
+	    }
+	    break;
+
+
+	case KEY_DOWN:
+
+	    if ( (unsigned) curs.L + 1 < lines.size() )
+	    {
+		++cline;
+		++curs.L;
+	    }
+	    else
+	    {
+		beep = true;
+		update = false;
+	    }
+	    break;
+
+
+	case KEY_PPAGE:
+
+	    if ( curs.L )
+	    {
+		setpos( wpos( curs.L - 3, curs.C ) );
+	    }
+	    else
+	    {
+		beep = true;
+		update = false;
+	    }
+	    break;
+
+
+	case KEY_NPAGE:
+
+	    if ( (unsigned) curs.L + 1 < lines.size() )
+	    {
+		setpos( wpos( curs.L + 3, curs.C ) );
+	    }
+	    else
+	    {
+		beep = true;
+		update = false;
+	    }
+	    break;
+
+
+	case KEY_SLEFT:
+	case KEY_HOME:
+
+	    if ( curs.C )
+	    {
+		curs.C = 0;
+	    }
+	    break;
+
+
+	case KEY_SRIGHT:
+	case KEY_END:
+
+	    if ( (unsigned) curs.C < ( *cline ) )
+	    {
+		curs.C = ( *cline );
+	    }
+	    break;
+
+
+	case KEY_BACKSPACE:
+	    beep = !delch( true );
+	    break;
+
+	case KEY_DC:
+	    beep = !delch();
+	    break;
+
+	case KEY_HOTKEY:
+	    update = false;
+	    break;
+
+	default:
+	    // if we are at limit of input
+
+	    if ( InputMaxLength >= 0 && InputMaxLength < (int) getText().length() )
+	    {
+		beep = true;
+		update = false;
+	    }
+	    else
+	    {
+		beep = !insert( key );
+	    }
+	    break;
+    }
+
+    cursorOn();
+
+    if ( beep )
+	::beep();
+
+    if ( update )
+	setpos( curs );
+
+    return handled;
+}
+
+
+
+bool NCTextPad::insert( wint_t key )
+{
+    if ( key == 10 )
+    {
+	return openLine();
+    }
+
+    if ( key < 32 || ( key >= 127 && key < 160 ) || UCHAR_MAX < key )
+    {
+	return false;
+    }
+
+    assertWidth( ++( *cline ) );
+
+    cchar_t cchar;
+    attr_t attr = 0;
+    short int color = 0;
+    int ret = wattr_get( w, &attr, &color, NULL ); // NOTE: (w)attr_get is not provided by NCursesWindow
+    if (ret != OK)
+	return false;
+
+    wchar_t wch[2];
+    wch[0] = key;
+    wch[1] = L'\0';
+
+    ret = setcchar( &cchar, wch, attr, color, NULL );
+    if (ret != OK)
+	return false;
+
+// libncurses6 enables ext_color from struct cchar_t (see curses.h).
+// Set ext_color to 0 to respect the settings got from attr_get (bnc#652240).
+#ifdef NCURSES_EXT_COLORS
+    cchar.ext_color = 0;
+#endif
+    ret = ins_wch( curs.L, curs.C++, &cchar );
+
+    return (ret == OK);
+}
+
+
+
+bool NCTextPad::openLine()
+{
+    assertHeight( lines.size() + 1 );
+    std::list::iterator newl( cline );
+    newl = lines.insert( ++newl, 0 );
+
+    if ( curs.C == 0 )
+    {
+	// eazy at line begin: new empty line above
+	insertln();
+
+	( *newl ) = ( *cline );
+	( *cline ) = 0;
+    }
+    else
+    {
+	// new empty line below
+	move( curs.L + 1, 0 );
+	insertln();
+
+	if ( (unsigned) curs.C < ( *cline ) )
+	{
+	    // copy down rest of line
+	    ( *newl ) = ( *cline ) - curs.C;
+	    ( *cline ) = curs.C;
+
+	    move( curs.L, curs.C );
+	    copywin( *this, curs.L, curs.C, curs.L + 1, 0, curs.L + 1, ( *newl ), false );
+	    clrtoeol();
+	}
+    }
+
+    cline = newl;
+
+    ++curs.L;
+    curs.C = 0;
+
+    return true;
+}
+
+
+
+bool NCTextPad::delch( bool previous )
+{
+    if ( previous )
+    {
+	if ( curs.C )
+	    --curs.C;
+	else if ( curs.L )
+	{
+	    --cline;
+	    --curs.L;
+	    curs.C = ( *cline );
+	}
+	else
+	    return false;
+    }
+
+    if ( (unsigned) curs.C < *cline )
+    {
+	// eazy not at line end
+	--( *cline );
+
+	NCPad::delch( curs.L, curs.C );
+    }
+    else if ( (unsigned) curs.L + 1 < lines.size() )
+    {
+	// at line end: join with next line
+	std::list::iterator nextl( cline );
+	++nextl;
+	( *cline ) += ( *nextl );
+	lines.erase( nextl );
+
+	assertWidth(( *cline ) );
+	copywin( *this, curs.L + 1, 0, curs.L, curs.C, curs.L, ( *cline ), false );
+
+	move( curs.L + 1, 0 );
+	deleteln();
+    }
+    else
+	return false;
+
+    return true;
+}
+
+
+void NCTextPad::setText( const NCtext & ntext )
+{
+    bkgd( MY_TEXT_STYLE );
+
+    bool ocurs = curson;
+
+    if ( ocurs )
+        cursorOff();
+
+    clear();
+    assertSze( wsze( ntext.Lines(), ntext.Columns() + 1 ) );
+    curs = 0;
+
+    cchar_t cchar;
+    attr_t attr = 0;
+    short int color = 0;
+    wattr_get( w, &attr, &color, NULL ); // NOTE: (w)attr_get is not provided by NCursesWindow
+
+    wchar_t wch[2];
+    wch[1] = L'\0';
+    lines.clear();
+
+    unsigned cl = 0;
+
+    for ( NCtext::const_iterator line = ntext.begin(); line != ntext.end(); ++line )
+    {
+	lines.push_back(( *line ).str().length() );
+
+	unsigned cc = 0;
+
+	for ( std::wstring::const_iterator c = line->str().begin(); c != line->str().end(); c++ )
+	{
+	    //replace tabs for right arrows (#66104)
+	    if ( *c == 9 ) // horizontal tabulation
+	    {
+		wch[0] = 8677; // U+21E5 RIGHTWARDS ARROW TO BAR (rightward tab)
+	    }
+	    else
+	    {
+		wch[0] = *c;
+	    }
+
+	    setcchar( &cchar, wch, attr, color, NULL );
+// libncurses6 enables ext_color from struct cchar_t (see curses.h).
+// Set ext_color to 0 to respect the settings got from attr_get (bcn#652240).
+#ifdef NCURSES_EXT_COLORS
+	    cchar.ext_color = 0;
+#endif
+	    ins_wch( cl, cc++, &cchar );
+	}
+
+	cl++;
+    }
+
+    if ( lines.empty() )
+	lines.push_back( 0U );
+
+    cline = lines.begin();
+
+    if ( ocurs )
+	cursorOn();
+
+    setpos( curs );
+}
+
+
+
+std::wstring NCTextPad::getText() const
+{
+    // just for inch(x,y) call, which isn't const due to
+    // hw cursor movement, but that's of no interest here.
+    NCTextPad * myself = const_cast( this );
+
+    cchar_t cchar;
+    std::wstring ret;
+    unsigned l = 0;
+    wchar_t wch[CCHARW_MAX+1];
+    attr_t attr;
+    short int colorpair;
+
+    for ( std::list::const_iterator cgetl( lines.begin() ); cgetl != lines.end(); ++cgetl )
+    {
+	for ( unsigned c = 0; c < ( *cgetl ); ++c )
+	{
+	    myself->in_wchar( l, c, &cchar );
+	    getcchar( &cchar, wch, &attr, &colorpair, NULL );
+
+	    //replace right arrow back for horizontal tab - see setText method above (#142509)
+
+	    if ( wch[0] == 8677 )
+		wch[0] = 9;
+
+	    ret += wch[0];
+	}
+
+	++l;
+	// do not append \n after the very last line (bnc #573553)
+	if ( l < lines.size() )
+	{
+	    ret += L"\n";
+	}
+    }
+
+    return ret;
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCTextPad & obj )
+{
+    str << "at " << obj.CurPos() << " on " << wsze( obj.height(), obj.width() )
+    << " lines " << obj.lines.size() << " (" << *obj.cline << ")";
+    return str;
+}
+
+void NCTextPad::setInputMaxLength( int nr )
+{
+    // if there is more text then the maximum number of chars,
+    // truncate the text and update the buffer
+    if ( nr >= 0 && nr < (int) getText().length() )
+    {
+	NCstring newtext = getText().substr( 0, nr );
+	setText( newtext );
+    }
+
+    InputMaxLength = nr;
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCTextPad.h b/deps/libyui/libyui-ncurses/src/NCTextPad.h
new file mode 100644
index 0000000000000000000000000000000000000000..50935f4ca7c2bd9c36a3f5a227f6bac2f76dcffe
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTextPad.h
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTextPad.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCTextPad_h
+#define NCTextPad_h
+
+#include 
+#include 
+
+#include "NCPad.h"
+#include "NCtext.h"
+
+
+class NCTextPad : public NCPad
+{
+
+    friend std::ostream & operator<<( std::ostream & str, const NCTextPad & obj );
+
+    NCTextPad & operator=( const NCTextPad & );
+    NCTextPad( const NCTextPad & );
+
+private:
+
+    std::list	     lines;
+    std::list::iterator cline;
+
+    wpos curs;
+    bool curson;
+
+    void cursor( bool on );
+    void cursorOn()  { cursor( true ); }
+
+    void cursorOff() { cursor( false ); }
+
+    bool insert( wint_t key );
+    bool delch( bool previous = false );
+    bool openLine();
+
+    void assertSze( wsze minsze );
+    void assertWidth( unsigned minw );
+    void assertHeight( unsigned minh );
+
+    // specifies how much characters can be inserted. -1 for unlimited input
+    int InputMaxLength;
+
+protected:
+
+    virtual int setpos( const wpos & newpos );
+
+public:
+
+    NCTextPad( int lines, int cols, const NCWidget & p );
+    virtual ~NCTextPad();
+
+public:
+
+    virtual void resize( wsze nsze );
+    virtual int setpos();
+    virtual wpos CurPos() const;
+    virtual bool handleInput( wint_t key );
+
+    void setText( const NCtext & ntext );
+    std::wstring getText() const;
+
+    // limits  the input to numberOfChars characters and truncates the text
+    // if appropriate
+    void setInputMaxLength( int nr );
+};
+
+
+#endif // NCTextPad_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTimeField.cc b/deps/libyui/libyui-ncurses/src/NCTimeField.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b660a30c0181615f03c57f995cfda66c0126f767
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTimeField.cc
@@ -0,0 +1,337 @@
+/*
+  Copyright (C) 2014 Angelo Naselli 
+
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTimeField.cc
+
+   Author:     Angelo Naselli 
+
+/-*/
+#include 
+#include 
+#include 
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCurses.h"
+#include "NCTimeField.h"
+#include "NCInputTextBase.h"
+
+#include 		// iswalnum()
+
+  
+const unsigned NCTimeField::fieldLength = 8;
+
+NCTimeField::NCTimeField ( YWidget * parent,
+                           const std::string & nlabel )
+  : YTimeField ( parent, nlabel )
+  , NCInputTextBase ( parent, false, fieldLength, fieldLength )
+{
+    // yuiDebug() << std::endl;
+
+  setLabel ( nlabel );
+
+  setValue ( "00:00:00" );
+}
+
+
+
+NCTimeField::~NCTimeField()
+{
+    // yuiDebug() << std::endl;
+}
+
+
+
+int NCTimeField::preferredWidth()
+{
+  return NCInputTextBase::preferredWidth();
+}
+
+
+
+int NCTimeField::preferredHeight()
+{
+  return NCInputTextBase::preferredHeight();
+}
+
+
+
+void NCTimeField::setSize ( int newwidth, int newheight )
+{
+  NCInputTextBase::setSize ( newwidth, newheight );
+}
+
+
+void NCTimeField::setEnabled ( bool do_bv )
+{
+  NCWidget::setEnabled ( do_bv );
+  YWidget::setEnabled ( do_bv );
+}
+
+void NCTimeField::setLabel ( const std::string & nlabel )
+{
+  _label  = NCstring ( nlabel );
+  _label.stripHotkey();
+  YTimeField::setLabel ( nlabel );
+  setDefsze();
+  Redraw();
+}
+
+
+bool NCTimeField::validTime(const std::string& input_time)
+{
+  tm tm1;
+  std::stringstream ss;
+  ss << input_time;
+  char c; 
+  
+  if (!(ss >> tm1.tm_hour))
+    return false;
+  ss >> c;
+  
+  if (!(ss >> tm1.tm_min))
+    return false;
+  ss >> c;
+  
+  if (!(ss >> tm1.tm_sec))
+    return false;
+
+  return (tm1.tm_hour<=23 && tm1.tm_min <= 59 && tm1.tm_sec <= 59);
+}
+
+
+void NCTimeField::setValue ( const std::string & ntext )
+{
+  if (validTime(ntext))
+  {
+    buffer = NCstring ( ntext ).str();
+
+    if ( buffer.length() > maxFldLength )
+    {
+      buffer = buffer.erase ( maxFldLength );
+    }
+
+    fldstart = 0;
+
+    tUpdate();
+  }
+}
+
+
+
+std::string NCTimeField::value()
+{
+  NCstring text ( buffer );
+
+  return text.Str();
+}
+
+
+NCursesEvent NCTimeField::wHandleInput ( wint_t key )
+{
+  NCursesEvent ret = NCursesEvent::none;
+  bool   beep   = false;
+  bool   update = true;
+
+  switch ( key )
+  {
+  case '\b': //ctrl-h
+  case 0x7f: //del
+  case KEY_BACKSPACE:
+
+    buffer.erase ( curpos, 1 );
+    buffer.insert ( std::wstring::size_type ( curpos ), 1, '0' );
+    if ( curpos == 3 || curpos == 6 )
+      curpos -= 2;
+    else
+      if ( curpos )
+        curpos--;
+
+    break;
+
+  case KEY_DC:
+
+    if ( curpos < buffer.length() )
+    {
+      buffer.erase ( curpos, 1 );
+      buffer.insert ( std::wstring::size_type ( curpos ), 1, '0' );
+    }
+    else
+    {
+      update = false;
+      beep   = true;
+    }
+
+    break;
+
+  case KEY_HOME:
+
+    if ( curpos )
+    {
+      curpos = 0;
+    }
+    else
+    {
+      update = false;
+      beep   = true;
+    }
+
+    break;
+
+  case KEY_END:
+
+    if ( curpos < maxCursor() )
+    {
+      curpos = maxCursor();
+    }
+    else
+    {
+      update = false;
+      beep   = true;
+    }
+
+    break;
+
+  case KEY_LEFT:
+
+    if ( curpos == 3 || curpos == 6 )
+      curpos -= 2;
+    else
+      if ( curpos )
+      {
+        --curpos;
+      }
+      else
+      {
+        update = false;
+        beep   = true;
+      }
+
+    break;
+
+  case KEY_RIGHT:
+
+    if ( curpos == 1 || curpos == 4 )
+      curpos += 2;
+    else
+      if ( curpos < maxCursor() )
+      {
+        ++curpos;
+      }
+      else
+      {
+        update = false;
+        beep   = true;
+      }
+
+    break;
+
+  case KEY_RETURN:
+    update = false;
+
+    if ( notify() || returnOnReturn_b )
+      ret = NCursesEvent::Activated;
+
+    break;
+
+  case KEY_HOTKEY:
+    update = false;
+
+    break;
+
+  default:
+    bool is_special = false;
+
+    if ( key > 0xFFFF )
+    {
+      is_special = true;
+      key -= 0xFFFF;
+    }
+
+    if ( ( !is_special && KEY_MIN < key && KEY_MAX > key )
+         ||
+         !iswprint ( key ) )
+    {
+      update = false;
+      beep   = true;
+    }
+    else
+    {
+      {
+        switch ( key )
+        {
+        case L'0':
+        case L'1':
+        case L'2':
+        case L'3':
+        case L'4':
+        case L'5':
+        case L'6':
+        case L'7':
+        case L'8':
+        case L'9':
+          {
+            std::string buf = NCstring(buffer).Str();
+            buffer.erase ( curpos, 1 );
+            buffer.insert ( std::wstring::size_type ( curpos ), 1, key );
+            
+            if (validTime(NCstring(buffer).Str()))
+            {
+                if ( curpos == 1 || curpos == 4 )
+                    curpos += 2;
+                else if ( curpos < maxCursor() )
+                    ++curpos;
+            }
+            else
+            {
+                update = false;
+                setValue(buf);
+                beep   = true;
+            }
+          }
+          break;
+
+        default:
+          update = false;
+          beep   = true;
+          break;
+        }
+      }
+
+    }
+
+    break;
+  }
+
+  if ( update )
+  {
+    tUpdate();
+
+    if ( notify() )
+      ret = NCursesEvent::ValueChanged;
+  }
+
+  if ( beep )
+    ::beep();
+
+  return ret;
+
+}
+
+
diff --git a/deps/libyui/libyui-ncurses/src/NCTimeField.h b/deps/libyui/libyui-ncurses/src/NCTimeField.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d878a2f9702ad75b70d6fdf45d0a576328c9eac
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTimeField.h
@@ -0,0 +1,88 @@
+/*
+  Copyright (C) Angelo Naselli
+
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTimeField.h
+
+   Author:     Angelo Naselli 
+
+/-*/
+
+#ifndef NCTimeField_h
+#define NCTimeField_h
+
+#include 
+
+#include 
+#include "NCWidget.h"
+#include "NCInputTextBase.h"
+
+
+class NCTimeField : public YTimeField, public NCInputTextBase
+{
+
+  friend std::ostream & operator<< ( std::ostream & str, const NCTimeField & obj );
+
+  NCTimeField & operator= ( const NCTimeField & );
+  NCTimeField ( const NCTimeField & );
+
+private:
+  static const unsigned fieldLength;
+  
+  bool validTime(const std::string& input_time);
+
+protected:
+
+  virtual const char * location() const
+  {
+    return "NCTimeField";
+  }
+
+public:
+
+  NCTimeField ( YWidget * parent,
+                const std::string & label
+              );
+  virtual ~NCTimeField();
+
+  virtual int preferredWidth();
+  virtual int preferredHeight();
+
+  virtual void setSize ( int newWidth, int newHeight );
+
+  virtual void setLabel ( const std::string & nlabel );
+
+  virtual void setValue ( const std::string & ntext );
+  virtual std::string value();
+
+  virtual void setEnabled ( bool do_bv );
+
+  virtual NCursesEvent wHandleInput ( wint_t key );
+
+  virtual bool setKeyboardFocus()
+  {
+    if ( !grabFocus() )
+      return YWidget::setKeyboardFocus();
+
+    return true;
+  }
+
+};
+
+
+#endif // NCTimeField_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTree.cc b/deps/libyui/libyui-ncurses/src/NCTree.cc
new file mode 100644
index 0000000000000000000000000000000000000000..910638ebc85dd510f443cf370675906230db1ae3
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTree.cc
@@ -0,0 +1,510 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTree.cc
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#define	 YUILogComponent "ncurses"
+#include 
+#include "NCTree.h"
+#include "YNCursesUI.h"
+
+#include 
+#include 
+
+using std::string;
+using std::endl;
+
+
+NCTree::NCTree( YWidget *      parent,
+                const string & nlabel,
+                bool           multiselection,
+                bool           recursiveselection )
+    : YTree( parent, nlabel, multiselection, recursiveselection )
+    , NCPadWidget( parent )
+    , _multiSelect( multiselection )
+    , _nextItemIndex( 0 )
+{
+    // yuiDebug() << endl;
+
+    if ( multiselection && recursiveselection )
+	yuiDebug() << "NCTree recursive multi selection ON" << endl;
+    else if ( multiselection )
+	yuiDebug() << "NCTree multi selection ON" << endl;
+
+    setLabel( nlabel );
+}
+
+
+NCTree::~NCTree()
+{
+
+}
+
+
+inline const NCTreeLine *
+NCTree::getTreeLine( unsigned idx ) const
+{
+    if ( myPad() )
+	return dynamic_cast( myPad()->GetLine( idx ) );
+    else
+	return 0;
+}
+
+
+inline NCTreeLine *
+NCTree::modifyTreeLine( unsigned idx )
+{
+    if ( myPad() )
+	return dynamic_cast( myPad()->ModifyLine( idx ) );
+    else
+        return 0;
+}
+
+
+int NCTree::preferredWidth()
+{
+    wsze sze = wsze::max( defsze, wsze( 0, labelWidth() + 2 ) );
+    return sze.W;
+}
+
+
+int NCTree::preferredHeight()
+{
+    wsze sze = wsze::max( defsze, wsze( 0, labelWidth() + 2 ) );
+    return sze.H;
+}
+
+
+void NCTree::setEnabled( bool do_bv )
+{
+    NCWidget::setEnabled( do_bv );
+    YWidget::setEnabled( do_bv );
+}
+
+
+void NCTree::setSize( int newwidth, int newheight )
+{
+    wRelocate( wpos( 0 ), wsze( newheight, newwidth ) );
+}
+
+
+YTreeItem * NCTree::getCurrentItem() const
+{
+    YTreeItem * yitem = 0;
+
+    if ( myPad() && myPad()->GetCurrentLine() )
+    {
+	const NCTreeLine * currentLine = dynamic_cast( myPad()->GetCurrentLine() );
+
+	if ( currentLine )
+	    yitem = currentLine->YItem();
+    }
+
+    // yuiDebug() << "-> " << ( yitem ? yitem->label().c_str() : "noitem" ) << endl;
+
+    return yitem;
+}
+
+
+void NCTree::deselectAllItems()
+{
+    if ( _multiSelect )
+    {
+	YItemCollection selectedItems = YTree::selectedItems();
+
+	for ( YItemConstIterator it = selectedItems.begin(); it != selectedItems.end(); ++it )
+	{
+	    selectItem( *it, false );
+	}
+    }
+
+    YTree::deselectAllItems();
+}
+
+
+void NCTree::selectItem( YItem * item, bool selected )
+{
+    if ( !myPad() )
+	return;
+
+    YTreeItem * treeItem =  dynamic_cast( item );
+    YUI_CHECK_PTR( treeItem );
+
+    YTreeItem * currentItem = getCurrentItem();
+
+    // retrieve position of the item
+    int at = treeItem->index();
+
+    NCTreeLine * currentLine = 0;
+    NCTableCol * currentCol  = 0;
+
+    if ( _multiSelect )
+    {
+	currentLine = modifyTreeLine( at );
+
+	if ( currentLine )
+	{
+	    currentCol = currentLine->GetCol(0);
+	}
+    }
+
+    if ( !selected )
+    {
+	if ( !_multiSelect && ( treeItem == currentItem ) )
+	{
+	    YTree::deselectAllItems();
+	}
+	else
+	{
+	    YTree::selectItem( treeItem, false );
+
+	    if ( currentCol )
+	    {
+                currentCol->setPrefix( currentLine->indentationStr() + "[ ] " );
+	    }
+	}
+    }
+    else
+    {
+	YTree::selectItem( treeItem, selected );
+
+	if ( _multiSelect && currentCol )
+	{
+            currentCol->setPrefix( currentLine->indentationStr() + "[x] " );
+	}
+
+	// Highlight the selected item and possibly expand the tree if it is in
+	// a currently hidden branch
+
+	myPad()->ShowItem( getTreeLine( at ) );
+    }
+}
+
+
+void NCTree::selectItem( int index )
+{
+    YItem * item = YTree::itemAt( index );
+
+    if ( item )
+	selectItem( item, true );
+    else
+	YUI_THROW( YUIException( "Can't find selected item" ) );
+}
+
+
+void NCTree::setLabel( const string & nlabel )
+{
+    YTree::setLabel( nlabel );
+    NCPadWidget::setLabel( NCstring( nlabel ) );
+}
+
+
+void NCTree::rebuildTree()
+{
+    DelPad();
+    Redraw();
+}
+
+
+NCPad * NCTree::CreatePad()
+{
+    wsze    psze( defPadSze() );
+    NCPad * npad = new NCTreePad( psze.H, psze.W, *this );
+    npad->bkgd( listStyle().item.plain );
+
+    return npad;
+}
+
+
+void NCTree::CreateTreeLines( NCTreeLine * parentLine,
+                              NCTreePad  * pad,
+                              YItem      * item )
+{
+    // Set the item index explicitely: It is set to -1 by default which makes
+    // selecting items painful.
+
+    item->setIndex( _nextItemIndex++ );
+
+    YTreeItem * treeItem = dynamic_cast( item );
+    YUI_CHECK_PTR( treeItem );
+
+    NCTreeLine * line = new NCTreeLine( parentLine, treeItem, _multiSelect );
+    pad->Append( line );
+
+    if ( item->selected() )
+    {
+        // Retrieve the position of the item
+        int at = treeItem->index();
+
+        NCTreeLine * currentLine = 0;
+        NCTableCol * currentCol = 0;
+
+        if ( _multiSelect )
+        {
+            currentLine = modifyTreeLine( at );
+
+            if ( currentLine )
+                currentCol = currentLine->GetCol(0);
+
+            if ( currentCol )
+            {
+                currentCol->setPrefix( currentLine->indentationStr() + "[x] " );
+            }
+        }
+
+        // Highlight the selected item and expand the tree if it is in a
+        // currently hidden branch
+
+        pad->ShowItem( getTreeLine( at ) );
+    }
+
+    // Recursively create TreeLines for the children of this item
+
+    for ( YItemIterator it = item->childrenBegin();  it < item->childrenEnd(); ++it )
+    {
+	CreateTreeLines( line, pad, *it );
+    }
+}
+
+
+YTreeItem * NCTree::currentItem()
+{
+    return getCurrentItem();
+}
+
+
+void NCTree::DrawPad()
+{
+    if ( !myPad() )
+    {
+	yuiWarning() << "PadWidget not yet created" << endl;
+	return;
+    }
+
+    _nextItemIndex = 0;
+
+    // Iterate over the toplevel items
+
+    for ( YItemIterator it = itemsBegin(); it < itemsEnd(); ++it )
+    {
+        // Create a TreeLine for this item.
+        // This will recurse into children if there are any.
+
+	CreateTreeLines( 0, myPad(), *it );
+    }
+
+    NCPadWidget::DrawPad();
+}
+
+
+NCursesEvent NCTree::wHandleInput( wint_t key )
+{
+    NCursesEvent ret = NCursesEvent::none;
+    YTreeItem * oldCurrentItem = getCurrentItem();
+
+    // Call the pad's input handler via NCPadWidget::handleInput()
+    // which may call its base pad class's input handler
+    // which may call the current item's input handler.
+    //
+    // Notice that most keys are handled on the level of the pad or the item,
+    // not here. See
+    // - NCTreePad::handleInput()
+    // - NCTablePadBase::handleInput()
+    // - NCTreeLine::handleInput()
+    // - NCTableLine::handleInput()
+
+    bool handled = handleInput( key ); // NCTreePad::handleInput()
+
+    const YItem * currentItem = getCurrentItem();
+
+    if ( !currentItem )
+	return ret;
+
+    if ( _multiSelect )
+    {
+	if ( ! handled )
+	{
+	    switch ( key )
+	    {
+		// KEY_SPACE is handled in NCTreeLine::handleInput()
+
+		case KEY_RETURN:
+
+		    if ( currentItem->selected() )
+			selectItem( const_cast(currentItem), false );
+		    else
+			selectItem( const_cast(currentItem), true );
+
+		    if ( notify() )
+			return NCursesEvent::ValueChanged;
+
+		    break;
+	    }
+	}
+    }
+    else
+    {
+	if ( ! handled )
+	{
+	    switch ( key )
+	    {
+		// KEY_SPACE is handled in NCTreeLine::handleInput
+		case KEY_RETURN:
+
+		    if ( notify() )
+			return NCursesEvent::Activated;
+
+		    break;
+	    }
+	}
+
+	YTree::selectItem( const_cast( currentItem ), true );
+    }
+
+    if ( notify() && immediateMode() && ( oldCurrentItem != currentItem ) )
+	    ret = NCursesEvent::SelectionChanged;
+
+    // yuiDebug() << "Notify: " << ( notify() ? "true" : "false" )
+    // << " Return event: " << ret.reason << endl;
+
+    return ret;
+}
+
+
+void NCTree::activate()
+{
+    // Send an activation event for this widget
+
+    NCursesEvent event = NCursesEvent::Activated;
+    event.widget = this;
+    YNCursesUI::ui()->sendEvent(event);
+}
+
+
+void NCTree::deleteAllItems()
+{
+    YTree::deleteAllItems();
+    myPad()->ClearTable();
+}
+
+
+//
+// ----------------------------------------------------------------------
+//
+
+
+NCTreeLine::NCTreeLine( NCTreeLine * parentLine,
+                        YTreeItem  * item,
+                        bool         multiSelection )
+    : NCTableLine( parentLine,
+                   item,
+                   0,                         // cols
+                   item ? item->index() : -1, // idx
+                   true,                      // nested
+                   S_NORMAL )                 // lineState
+    , _multiSelect( multiSelection )
+{
+    if ( _multiSelect )
+        _prefixPlaceholder += item->selected() ? "[x] " : "[ ] ";
+
+    NCTableCol * cell = new NCTableCol( NCstring( _yitem->label() ) );
+    cell->setPrefix( prefixPlaceholder() );
+    Append( cell );
+}
+
+
+NCTreeLine::~NCTreeLine()
+{
+
+}
+
+
+bool NCTreeLine::ChangeToVisible()
+{
+    if ( isVisible() )
+        return false;   // no status change
+
+    if ( parent() )
+    {
+        // Make sure the parent is visible.
+        // This recurses upwards until the toplevel.
+
+        parent()->ChangeToVisible();
+
+
+        // Make sure this line and all siblings on this level are visible
+
+        for ( NCTreeLine * sibling = parent()->firstChild();
+              sibling;
+              sibling = sibling->nextSibling() )
+        {
+            sibling->ClearState( S_HIDDEN );
+            sibling->YItem()->setOpen( true );
+        }
+    }
+    else // No parent (i.e. this is a toplevel item)
+    {
+        // Make sure this item is visible
+
+        ClearState( S_HIDDEN );
+        YItem()->setOpen( true );
+    }
+
+    return true; // status change (the line was invisible before)
+}
+
+
+unsigned NCTreeLine::Hotspot( unsigned & at ) const
+{
+    return 6;
+}
+
+
+bool NCTreeLine::handleInput( wint_t key )
+{
+    bool handled = false;
+
+    switch ( key )
+    {
+        // At this time, there are no more special keys to handle on this
+        // level. This method is a stub for future extension if any more keys
+        // need to be handled.
+        //
+        // Add 'case KEY_XXX' branches here if there should be any
+        // and don't forget to set 'handled' to 'true'.
+#if 0
+        case KEY_SOMETHING:     // Sample
+            doSomething();
+            handled = true;
+            break;
+#endif
+
+        default: // Call parent class input handler
+            handled = NCTableLine::handleInput( key );
+            break;
+    }
+
+    return handled;
+}
+
diff --git a/deps/libyui/libyui-ncurses/src/NCTree.h b/deps/libyui/libyui-ncurses/src/NCTree.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea0df32b06e7834eb3cb1195f688d3aaba7bac1e
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTree.h
@@ -0,0 +1,319 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTree.h
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#ifndef NCTree_h
+#define NCTree_h
+
+#include 
+
+#include 
+#include "NCPadWidget.h"
+#include "NCTreePad.h"
+#include "NCTablePad.h"
+
+class NCTreeLine;
+
+/**
+ * A tree selection widget with one-column tree items and optionally multy
+ * selection.
+ *
+ * See also
+ * https://github.com/libyui/libyui-ncurses/blob/master/doc/nctable-and-nctree.md
+ **/
+class NCTree : public YTree, public NCPadWidget
+{
+    friend std::ostream & operator<<( std::ostream & str, const NCTree & obj );
+
+public:
+
+    NCTree( YWidget *           parent,
+            const std::string & label,
+            bool                multiselection     = false,
+            bool                recursiveselection = false );
+
+    virtual ~NCTree();
+
+    /**
+     * Recursively build the tree in this widget according to the items.
+     *
+     * Implemented from YTree.
+     **/
+    virtual void rebuildTree();
+
+    /**
+     * Return a pointer to the current item (the item under the cursor).
+     **/
+    virtual YTreeItem * getCurrentItem() const;
+
+    /**
+     * Get the current item. This is an alias for getCurrentItem.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual YTreeItem * currentItem();
+
+    virtual void deselectAllItems();
+
+    /**
+     * Select or deselect an item.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void selectItem( YItem *item, bool selected );
+
+    /**
+     * Select the item with the specified index.
+     **/
+    virtual void selectItem( int index );
+
+    /**
+     * Delete all items and clear the TreePad.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void deleteAllItems();
+
+    /**
+     * libyui geometry management:
+     * Return the preferred width for this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual int preferredWidth();
+
+    /**
+     * libyui geometry management:
+     * Return the preferred height for this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual int preferredHeight();
+
+    /**
+     * libyui geometry management:
+     * Apply the width and height assigned from the parent layout widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void setSize( int newWidth, int newHeight );
+
+    /**
+     * Set the label (the caption) above the tree.
+     *
+     * Implemented from YTree.
+     **/
+    virtual void setLabel( const std::string & nlabel );
+
+    /**
+     * Enable or disable this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void setEnabled( bool do_bv );
+
+    /**
+     * Set the keyboard focus to this widget.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual bool setKeyboardFocus()
+    {
+	if ( !grabFocus() )
+	    return YWidget::setKeyboardFocus();
+
+	return true;
+    }
+
+    /**
+     * Activate the item selected in the tree.
+     * This can be used in tests to simulate user input.
+     *
+     * Implemented from YSelectionWidget.
+     **/
+    virtual void activate();
+
+    /**
+     * Keyboard input handler.
+     *
+     * Implemented from NCWidget.
+     **/
+    virtual NCursesEvent wHandleInput( wint_t key );
+
+
+protected:
+
+    /**
+     * Code location for logging.
+     *
+     * Implemented from NCWidget.
+     **/
+    virtual const char * location() const { return "NCTree"; }
+
+    /**
+     * Create an empty pad.
+     **/
+    virtual NCPad * CreatePad();
+
+    /**
+     * Return the TreePad that belongs to this widget.
+     *
+     * Overloaded from NCPadWidget to narrow the type to the actual one used in
+     * this widget.
+     **/
+    virtual NCTreePad * myPad() const
+        { return dynamic_cast( NCPadWidget::myPad() ); }
+
+    /**
+     * Fill the TreePad with lines (using CreateTreeLines to create them)
+     **/
+    virtual void DrawPad();
+
+
+    /**
+     * Return a const pointer to the tree line at the specified index for
+     * read-only operations.
+     **/
+    const NCTreeLine * getTreeLine( unsigned idx ) const;
+
+    /**
+     * Return a non-const pointer to the tree line at the specified index for
+     * read-write operations. This also marks that line as "dirty", i.e. it
+     * needs to be updated on the screen.
+     **/
+    NCTreeLine * modifyTreeLine( unsigned idx );
+
+    /**
+     * Optimization for NCurses from libyui:
+     * Notification that multiple changes are about to come.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void startMultipleChanges() { startMultidraw(); }
+
+    /**
+     * Optimization for NCurses from libyui:
+     * Notification that multiple changes are now finished.
+     *
+     * Implemented from YWidget.
+     **/
+    virtual void doneMultipleChanges()	{ stopMultidraw(); }
+
+    /**
+     * Create TreeLines and append them to the TreePad.
+     * If 'item' has any children, this is called recursively for them.
+     **/
+    void CreateTreeLines( NCTreeLine * parentLine,
+                          NCTreePad  * pad,
+                          YItem      * item );
+
+private:
+
+    // Disable unwanted assignment operator and copy constructor
+
+    NCTree & operator=( const NCTree & );
+    NCTree( const NCTree & );
+
+
+    //
+    // Data members
+    //
+
+    bool _multiSelect;
+    int  _nextItemIndex; // Only used in CreateTreeLines()
+};
+
+
+/**
+ * One line in a tree widdget.
+ *
+ * This is just a very thin wrapper around NCTableLine which provides most of
+ * the functionality.
+ *
+ * Notice that on the libyui level, the inheritance hierarchy is
+ *   YTableItem < YTreeItem < YItem
+ * whereas on the libyui-ncurses level, it is
+ *  NCTreeLine < NCTableLine
+ * i.e. just the other way round.
+ **/
+class NCTreeLine : public NCTableLine
+{
+public:
+
+    NCTreeLine( NCTreeLine * parentLine,
+                YTreeItem  * origItem,
+                bool         multiSelection );
+
+    virtual ~NCTreeLine();
+
+public:
+
+    /**
+     * Return the corresponding YTreeItem.
+     **/
+    YTreeItem * YItem() const { return dynamic_cast( _yitem ); }
+
+    /**
+     * Change a line that may have been invisible until now to be visible.
+     *
+     * This also makes the parent lines (and its parent line until the
+     * toplevel) visible as well as all sibling lines of this line.
+     *
+     * Return 'true' if there was a status change, i.e. if it was invisible
+     * before, 'false' otherwise.
+     *
+     * Reimplemented from NCTableLine.
+     **/
+    virtual bool ChangeToVisible();
+
+    virtual unsigned Hotspot( unsigned & at ) const;
+
+    /**
+     * Handle keyboard input. Return 'true' if the key event is handled,
+     * 'false' to propagate it up to the pad.
+     **/
+    virtual bool handleInput( wint_t key );
+
+
+    //
+    // Some covariants of the tree operations returning this derived class
+    //
+
+    virtual NCTreeLine * parent()      const { return dynamic_cast( _parent      ); }
+    virtual NCTreeLine * firstChild()  const { return dynamic_cast( _firstChild  ); }
+    virtual NCTreeLine * nextSibling() const { return dynamic_cast( _nextSibling ); }
+
+
+private:
+
+    //
+    // Data members
+    //
+
+    bool _multiSelect;
+};
+
+
+#endif // NCTree_h
diff --git a/deps/libyui/libyui-ncurses/src/NCTreePad.cc b/deps/libyui/libyui-ncurses/src/NCTreePad.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e771769c116adcb737bb1b393749db8b891d8d3f
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTreePad.cc
@@ -0,0 +1,123 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTreePad.cc
+
+   Authors:    Michael Andres 
+               Stefan Hundhammer 
+
+/-*/
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCTreePad.h"
+
+
+
+NCTreePad::NCTreePad( int lines, int cols, const NCWidget & p )
+    : NCTablePadBase( lines, cols, p )
+{
+}
+
+
+NCTreePad::~NCTreePad()
+{
+}
+
+
+void NCTreePad::Destwin( NCursesWindow * dwin )
+{
+    NCPad::Destwin( dwin );
+
+    if ( destwin )
+    {
+	maxspos.L = visibleLines() > (unsigned) srect.Sze.H ? visibleLines() - srect.Sze.H : 0;
+    }
+}
+
+
+void NCTreePad::ShowItem( const NCTableLine * item )
+{
+    if ( !item )
+	return;
+
+    if ( const_cast( item )->ChangeToVisible() || _dirtyFormat )
+	UpdateFormat();
+
+    for ( unsigned i = 0; i < visibleLines(); ++i )
+    {
+	if ( _visibleItems[i] == item )
+	{
+	    setpos( wpos( i, srect.Pos.C ) );
+	    break;
+	}
+    }
+}
+
+
+int NCTreePad::DoRedraw()
+{
+    if ( !NCPad::Destwin() )
+    {
+	dirty = true;
+	return OK;
+    }
+
+    prepareRedraw();
+    drawContentLines();
+    drawHeader();
+
+    dirty = false;
+
+    return update();
+}
+
+
+bool NCTreePad::handleInput( wint_t key )
+{
+    bool handled = false;
+
+    switch ( key )
+    {
+        // At this time, there are no more special keys to handle on this
+        // level. This method is a stub for future extension if any more keys
+        // need to be handled.
+        //
+        // Add 'case KEY_XXX' branches here if there should be any
+        // and don't forget to set 'handled' to 'true'.
+#if 0
+        case KEY_SOMETHING:     // Sample
+            doSomething();
+            handled = true;
+            break;
+#endif
+
+        default: // Call parent class input handler
+
+            // This also calls currentItemHandleInput() as the first thing it
+            // does to forward key presses to the item at the current cursor
+            // position. Many operations such as opening, closing or selecting
+            // an item are done on that level.
+            handled = NCTablePadBase::handleInput( key );
+            break;
+    }
+
+    return handled;
+}
+
diff --git a/deps/libyui/libyui-ncurses/src/NCTreePad.h b/deps/libyui/libyui-ncurses/src/NCTreePad.h
new file mode 100644
index 0000000000000000000000000000000000000000..951ebf6eb996a7696f443814cbd0652ccf56af26
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCTreePad.h
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2020 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCTreePad.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCTreePad_h
+#define NCTreePad_h
+
+#include 
+#include 
+
+#include "NCTableItem.h"
+#include "NCTablePadBase.h"
+#include "NCstring.h"
+
+class NCTableLine;
+class NCTableCol;
+
+
+/**
+ * An NCPad for an NCTree.
+ *
+ * Most of its former functionality is now handled in the NCTablePadBase base
+ * class.
+ *
+ * See also
+ * https://github.com/libyui/libyui-ncurses/blob/master/doc/nctable-and-nctree.md
+ **/
+class NCTreePad : public NCTablePadBase
+{
+public:
+
+    NCTreePad( int lines, int cols, const NCWidget & p );
+    virtual ~NCTreePad();
+
+    void ShowItem( const NCTableLine * item );
+
+    virtual void Destwin( NCursesWindow * dwin );
+
+    /**
+     * Handle a keyboard input event. Return 'true' if the event is now
+     * handled, 'false' if it should be propagated to the parent widget.
+     *
+     * Most of the keys are now handled in the NCTablePadBase base class or in
+     * the individual items' handlers (NCTreeLine, NCTableLine). This method
+     * is mostly here as a stub for future extensions.
+     *
+     * Reimplemented from NCTablePadBase and NCPad.
+     **/
+    virtual bool handleInput( wint_t key );
+
+
+protected:
+
+    /**
+     * Redraw the pad.
+     *
+     * Reimplemented from NCTablePadBase and NCPad.
+     **/
+    virtual int DoRedraw();
+
+
+private:
+
+    NCTreePad & operator=( const NCTreePad & );
+    NCTreePad( const NCTreePad & );
+};
+
+
+#endif // NCTreePad_h
diff --git a/deps/libyui/libyui-ncurses/src/NCWidget.cc b/deps/libyui/libyui-ncurses/src/NCWidget.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7db157c39f82e168d4e4922ba3713bd2cdfca540
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCWidget.cc
@@ -0,0 +1,586 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCWidget.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#include 
+
+#define	 YUILogComponent "ncurses"
+#include 
+#include "tnode.h"
+#include "NCWidget.h"
+#include 
+
+
+NCWidget::NCWidget( YWidget * parent )
+    : tnode( this )
+    , magic( YWIDGET_MAGIC )
+    , grabedBy( 0 )
+    , win( 0 )
+    , defsze( 11, 45 )
+    , framedim( 0, 0 )
+    , inparent( -1, -1 )
+    , noUpdates( false )
+    , skipNoDimWin( true )
+    , wstate( NC::WSnormal )
+    , hotlabel( 0 )
+{
+    NCWidget * myparent = dynamic_cast( parent );
+
+    if ( myparent )
+    {
+	ReparentTo( *myparent );
+
+	// yuiDebug() <<  "CCC " << this << " parent " << myparent << std::endl;
+    }
+}
+
+
+NCWidget::NCWidget( NCWidget * myparent )
+    : tnode( this )
+    , magic( YWIDGET_MAGIC )
+    , grabedBy( 0 )
+    , win( 0 )
+    , defsze( 11, 45 )
+    , framedim( 0, 0 )
+    , inparent( -1, -1 )
+    , noUpdates( false )
+    , skipNoDimWin( true )
+    , wstate( NC::WSnormal )
+    , hotlabel( 0 )
+{
+    if ( myparent )
+    {
+	ReparentTo( *myparent );
+    }
+
+    // yuiDebug() <<  "CCC " << this << " parent " << myparent << std::endl;
+}
+
+
+
+NCWidget::~NCWidget()
+{
+    // yuiDebug() << "DD+ " << this << std::endl;
+    wDelete();
+
+    while ( Fchild() )
+	Fchild()->Disconnect();
+
+    Disconnect();
+
+    invalidate();
+
+    // yuiDebug() << "DD- " << this << std::endl;
+}
+
+
+
+
+void NCWidget::PreDisconnect()
+{
+    grabRelease( 0 );
+}
+
+
+
+void NCWidget::PostDisconnect()
+{}
+
+
+
+void NCWidget::PreReparent()
+{}
+
+
+
+void NCWidget::PostReparent()
+{}
+
+
+
+bool NCWidget::grabFocus()
+{
+    return Top().Value()->wantFocus( *this );
+}
+
+
+
+// Actualy perform sreen update.
+void NCWidget::wUpdate( bool forced_br )
+{
+    if ( !win )
+	return;
+
+    if ( noUpdates && !forced_br )
+	return;
+
+    NCurses::Update();
+}
+
+
+
+// Redirect Update request to topmost widget
+void NCWidget::Update()
+{
+    if ( noUpdates )
+	return;
+
+    if ( Parent() )
+    {
+	Parent()->Value()->Update();
+    }
+    else
+    {
+	wUpdate();
+    }
+}
+
+
+
+NCursesWindow * NCWidget::ParentWin()
+{
+    if ( !Parent() )
+    {
+	return 0;
+    }
+
+    return Parent()->Value()->win;
+}
+
+
+
+void NCWidget::wMoveChildTo( NCWidget & child, const wpos & newpos )
+{
+    // yuiDebug() << "mc+ " << DLOC << child << " -> " << newpos << " in " << this << std::endl;
+
+    try
+    {
+	child.wMoveTo( newpos );
+	Redraw( true );
+    }
+    catch ( NCursesError & err )
+    {
+	yuiError() << DLOC << child << " -> " << newpos << " in " << this << std::endl;
+	yuiError() << err << std::endl;
+	::endwin();
+	abort();
+    }
+
+    // yuiDebug() << "mc- " << DLOC << child << std::endl;
+}
+
+
+
+void NCWidget::wRelocate( const wrect & newrect )
+{
+    // yuiDebug() << "rl+ " << this << " -> " << newrect << std::endl;
+
+    try
+    {
+	if ( win )
+	{
+	    wDelete();
+	}
+
+	wCreate( newrect );
+	SetState( wstate, true );
+    }
+    catch ( NCursesError & err )
+    {
+	yuiError() << *this << std::endl;
+	yuiError() << err << std::endl;
+	::endwin();
+	abort();
+    }
+
+    // yuiDebug() << "rl- " << this << std::endl;
+}
+
+
+
+void NCWidget::wMoveTo( const wpos & newpos )
+{
+    if ( !win )
+    {
+	// yuiDebug() << "No win to move: " << this << " -> " << newpos << std::endl;
+	return;
+    }
+
+    if ( !Parent() )
+	throw NCError( "wMoveTo: got no parent" );
+
+    if ( skipNoDimWin && inparent.Sze.H == 0 )
+    {
+	// yuiDebug() << "Skip widget with zero height: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+	return;
+    }
+
+    if ( skipNoDimWin && inparent.Sze.W == 0 )
+    {
+	// yuiDebug() << "Skip widget with zero width: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+	return;
+    }
+
+    if ( inparent.Pos != newpos )
+    {
+	// yuiDebug() << "mv+ " << this << " -> " << newpos << " par " << Parent()->Value() << std::endl;
+	NCWidget & p( *Parent()->Value() );
+	p.win->mvsubwin( win,
+			 newpos.L + Parent()->Value()->framedim.Pos.L,
+			 newpos.C + Parent()->Value()->framedim.Pos.C );
+	inparent.Pos = newpos;
+	// yuiDebug() << "mv- " << this << std::endl;
+    }
+}
+
+
+
+void NCWidget::wCreate( const wrect & newrect )
+{
+    if ( win )
+	throw NCError( "wCreate: already have win" );
+
+    if ( !Parent() )
+	throw NCError( "wCreate: got no parent" );
+
+    inparent = newrect;
+
+    if ( skipNoDimWin && inparent.Sze == wsze( 0, 0 ) )
+    {
+	// yuiDebug() << "Skip nodim widget: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+	return;
+    }
+
+    if ( skipNoDimWin && inparent.Sze.H == 0 )
+    {
+	// yuiDebug() << "Skip widget with zero height: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+	return;
+    }
+
+    if ( skipNoDimWin && inparent.Sze.W == 0 )
+    {
+	// yuiDebug() << "Skip widget with zero width: " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+	return;
+    }
+
+    NCursesWindow * parw = ParentWin();
+
+    if ( Parent() && !parw )
+    {
+	yuiError() << "Can't create widget in nodim parent: " << this
+                   << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+	inparent.Sze = wsze( 0, 0 );
+	return;
+    }
+
+    // yuiDebug() << "cw+ " << this << ' ' << inparent << " par " << Parent()->Value() << std::endl;
+
+    if ( parw )
+    {
+	try
+	{
+	    win = new NCursesWindow( *parw,
+				     inparent.Sze.H, inparent.Sze.W,
+				     inparent.Pos.L + Parent()->Value()->framedim.Pos.L,
+				     inparent.Pos.C + Parent()->Value()->framedim.Pos.C,
+				     'r' );
+	}
+	catch ( ... )
+	{
+	    try
+	    {
+		win = new NCursesWindow( *parw,
+					 inparent.Sze.H, inparent.Sze.W,
+					 inparent.Pos.L,
+					 inparent.Pos.C,
+					 'r' );
+	    }
+	    catch ( ... )
+	    {
+		inparent.Sze = wsze( 1, 1 );
+		inparent.Pos = wpos( 0, 0 );
+		win = new NCursesWindow( *parw, 1, 1, 0, 0, 'r' );
+	    }
+	}
+    }
+    else
+    {
+	win = new NCursesWindow( inparent.Sze.H, inparent.Sze.W,
+				 inparent.Pos.L, inparent.Pos.C );
+    }
+
+    // yuiDebug() << "cw- " << this << ' ' << inparent << std::endl;
+}
+
+
+
+void NCWidget::wDelete()
+{
+    if ( win )
+    {
+	// yuiDebug() << "wd+ " << this << std::endl;
+
+	for ( tnode * ch = Fchild(); ch; ch = ch->Nsibling() )
+	{
+	    ch->Value()->wDelete();
+	}
+
+	win->clear();
+
+	delete win;
+	win = 0;
+	inparent = wrect( -1, -1 );
+	// yuiDebug() << "wd- " << this << std::endl;
+    }
+}
+
+
+
+wpos NCWidget::ScreenPos() const
+{
+    if ( !win )
+	return -1;
+
+    if ( Parent() )
+    {
+	return Parent()->Value()->ScreenPos() + inparent.Pos;
+    }
+
+    return wsze( win->begy(), win->begx() );
+}
+
+
+
+void NCWidget::SetState( const NC::WState newstate, bool force )
+{
+    if ( newstate != wstate || force )
+    {
+	// yuiDebug() << DLOC << wstate << " -> " << newstate << std::endl;
+	wstate = newstate;
+
+	if ( win )
+	{
+	    win->bkgd( wStyle().getWidget( wstate ).plain );
+	}
+
+	Redraw();
+    }
+}
+
+
+
+void NCWidget::setEnabled( bool do_bv )
+{
+    // yuiDebug() << DLOC << this << ' ' << do_bv << ' ' << wstate << std::endl;
+
+    tnode *c = this;
+
+    // If widget has children ([HV]Boxes, alignments,...), disable all of
+    // them recursively (#256707).
+
+    if ( c->HasChildren() )
+    {
+	yuiDebug() <<  this << "setEnabled children recursively" << std::endl;
+
+	for ( c = this->Next();
+	      c && c->IsDescendantOf( this );
+	      c = c->Next() )
+	{
+	    if ( c->Value()->GetState() != NC::WSdumb )
+		c->Value()->setEnabled( do_bv );
+	}
+    }
+
+    else
+    {
+	if ( wstate == NC::WSdumb )
+	    return;
+
+	if ( do_bv && wstate == NC::WSdisabled )
+	{
+	    SetState( NC::WSnormal );
+	}
+	else if ( !do_bv && wstate != NC::WSdisabled )
+	{
+	    if ( wstate == NC::WSactive )
+		grabRelease( 0 );
+
+	    SetState( NC::WSdisabled );
+	}
+    }
+}
+
+
+
+void NCWidget::Redraw( bool sub )
+{
+    if ( !win )
+    {
+	return;
+    }
+
+    bool savNoUpdates = noUpdates;
+
+    noUpdates = true;
+
+    if ( sub )
+    {
+	win->clear();
+	wRedraw();
+
+	for ( tnode * ch = Fchild(); ch; ch = ch->Nsibling() )
+	{
+	    ch->Value()->Redraw( sub );
+	}
+    }
+    else
+    {
+	wRedraw();
+    }
+
+    noUpdates = savNoUpdates;
+
+    Update();
+}
+
+
+
+void NCWidget::wRedraw()
+{
+}
+
+
+
+void NCWidget::Recoded()
+{
+    if ( !win )
+    {
+	return;
+    }
+
+    bool savNoUpdates = noUpdates;
+
+    noUpdates = true;
+    wRecoded();
+
+    for ( tnode * ch = Fchild(); ch; ch = ch->Nsibling() )
+    {
+	ch->Value()->Recoded();
+    }
+
+    noUpdates = savNoUpdates;
+
+    Update();
+}
+
+
+
+void NCWidget::wRecoded()
+{
+    wRedraw();
+}
+
+
+
+bool NCWidget::HasHotkey( int key )
+{
+    if ( key < 0 || UCHAR_MAX < key )
+	return false;
+
+    if ( !( hotlabel && hotlabel->hasHotkey() ) )
+	return false;
+
+    return( tolower( key ) == tolower( hotlabel->hotkey() ) );
+}
+
+
+
+bool NCWidget::HasFunctionHotkey( int key ) const
+{
+    const YWidget * w = dynamic_cast( this );
+
+    if ( w )
+    {
+	if ( key < 0 || ( ! w->hasFunctionKey() ) )
+	    return false;
+
+	return( key == KEY_F( w->functionKey() ) );
+    }
+    else
+    {
+	yuiError() << "No YWidget" << std::endl;
+	return false;
+    }
+}
+
+
+
+NCursesEvent NCWidget::wHandleHotkey( wint_t /*key*/ )
+{
+    return wHandleInput( KEY_HOTKEY );
+}
+
+
+
+NCursesEvent NCWidget::wHandleInput( wint_t /*key*/ )
+{
+    return NCursesEvent::none;
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCWidget * obj )
+{
+    if ( obj && obj->isValid() )
+	return str << *obj;
+
+    return str << "(NoNCWidget)";
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCWidget & obj )
+{
+    if ( obj.isValid() )
+	return str << obj.location() << ( void* )&obj
+	       << '(' << obj.win
+	       << ' ' << obj.inparent
+	       << ' ' << obj.wstate
+	       << ')';
+
+    return str << "( invalid NCWidget)";
+}
+
+
+
+void NCWidget::DumpOn( std::ostream & str, std::string prfx ) const
+{
+    str
+    //<< prfx << "|" << std::endl
+    << prfx << "+-" << this << std::endl;
+    prfx += ( Nsibling() ? "| " : "  " );
+
+    for ( const tnode * ch = Fchild(); ch; ch = ch->Nsibling() )
+    {
+	ch->Value()->DumpOn( str, prfx );
+    }
+}
+
diff --git a/deps/libyui/libyui-ncurses/src/NCWidget.h b/deps/libyui/libyui-ncurses/src/NCWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b1825c9d3a04afce30db1ab25861a4c34f35409
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCWidget.h
@@ -0,0 +1,191 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCWidget.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCWidget_h
+#define NCWidget_h
+
+
+#include 
+
+#include "NCurses.h"
+#include "tnode.h"
+
+class NCursesWindow;
+class NClabel;
+
+
+#define DLOC location() << ' '
+
+#define YWIDGET_MAGIC	42
+
+// debug option: enable verbose event logging
+#define VERBOSE_EVENTS 0
+
+class NCWidget : public tnode, protected NCursesError
+{
+private:
+
+    friend std::ostream & operator<<( std::ostream & str, const NCWidget & obj );
+    friend std::ostream & operator<<( std::ostream & str, const NCWidget * obj );
+
+    NCWidget & operator=( const NCWidget & );
+    NCWidget( const NCWidget & );
+
+
+    /**
+     * Make this widget invalid. This operation cannot be reversed.
+     */
+    void invalidate() { magic = 0; }
+
+    /**
+     * This object is only valid if this magic number is YWIDGET_MAGIC.
+     */
+    int magic;
+
+protected:
+
+    virtual const char * location() const { return "NCWidget"; }
+
+    virtual void PreDisconnect();
+    virtual void PostDisconnect();
+    virtual void PreReparent();
+    virtual void PostReparent();
+
+    NCursesWindow * ParentWin();
+
+    NCWidget *const grabedBy;
+    bool grabFocus();
+    virtual void grabNotify( NCWidget * ) {}
+
+    virtual bool wantFocus( NCWidget & ngrab ) { return false; }
+
+public:
+
+    void grabSet( NCWidget * ngrab )
+    {
+	if ( grabedBy && grabedBy != ngrab )
+	    grabedBy->grabNotify( this );
+
+	const_cast( grabedBy ) = ngrab;
+    }
+
+    void grabRelease( NCWidget * ograb )
+    {
+	if ( grabedBy && grabedBy != ograb )
+	    grabedBy->grabNotify( this );
+
+	const_cast( grabedBy ) = 0;
+    }
+
+protected:
+
+    NCursesWindow * win;        ///< (owned)
+    wsze	    defsze;
+    wrect	    framedim;
+    wrect	    inparent;
+    bool	    noUpdates;
+    bool	    skipNoDimWin;
+
+    void wMoveChildTo( NCWidget & child, const wpos & newpos );
+    void wRelocate( const wrect & newrect );
+    void wRelocate( const wpos & newpos, const wsze & newsze )
+    {
+	wRelocate( wrect( newpos, newsze ) );
+    }
+
+    virtual void wCreate( const wrect & newrect );
+    virtual void wMoveTo( const wpos & newpos );
+    virtual void wDelete();
+    virtual void wUpdate( bool forced_br = false );
+
+    wpos ScreenPos() const;
+
+    NC::WState wstate;
+
+    virtual void wRedraw();
+    virtual void wRecoded();
+
+    NClabel * hotlabel;
+
+public:
+
+    NCWidget( NCWidget * myparent );
+    NCWidget( YWidget * parent = 0 );
+    virtual ~NCWidget();
+
+    bool isValid() const	{ return magic == YWIDGET_MAGIC; }
+
+    bool winExist() const	{ return win != ( NCursesWindow * )0; }
+
+    virtual const NCstyle::Style & wStyle() const
+    {
+	if ( Parent() )
+	    return Top().Value()->wStyle();
+
+	return NCurses::style()[NCstyle::DefaultStyle];
+    }
+
+    const NCstyle::StWidget & widgetStyle( bool nonactive = false ) const
+	{ return wStyle().getWidget( GetState(), nonactive ); }
+
+    const NCstyle::StWidget & frameStyle()  const
+	{ return wStyle().getFrame( GetState() ); }
+
+    const NCstyle::StList   & listStyle()   const
+	{ return wStyle().getList( GetState() ); }
+
+    wsze wGetDefsze() const { return defsze; }
+
+    wrect wGetSize() const { return inparent; }
+
+    void Update();
+    void Redraw( bool sub = false );
+    void Recoded();
+
+    NC::WState GetState() const { return wstate; }
+
+    void SetState( const NC::WState newstate, bool force = false );
+
+    /**
+     * Pure virtual to make sure every widget implements it. Necessary to make
+     * sure that UI requests via YWidget::setEnabled perform, and behave the
+     * same way as direct calls to NCWidget::setEnabled.
+     **/
+    virtual void setEnabled( bool do_bv ) = 0;
+
+    virtual bool HasHotkey( int key );
+    virtual bool HasFunctionHotkey( int key ) const;
+
+    virtual NCursesEvent wHandleHotkey( wint_t key );
+    virtual NCursesEvent wHandleInput( wint_t key );
+
+    void DumpOn( std::ostream & str, std::string prfx ) const;
+};
+
+
+#include "NCstring.h"
+#include "NCtext.h"
+
+
+#endif // NCWidget_h
diff --git a/deps/libyui/libyui-ncurses/src/NCWidgetFactory.cc b/deps/libyui/libyui-ncurses/src/NCWidgetFactory.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bd5dada05da61e0bdb53c832b7f0e193d71ff2db
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCWidgetFactory.cc
@@ -0,0 +1,435 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2019 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+  File:		NCWidgetFactory.cc
+
+  Authors:	Stefan Hundhammer 
+		Gabriele Mohr 
+
+/-*/
+
+#include "NCWidgetFactory.h"
+#include 
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "YNCursesUI.h"
+
+#include 
+
+
+NCWidgetFactory::NCWidgetFactory()
+    : YWidgetFactory()
+{
+    // NOP
+}
+
+
+NCWidgetFactory::~NCWidgetFactory()
+{
+    // NOP
+}
+
+
+
+
+//
+// Dialogs
+//
+
+NCDialog *
+NCWidgetFactory::createDialog( YDialogType dialogType, YDialogColorMode colorMode )
+{
+    // yuiDebug() << "Flush input buffer - new dialog" << std::endl;
+    ::flushinp();
+
+    NCDialog * dialog = new NCDialog( dialogType, colorMode );
+    YUI_CHECK_NEW( dialog );
+
+    return dialog;
+}
+
+
+//
+// Common Leaf Widgets
+//
+
+NCPushButton *
+NCWidgetFactory::createPushButton( YWidget * parent, const std::string & label )
+{
+    NCPushButton * pushButton = new NCPushButton( parent, label );
+    YUI_CHECK_NEW( pushButton );
+
+    return pushButton;
+}
+
+
+
+NCLabel *
+NCWidgetFactory::createLabel( YWidget *		parent,
+			      const std::string &	text,
+			      bool		isHeading,
+			      bool		isOutputField )
+{
+    NCLabel * label = new NCLabel( parent, text, isHeading, isOutputField );
+    YUI_CHECK_NEW( label );
+
+    return label;
+}
+
+
+NCInputField *
+NCWidgetFactory::createInputField( YWidget * parent, const std::string & label, bool passwordMode )
+{
+    NCInputField * inputField = new NCInputField( parent, label, passwordMode );
+    YUI_CHECK_NEW( inputField );
+
+    return inputField;
+}
+
+
+NCCheckBox *
+NCWidgetFactory::createCheckBox( YWidget * parent, const std::string & label, bool isChecked )
+{
+    NCCheckBox * checkBox = new NCCheckBox( parent, label, isChecked );
+    YUI_CHECK_NEW( checkBox );
+
+    return checkBox;
+}
+
+
+NCRadioButton *
+NCWidgetFactory::createRadioButton( YWidget * parent, const std::string & label, bool checked )
+{
+    NCRadioButton * radioButton = new NCRadioButton( parent, label, checked );
+    YUI_CHECK_NEW( radioButton );
+
+    // Register radio button with its button group.
+    // This has to be done after all constructors are done so virtual functions
+    // can be used.
+
+    if ( radioButton->buttonGroup() )
+	radioButton->buttonGroup()->addRadioButton( radioButton );
+
+    return radioButton;
+}
+
+
+NCComboBox *
+NCWidgetFactory::createComboBox( YWidget * parent, const std::string & label, bool editable	)
+{
+    NCComboBox * comboBox = new NCComboBox( parent, label, editable );
+    YUI_CHECK_NEW( comboBox );
+
+    return comboBox;
+}
+
+
+NCSelectionBox *
+NCWidgetFactory::createSelectionBox( YWidget * parent, const std::string & label )
+{
+    NCSelectionBox * selectionBox = new NCSelectionBox( parent, label );
+    YUI_CHECK_NEW( selectionBox );
+
+    return selectionBox;
+}
+
+
+NCTree *
+NCWidgetFactory::createTree( YWidget * parent, const std::string & label, bool multiselection, bool recursiveselection )
+{
+    NCTree * tree = new NCTree( parent, label, multiselection, recursiveselection );
+    YUI_CHECK_NEW( tree );
+
+    return tree;
+}
+
+
+NCTable *
+NCWidgetFactory::createTable( YWidget * parent, YTableHeader * tableHeader, bool multiSelection )
+{
+    NCTable *table = new NCTable( parent, tableHeader, multiSelection );
+    YUI_CHECK_NEW( table );
+
+    return table;
+}
+
+
+NCProgressBar *
+NCWidgetFactory::createProgressBar( YWidget * parent, const std::string & label, int maxValue )
+{
+    NCProgressBar * progressBar = new NCProgressBar( parent, label, maxValue );
+    YUI_CHECK_NEW( progressBar );
+
+    return progressBar;
+}
+
+
+NCBusyIndicator *
+NCWidgetFactory::createBusyIndicator( YWidget * parent, const std::string & label, int timeout)
+{
+   NCBusyIndicator * busyIndicator = new NCBusyIndicator( parent, label, timeout );
+   YUI_CHECK_NEW( busyIndicator );
+
+   return busyIndicator;
+}
+
+
+NCRichText *
+NCWidgetFactory::createRichText( YWidget * parent, const std::string & text, bool plainTextMode )
+{
+    NCRichText * richText = new NCRichText( parent, text, plainTextMode );
+    YUI_CHECK_NEW( richText );
+
+    return richText;
+}
+
+
+//
+// Less Common Leaf Widgets
+//
+
+NCIntField *
+NCWidgetFactory::createIntField( YWidget * parent, const std::string & label, int minVal, int maxVal, int initialVal )
+{
+    NCIntField * intField = new NCIntField( parent, label, minVal, maxVal, initialVal );
+    YUI_CHECK_NEW( intField );
+
+    return intField;
+}
+
+
+NCMenuButton *
+NCWidgetFactory::createMenuButton( YWidget * parent, const std::string & label )
+{
+    NCMenuButton * menuButton = new NCMenuButton( parent, label );
+    YUI_CHECK_NEW( menuButton );
+
+    return menuButton;
+}
+
+
+NCMenuBar *
+NCWidgetFactory::createMenuBar( YWidget * parent )
+{
+    NCMenuBar * menuBar = new NCMenuBar( parent );
+    YUI_CHECK_NEW( menuBar );
+
+    return menuBar;
+}
+
+
+NCMultiLineEdit *
+NCWidgetFactory::createMultiLineEdit( YWidget * parent, const std::string & label )
+{
+    NCMultiLineEdit * multiLineEdit = new NCMultiLineEdit( parent, label );
+    YUI_CHECK_NEW( multiLineEdit );
+
+    return multiLineEdit;
+}
+
+
+NCLogView *
+NCWidgetFactory::createLogView( YWidget * parent, const std::string & label, int visibleLines, int storedLines )
+{
+    NCLogView * logView = new NCLogView( parent, label, visibleLines, storedLines );
+    YUI_CHECK_NEW( logView );
+
+    return logView;
+}
+
+
+NCMultiSelectionBox *
+NCWidgetFactory::createMultiSelectionBox( YWidget * parent, const std::string & label )
+{
+    NCMultiSelectionBox * multiSelectionBox = new NCMultiSelectionBox( parent, label );
+    YUI_CHECK_NEW( multiSelectionBox );
+
+    return multiSelectionBox;
+}
+
+
+NCItemSelector *
+NCWidgetFactory::createItemSelector( YWidget * parent, bool enforceSingleSelection )
+{
+    NCItemSelector * itemSelector = new NCItemSelector( parent, enforceSingleSelection );
+    YUI_CHECK_NEW( itemSelector );
+
+    return itemSelector;
+}
+
+
+NCCustomStatusItemSelector *
+NCWidgetFactory::createCustomStatusItemSelector( YWidget * parent, const YItemCustomStatusVector & customStates )
+{
+    NCCustomStatusItemSelector * itemSelector = new NCCustomStatusItemSelector( parent, customStates );
+    YUI_CHECK_NEW( itemSelector );
+
+    return itemSelector;
+}
+
+
+
+//
+// Layout Helpers
+//
+
+NCSpacing *
+NCWidgetFactory::createSpacing( YWidget * parent, YUIDimension dim, bool stretchable, YLayoutSize_t size )
+{
+    NCSpacing * spacing = new NCSpacing( parent, dim, stretchable, size );
+    YUI_CHECK_NEW( spacing );
+
+    return spacing;
+}
+
+
+NCLayoutBox *
+NCWidgetFactory::createLayoutBox( YWidget * parent, YUIDimension dim )
+{
+    NCLayoutBox * layoutBox = new NCLayoutBox( parent, dim );
+    YUI_CHECK_NEW( layoutBox );
+
+    return layoutBox;
+}
+
+
+NCButtonBox *
+NCWidgetFactory::createButtonBox( YWidget * parent )
+{
+    NCButtonBox * buttonBox = new NCButtonBox( parent );
+    YUI_CHECK_NEW( buttonBox );
+
+    return buttonBox;
+}
+
+
+NCEmpty *
+NCWidgetFactory::createEmpty( YWidget * parent )
+{
+    NCEmpty * empty = new NCEmpty( parent );
+    YUI_CHECK_NEW( empty );
+
+    return empty;
+}
+
+
+NCAlignment *
+NCWidgetFactory::createAlignment( YWidget *	 parent,
+				  YAlignmentType horAlignment,
+				  YAlignmentType vertAlignment )
+{
+    NCAlignment * alignment = new NCAlignment( parent, horAlignment, vertAlignment );
+    YUI_CHECK_NEW( alignment );
+
+    return alignment;
+}
+
+
+NCSquash *
+NCWidgetFactory::createSquash( YWidget * parent, bool horSquash, bool vertSquash )
+{
+    NCSquash * squash = new NCSquash( parent, horSquash, vertSquash );
+    YUI_CHECK_NEW( squash );
+
+    return squash;
+}
+
+
+NCFrame *
+NCWidgetFactory::createFrame( YWidget * parent, const std::string & label )
+{
+    NCFrame * frame = new NCFrame( parent, label );
+    YUI_CHECK_NEW( frame );
+
+    return frame;
+}
+
+
+NCCheckBoxFrame *
+NCWidgetFactory::createCheckBoxFrame( YWidget *	parent, const std::string & label, bool checked )
+{
+    NCCheckBoxFrame * checkBoxFrame = new NCCheckBoxFrame( parent, label, checked );
+    YUI_CHECK_NEW( checkBoxFrame );
+
+    return checkBoxFrame;
+}
+
+
+NCRadioButtonGroup *
+NCWidgetFactory::createRadioButtonGroup( YWidget * parent )
+{
+    NCRadioButtonGroup * radioButtonGroup = new NCRadioButtonGroup( parent );
+    YUI_CHECK_NEW( radioButtonGroup );
+
+    return radioButtonGroup;
+}
+
+
+NCReplacePoint *
+NCWidgetFactory::createReplacePoint( YWidget * parent )
+{
+    NCReplacePoint * replacePoint = new NCReplacePoint( parent );
+    YUI_CHECK_NEW( replacePoint );
+
+    return replacePoint;
+}
+
+
+NCImage *
+NCWidgetFactory::createImage( YWidget * parent, const std::string & imageFileName, bool animated )
+{
+    NCImage * image = new NCImage( parent, imageFileName, animated );
+    YUI_CHECK_NEW( image );
+
+    return image;
+}
+
+
+YPackageSelector *
+NCWidgetFactory::createPackageSelector( YWidget * parent, long modeFlags )
+{
+    NCPackageSelectorPluginStub * plugin = YNCursesUI::ui()->packageSelectorPlugin();
+
+    if ( plugin )
+	return plugin->createPackageSelector( parent, modeFlags );
+    else
+	return 0;
+}
+
+
+// Creates special widgets used for the package selection dialog.
+// This is special to the NCurses UI;  there is no  a corresponding widget
+// in the Qt UI.
+YWidget *
+NCWidgetFactory::createPkgSpecial( YWidget * parent, const std::string & subwidget )
+{
+    YWidget * w = 0;
+
+    NCPackageSelectorPluginStub * plugin = YNCursesUI::ui()->packageSelectorPlugin();
+
+    if ( plugin )
+    {
+	w = plugin->createPkgSpecial( parent, subwidget );
+    }
+
+    return w;
+}
+
+
diff --git a/deps/libyui/libyui-ncurses/src/NCWidgetFactory.h b/deps/libyui/libyui-ncurses/src/NCWidgetFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..b489f5905e7af8828095bd5d4252f9103cfa0092
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCWidgetFactory.h
@@ -0,0 +1,180 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  Copyright (C) 2019 SUSE LLC
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+  File:         NCWidgetFactory.h
+
+  Author:       Gabriele Mohr 
+
+/-*/
+
+#ifndef NCWidgetFactory_h
+#define NCWidgetFactory_h
+
+
+#include 
+
+#include "NCAlignment.h"
+#include "NCBusyIndicator.h"
+#include "NCButtonBox.h"
+#include "NCCheckBox.h"
+#include "NCCheckBoxFrame.h"
+#include "NCComboBox.h"
+#include "NCCustomStatusItemSelector.h"
+#include "NCDialog.h"
+#include "NCEmpty.h"
+#include "NCFrame.h"
+#include "NCImage.h"
+#include "NCInputField.h"
+#include "NCIntField.h"
+#include "NCItemSelector.h"
+#include "NCLabel.h"
+#include "NCLogView.h"
+#include "NCMenuBar.h"
+#include "NCMenuButton.h"
+#include "NCMultiLineEdit.h"
+#include "NCMultiSelectionBox.h"
+#include "NCPackageSelectorPluginStub.h"
+#include "NCProgressBar.h"
+#include "NCPushButton.h"
+#include "NCRadioButton.h"
+#include "NCRadioButtonGroup.h"
+#include "NCReplacePoint.h"
+#include "NCRichText.h"
+#include "NCSelectionBox.h"
+#include "NCSpacing.h"
+#include "NCSquash.h"
+#include "NCTable.h"
+#include "NCTree.h"
+#include "NCLayoutBox.h"
+
+
+/**
+ * Concrete widget factory for mandatory widgets.
+ **/
+class NCWidgetFactory: public YWidgetFactory
+{
+public:
+    // Note: Using covariant return types for all createSomeWidget() methods
+    // (returning NCSomeWidget where the base class declares virtual methods that
+    // return YSomeWidget)
+
+
+    //
+    // Dialogs
+    //
+
+    virtual NCDialog *          createDialog            ( YDialogType dialogType, YDialogColorMode colorMode = YDialogNormalColor );
+
+    //
+    // Layout Boxes
+    //
+
+    virtual NCLayoutBox *       createLayoutBox         ( YWidget * parent, YUIDimension dim );
+    virtual NCButtonBox * 	createButtonBox		( YWidget * parent );
+
+
+    //
+    // Common Leaf Widgets
+    //
+
+    virtual NCPushButton *      createPushButton        ( YWidget * parent, const std::string & label );
+    virtual NCLabel *           createLabel             ( YWidget * parent, const std::string & text,  bool isHeading    = false, bool isOutputField = false );
+    virtual NCInputField *      createInputField        ( YWidget * parent, const std::string & label, bool passwordMode = false );
+    virtual NCCheckBox *        createCheckBox          ( YWidget * parent, const std::string & label, bool isChecked    = false );
+    virtual NCRadioButton *     createRadioButton       ( YWidget * parent, const std::string & label, bool isChecked    = false );
+    virtual NCComboBox *        createComboBox          ( YWidget * parent, const std::string & label, bool editable     = false );
+    virtual NCSelectionBox *    createSelectionBox      ( YWidget * parent, const std::string & label );
+    virtual NCTree *            createTree              ( YWidget * parent, const std::string & label, bool multiselection = false, bool recursiveselection = false );
+    virtual NCTable *           createTable             ( YWidget * parent, YTableHeader * tableHeader, bool multiSelection = false );
+    virtual NCProgressBar *     createProgressBar       ( YWidget * parent, const std::string & label, int maxValue = 100 );
+    virtual NCRichText *        createRichText          ( YWidget * parent, const std::string & text = std::string(), bool plainTextMode = false );
+
+
+    //
+    // Less Common Leaf Widgets
+    //
+
+    virtual NCIntField *        createIntField          ( YWidget * parent, const std::string & label, int minVal, int maxVal, int initialVal );
+    virtual NCMenuButton *      createMenuButton        ( YWidget * parent, const std::string & label );
+    virtual NCMenuBar *         createMenuBar           ( YWidget * parent );
+    virtual NCMultiLineEdit *   createMultiLineEdit     ( YWidget * parent, const std::string & label );
+    virtual NCImage *           createImage             ( YWidget * parent, const std::string & imagePath, bool animated = false );
+    virtual NCLogView *         createLogView           ( YWidget * parent, const std::string & label, int visibleLines, int storedLines = 0 );
+    virtual NCMultiSelectionBox*createMultiSelectionBox ( YWidget * parent, const std::string & label );
+    virtual YPackageSelector *  createPackageSelector   ( YWidget * parent, long ModeFlags = 0 );
+    virtual NCBusyIndicator *   createBusyIndicator     ( YWidget * parent, const std::string & label, int timeout = 1000 );
+
+    // NCurses only
+    virtual YWidget *           createPkgSpecial        ( YWidget * parent,  const std::string & subwidgetName );
+
+
+    //
+    // Layout Helpers
+    //
+
+    virtual NCSpacing *         createSpacing           ( YWidget * parent, YUIDimension dim, bool stretchable = false, YLayoutSize_t size = 0.0 );
+    virtual NCEmpty *           createEmpty             ( YWidget * parent );
+    virtual NCAlignment *       createAlignment         ( YWidget * parent, YAlignmentType horAlignment, YAlignmentType vertAlignment );
+    virtual NCSquash *          createSquash            ( YWidget * parent, bool horSquash, bool vertSquash );
+
+
+    //
+    // Visual Grouping
+    //
+
+    virtual NCFrame *           createFrame             ( YWidget * parent, const std::string & label );
+    virtual NCCheckBoxFrame *   createCheckBoxFrame     ( YWidget * parent, const std::string & label, bool checked );
+
+
+    //
+    // Logical Grouping
+    //
+
+    virtual NCRadioButtonGroup *createRadioButtonGroup  ( YWidget * parent );
+    virtual NCReplacePoint *    createReplacePoint      ( YWidget * parent );
+
+
+    //
+    // More leaf widgets (moved to the end to maintain ABI compatibility)
+    //
+
+    virtual NCItemSelector *             createItemSelector              ( YWidget * parent, bool enforceSingleSelection = true );
+    virtual NCCustomStatusItemSelector * createCustomStatusItemSelector  ( YWidget * parent, const YItemCustomStatusVector & customStates );
+
+
+protected:
+
+    friend class YNCursesUI;
+
+    /**
+     * Constructor.
+     *
+     * Use YUI::widgetFactory() to get the singleton for this class.
+     **/
+    NCWidgetFactory();
+
+    /**
+     * Destructor.
+     **/
+    virtual ~NCWidgetFactory();
+
+}; // class NCWidgetFactory
+
+
+#endif // NCWidgetFactory_h
diff --git a/deps/libyui/libyui-ncurses/src/NCWordWrapper.cc b/deps/libyui/libyui-ncurses/src/NCWordWrapper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9f29875573db0db69e251b559806e967c9a654fd
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCWordWrapper.cc
@@ -0,0 +1,293 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCWordWrapper.h
+
+   Author:     Stefan Hundhammer 
+
+/-*/
+
+
+#include 
+#include 
+#include "NCWordWrapper.h"
+
+
+#define DEFAULT_LINE_WIDTH      78
+
+using std::wstring;
+using std::endl;
+using std::wcout;
+
+
+NCWordWrapper::NCWordWrapper():
+    _lineWidth( DEFAULT_LINE_WIDTH ),
+    _lines( 0 ),
+    _dirty( false )
+{
+
+}
+
+
+void NCWordWrapper::setText( const wstring & origText )
+{
+    if ( origText != _origText )
+    {
+        _origText = origText;
+        _dirty = true;
+    }
+}
+
+
+void NCWordWrapper::setLineWidth( int width )
+{
+    if ( width != _lineWidth )
+    {
+        _lineWidth = width;
+        _dirty = true;
+    }
+}
+
+
+void NCWordWrapper::clear()
+{
+    _origText.clear();
+    _wrappedText.clear();
+    _lineWidth = DEFAULT_LINE_WIDTH;
+    _lines = 0;
+    _dirty = false;
+}
+
+
+int NCWordWrapper::lines()
+{
+    ensureWrapped();
+
+    return _lines;
+}
+
+
+const wstring & NCWordWrapper::wrappedText()
+{
+    ensureWrapped();
+
+    return _wrappedText;
+}
+
+
+void NCWordWrapper::ensureWrapped()
+{
+    if ( _dirty )
+        wrap();
+
+    _dirty = false;
+}
+
+
+wstring NCWordWrapper::normalizeWhitespace( const wstring & orig )
+{
+    wstring normalized;
+    normalized.reserve( orig.size() );
+    bool skippingWhitespace = false;
+
+    for ( wchar_t c: orig )
+    {
+        switch ( c )
+        {
+	    case L' ':  // Whitespace
+	    case L'\t':
+	    case L'\n':
+	    case L'\v':
+	    case L'\r':
+            case L'\f':
+                // Don't add any whitespace right now: Wait until there is real content.
+
+                if ( ! normalized.empty() ) // Ignore any leading whitspace
+                    skippingWhitespace = true;
+                break;
+
+            default:    // Non-whitespace
+
+                // Add one blank for any skipped whitespace.
+                //
+                // This will not add trailing whitespace which is exactly the
+                // desired behaviour.
+
+                if ( skippingWhitespace )
+                    normalized += ' ';
+
+                normalized += c;
+                skippingWhitespace = false;
+                break;
+        }
+    }
+
+    return normalized;
+}
+
+
+void NCWordWrapper::wrap()
+{
+    wstring unwrapped = normalizeWhitespace( _origText );
+    _wrappedText.clear();
+    _wrappedText.reserve( unwrapped.size() );
+    _lines = 0;
+
+    while ( ! unwrapped.empty() )
+    {
+        wstring line = nextLine( unwrapped );
+
+#ifdef WORD_WRAPPER_TESTER
+        wcout << "Line: \"" << line << "\"  length: " << line.size() << endl;
+        wcout << "Rest: \"" << unwrapped << "\"\n" << endl;
+#endif
+
+        if ( ! _wrappedText.empty() )
+            _wrappedText += L'\n';
+
+        _wrappedText += line;
+        _lines++;
+    }
+
+    _dirty = false;
+}
+
+
+wstring NCWordWrapper::nextLine( wstring & unwrapped )
+{
+    wstring line;
+
+#ifdef WORD_WRAPPER_TESTER
+    wcout << "nextLine( \"" << unwrapped << "\" )" << endl;
+#endif
+
+    if ( (int) unwrapped.size() <= _lineWidth )
+    {
+        // The remaining unwrapped text fits into one line
+
+        line = unwrapped;
+        unwrapped.clear();
+
+        return line;
+    }
+
+
+    // Try to wrap at the rightmost possible whitespace
+
+    int pos = _lineWidth; // The whitespace will be removed here
+
+    while ( pos > 0 && unwrapped[ pos ] != L' ' )
+        --pos;
+
+    if ( unwrapped[ pos ] == L' ' )
+    {
+        line = unwrapped.substr( 0, pos );
+        unwrapped.erase( 0, pos + 1 );
+
+        return line;
+    }
+
+
+    // Try to wrap at the rightmost possible non-alphanum character
+
+    pos = _lineWidth - 1; // We'll need to keep the separator character
+
+    while ( pos > 0 && iswalnum( unwrapped[ pos ] ) )
+        --pos;
+
+    if ( ! iswalnum( unwrapped[ pos ] ) )
+    {
+#ifdef WORD_WRAPPER_TESTER
+        wcout << "iswalnum wrap" << endl;
+#endif
+
+        line = unwrapped.substr( 0, pos + 1 );
+        unwrapped.erase( 0, pos + 1 );
+
+        return line;
+    }
+
+
+    // Still no chance to break the line? So we'll have to break in mid-word.
+    // This is crude and brutal, but in some locales (Chinese, Japanese,
+    // Korean) there is very little whitespace, so sometimes we have no other
+    // choice.
+
+#ifdef WORD_WRAPPER_TESTER
+    wcout << "desperation wrap" << endl;
+#endif
+
+    pos = _lineWidth - 1;
+    line = unwrapped.substr( 0, pos + 1 );
+    unwrapped.erase( 0, pos + 1 );
+
+    return line;
+}
+
+
+// ----------------------------------------------------------------------
+
+
+// Standalone test frame for this class.
+//
+// Build with
+//
+//     g++ -D WORD_WRAPPER_TESTER -o word-wrapper-tester NCWordWrapper.cc
+//
+// Usage:
+//
+//    ./word-wrapper-tester "text to wrap" 
+//
+// Notice that this does not do any fancy UTF-8 recoding of the command line
+// arguments, so non-ASCII characters may be slightly broken. This is expected,
+// and for the sake of simplicity, this will not be fixed. This only affects
+// this test frame; the tested class can handle UTF-8 characters just fine
+// (thus "Lörem üpsum" instead of "Lorem ipsum" in the AutoWrap*.cc libyui
+// examples).
+
+#ifdef WORD_WRAPPER_TESTER
+
+
+int main( int argc, char *argv[] )
+{
+    NCWordWrapper wrapper;
+
+    if ( argc != 3 )
+    {
+        std::cerr << "\nUsage: " << argv[0] << " \"text to wrap\" \n" << endl;
+        exit( 1 );
+    }
+
+    std::string src( argv[1] );
+    wstring input( src.begin(), src.end() );
+    int lineWidth = atoi( argv[2] );
+
+    wcout << "Wrapping to " << lineWidth << " columns:\n\"" << input << "\"\n" << endl;
+
+    wrapper.setText( input );
+    wrapper.setLineWidth( lineWidth );
+    wrapper.wrap();
+
+    wcout << "         10        20        30        40        50" << endl;
+    wcout << "12345678901234567890123456789012345678901234567890"  << endl;
+    wcout << wrapper.wrappedText() << endl;
+    wcout << "-- Wrapped lines: " << wrapper.lines() << endl;
+}
+
+#endif
diff --git a/deps/libyui/libyui-ncurses/src/NCWordWrapper.h b/deps/libyui/libyui-ncurses/src/NCWordWrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe42a6ccb88d3c4186b630f5471a573c4d498333
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCWordWrapper.h
@@ -0,0 +1,124 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCWordWrapper.h
+
+   Author:     Stefan Hundhammer 
+
+/-*/
+
+
+#ifndef NCWordWrapper_h
+#define NCWordWrapper_h
+
+#include 
+
+/**
+ * Helper class to word-wrap text into a specified maximum line width.
+ * Whitespace is normalized in the process, i.e. any sequence of whitespace
+ * (blanks, newlines, tabs, ...) is replaced by a single blank. All lines end
+ * with a single newline character except the last one which has no newline.
+ **/
+class NCWordWrapper
+{
+public:
+
+    /**
+     * Constructor.
+     **/
+    NCWordWrapper();
+
+    /**
+     * Set the original text to wrap.
+     **/
+    void setText( const std::wstring & origText );
+
+    /**
+     * Set the maximum line width to wrap into.
+     **/
+    void setLineWidth( int width );
+
+    /**
+     * Return the number of lines after wrapping the original text.
+     **/
+    int lines();
+
+    /**
+     * Wrap the original text and return the wrapped text.
+     **/
+    const std::wstring & wrappedText();
+
+    /**
+     * Return the original unwrapped text.
+     **/
+    const std::wstring & origText() const { return _origText; }
+
+    /**
+     * Return the last used maximum line width.
+     **/
+    int lineWidth() const { return _lineWidth; }
+
+    /**
+     * Return a string where any sequence of whitespace in the original text is
+     * replaced with a single blank and without leading or trailing whitespace.
+     **/
+    static std::wstring normalizeWhitespace( const std::wstring & orig );
+
+    /**
+     * Do the wrapping.
+     *
+     * This normally doesn't need to be called manually; it is done
+     * automatically when retrieving the wrapped text or the number of wrapped
+     * lines (and when the internal 'dirty' flag is set).
+     *
+     * But it can be useful to call it manually for debugging and testing.
+     **/
+    void wrap();
+
+    /**
+     * Clear the old content.
+     **/
+    void clear();
+
+
+protected:
+
+    /**
+     * Do the wrapping if necessary.
+     **/
+    void ensureWrapped();
+
+    /**
+     * Return the next line that fits into the line width and removed it from
+     * 'unwrapped'.
+     **/
+    std::wstring nextLine( std::wstring & unwrapped );
+
+    //
+    // Data members
+    //
+
+    std::wstring _origText;
+    std::wstring _wrappedText;
+    int          _lineWidth;
+    int          _lines;
+    bool         _dirty;
+};
+
+#endif  // NCWordWrapper_h
diff --git a/deps/libyui/libyui-ncurses/src/NCi18n.h b/deps/libyui/libyui-ncurses/src/NCi18n.h
new file mode 100644
index 0000000000000000000000000000000000000000..15fed0bf8967d3cc47cd3bc4685fb30702821d4b
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCi18n.h
@@ -0,0 +1,70 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+  File:		NCi18n.h
+
+  Authors:	Gabriele Strattner 
+
+/-*/
+
+#ifndef NCi18n_h
+#define NCi18n_h
+
+#include 
+#include 
+
+
+/**
+ *  define _(...) for gettext
+ *  msgid:  text which has to be translated
+ *  return: NCstring
+ */
+
+inline std::string _( const char * msgid )
+{
+    return gettext( msgid );
+}
+
+/**
+ * define _(...) for ngettext
+ * msgid1: message singular
+ * msgid2: message plural form
+ * n:	   choose singular/plural form based on this value
+ * return: NCstring
+ */
+inline std::string _( const char * msgid1, const char * msgid2, unsigned long int n )
+{
+    return ngettext( msgid1, msgid2, n );
+}
+
+inline void setTextdomain( const char * domain )
+{
+    bindtextdomain( domain,  YSettings::localeDir().c_str() );
+    bind_textdomain_codeset( domain, "UTF-8" );
+    textdomain( domain );
+#if defined(__GLIBC__)
+    // Make change known
+    {
+	extern int _nl_msg_cat_cntr;
+	++_nl_msg_cat_cntr;
+    }
+#endif
+}
+
+
+#endif // NCi18n_h
diff --git a/deps/libyui/libyui-ncurses/src/NCstring.cc b/deps/libyui/libyui-ncurses/src/NCstring.cc
new file mode 100644
index 0000000000000000000000000000000000000000..48834568c173acbe1a87594c8dbd382d044ed1ea
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCstring.cc
@@ -0,0 +1,389 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCstring.cc
+
+   Author:     Gabriele Strattner 
+
+/-*/
+
+#include 
+#include 
+#include 
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCstring.h"
+
+
+// The default encoding is UTF-8. For real terminals this may be
+// changed with setConsoleFont().
+
+std::string	NCstring::termEncoding( "UTF-8" );
+
+
+NCstring:: NCstring()
+	: hotk( 0 )
+	, hotp( std::wstring::npos )
+	, wstr( L"" )
+
+{
+}
+
+
+NCstring::NCstring( const NCstring & nstr )
+	: hotk( nstr.hotk )
+	, hotp( nstr.hotp )
+	, wstr( nstr.wstr )
+{
+}
+
+
+NCstring::NCstring( const std::wstring & widestr )
+	: hotk( 0 )
+	, hotp( std::wstring::npos )
+	, wstr( widestr )
+{
+}
+
+
+NCstring::NCstring( const std::string & str )
+	: hotk( 0 )
+	, hotp( std::wstring::npos )
+{
+    bool ok = RecodeToWchar( str, "UTF-8", &wstr );
+
+    if ( !ok )
+    {
+	yuiError() << "ERROR: RecodeToWchar() failed" << std::endl;
+    }
+}
+
+
+NCstring::NCstring( const char * cstr )
+	: hotk( 0 )
+	, hotp( std::wstring::npos )
+{
+    bool ok = RecodeToWchar( cstr, "UTF-8", &wstr );
+
+    if ( !ok )
+    {
+	yuiError() << "ERROR: RecodeToWchar() failed" << std::endl;
+    }
+}
+
+
+std::ostream & operator<<( std::ostream & str, const NCstring & obj )
+{
+    return str <<  obj.Str() ;
+}
+
+
+NCstring & NCstring::operator=( const NCstring & nstr )
+{
+    if ( &nstr != this )
+    {
+	hotk	  = nstr.hotk;
+	hotp	  = nstr.hotp;
+	wstr	  = nstr.wstr;
+    }
+
+    return *this;
+}
+
+
+NCstring & NCstring::operator+=( const NCstring & nstr )
+{
+    wstr.append( nstr.wstr );
+    return *this;
+}
+
+static iconv_t fromwchar_cd	= ( iconv_t )( -1 );
+static std::string  to_name		= "";
+
+
+
+bool NCstring::RecodeFromWchar( const std::wstring & in, const std::string & to_encoding, std::string* out )
+{
+    iconv_t cd = ( iconv_t )( -1 );
+    static bool complained = false;
+    *out = "";
+
+    if ( in.length() == 0 )
+	return true;
+
+    // iconv_open not yet called
+    if ( fromwchar_cd == ( iconv_t )( -1 )
+	 || to_name != to_encoding )
+    {
+	if ( fromwchar_cd != ( iconv_t )( -1 ) )
+	{
+	    iconv_close( fromwchar_cd );
+	}
+
+	fromwchar_cd = iconv_open( to_encoding.c_str(), "WCHAR_T" );
+
+	// yuiDebug() << "iconv_open( " << to_encoding.c_str() << ", \"WCHAR_T\" )" << std::endl;
+
+	if ( fromwchar_cd == ( iconv_t )( -1 ) )
+	{
+	    if ( !complained )
+	    {
+		yuiError() << "ERROR: iconv_open failed" << std::endl;
+		complained = true;
+	    }
+
+	    return false;
+	}
+	else
+	{
+	    to_name = to_encoding;
+	}
+    }
+
+    cd = fromwchar_cd;		// set iconv handle
+
+    size_t in_len = in.length() * sizeof( std::wstring::value_type );	// number of in bytes
+    char* in_ptr = (char *) in.data();
+
+    size_t tmp_size = ( in_len * sizeof( char ) ) * 2;
+    // tmp buffer size: in_len bytes * 2, that means 1 wide charatcer (4 Byte) can be transformed
+    // into an encoding which needs at most 8 Byte for one character (should be enough)
+
+    char* tmp = (char *) malloc( tmp_size + sizeof( char ) );
+
+    do
+    {
+
+	char *tmp_ptr = tmp;
+	size_t tmp_len = tmp_size;
+	*( (char *) tmp_ptr ) = '\0';
+
+	size_t iconv_ret = iconv( cd, &in_ptr, &in_len, &tmp_ptr, &tmp_len );
+
+	*( (char *) tmp_ptr ) = '\0';
+	*out += std::string( tmp );
+
+	if ( iconv_ret == ( size_t )( -1 ) )
+	{
+	    if ( !complained )
+	    {
+		yuiError() << "ERROR iconv: " << errno << std::endl;
+		complained = true;
+	    }
+
+	    if ( errno == EINVAL || errno == EILSEQ )
+	    {
+		*out += '?';
+	    }
+
+	    in_ptr += sizeof( std::wstring::value_type );
+
+	    in_len -= sizeof( std::wstring::value_type );
+	}
+
+    }
+    while ( in_len != 0 );
+
+    free( tmp );
+
+    return true;
+}
+
+static iconv_t towchar_cd	= ( iconv_t )( -1 );
+static std::string  from_name	= "";
+
+
+
+bool NCstring::RecodeToWchar( const std::string& in, const std::string &from_encoding, std::wstring* out )
+{
+    iconv_t cd = ( iconv_t )( -1 );
+    static bool complained = false;
+    *out = L"";
+
+    if ( in.length() == 0 )
+	return true;
+
+    // iconv_open not yet called
+    if ( towchar_cd == ( iconv_t )( -1 )
+	 || from_name != from_encoding )
+    {
+	if ( towchar_cd != ( iconv_t )( -1 ) )
+	{
+	    iconv_close( towchar_cd );
+	}
+
+	towchar_cd = iconv_open( "WCHAR_T", from_encoding.c_str() );
+
+	// yuiDebug() << "iconv_open( \"WCHAR_T\", " << from_encoding.c_str() << " )" << std::endl;
+
+	if ( towchar_cd == ( iconv_t )( -1 ) )
+	{
+	    if ( !complained )
+	    {
+		yuiError() << "Error: RecodeToWchar iconv_open() failed" << std::endl;
+		complained = true;
+	    }
+
+	    return false;
+	}
+	else
+	{
+	    from_name = from_encoding;
+	}
+    }
+
+    cd = towchar_cd;		// set iconv handle
+
+    size_t in_len = in.length();		// number of bytes of input std::string
+    char* in_ptr = const_cast ( in.c_str() );
+
+    size_t tmp_size = in_len * sizeof( wchar_t );	// buffer size: at most in_len wide characters
+    char* tmp = (char*) malloc( tmp_size + sizeof( wchar_t ) );		// + L'\0'
+
+    do
+    {
+
+	size_t tmp_len = tmp_size;
+	char* tmp_ptr = tmp;
+
+	size_t iconv_ret = iconv( cd, &in_ptr, &in_len, &tmp_ptr, &tmp_len );
+
+	*( (wchar_t *) tmp_ptr ) = L'\0';
+
+	*out += std::wstring( (wchar_t *) tmp );
+
+	if ( iconv_ret == ( size_t )( -1 ) )
+	{
+	    if ( !complained )
+	    {
+		// EILSEQ	84	Illegal byte sequence.
+		// EINVAL	22	Invalid argument
+		// E2BIG	7	Argument list too long
+		yuiError() << "ERROR iconv: " << errno << std::endl;
+		complained = true;
+	    }
+
+	    if ( errno == EINVAL || errno == EILSEQ )
+	    {
+		*out += L'?';
+	    }
+
+	    in_ptr++;
+
+	    in_len--;
+	}
+
+    }
+    while ( in_len != 0 );
+
+    free( tmp );
+
+    return true;
+}
+
+
+std::string NCstring::Str() const
+{
+    std::string utf8str;
+    RecodeFromWchar( wstr, "UTF-8", &utf8str );
+
+    return utf8str;
+}
+
+
+
+void NCstring::getHotkey() const
+{
+
+    hotp = std::wstring::npos;
+    const wchar_t shortcutMarker = L'&';
+    const wchar_t replacementShortcutMarker = L'_';
+
+    // I'm not really happy with using replacement markers and copying the std::string
+    // but is there an other way?
+    // If hotkey is looked up before un-escaping, its position won't be up-to-date anymore
+    // as chars got deleted from the std::string
+    // And vice versa: if un-escaping is done before looking up hotkey position, it's no
+    // longer possible to tell hotkey marker and regular & (previous &&) apart (this is
+    // the 'Foo&&Bar&Geeez' case) fB.
+
+    bool have_shortcut = false;
+    std::wstring::size_type len = wstr.length();
+    std::wstring newstr;
+    newstr.reserve( len );
+
+    for (std::wstring::iterator it = wstr.begin(); it != wstr.end(); it++) {
+        if ( *it == shortcutMarker &&
+             (it + 1 != wstr.end()) ) {
+
+    	    // double && un-escaping - bnc#559226
+    	    // foo&&bar => foo&bar
+	    if ( *(it+1) == shortcutMarker) {
+                newstr += shortcutMarker;  // add only one &
+                it++; // .. and jump forth to skip the 2nd one
+	    }
+	    // regular hotkey &X
+	    else {
+		// take the first one only (we can't do multiple hotkeys per 1 line
+	        // so we just discard the rest, argh)
+		if ( !have_shortcut) {
+		    newstr += replacementShortcutMarker;
+		    have_shortcut = true;
+		}
+	    }
+        }
+        else
+           newstr += *it;
+    }
+
+    wstr = newstr;
+
+    std::wstring::size_type tpos = wstr.find_first_of( replacementShortcutMarker );
+
+    if ( tpos != std::wstring::npos && tpos != wstr.size() - 1 )
+    {
+	size_t realpos = 0, t;
+
+	for ( t = 0; t < tpos; t++ )
+	    realpos += wcwidth( wstr[t] );
+
+	wstr.erase( tpos, 1 );
+
+	hotk = wstr[tpos];
+
+	hotp = realpos;
+    }
+
+}
+
+
+
+bool NCstring::setTerminalEncoding( const std::string & encoding )
+{
+    if ( termEncoding != encoding )
+    {
+	yuiMilestone() << "Terminal encoding set to: " << encoding << std::endl;
+	termEncoding = encoding;
+	return true;
+    }
+    else
+    {
+	return false;
+    }
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCstring.h b/deps/libyui/libyui-ncurses/src/NCstring.h
new file mode 100644
index 0000000000000000000000000000000000000000..1df50a70ebfd86b9304f604b7bdf6d7dd41cf107
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCstring.h
@@ -0,0 +1,106 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCstring.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCstring_h
+#define NCstring_h
+
+#include 
+#include 
+
+
+/// A string with an optional hot key.
+///
+/// The current implementation stores a std::wstring.
+class NCstring
+{
+private:
+
+    friend std::ostream & operator<<( std::ostream & str, const NCstring & obj );
+
+    mutable wchar_t hotk;                 ///< hotkey
+    /// Position of hotkey in columns(!). *npos* means unset.
+    ///
+    /// CJK characters take 2 columns. So in the Chinese "Yes" button,
+    /// L"是(Y)", *hotp* for L'Y' is 3 even though
+    ///its wchar_t offset is 2 (and its UTF-8 offset is 4).
+    mutable std::wstring::size_type hotp;
+    mutable std::wstring   wstr;	  ///< the actual string
+
+    /// The encoding of the terminal; the value is ignored by this class.
+    /// WTF, really: other classes care
+    /// but this class just uses UTF-8 for non-wide characters.
+    static std::string	termEncoding;
+
+public:
+
+    NCstring();
+
+    NCstring( const NCstring & nstr );
+
+    NCstring( const std::wstring & wstr );
+
+    /// Init from a UTF-8 string.
+    NCstring( const std::string & str );
+
+    /// Init from a UTF-8 string.
+    NCstring( const char * cstr );
+
+    ~NCstring() {}
+
+    /// Get a UTF-8 string.
+    std::string Str() const;
+
+public:
+
+    NCstring & operator=( const NCstring & nstr );
+
+    NCstring & operator+=( const NCstring & nstr );
+
+    const std::wstring & str()      const { return wstr; }
+
+private:
+
+    friend class NClabel;
+
+    wchar_t	            hotkey() const { return hotk; }
+    std::wstring::size_type hotpos() const { return hotp; }
+
+public:
+
+    static bool RecodeToWchar  ( const std::string & in,  const std::string & from_encoding, std::wstring * out );
+    static bool RecodeFromWchar( const std::wstring & in, const std::string & to_encoding,   std::string  * out );
+
+    static const std::string & terminalEncoding()
+    {
+	return termEncoding;
+    }
+
+    static bool setTerminalEncoding( const std::string & encoding = "" );
+
+    /// (mutates the const object)
+    void getHotkey() const;
+};
+
+
+#endif // NCstring_h
diff --git a/deps/libyui/libyui-ncurses/src/NCstyle.braille.h b/deps/libyui/libyui-ncurses/src/NCstyle.braille.h
new file mode 100644
index 0000000000000000000000000000000000000000..764929d72114014ca7bfc8973cf27e3b1ce822be
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCstyle.braille.h
@@ -0,0 +1,295 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCstyle.braille.h
+
+   Author:     Generated by class NCstyle
+
+/-*/
+
+#ifndef NCstyle_braille_h
+#define NCstyle_braille_h
+
+#include "NCstyle.h"
+
+inline void NCstyleInit_braille( std::vector & styleSet )
+{
+    //=================================================================
+    // init global attributes
+    //=================================================================
+    NCattrset * attrset( &styleSet[NCstyle::DefaultStyle].getAttrGlobal() );
+    attrset->setAttr( NCstyle::AppTitle, 14080 );
+    attrset->setAttr( NCstyle::AppText, 8192 );
+    //=================================================================
+    // init local attributes
+    //=================================================================
+    // DefaultStyle
+    attrset = &styleSet[NCstyle::DefaultStyle].getAttrLocal();
+    attrset->setAttr( NCstyle::DialogBorder, 8192 );
+    attrset->setAttr( NCstyle::DialogTitle, 8192 );
+    attrset->setAttr( NCstyle::DialogActiveBorder, 13056 );
+    attrset->setAttr( NCstyle::DialogActiveTitle, 13056 );
+    attrset->setAttr( NCstyle::DialogText, 8192 );
+    attrset->setAttr( NCstyle::DialogHeadline, 8192 );
+    attrset->setAttr( NCstyle::DialogDisabled, 8448 );
+    attrset->setAttr( NCstyle::DialogPlain, 8192 );
+    attrset->setAttr( NCstyle::DialogLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogData, 9216 );
+    attrset->setAttr( NCstyle::DialogHint, 9728 );
+    attrset->setAttr( NCstyle::DialogScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActivePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveScrl, 13568 );
+    attrset->setAttr( NCstyle::DialogFramePlain, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameData, 9216 );
+    attrset->setAttr( NCstyle::DialogFrameHint, 9728 );
+    attrset->setAttr( NCstyle::DialogFrameScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActiveFramePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveFrameHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveFrameScrl, 13568 );
+    attrset->setAttr( NCstyle::ListTitle, 8192 );
+    attrset->setAttr( NCstyle::ListPlain, 8192 );
+    attrset->setAttr( NCstyle::ListLabel, 8192 );
+    attrset->setAttr( NCstyle::ListData, 9216 );
+    attrset->setAttr( NCstyle::ListHint, 9472 );
+    attrset->setAttr( NCstyle::ListSelPlain, 8192 );
+    attrset->setAttr( NCstyle::ListSelLabel, 8192 );
+    attrset->setAttr( NCstyle::ListSelData, 9216 );
+    attrset->setAttr( NCstyle::ListSelHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveTitle, 8192 );
+    attrset->setAttr( NCstyle::ListActivePlain, 8192 );
+    attrset->setAttr( NCstyle::ListActiveLabel, 8192 );
+    attrset->setAttr( NCstyle::ListActiveData, 9216 );
+    attrset->setAttr( NCstyle::ListActiveHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveSelPlain, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelLabel, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelData, 13312 );
+    attrset->setAttr( NCstyle::ListActiveSelHint, 13568 );
+    attrset->setAttr( NCstyle::RichTextPlain, 8192 );
+    attrset->setAttr( NCstyle::RichTextTitle, 8192 );
+    attrset->setAttr( NCstyle::RichTextLink, 8192 );
+    attrset->setAttr( NCstyle::RichTextArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextActiveArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextVisitedLink, 0 );
+    attrset->setAttr( NCstyle::RichTextB, 8192 );
+    attrset->setAttr( NCstyle::RichTextI, 8192 );
+    attrset->setAttr( NCstyle::RichTextT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBI, 8192 );
+    attrset->setAttr( NCstyle::RichTextBT, 8192 );
+    attrset->setAttr( NCstyle::RichTextIT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBIT, 8192 );
+    attrset->setAttr( NCstyle::ProgbarCh, 16128 );
+    attrset->setAttr( NCstyle::ProgbarBgch, 4194481 );
+    attrset->setAttr( NCstyle::TextCursor, 2048 );
+    // InfoStyle
+    attrset = &styleSet[NCstyle::InfoStyle].getAttrLocal();
+    attrset->setAttr( NCstyle::DialogBorder, 9472 );
+    attrset->setAttr( NCstyle::DialogTitle, 9472 );
+    attrset->setAttr( NCstyle::DialogActiveBorder, 4864 );
+    attrset->setAttr( NCstyle::DialogActiveTitle, 4864 );
+    attrset->setAttr( NCstyle::DialogText, 8192 );
+    attrset->setAttr( NCstyle::DialogHeadline, 8192 );
+    attrset->setAttr( NCstyle::DialogDisabled, 8448 );
+    attrset->setAttr( NCstyle::DialogPlain, 8192 );
+    attrset->setAttr( NCstyle::DialogLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogData, 9216 );
+    attrset->setAttr( NCstyle::DialogHint, 9728 );
+    attrset->setAttr( NCstyle::DialogScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActivePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveScrl, 13568 );
+    attrset->setAttr( NCstyle::DialogFramePlain, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameData, 9216 );
+    attrset->setAttr( NCstyle::DialogFrameHint, 9728 );
+    attrset->setAttr( NCstyle::DialogFrameScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActiveFramePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveFrameHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveFrameScrl, 13568 );
+    attrset->setAttr( NCstyle::ListTitle, 8192 );
+    attrset->setAttr( NCstyle::ListPlain, 8192 );
+    attrset->setAttr( NCstyle::ListLabel, 8192 );
+    attrset->setAttr( NCstyle::ListData, 9216 );
+    attrset->setAttr( NCstyle::ListHint, 9472 );
+    attrset->setAttr( NCstyle::ListSelPlain, 8192 );
+    attrset->setAttr( NCstyle::ListSelLabel, 8192 );
+    attrset->setAttr( NCstyle::ListSelData, 9216 );
+    attrset->setAttr( NCstyle::ListSelHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveTitle, 8192 );
+    attrset->setAttr( NCstyle::ListActivePlain, 8192 );
+    attrset->setAttr( NCstyle::ListActiveLabel, 8192 );
+    attrset->setAttr( NCstyle::ListActiveData, 9216 );
+    attrset->setAttr( NCstyle::ListActiveHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveSelPlain, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelLabel, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelData, 13312 );
+    attrset->setAttr( NCstyle::ListActiveSelHint, 13568 );
+    attrset->setAttr( NCstyle::RichTextPlain, 8192 );
+    attrset->setAttr( NCstyle::RichTextTitle, 8192 );
+    attrset->setAttr( NCstyle::RichTextLink, 8192 );
+    attrset->setAttr( NCstyle::RichTextArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextActiveArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextVisitedLink, 0 );
+    attrset->setAttr( NCstyle::RichTextB, 8192 );
+    attrset->setAttr( NCstyle::RichTextI, 8192 );
+    attrset->setAttr( NCstyle::RichTextT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBI, 8192 );
+    attrset->setAttr( NCstyle::RichTextBT, 8192 );
+    attrset->setAttr( NCstyle::RichTextIT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBIT, 8192 );
+    attrset->setAttr( NCstyle::ProgbarCh, 16128 );
+    attrset->setAttr( NCstyle::ProgbarBgch, 4194481 );
+    attrset->setAttr( NCstyle::TextCursor, 2048 );
+    // WarnStyle
+    attrset = &styleSet[NCstyle::WarnStyle].getAttrLocal();
+    attrset->setAttr( NCstyle::DialogBorder, 9728 );
+    attrset->setAttr( NCstyle::DialogTitle, 9728 );
+    attrset->setAttr( NCstyle::DialogActiveBorder, 2816 );
+    attrset->setAttr( NCstyle::DialogActiveTitle, 2816 );
+    attrset->setAttr( NCstyle::DialogText, 8192 );
+    attrset->setAttr( NCstyle::DialogHeadline, 8192 );
+    attrset->setAttr( NCstyle::DialogDisabled, 8448 );
+    attrset->setAttr( NCstyle::DialogPlain, 8192 );
+    attrset->setAttr( NCstyle::DialogLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogData, 9216 );
+    attrset->setAttr( NCstyle::DialogHint, 9728 );
+    attrset->setAttr( NCstyle::DialogScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActivePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveScrl, 13568 );
+    attrset->setAttr( NCstyle::DialogFramePlain, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameData, 9216 );
+    attrset->setAttr( NCstyle::DialogFrameHint, 9728 );
+    attrset->setAttr( NCstyle::DialogFrameScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActiveFramePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveFrameHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveFrameScrl, 13568 );
+    attrset->setAttr( NCstyle::ListTitle, 8192 );
+    attrset->setAttr( NCstyle::ListPlain, 8192 );
+    attrset->setAttr( NCstyle::ListLabel, 8192 );
+    attrset->setAttr( NCstyle::ListData, 9216 );
+    attrset->setAttr( NCstyle::ListHint, 9472 );
+    attrset->setAttr( NCstyle::ListSelPlain, 8192 );
+    attrset->setAttr( NCstyle::ListSelLabel, 8192 );
+    attrset->setAttr( NCstyle::ListSelData, 9216 );
+    attrset->setAttr( NCstyle::ListSelHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveTitle, 8192 );
+    attrset->setAttr( NCstyle::ListActivePlain, 8192 );
+    attrset->setAttr( NCstyle::ListActiveLabel, 8192 );
+    attrset->setAttr( NCstyle::ListActiveData, 9216 );
+    attrset->setAttr( NCstyle::ListActiveHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveSelPlain, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelLabel, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelData, 13312 );
+    attrset->setAttr( NCstyle::ListActiveSelHint, 13568 );
+    attrset->setAttr( NCstyle::RichTextPlain, 8192 );
+    attrset->setAttr( NCstyle::RichTextTitle, 8192 );
+    attrset->setAttr( NCstyle::RichTextLink, 8192 );
+    attrset->setAttr( NCstyle::RichTextArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextActiveArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextVisitedLink, 0 );
+    attrset->setAttr( NCstyle::RichTextB, 8192 );
+    attrset->setAttr( NCstyle::RichTextI, 8192 );
+    attrset->setAttr( NCstyle::RichTextT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBI, 8192 );
+    attrset->setAttr( NCstyle::RichTextBT, 8192 );
+    attrset->setAttr( NCstyle::RichTextIT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBIT, 8192 );
+    attrset->setAttr( NCstyle::ProgbarCh, 16128 );
+    attrset->setAttr( NCstyle::ProgbarBgch, 4194481 );
+    attrset->setAttr( NCstyle::TextCursor, 2048 );
+    // PopupStyle
+    attrset = &styleSet[NCstyle::PopupStyle].getAttrLocal();
+    attrset->setAttr( NCstyle::DialogBorder, 8448 );
+    attrset->setAttr( NCstyle::DialogTitle, 8448 );
+    attrset->setAttr( NCstyle::DialogActiveBorder, 13056 );
+    attrset->setAttr( NCstyle::DialogActiveTitle, 13056 );
+    attrset->setAttr( NCstyle::DialogText, 8192 );
+    attrset->setAttr( NCstyle::DialogHeadline, 8192 );
+    attrset->setAttr( NCstyle::DialogDisabled, 8448 );
+    attrset->setAttr( NCstyle::DialogPlain, 8192 );
+    attrset->setAttr( NCstyle::DialogLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogData, 9216 );
+    attrset->setAttr( NCstyle::DialogHint, 9728 );
+    attrset->setAttr( NCstyle::DialogScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActivePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveScrl, 13568 );
+    attrset->setAttr( NCstyle::DialogFramePlain, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameLabel, 8192 );
+    attrset->setAttr( NCstyle::DialogFrameData, 9216 );
+    attrset->setAttr( NCstyle::DialogFrameHint, 9728 );
+    attrset->setAttr( NCstyle::DialogFrameScrl, 9472 );
+    attrset->setAttr( NCstyle::DialogActiveFramePlain, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameLabel, 12288 );
+    attrset->setAttr( NCstyle::DialogActiveFrameData, 13312 );
+    attrset->setAttr( NCstyle::DialogActiveFrameHint, 13824 );
+    attrset->setAttr( NCstyle::DialogActiveFrameScrl, 13568 );
+    attrset->setAttr( NCstyle::ListTitle, 8192 );
+    attrset->setAttr( NCstyle::ListPlain, 8192 );
+    attrset->setAttr( NCstyle::ListLabel, 8192 );
+    attrset->setAttr( NCstyle::ListData, 9216 );
+    attrset->setAttr( NCstyle::ListHint, 9472 );
+    attrset->setAttr( NCstyle::ListSelPlain, 8192 );
+    attrset->setAttr( NCstyle::ListSelLabel, 8192 );
+    attrset->setAttr( NCstyle::ListSelData, 9216 );
+    attrset->setAttr( NCstyle::ListSelHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveTitle, 8192 );
+    attrset->setAttr( NCstyle::ListActivePlain, 8192 );
+    attrset->setAttr( NCstyle::ListActiveLabel, 8192 );
+    attrset->setAttr( NCstyle::ListActiveData, 9216 );
+    attrset->setAttr( NCstyle::ListActiveHint, 9472 );
+    attrset->setAttr( NCstyle::ListActiveSelPlain, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelLabel, 12288 );
+    attrset->setAttr( NCstyle::ListActiveSelData, 13312 );
+    attrset->setAttr( NCstyle::ListActiveSelHint, 13568 );
+    attrset->setAttr( NCstyle::RichTextPlain, 8192 );
+    attrset->setAttr( NCstyle::RichTextTitle, 8192 );
+    attrset->setAttr( NCstyle::RichTextLink, 8192 );
+    attrset->setAttr( NCstyle::RichTextArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextActiveArmedlink, 8192 );
+    attrset->setAttr( NCstyle::RichTextVisitedLink, 0 );
+    attrset->setAttr( NCstyle::RichTextB, 8192 );
+    attrset->setAttr( NCstyle::RichTextI, 8192 );
+    attrset->setAttr( NCstyle::RichTextT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBI, 8192 );
+    attrset->setAttr( NCstyle::RichTextBT, 8192 );
+    attrset->setAttr( NCstyle::RichTextIT, 8192 );
+    attrset->setAttr( NCstyle::RichTextBIT, 8192 );
+    attrset->setAttr( NCstyle::ProgbarCh, 16128 );
+    attrset->setAttr( NCstyle::ProgbarBgch, 4194481 );
+    attrset->setAttr( NCstyle::TextCursor, 2048 );
+}
+
+#endif // NCstyle_braille_h
diff --git a/deps/libyui/libyui-ncurses/src/NCstyle.cc b/deps/libyui/libyui-ncurses/src/NCstyle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..867767ecd058e80cb2db08cf3b5960a4538a5dad
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCstyle.cc
@@ -0,0 +1,384 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCstyle.cc
+
+   Author:     Michael Andres 
+
+/-*/
+
+#include 
+#include "fnmatch.h"
+
+#define  YUILogComponent "ncurses"
+#include 
+#include "NCurses.h"
+#include "NCStyleDef.h"
+
+#include "NCstyle.mono.h"
+#include "NCstyle.braille.h"
+#include "NCstyle.linux.h"
+#include "NCstyle.xterm.h"
+#include "NCstyle.rxvt.h"
+#include "NCstyle.highcontrast.h"
+#include "NCstyle.inverted.h"
+
+//initialize number of colors and color pairs
+int NCattribute::_colors = ::COLORS;
+int NCattribute::_pairs = ::COLOR_PAIRS;
+
+
+
+unsigned NCstyle::Style::sanitycheck()
+{
+    return MaxSTglobal;
+}
+
+NCattrset NCstyle::Style::attrGlobal( sanitycheck() );
+
+
+
+// Initialize subclass StDialog in Style constructor
+//		      (esp. copy constructor). Default copy constructor
+//		      is not appropriate, because StDialog contains
+//		      references to subclass NCattrset.
+NCstyle::StDialog NCstyle::Style::initDialog()
+{
+    return StDialog( StBase( attr( DialogTitle ),
+			     attr( DialogBorder ) ),
+		     StBase( attr( DialogActiveTitle ),
+			     attr( DialogActiveBorder ) ),
+		     StBase( attr( DialogHeadline ),
+			     attr( DialogText ) ),
+		     StWidget( attr( DialogDisabled ),
+			       attr( DialogDisabled ),
+			       attr( DialogDisabled ),
+			       attr( DialogDisabled ),
+			       attr( DialogDisabled ) ),
+		     StWidget( attr( DialogPlain ),
+			       attr( DialogLabel ),
+			       attr( DialogData ),
+			       attr( DialogHint ),
+			       attr( DialogScrl ) ),
+		     StWidget( attr( DialogActivePlain ),
+			       attr( DialogActiveLabel ),
+			       attr( DialogActiveData ),
+			       attr( DialogActiveHint ),
+			       attr( DialogActiveScrl ) ),
+		     StWidget( attr( DialogFramePlain ),
+			       attr( DialogFrameLabel ),
+			       attr( DialogFrameData ),
+			       attr( DialogFrameHint ),
+			       attr( DialogFrameScrl ) ),
+		     StWidget( attr( DialogActiveFramePlain ),
+			       attr( DialogActiveFrameLabel ),
+			       attr( DialogActiveFrameData ),
+			       attr( DialogActiveFrameHint ),
+			       attr( DialogActiveFrameScrl ) ),
+		     StList( attr( ListTitle ),
+			     StItem( attr( ListPlain ),
+				     attr( ListLabel ),
+				     attr( ListData ),
+				     attr( ListHint ) ),
+			     StItem( attr( ListSelPlain ),
+				     attr( ListSelLabel ),
+				     attr( ListSelData ),
+				     attr( ListSelHint ) ) ),
+		     StList( attr( ListActiveTitle ),
+			     StItem( attr( ListActivePlain ),
+				     attr( ListActiveLabel ),
+				     attr( ListActiveData ),
+				     attr( ListActiveHint ) ),
+			     StItem( attr( ListActiveSelPlain ),
+				     attr( ListActiveSelLabel ),
+				     attr( ListActiveSelData ),
+				     attr( ListActiveSelHint ) ) ),
+		     StList( attr( DialogDisabled ),
+			     StItem( attr( DialogDisabled ),
+				     attr( DialogDisabled ),
+				     attr( DialogDisabled ),
+				     attr( DialogDisabled ) ),
+			     StItem( attr( DialogDisabled ),
+				     attr( DialogDisabled ),
+				     attr( DialogDisabled ),
+				     attr( DialogDisabled ) ) ),
+		     StProgbar( attr( ProgbarCh ),
+				attr( ProgbarBgch ) ),
+		     StRichtext( attr( RichTextPlain ),
+				 attr( RichTextTitle ),
+				 attr( RichTextLink ),
+				 attr( RichTextArmedlink ),
+				 attr( RichTextActiveArmedlink ),
+				 attr( RichTextVisitedLink ),
+				 attr( RichTextB ),
+				 attr( RichTextI ),
+				 attr( RichTextT ),
+				 attr( RichTextBI ),
+				 attr( RichTextBT ),
+				 attr( RichTextIT ),
+				 attr( RichTextBIT ) ),
+		     attr( TextCursor )
+		   );
+}
+
+
+
+NCstyle::Style::Style()
+	: NCattrset( MaxSTlocal )
+	, StDialog( initDialog() )
+{}
+
+
+
+NCstyle::Style::Style( const Style & rhs )
+	: NCattrset( rhs )
+	, StDialog( initDialog() )
+{}
+
+
+
+NCstyle::Style::~Style()
+{}
+
+
+
+
+
+#define PRT(t) case NCstyle::t: return #t;
+
+std::string NCstyle::dumpName( NCstyle::StyleSet a )
+{
+    switch ( a )
+    {
+	PRT( DefaultStyle );
+	PRT( InfoStyle );
+	PRT( WarnStyle );
+	PRT( PopupStyle );
+
+	case NCstyle::MaxStyleSet:
+	    break;
+    }
+
+    return "unknown";
+}
+
+std::string NCstyle::dumpName( NCstyle::STglobal a )
+{
+    switch ( a )
+    {
+	PRT( AppTitle );
+	PRT( AppText );
+
+	case NCstyle::MaxSTglobal:
+	    break;
+    }
+
+    return "unknown";
+}
+
+std::string NCstyle::dumpName( NCstyle::STlocal a )
+{
+    switch ( a )
+    {
+	PRT( DialogBorder );
+	PRT( DialogTitle );
+	PRT( DialogActiveBorder );
+	PRT( DialogActiveTitle );
+	//
+	PRT( DialogText );
+	PRT( DialogHeadline );
+	//
+	PRT( DialogDisabled );
+	//
+	PRT( DialogPlain );
+	PRT( DialogLabel );
+	PRT( DialogData );
+	PRT( DialogHint );
+	PRT( DialogScrl );
+	PRT( DialogActivePlain );
+	PRT( DialogActiveLabel );
+	PRT( DialogActiveData );
+	PRT( DialogActiveHint );
+	PRT( DialogActiveScrl );
+	//
+	PRT( DialogFramePlain );
+	PRT( DialogFrameLabel );
+	PRT( DialogFrameData );
+	PRT( DialogFrameHint );
+	PRT( DialogFrameScrl );
+	PRT( DialogActiveFramePlain );
+	PRT( DialogActiveFrameLabel );
+	PRT( DialogActiveFrameData );
+	PRT( DialogActiveFrameHint );
+	PRT( DialogActiveFrameScrl );
+	//
+	PRT( ListTitle );
+	PRT( ListPlain );
+	PRT( ListLabel );
+	PRT( ListData );
+	PRT( ListHint );
+	PRT( ListSelPlain );
+	PRT( ListSelLabel );
+	PRT( ListSelData );
+	PRT( ListSelHint );
+	//
+	PRT( ListActiveTitle );
+	PRT( ListActivePlain );
+	PRT( ListActiveLabel );
+	PRT( ListActiveData );
+	PRT( ListActiveHint );
+	PRT( ListActiveSelPlain );
+	PRT( ListActiveSelLabel );
+	PRT( ListActiveSelData );
+	PRT( ListActiveSelHint );
+	//
+	PRT( RichTextPlain );
+	PRT( RichTextTitle );
+	PRT( RichTextLink );
+	PRT( RichTextArmedlink );
+	PRT( RichTextActiveArmedlink );
+	PRT( RichTextVisitedLink );
+	PRT( RichTextB );
+	PRT( RichTextI );
+	PRT( RichTextT );
+	PRT( RichTextBI );
+	PRT( RichTextBT );
+	PRT( RichTextIT );
+	PRT( RichTextBIT );
+	//
+	PRT( ProgbarCh );
+	PRT( ProgbarBgch );
+	//
+	PRT( TextCursor );
+
+	case NCstyle::MaxSTlocal:
+	    break;
+    }
+
+    return "unknown";
+}
+
+#undef PRT
+
+
+
+NCstyle::NCstyle( std::string term_t )
+    : styleName( "linux" )
+    , term( term_t )
+    , styleSet( MaxStyleSet )
+    , fakestyle_e( MaxStyleSet )
+{
+    char *user_defined_style = getenv( "Y2NCURSES_COLOR_THEME" );
+
+    if ( user_defined_style && *user_defined_style )
+    {
+	styleName = user_defined_style;
+	yuiMilestone() << "User-defined style found: " << styleName.c_str() << std::endl;
+    }
+    else
+    {
+	if ( NCattribute::colors() )
+	{
+	    if ( getenv( "Y2_BRAILLE" ) != NULL )
+	    {
+		styleName = "braille";
+	    }
+	    else
+	    {
+		if ( ! fnmatch( "xterm*", term_t.c_str(), 0 ) )
+		    styleName = "xterm";
+		else if ( ! fnmatch( "rxvt*", term_t.c_str(), 0 ) )
+		    styleName = "rxvt";
+	    }
+	}
+	else
+	{
+	    styleName = "mono";
+	}
+    }
+
+    yuiMilestone() << "Init " << term_t << " using " << ( NCattribute::colors() ? "color" : "bw" )
+		   << " => " << MaxStyleSet << " styles in " << styleName << std::endl;
+
+#define IF_STYLE_INIT(n) if ( styleName == #n ) { NCstyleInit_##n( styleSet ); }
+    IF_STYLE_INIT( linux )
+	else IF_STYLE_INIT( xterm )
+            else IF_STYLE_INIT( rxvt )
+                else IF_STYLE_INIT( mono )
+                    else IF_STYLE_INIT( braille )
+                        else IF_STYLE_INIT( highcontrast )
+                            else IF_STYLE_INIT( inverted )
+                                else NCstyleInit_linux( styleSet );
+}
+
+
+
+NCstyle::~NCstyle()
+{
+}
+
+
+
+void NCstyle::nextStyle()
+{
+    if ( !NCattribute::colors() ) return;
+
+    if ( styleName == "mono" )
+    {
+	if ( term == "xterm" )
+	{
+	    styleName = "xterm";
+	    NCstyleInit_xterm( styleSet );
+	}
+	else if ( term == "rxvt" )
+	{
+	    styleName = "rxvt";
+	    NCstyleInit_rxvt( styleSet );
+	}
+	else
+	{
+	    styleName = "linux";
+	    NCstyleInit_linux( styleSet );
+	}
+    }
+    else if ( styleName == "braille" )
+    {
+	styleName = "mono";
+	NCstyleInit_mono( styleSet );
+    }
+    else
+    {
+	styleName = "braille";
+	NCstyleInit_braille( styleSet );
+    }
+}
+
+
+
+void NCstyle::changeSyle()
+{
+    NCDefineStyle( *this );
+}
+
+
+
+void NCstyle::fakestyle( StyleSet f )
+{
+    fakestyle_e = f;
+    NCurses::Redraw();
+}
diff --git a/deps/libyui/libyui-ncurses/src/NCstyle.h b/deps/libyui/libyui-ncurses/src/NCstyle.h
new file mode 100644
index 0000000000000000000000000000000000000000..86676ccb8f8b7bb54ef754674d17e4e358f3a9c8
--- /dev/null
+++ b/deps/libyui/libyui-ncurses/src/NCstyle.h
@@ -0,0 +1,609 @@
+/*
+  Copyright (C) 2000-2012 Novell, Inc
+  This library 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.1 of the
+  License, or (at your option) version 3.0 of the License. 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 Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       NCstyle.h
+
+   Author:     Michael Andres 
+
+/-*/
+
+#ifndef NCstyle_h
+#define NCstyle_h
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "NCtypes.h"
+
+
+struct NCattribute
+{
+    //
+    // available colors and color pairs
+    //
+    static int _colors;
+    static int _pairs;
+
+    //if we have color support, return number of available colors
+    //(at most 8 though)
+    //will be initialized by init_color() function
+    inline static int colors()	    { return _colors ? _colors : ::COLORS; }
+
+    // do the same with color pairs
+    inline static int color_pairs() { return _pairs ? _pairs : ::COLOR_PAIRS; }
+
+    //
+    //
+    // color pair to chtype
+    //
+    inline static chtype color_pair( short fg, short bg ) { return colors() ? COLOR_PAIR( bg * colors() + COLOR_WHITE - fg ) : A_NORMAL; }
+
+    inline static chtype color_pair( int i )		  { return colors() ? COLOR_PAIR( i ) : A_NORMAL; }
+
+    inline static short  fg_color_pair( int i )		  { return colors() ? ( COLOR_WHITE - ( i % colors() ) ) : -1; }
+
+    inline static short  bg_color_pair( int i )		  { return colors() ? ( i / colors() ) : -1; }
+
+    //
+    // chtype to color pair
+    //
+    inline static int	 color_pair_of( chtype ch )	  { return PAIR_NUMBER( ch ); }
+
+    inline static short  fg_color_of( chtype ch )	  { return fg_color_pair( color_pair_of( ch ) ); }
+
+    inline static short  bg_color_of( chtype ch )	  { return bg_color_pair( color_pair_of( ch ) ); }
+
+    //
+    // chtype manipualtion
+    //
+    static const chtype style_mask = A_ATTRIBUTES & ~A_COLOR & ~A_ALTCHARSET;
+    static const chtype color_mask = A_COLOR;
+    static const chtype char_mask  = A_CHARTEXT | A_ALTCHARSET;
+    //
+    inline static chtype getStyle( chtype a )		  { return a & style_mask; }
+
+    inline static chtype getColor( chtype a )		  { return a & color_mask; }
+
+    inline static chtype getChar( chtype a )		  { return a & char_mask;  }
+
+    inline static chtype getNonChar( chtype a )		  { return a & ~char_mask;  }
+
+    inline static void	 setStyle( chtype & a, chtype ch ) { a = ( a & ~style_mask ) | ( ch & style_mask ); }
+
+    inline static void	 setColor( chtype & a, chtype ch ) { if ( colors() ) a = ( a & ~color_mask ) | ( ch & color_mask ); }
+
+    inline static void	 setChar( chtype & a, chtype ch ) { a = ( a & ~char_mask ) | ( ch & char_mask );  }
+
+    inline static void	 addStyle( chtype & a, chtype ch ) { a = a | ( ch & style_mask ); }
+
+    inline static void	 delStyle( chtype & a, chtype ch ) { a = a & ~( ch & style_mask ); }
+
+    inline static void	 toggleStyle( chtype & a, chtype ch ) { setStyle( a, ( a & ~ch ) | (( a ^ ch ) & ch ) ); }
+
+    inline static void	 addAlt( chtype & a ) { a |= A_ALTCHARSET; }
+
+    inline static void	 delAlt( chtype & a ) { a &= ~A_ALTCHARSET; }
+
+    //
+    inline static short  getFg( chtype a )		{ return fg_color_of( a ); }
+
+    inline static short  getBg( chtype a )		{ return bg_color_of( a ); }
+
+    inline static void	 setFg( chtype & a, short c )	{ if ( colors() ) setColor( a, color_pair(( colors() + c ) % colors(), getBg( a ) ) ); }
+
+    inline static void	 setBg( chtype & a, short c )	{ if ( colors() ) setColor( a, color_pair( getFg( a ), ( colors() + c ) % colors() ) ); }
+
+    // debug aid
+
+    /** Color name */
+    inline static std::string colorAsString( short i )
+    {
+	switch ( i )
+	{
+	    #define OUTS(X)	case COLOR_##X: return #X
+	    OUTS( BLACK );
+	    OUTS( RED );
+	    OUTS( GREEN );
+	    OUTS( YELLOW );
+	    OUTS( BLUE );
+	    OUTS( MAGENTA );
+	    OUTS( CYAN );
+	    OUTS( WHITE );
+	    #undef OUTS
+	}
+	return "COLOR?";
+    }
+
+    /** String representation of color_pair "[fg,bg]" */
+    inline static std::string color_pairAsString( int i )
+    {
+	return std::string( "[" ) + colorAsString( fg_color_pair( i ) )
+		+ "," + colorAsString( bg_color_pair( i ) ) + "]";
+    }
+
+private:
+
+    friend class NCurses;
+
+    static void init_colors()
+    {
+
+	//get number of available colors (property of the terminal)
+	//the same with color pairs
+
+	_colors = ::COLORS;
+	_pairs = ::COLOR_PAIRS;
+
+	//if we have more than 8 colors available, use only 8 anyway
+	//in order to preserve the same color palette even for
+	//e.g. 256color terminal
+
+	if ( _colors > COLOR_WHITE + 1 )
+	    //_colors = 8 at all times
+	    _colors = COLOR_WHITE + 1;
+
+	if ( _pairs > _colors * _colors )
+	    //_pairs == 64 at all times
+	    _pairs = _colors * _colors;
+
+	for ( short i = 1; i < color_pairs(); ++i )
+	    ::init_pair( i, fg_color_pair( i ), bg_color_pair( i ) );
+    }
+};
+
+
+
+class NCattrset
+{
+
+private:
+
+    std::vector attr;
+
+public:
+
+    NCattrset( unsigned num ) : attr( num, A_NORMAL ) {}
+
+    virtual ~NCattrset() {}
+
+public:
+
+    const chtype & operator[]( unsigned a ) const { return attr[a]; }
+
+    chtype getAttr( unsigned a ) const { return attr[a]; }
+
+    chtype getStyle( unsigned a ) const { return NCattribute::getStyle( attr[a] ); }
+
+    chtype getColor( unsigned a ) const { return NCattribute::getColor( attr[a] ); }
+
+    chtype getChar( unsigned a ) const { return NCattribute::getChar( attr[a] ); }
+
+    chtype getNonChar( unsigned a ) const { return NCattribute::getNonChar( attr[a] ); }
+
+    void setAttr( unsigned a, chtype ch ) { attr[a] = ch; }
+
+    void setStyle( unsigned a, chtype ch ) { NCattribute::setStyle( attr[a], ch ); }
+
+    void setColor( unsigned a, chtype ch ) { NCattribute::setColor( attr[a], ch ); }
+
+    void setChar( unsigned a, chtype ch ) { NCattribute::setChar( attr[a], ch ); }
+
+    void addStyle( unsigned a, chtype ch ) { NCattribute::addStyle( attr[a], ch ); }
+
+    void delStyle( unsigned a, chtype ch ) { NCattribute::delStyle( attr[a], ch ); }
+
+    void toggleStyle( unsigned a, chtype ch ) { NCattribute::toggleStyle( attr[a], ch ); }
+
+    void addAlt( unsigned a ) { NCattribute::addAlt( attr[a] ); }
+
+    void delAlt( unsigned a ) { NCattribute::delAlt( attr[a] ); }
+
+public:
+
+    short getFg( unsigned a ) const { return NCattribute::getFg( attr[a] ); }
+
+    short getBg( unsigned a ) const { return NCattribute::getBg( attr[a] ); }
+
+    void setFg( unsigned a, short c ) { NCattribute::setFg( attr[a], c ); }
+
+    void setBg( unsigned a, short c ) { NCattribute::setBg( attr[a], c ); }
+};
+
+
+
+class NCstyle
+{
+
+    friend class NCStyleDef;
+
+public:
+
+    enum STglobal
+    {
+	AppTitle,
+	AppText,
+	// last entry
+	MaxSTglobal
+    };
+
+    enum STlocal
+    {
+	DialogBorder,
+	DialogTitle,
+	DialogActiveBorder,
+	DialogActiveTitle,
+	//
+	DialogText,
+	DialogHeadline,
+	//
+	DialogDisabled,
+	//
+	DialogPlain,
+	DialogLabel,
+	DialogData,
+	DialogHint,
+	DialogScrl,
+	DialogActivePlain,
+	DialogActiveLabel,
+	DialogActiveData,
+	DialogActiveHint,
+	DialogActiveScrl,
+	//
+	DialogFramePlain,
+	DialogFrameLabel,
+	DialogFrameData,
+	DialogFrameHint,
+	DialogFrameScrl,
+	DialogActiveFramePlain,
+	DialogActiveFrameLabel,
+	DialogActiveFrameData,
+	DialogActiveFrameHint,
+	DialogActiveFrameScrl,
+	//
+	ListTitle,
+	ListPlain,
+	ListLabel,
+	ListData,
+	ListHint,
+	ListSelPlain,
+	ListSelLabel,
+	ListSelData,
+	ListSelHint,
+	//
+	ListActiveTitle,
+	ListActivePlain,
+	ListActiveLabel,
+	ListActiveData,
+	ListActiveHint,
+	ListActiveSelPlain,
+	ListActiveSelLabel,
+	ListActiveSelData,
+	ListActiveSelHint,
+	//
+	RichTextPlain,
+	RichTextTitle,
+	RichTextLink,
+	RichTextArmedlink,
+	RichTextActiveArmedlink,
+	RichTextVisitedLink,
+	RichTextB,
+	RichTextI,
+	RichTextT,
+	RichTextBI,
+	RichTextBT,
+	RichTextIT,
+	RichTextBIT,
+	//
+	ProgbarCh,
+	ProgbarBgch,
+	//
+	TextCursor,
+	// last entry
+	MaxSTlocal
+    };
+
+public:
+
+    struct StBase
+    {
+	const chtype & title;
+	const chtype & text;
+	StBase( const chtype & ti, const chtype & te )
+		: title( ti ), text( te )
+	{}
+    };
+
+    struct STChar
+    {
+	const chtype & chattr;
+	chtype getChar()    const { return NCattribute::getChar( chattr ); }
+
+	chtype getNonChar() const { return NCattribute::getNonChar( chattr ); }
+
+	STChar( const chtype & cha )
+		: chattr( cha )
+	{}
+    };
+
+    struct StItem
+    {
+	const chtype & plain;
+	const chtype & label;
+	const chtype & data;
+	const chtype & hint;
+	StItem( const chtype & p, const chtype & l, const chtype & d, const chtype & h )
+		: plain( p ), label( l ), data( d ), hint( h )
+	{}
+    };
+
+    struct StWidget : public StItem
+    {
+	const chtype & scrl;
+	StWidget( const chtype & p, const chtype & l, const chtype & d, const chtype & h,
+		  const chtype & s )
+		: StItem( p, l, d, h ), scrl( s )
+	{}
+    };
+
+    struct StList
+    {
+	const chtype & title;
+	const StItem   item;
+	const StItem   selected;
+	StList( const chtype & t, const StItem & i, const StItem & s )
+		: title( t ), item( i ), selected( s )
+	{}
+
+	const StItem & getItem( bool sel ) const { return sel ? selected : item; }
+    };
+
+    struct StProgbar
+    {
+	const STChar bar;
+	const STChar nonbar;
+	StProgbar( const chtype & b, const chtype & nb )
+		: bar( b ), nonbar( nb )
+	{}
+    };
+
+    struct StRichtext
+    {
+	const chtype & plain;
+	const chtype & title;
+	const chtype & link;
+	const chtype & armedlink;
+	const chtype & activearmedlink;
+	const chtype & visitedlink;
+	const chtype & B;
+	const chtype & I;
+	const chtype & T;
+	const chtype & BI;
+	const chtype & BT;
+	const chtype & IT;
+	const chtype & BIT;
+
+	StRichtext( const chtype & p, const chtype & tit,
+		    const chtype & l, const chtype & al, const chtype & aal, const chtype & vl,
+		    const chtype & b, const chtype & i, const chtype & t,
+		    const chtype & bi, const chtype & bt, const chtype & it,
+		    const chtype & bit )
+		: plain( p ), title( tit ),
+		link( l ), armedlink( al ), activearmedlink( aal ), visitedlink( vl ),
+		B( b ), I( i ), T( t ),
+		BI( bi ), BT( bt ), IT( it ),
+		BIT( bit )
+	{}
+
+	const chtype & getArmed( NC::WState s ) const
+	{
+	    return ( s == NC::WSactive ) ? activearmedlink : armedlink;
+	}
+    };
+
+    struct StDialog
+    {
+	StBase	  border;
+	StBase	  activeBorder;
+	StBase	  dumb;
+	StWidget  disabled;
+	StWidget  normal;
+	StWidget  active;
+	StWidget  frame;
+	StWidget  activeFrame;
+	StList	  list;
+	StList	  activeList;
+	StList	  disabledList;
+	StProgbar  progbar;
+	StRichtext richtext;
+	const chtype & cursor;
+	//
+	StDialog( const StBase & b, const StBase & ab, const StBase & d, const StWidget & dis,
+		  const StWidget & n, const StWidget & a,
+		  const StWidget & f, const StWidget & af,
+		  const StList & l, const StList & al, const StList & dl,
+		  const StProgbar & pbar,
+		  const StRichtext & rtext,
+		  const chtype & curs )
+		: border( b ), activeBorder( ab ), dumb( d ), disabled( dis ),
+		normal( n ), active( a ),
+		frame( f ), activeFrame( af ),
+		list( l ), activeList( al ), disabledList( dl ),
+		progbar( pbar ),
+		richtext( rtext ),
+		cursor( curs )
+	{}
+
+public:
+
+	const StBase & getDlgBorder( bool active ) const { return active ? activeBorder : border; }
+
+	const StBase & getDumb()		   const { return dumb; }
+
+	const StWidget & getWidget( NC::WState s, bool nonactive = false ) const
+	{
+	    switch ( s )
+	    {
+
+		case NC::WSdisabled:
+		    return disabled;
+
+		case NC::WSactive:
+		    return nonactive ? normal : active;
+
+		case NC::WSnormal:
+
+		case NC::WSdumb:
+		    break;
+	    }
+
+	    return normal;
+	}
+
+	const StWidget & getFrame( NC::WState s ) const
+	{
+	    switch ( s )
+	    {
+
+		case NC::WSdisabled:
+		    return disabled;
+
+		case NC::WSactive:
+		    return activeFrame;
+
+		case NC::WSnormal:
+
+		case NC::WSdumb:
+		    break;
+	    }
+
+	    return frame;
+	}
+
+	const StList & getList( NC::WState s ) const
+	{
+	    switch ( s )
+	    {
+
+		case NC::WSdisabled:
+		    return disabledList;
+
+		case NC::WSactive:
+		    return activeList;
+
+		case NC::WSnormal:
+
+		case NC::WSdumb:
+		    break;
+	    }
+
+	    return list;
+	}
+    };
+
+public:
+
+
+    class Style : private NCattrset, public StDialog
+    {
+
+	friend class NCstyle;
+
+	Style & operator=( const Style & ); // no assignment
+
+    private:
+
+	static unsigned sanitycheck();
+	static NCattrset attrGlobal;
+
+    public:
+
+	NCattrset & getAttrGlobal() { return attrGlobal; }
+
+	NCattrset & getAttrLocal() { return *this; }
+
+    private:
+
+	StDialog initDialog(); // use this to initialize StDialog
+
+    public:
+
+	Style();
+	Style( const Style & rhs );
+	virtual ~Style();
+
+    public:
+
+	const chtype & attr( STglobal a ) const { return attrGlobal[a]; }
+
+	const chtype & attr( STlocal a )  const { return NCattrset::operator[]( a ); }
+
+	const chtype & operator()( STglobal a ) const { return attr( a ); }
+
+	const chtype & operator()( STlocal a )	const { return attr( a ); }
+    };
+
+public:
+
+    enum StyleSet
+    {
+	DefaultStyle,
+	InfoStyle,
+	WarnStyle,
+	PopupStyle,
+	// last entry
+	MaxStyleSet
+    };
+
+private:
+
+    std::string		styleName;
+    std::string		term;
+    std::vector