├── AUTHORS ├── CMakeLists.txt ├── ChangeLog ├── INSTALL ├── LICENSE ├── README.md ├── TODO ├── cmake └── Modules │ └── FindLibconfig++.cmake ├── etc ├── blacklist ├── colors.commander ├── colors.cyan ├── colors.dark ├── colors.green ├── colors.light ├── colors.red ├── ignore_versions ├── sboui-backend.conf ├── sboui-sync.py.in └── sboui.conf ├── icons └── sboui.svg ├── include ├── AbstractListBox.h ├── Blacklist.h ├── BuildActionBox.h ├── BuildListBox.h ├── BuildListItem.h ├── BuildOptionsBox.h ├── BuildOrderBox.h ├── CLOParser.h ├── CategoryListBox.h ├── CategoryListItem.h ├── Color.h ├── ColorTheme.h ├── ComboBox.h ├── ComboBoxList.h ├── CursesWidget.h ├── DefaultOptionsBox.h ├── DirListBox.h ├── DirListing.h ├── FilterBox.h ├── HelpItem.h ├── HelpWindow.h ├── IgnoreVersions.h ├── InputBox.h ├── InputItem.h ├── InstallBox.h ├── KeyHelpWindow.h ├── Label.h ├── ListBox.h ├── ListItem.h ├── MainWindow.h ├── Menubar.h ├── MenubarList.h ├── MenubarListItem.h ├── MessageBox.h ├── MouseEvent.h ├── MouseHelpWindow.h ├── OptionsWindow.h ├── PackageInfoBox.h ├── QuickSearch.h ├── ScrollBox.h ├── SearchBox.h ├── SelectionBox.h ├── ShellReader.h ├── TagList.h ├── TextInput.h ├── ToggleInput.h ├── backend.h ├── filters.h ├── requirements.h ├── settings.h ├── signals.h └── string_util.h ├── man ├── sboui-backend.8 ├── sboui-backend.conf.5 ├── sboui-update-notifier.1 ├── sboui.8 └── sboui.conf.5 ├── sboui.desktop.in ├── screenshots ├── commander.png ├── install.png ├── options.png └── package_info.png └── src ├── AbstractListBox.cpp ├── Blacklist.cpp ├── BuildActionBox.cpp ├── BuildListBox.cpp ├── BuildListItem.cpp ├── BuildOptionsBox.cpp ├── BuildOrderBox.cpp ├── CLOParser.cpp ├── CategoryListBox.cpp ├── CategoryListItem.cpp ├── Color.cpp ├── ColorTheme.cpp ├── ComboBox.cpp ├── ComboBoxList.cpp ├── CursesWidget.cpp ├── DefaultOptionsBox.cpp ├── DirListBox.cpp ├── DirListing.cpp ├── FilterBox.cpp ├── HelpItem.cpp ├── HelpWindow.cpp ├── IgnoreVersions.cpp ├── InputBox.cpp ├── InputItem.cpp ├── InstallBox.cpp ├── KeyHelpWindow.cpp ├── Label.cpp ├── ListBox.cpp ├── ListItem.cpp ├── MainWindow.cpp ├── Menubar.cpp ├── MenubarList.cpp ├── MenubarListItem.cpp ├── MessageBox.cpp ├── MouseEvent.cpp ├── MouseHelpWindow.cpp ├── OptionsWindow.cpp ├── PackageInfoBox.cpp ├── QuickSearch.cpp ├── ScrollBox.cpp ├── SearchBox.cpp ├── SelectionBox.cpp ├── ShellReader.cpp ├── TagList.cpp ├── TextInput.cpp ├── ToggleInput.cpp ├── backend.cpp ├── filters.cpp ├── requirements.cpp ├── sboui-backend.in ├── sboui-systray.py ├── sboui-update-notifier.in ├── sboui.cpp ├── sboui_launch.in ├── sboui_update_launch.in ├── settings.cpp ├── signals.cpp └── string_util.cpp /AUTHORS: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016-2018 2 | 3 | Daniel Prosser is the author of sboui. 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Set up project 2 | cmake_minimum_required(VERSION 3.5) 3 | set(SBOUI_VERSION 2.4) 4 | project(sboui) 5 | 6 | # Sources and include directories 7 | include_directories(include) 8 | file(GLOB SOURCES "src/*.cpp") 9 | 10 | # Create executable 11 | add_executable(sboui ${SOURCES}) 12 | set_property(TARGET sboui PROPERTY CXX_STANDARD 11) 13 | set_property(TARGET sboui PROPERTY CXX_STANDARD_REQUIRED ON) 14 | 15 | # Default compiler flags 16 | set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall") 17 | set(CMAKE_CXX_FLAGS_RELEASE "-O2 -fopenmp") 18 | 19 | # Some default directories 20 | set(CONFDIR /etc/sboui 21 | CACHE PATH "Directory to install sboui.conf and sboui-backend.conf." 22 | ) 23 | set(DATADIR ${CMAKE_INSTALL_PREFIX}/share/sboui 24 | CACHE PATH "Directory to install shared data." 25 | ) 26 | set(MANDIR ${CMAKE_INSTALL_PREFIX}/man 27 | CACHE PATH "Base directory to install manuals." 28 | ) 29 | set(PACKAGEDIR /var/lib/pkgtools/packages 30 | CACHE PATH "Location of installed packages list." 31 | ) 32 | 33 | set(CRONDIR /etc/cron.hourly 34 | CACHE PATH "Directory for sboui --sync cronjob (only if INSTALL_SYSTRAY_NOTIFIER is enabled)." 35 | ) 36 | 37 | # Variables related to the Exec command in the desktop launcher 38 | set(GRAPHICAL_SU kdesu 39 | CACHE STRING "Graphical frontend for su (for desktop launcher)") 40 | set(TERMINAL_EMULATOR xterm 41 | CACHE STRING "Terminal emulator (for desktop launcher)") 42 | 43 | # Whether to install --sync cronjob and systray update notifier 44 | set(INSTALL_SYSTRAY_NOTIFIER FALSE 45 | CACHE BOOL "Whether to install --sync cronjob and systray update notifier") 46 | 47 | # kdesu requires -c to before command 48 | if (${GRAPHICAL_SU} STREQUAL "kdesu") 49 | set(GRAPHICAL_SU_CMD "${GRAPHICAL_SU} -c") 50 | else (${GRAPHICAL_SU} STREQUAL "kdesu") 51 | set(GRAPHICAL_SU_CMD "${GRAPHICAL_SU}") 52 | endif (${GRAPHICAL_SU} STREQUAL "kdesu") 53 | 54 | # Preprocessor definitions 55 | add_definitions(-DPACKAGE_VERSION=\"${SBOUI_VERSION}\") 56 | add_definitions(-DCONFDIR=\"${CONFDIR}\") 57 | add_definitions(-DPACKAGE_DIR=\"${PACKAGEDIR}\") 58 | add_definitions(-DDATADIR=\"${DATADIR}\") 59 | 60 | # Check for curses library 61 | set(CURSES_NEED_WIDE TRUE) 62 | find_package(Curses REQUIRED) 63 | if (CURSES_FOUND) 64 | include_directories(${CURSES_INCLUDE_DIRS}) 65 | target_link_libraries(sboui ${CURSES_LIBRARIES}) 66 | endif (CURSES_FOUND) 67 | 68 | # Check for libconfig++ 69 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") 70 | find_package(Libconfig++ REQUIRED) 71 | if (LIBCONFIG++_FOUND) 72 | include_directories(${LIBCONFIG++_INCLUDE_DIR}) 73 | target_link_libraries(sboui ${LIBCONFIG++_LIBRARY}) 74 | endif (LIBCONFIG++_FOUND) 75 | 76 | # Configure files 77 | configure_file(src/sboui-backend.in sboui-backend @ONLY) 78 | configure_file(src/sboui_launch.in sboui_launch @ONLY) 79 | configure_file(src/sboui_update_launch.in sboui_update_launch @ONLY) 80 | configure_file(src/sboui-update-notifier.in sboui-update-notifier) 81 | configure_file(sboui.desktop.in sboui.desktop) 82 | configure_file(etc/sboui-sync.py.in sboui-sync.py) 83 | 84 | # Install rules 85 | install(TARGETS sboui DESTINATION sbin) 86 | install(FILES ${CMAKE_BINARY_DIR}/sboui-backend 87 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE 88 | GROUP_READ GROUP_EXECUTE 89 | WORLD_READ WORLD_EXECUTE 90 | DESTINATION sbin) 91 | install(FILES ${CMAKE_BINARY_DIR}/sboui_launch 92 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE 93 | GROUP_READ GROUP_EXECUTE 94 | WORLD_READ WORLD_EXECUTE 95 | DESTINATION libexec/sboui) 96 | install(FILES ${CMAKE_BINARY_DIR}/sboui_update_launch 97 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE 98 | GROUP_READ GROUP_EXECUTE 99 | WORLD_READ WORLD_EXECUTE 100 | DESTINATION libexec/sboui) 101 | install(FILES etc/sboui.conf etc/sboui-backend.conf etc/blacklist etc/ignore_versions 102 | DESTINATION ${CONFDIR}) 103 | file(GLOB COLOR_THEMES etc/colors.*) 104 | install(FILES ${COLOR_THEMES} DESTINATION ${DATADIR}/themes) 105 | install(FILES man/sboui.8 man/sboui-backend.8 DESTINATION ${MANDIR}/man8) 106 | install(FILES man/sboui.conf.5 man/sboui-backend.conf.5 107 | DESTINATION ${MANDIR}/man5) 108 | install(FILES ${CMAKE_BINARY_DIR}/sboui.desktop 109 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) 110 | install(FILES icons/sboui.svg 111 | DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps) 112 | 113 | # The following are only installed if INSTALL_SYSTRAY_NOTIFIER is enabled 114 | if(INSTALL_SYSTRAY_NOTIFIER) 115 | install(FILES ${CMAKE_BINARY_DIR}/sboui-update-notifier 116 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE 117 | GROUP_READ GROUP_EXECUTE 118 | WORLD_READ WORLD_EXECUTE 119 | DESTINATION bin) 120 | install(FILES src/sboui-systray.py 121 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE 122 | GROUP_READ GROUP_EXECUTE 123 | WORLD_READ WORLD_EXECUTE 124 | DESTINATION libexec/sboui) 125 | install(FILES ${CMAKE_BINARY_DIR}/sboui-sync.py 126 | PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE 127 | GROUP_READ GROUP_EXECUTE 128 | WORLD_READ WORLD_EXECUTE 129 | DESTINATION ${CRONDIR}) 130 | install(FILES man/sboui-update-notifier.1 131 | DESTINATION ${MANDIR}/man1) 132 | endif(INSTALL_SYSTRAY_NOTIFIER) 133 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ========================= 3 | 4 | sboui uses a combination of CMake and Makefiles to build and install. CMake 5 | is responsible for determining system-dependent parameters, such as locating 6 | and testing the compiler and required libraries. It then generates Makefiles, 7 | which are scripts that build (by invoking the compiler and linker) and 8 | install the software. A basic workflow for building and installing is as 9 | follows: 10 | 11 | cd /path/to/sboui/top/dir 12 | mkdir build 13 | cd build 14 | cmake .. 15 | make 16 | make install 17 | cd .. 18 | 19 | This process compile the software in the /path/to/sboui/top/dir/build 20 | directory and install it to the default install path (root privileges may be 21 | needed for the install step). Some influential variables that may be passed 22 | to the cmake command include: 23 | 24 | * CMAKE_CXX_COMPILER (name of compiler executable) 25 | * CMAKE_INSTALL_PREFIX (location to install) 26 | * CMAKE_BUILD_TYPE (typically "Release" or "Debug") 27 | * LIBCONFIG++_INCLUDE_DIR (location of libconfig++.h header file) 28 | * LIBCONFIG++_LIBRARY (full path to libconfig++ library) 29 | 30 | Other variables are available as well. They can be viewed by navigating to 31 | the build directory, running `cmake` to set up the build, and then running 32 | `ccmake ..`. Any of these variables can be defined by passing them as options 33 | to CMake as follows: 34 | 35 | cmake \ 36 | -D{variable1 name}={variable1 value} \ 37 | -D{variable2 name}={variable2 value} \ 38 | (etc) \ 39 | .. 40 | 41 | where {variableX name} and {variableX value} are substituted by the actual 42 | names and values. String values are typically enclosed in quotes. 43 | 44 | Note that the libconfig++ library is required, and the `cmake` command will 45 | fail if it is not present. The project website for libconfig++ is: 46 | 47 | http://www.hyperrealm.com/libconfig/ 48 | 49 | If libconfig++ is not installed in standard system paths (e.g., /usr/include 50 | for the header file and /usr/lib for the library), you may set the variables 51 | LIBCONFIG++_INCLUDE_DIR and LIBCONFIG++_LIBRARY. 52 | 53 | By default, the sboui's configuration file, called sboui.conf, will always be 54 | installed in /etc/sboui, because that is where the program expects it to be. 55 | To override this location, set the CONFDIR variable as desired. 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Expat/MIT License 2 | 3 | Copyright (c) 2017 Daniel Prosser 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Overview 2 | ================================================================================ 3 | sboui is a package management tool for SlackBuilds.org (SBo). It features an 4 | ncurses user interface that combines the user-friendliness typically found in 5 | a GUI with the efficiency, light weight, and portability of a text interface. 6 | It can function as a stand-alone package manager or serve as a front-end to 7 | sbopkg, sbotools, or custom package managers. Its main features include: 8 | 9 | * Efficient operation with the keyboard, and full mouse support 10 | * Forward and inverse dependency resolution 11 | * Automatic rebuilding of inverse dependencies (optional) 12 | * Blacklisting 13 | * Storing build options for individual SlackBuild scripts 14 | * "Tagging" to operate on multiple SlackBuilds 15 | * Searching the repository by name or by content in READMEs 16 | * A menu bar, buttons, drop-downs, and other elements typically found in GUI 17 | * For desktop users, a system tray notifier for SBo updates (optional) and a 18 | .desktop file 19 | 20 | Installation 21 | ================================================================================ 22 | sboui is available from SlackBuilds.org, which is the recommended method for 23 | obtaining it. Of course, custom and local builds are also possible; see the 24 | INSTALL file for more information. 25 | 26 | Operation 27 | ================================================================================ 28 | The interface and operation of sboui was inspired by Midnight Commander, a 29 | two-pane file manager with a text-based interface. If you are familiar with 30 | that application, sboui should be very easy to pick up. 31 | 32 | On first-time use, you may first need to set up the repository. You can do this 33 | with the sync command, which can be found under Actions in the menu bar, using 34 | the 's' keyboard shortcut, or from the command line using the --sync command 35 | line option. You should also run the sync command regularly to check for 36 | updates. 37 | 38 | If you already have a local repository set up (for example, if you are using 39 | sboui as a front-end to sbopkg or sbotools), then make sure that repo_dir is set 40 | correctly in the config file. All settings can also be edited interactively in 41 | the Options window (under File in the menu bar or using the 'o' keyboard 42 | shortcut). sboui can also automatically set the relevant config variables when 43 | changing the package manager from the Options window. 44 | 45 | To install a package, browse for it in the main window or use a search to locate 46 | it. Search can be found under Actions in the menu bar, or using the '/' keyboard 47 | shortcut. Select the desired package in the right pane and click Enter or 48 | double-click with the mouse. This will bring up a list of actions that can be 49 | performed for that package, including viewing the README, browsing the files for 50 | the SlackBuild in the repository, installing, etc. When a package is installed, 51 | upgraded, reinstalled, or removed, sboui automatically computes the build order 52 | and offers suggestions for each package in the build order. If you do not wish 53 | to perform the suggested action for each of these packages, you can toggle it by 54 | left-clicking in the box or using the space bar. 55 | 56 | To upgrade all, you can use the Ctrl-u keyboard combination, look in the menu 57 | bar under Actions, or use the --upgrade-all command line option. This action is 58 | a convenience method which does the following: filter by upgradable SlackBuilds, 59 | tag all, and then upgrade tagged. The same can be done manually if desired. 60 | To tag, use the 't' keyboard shortcut with any SlackBuild highlighted in most 61 | display lists in sboui, or, alternatively, right-click with the mouse. Entire 62 | groups can be tagged by tagging an entry in the Groups list. Filters can be 63 | selected in the menu bar or with the 'f' keyboard shortcut. 64 | 65 | This has been a brief introduction to sboui's capabilities and usage. Please 66 | take a look at the keyboard and mouse shortcuts under Help in the menu as well 67 | well as the man pages, and have fun! 68 | 69 | Using sboui with custom package managers 70 | ================================================================================ 71 | sboui can be used with custom SBo package management tools, instead of the 72 | built-in package manager (sboui-backend), sbopkg, or sbotools. The process is 73 | fairly simple, but there are a few requirements: 74 | 75 | * The package manager must store a local copy of the SlackBuilds.org repository. 76 | Use the repo_dir config variable to point to the top level. 77 | * It must implement a sync / update command, referenced by sync_cmd. 78 | * It must implement install, upgrade, and reinstall commands. In general, these 79 | can all actually be the same command, as long as it handles all these use 80 | cases. These commands should not resolve dependencies, because sboui handles 81 | that part. sboui will tack on the name of the package to be installed at the 82 | end of these commands (install_cmd, upgrade_cmd, and reinstall_cmd). For 83 | example, install_cmd for sbopkg is "sbopkg -B -i". 84 | 85 | In addition to the above, the following are recommended for optimal user 86 | experience: 87 | 88 | * When there is an error, the package manager should exit with a return value 89 | other than 0. Otherwise, sboui will indicate that the command succeeded when 90 | it actually failed. 91 | * No prompts or questions should be presented to the user by any of these 92 | commands, because sboui will do the same, resulting in tedious duplicated 93 | prompts. 94 | 95 | Screenshots 96 | ================================================================================ 97 | ![alt tag](https://raw.githubusercontent.com/montagdude/sboui/master/screenshots/commander.png) 98 | ![alt tag](https://raw.githubusercontent.com/montagdude/sboui/master/screenshots/install.png) 99 | ![alt tag](https://raw.githubusercontent.com/montagdude/sboui/master/screenshots/options.png) 100 | ![alt tag](https://raw.githubusercontent.com/montagdude/sboui/master/screenshots/package_info.png) 101 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - Add slpkg (see forum post 6/5/23) 2 | - psutil split into python2 and python3 versions - fix optional dependency name 3 | - Change update notifier to python3 4 | - gnucash picking up wrong build options (not sure if reproducible) 5 | - Segfault when using my custom repository with -f /etc/sboui/sboui-custom.conf. Seems to be caused by buildopts (moving the existing files out fixes it). 6 | - Action to clean /tmp/SBo 7 | - Build options not removed properly in sub-actions dialog 8 | -------------------------------------------------------------------------------- /cmake/Modules/FindLibconfig++.cmake: -------------------------------------------------------------------------------- 1 | find_path(LIBCONFIG++_INCLUDE_DIR libconfig.h++) 2 | find_library(LIBCONFIG++_LIBRARY NAMES config++) 3 | 4 | if (LIBCONFIG++_INCLUDE_DIR AND LIBCONFIG++_LIBRARY) 5 | set(LIBCONFIG++_FOUND TRUE) 6 | endif (LIBCONFIG++_INCLUDE_DIR AND LIBCONFIG++_LIBRARY) 7 | 8 | if (LIBCONFIG++_FOUND) 9 | message(STATUS "Found libconfig++ header in ${LIBCONFIG++_INCLUDE_DIR}") 10 | message(STATUS "Found libconfig++ library: ${LIBCONFIG++_LIBRARY}") 11 | else (LIBCONFIG++_FOUND) 12 | if (NOT LIBCONFIG++_INCLUDE_DIR) 13 | message(FATAL_ERROR "Could NOT find libconfig++.h!") 14 | endif (NOT LIBCONFIG++_INCLUDE_DIR) 15 | 16 | if (NOT LIBCONFIG++_LIBRARY) 17 | message(FATAL_ERROR "Could NOT find libconfig++ library!") 18 | endif (NOT LIBCONFIG++_LIBRARY) 19 | endif (LIBCONFIG++_FOUND) 20 | -------------------------------------------------------------------------------- /etc/blacklist: -------------------------------------------------------------------------------- 1 | # This is sboui's blacklist file. It operates on package names as well as any 2 | # SlackBuild name in the repo. sboui will not install, remove, upgrade, or 3 | # reinstall any package or SlackBuild listed here. 4 | 5 | # Example blacklisting by name: 6 | #avl 7 | #vlc 8 | #i3 9 | 10 | # You can blacklist using regular expressions 11 | # 12 | # You don't need to use the full regex here, because all of the following 13 | # will be checked for the regex: name, version, arch, build, and full package 14 | # name. 15 | # 16 | # This one will blacklist all Alien Bob packages 17 | #[0-9]+alien 18 | # 19 | # This one would blacklist anything with "flash" in the name 20 | #(.*)flash(.*) 21 | -------------------------------------------------------------------------------- /etc/colors.commander: -------------------------------------------------------------------------------- 1 | theme_name = "commander" 2 | fg_normal = "white" 3 | bg_normal = "blue" 4 | fg_title = "brightblack" 5 | bg_title = "white" 6 | fg_info = "brightblack" 7 | bg_info = "white" 8 | fg_highlight_active = "black" 9 | bg_highlight_active = "cyan" 10 | fg_highlight_inactive = "white" 11 | bg_highlight_inactive = "black" 12 | header = "brightyellow" 13 | header_popup = "brightblue" 14 | tagged = "brightyellow" 15 | fg_popup = "white" 16 | bg_popup = "black" 17 | fg_warning = "white" 18 | bg_warning = "red" 19 | hotkey = "brightblue" 20 | fg_combobox = "black" 21 | bg_combobox = "white" 22 | -------------------------------------------------------------------------------- /etc/colors.cyan: -------------------------------------------------------------------------------- 1 | theme_name = "cyan" 2 | fg_normal = "black" 3 | bg_normal = "cyan" 4 | fg_title = "brightwhite" 5 | bg_title = "black" 6 | fg_info = "brightwhite" 7 | bg_info = "black" 8 | fg_highlight_active = "brightcyan" 9 | bg_highlight_active = "magenta" 10 | fg_highlight_inactive = "white" 11 | bg_highlight_inactive = "black" 12 | header = "brightyellow" 13 | header_popup = "brightmagenta" 14 | tagged = "brightyellow" 15 | fg_popup = "white" 16 | bg_popup = "black" 17 | fg_warning = "white" 18 | bg_warning = "red" 19 | hotkey = "brightyellow" 20 | fg_combobox = "white" 21 | bg_combobox = "black" 22 | -------------------------------------------------------------------------------- /etc/colors.dark: -------------------------------------------------------------------------------- 1 | theme_name = "dark" 2 | fg_normal = "white" 3 | bg_normal = "black" 4 | fg_title = "brightwhite" 5 | bg_title = "blue" 6 | fg_info = "brightwhite" 7 | bg_info = "blue" 8 | fg_highlight_active = "brightwhite" 9 | bg_highlight_active = "cyan" 10 | fg_highlight_inactive = "black" 11 | bg_highlight_inactive = "white" 12 | header = "brightyellow" 13 | header_popup = "brightblack" 14 | tagged = "brightred" 15 | fg_popup = "blue" 16 | bg_popup = "white" 17 | fg_warning = "white" 18 | bg_warning = "red" 19 | hotkey = "brightred" 20 | fg_combobox = "blue" 21 | bg_combobox = "white" 22 | -------------------------------------------------------------------------------- /etc/colors.green: -------------------------------------------------------------------------------- 1 | theme_name = "green" 2 | fg_normal = "black" 3 | bg_normal = "green" 4 | fg_title = "black" 5 | bg_title = "cyan" 6 | fg_info = "black" 7 | bg_info = "cyan" 8 | fg_highlight_active = "brightwhite" 9 | bg_highlight_active = "blue" 10 | fg_highlight_inactive = "black" 11 | bg_highlight_inactive = "white" 12 | header = "brightblack" 13 | header_popup = "brightblack" 14 | tagged = "brightmagenta" 15 | fg_popup = "black" 16 | bg_popup = "white" 17 | fg_warning = "white" 18 | bg_warning = "red" 19 | hotkey = "brightred" 20 | fg_combobox = "black" 21 | bg_combobox = "cyan" 22 | -------------------------------------------------------------------------------- /etc/colors.light: -------------------------------------------------------------------------------- 1 | theme_name = "light" 2 | fg_normal = "black" 3 | bg_normal = "white" 4 | fg_title = "brightwhite" 5 | bg_title = "cyan" 6 | fg_info = "brightwhite" 7 | bg_info = "cyan" 8 | fg_highlight_active = "brightwhite" 9 | bg_highlight_active = "blue" 10 | fg_highlight_inactive = "white" 11 | bg_highlight_inactive = "black" 12 | header = "brightred" 13 | header_popup = "brightwhite" 14 | tagged = "brightred" 15 | fg_popup = "white" 16 | bg_popup = "black" 17 | fg_warning = "white" 18 | bg_warning = "red" 19 | hotkey = "brightmagenta" 20 | fg_combobox = "white" 21 | bg_combobox = "black" 22 | -------------------------------------------------------------------------------- /etc/colors.red: -------------------------------------------------------------------------------- 1 | theme_name = "red" 2 | fg_normal = "white" 3 | bg_normal = "red" 4 | fg_title = "brightwhite" 5 | bg_title = "black" 6 | fg_info = "brightwhite" 7 | bg_info = "black" 8 | fg_highlight_active = "brightblack" 9 | bg_highlight_active = "yellow" 10 | fg_highlight_inactive = "white" 11 | bg_highlight_inactive = "black" 12 | header = "brightwhite" 13 | header_popup = "brightblack" 14 | tagged = "brightyellow" 15 | fg_popup = "black" 16 | bg_popup = "white" 17 | fg_warning = "white" 18 | bg_warning = "red" 19 | hotkey = "brightred" 20 | fg_combobox = "black" 21 | bg_combobox = "white" 22 | -------------------------------------------------------------------------------- /etc/ignore_versions: -------------------------------------------------------------------------------- 1 | # This file lists versions of SlackBuilds to ignore when checking which are 2 | # upgradable. This can be useful if you have upgraded a SlackBuild beyond the 3 | # version on SlackBuilds.org and don't want it to be tagged as upgradable. 4 | # Multiple versions can be listed for a single SlackBuild if desired. 5 | # e.g.: 6 | #jdk11:11.0.22 7 | #jdk11:11.0.23 8 | #libreoffice:24.2.5 9 | -------------------------------------------------------------------------------- /etc/sboui-backend.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Configuration file for sboui-backend 3 | # 4 | 5 | # Repository to use. Note Ponce repo is for -current only. 6 | REPO=git://git.slackbuilds.org/slackbuilds.git 7 | #REPO=https://github.com/Ponce/slackbuilds.git 8 | 9 | # Branch (not applicable to Ponce repo). e.g., master, 15.0, 14.2, etc. 10 | BRANCH=15.0 11 | 12 | # Location to clone git repository 13 | REPO_DIR=/var/lib/sboui/repo 14 | 15 | # Whether to remove built package after installing (yes/no) 16 | CLEAN_PACKAGE=no 17 | 18 | # Whether to remove temporary source and package directories after building 19 | CLEAN_TMP=no 20 | 21 | # Whether to remove source tarball(s) after downloading 22 | CLEAN_SOURCE=yes 23 | -------------------------------------------------------------------------------- /etc/sboui-sync.py.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # This script checks the SBo RSS feed for updates. If an update has been posted, 4 | # it runs sboui --sync to sync the local repository. This is intended to be run 5 | # regularly (say, hourly or daily) by root as a cronjob. 6 | 7 | import sys 8 | import subprocess 9 | import requests 10 | from datetime import datetime 11 | 12 | def last_rss_update(): 13 | 14 | # Download only the headers of the RSS feed to check last modified date 15 | 16 | try: 17 | response = requests.head('http://slackbuilds.org/rss/ChangeLog.rss') 18 | except requests.exceptions.ConnectionError: 19 | sys.stderr.write("Unable to download ChangeLog.rss: no connection.\n") 20 | sys.exit(1) 21 | 22 | if response.status_code != requests.codes.ok: 23 | sys.stderr.write(("Unable to download ChangeLog.rss: " + 24 | "got response {}.\n".format(response.status_code))) 25 | sys.exit(1) 26 | 27 | return datetime.strptime(response.headers['Last-Modified'], 28 | '%a, %d %b %Y %H:%M:%S %Z') 29 | 30 | def last_local_update(): 31 | 32 | try: 33 | f = open('/var/lib/sboui/last-sync.txt') 34 | except IOError: 35 | return datetime(1900, 1, 1, 0, 0, 0) 36 | 37 | try: 38 | last_update = datetime.strptime(f.readline().strip(), 39 | '%a, %d %b %Y %H:%M:%S %Z') 40 | except ValueError: 41 | return datetime(1900, 1, 1, 0, 0, 0) 42 | 43 | f.close() 44 | return last_update 45 | 46 | if __name__ == "__main__": 47 | 48 | # Sync local repository if RSS feed has been updated 49 | 50 | if last_rss_update() > last_local_update(): 51 | subprocess.call(['${CMAKE_INSTALL_PREFIX}/sbin/sboui', '-s']) 52 | else: 53 | print('Already up-to-date; not syncing.') 54 | -------------------------------------------------------------------------------- /etc/sboui.conf: -------------------------------------------------------------------------------- 1 | # sboui configuration file 2 | 3 | # Please read the sboui.conf(5) man page for more information about these 4 | # variables 5 | 6 | ## Package manager settings 7 | ## These are the only strictly required settings in this file 8 | repo_dir = "/var/lib/sboui/repo" # Standard location for built-in 9 | #repo_dir = "/var/lib/sbopkg/SBo/14.2" # Standard location for sbopkg 10 | #repo_dir = "/usr/sbo/repo" # Standard location for sbotools 11 | package_manager = "built-in" 12 | 13 | ## The following are only required for custom package_manager 14 | ## sboui will set correct defaults built-in for sbopkg, sbotools, and built-in 15 | # sync_cmd = "sbopkg -r" 16 | # install_cmd = "sbopkg -B -i" 17 | # upgrade_cmd = "sbopkg -B -i" 18 | # reinstall_cmd = "sbopkg -B -i" 19 | 20 | ## Tag at end of package name identifying repository 21 | # repo_tag = "_SBo" 22 | 23 | ## Additional CLOs and environment variables when invoking package manager 24 | # install_clos = "" 25 | # install_vars = "" 26 | # upgrade_clos = "" 27 | # upgrade_vars = "" 28 | 29 | ## Application behavior 30 | resolve_deps = true 31 | rebuild_inv_deps = false 32 | confirm_changes = true 33 | save_buildopts = true 34 | warn_invalid_pkgnames = true 35 | cumulative_filters = true; 36 | layout = "horizontal" 37 | 38 | ## Color settings. Color themes stored in /usr/share/sboui/themes or 39 | ## $HOME/.local/share/sboui/themes 40 | enable_color = true 41 | #color_theme = "default (dark)" 42 | -------------------------------------------------------------------------------- /include/AbstractListBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "MouseEvent.h" 7 | #include "CursesWidget.h" 8 | 9 | class ListItem; 10 | 11 | /******************************************************************************* 12 | 13 | Template list box class. Used by both ListBox class (selectable items) and 14 | ScrollBox class (non-selectable items). 15 | 16 | *******************************************************************************/ 17 | class AbstractListBox: public CursesWidget { 18 | 19 | protected: 20 | 21 | std::string _name; 22 | std::vector _items; 23 | int _firstprint; 24 | 25 | virtual void redrawFrame(); 26 | virtual void redrawSingleItem(unsigned int idx) = 0; 27 | virtual void redrawScrollIndicator() const = 0; 28 | virtual void redrawAllItems(); 29 | 30 | public: 31 | 32 | /* Constructors */ 33 | 34 | AbstractListBox(); 35 | AbstractListBox(WINDOW *win, const std::string & name); 36 | 37 | /* Edit list */ 38 | 39 | virtual void addItem(ListItem *item); 40 | virtual void removeItem(unsigned int idx); 41 | virtual void clearList(); 42 | 43 | /* Set attributes */ 44 | 45 | void setName(const std::string & name); 46 | 47 | /* Get attributes */ 48 | 49 | const std::string & name() const; 50 | unsigned int numItems() const; 51 | virtual void minimumSize(int & height, int & width) const; 52 | virtual void preferredSize(int & height, int & width) const; 53 | 54 | /* Returns pointer to item */ 55 | 56 | ListItem * itemByIdx(unsigned int idx); 57 | 58 | /* Handles mouse event */ 59 | 60 | std::string handleMouseEvent(MouseEvent *mevent) = 0; 61 | 62 | /* Draws frame, items, etc. as needed */ 63 | 64 | virtual void draw(bool force=false); 65 | 66 | /* User interaction loop */ 67 | 68 | virtual std::string exec(MouseEvent * mevent=NULL) = 0; 69 | }; 70 | -------------------------------------------------------------------------------- /include/Blacklist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /******************************************************************************* 8 | 9 | Reads blacklist files and checks packages and SlackBuilds for matches 10 | 11 | *******************************************************************************/ 12 | class Blacklist { 13 | 14 | private: 15 | 16 | std::vector _patterns; 17 | 18 | public: 19 | 20 | /* Constructor */ 21 | 22 | Blacklist(); 23 | 24 | /* Reads blacklist patterns from file */ 25 | 26 | int read(const std::string & filename); 27 | 28 | /* Checks installed package for matches in name, version, arch, build, and 29 | fullname */ 30 | 31 | bool blacklisted(const std::string & pkg) const; 32 | bool blacklisted(const std::string & pkg, const std::string & name, 33 | const std::string & version, const std::string & arch, 34 | const std::string & build) const; 35 | 36 | /* Checks not-installed package for match in name only */ 37 | 38 | bool nameBlacklisted(const std::string & name) const; 39 | }; 40 | -------------------------------------------------------------------------------- /include/BuildActionBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ListItem.h" 5 | #include "BuildListItem.h" 6 | #include "SelectionBox.h" 7 | 8 | /******************************************************************************* 9 | 10 | SelectionBox for installing/upgrading/removing/etc. a SlackBuild 11 | 12 | *******************************************************************************/ 13 | class BuildActionBox: public SelectionBox { 14 | 15 | public: 16 | 17 | /* Constructors */ 18 | 19 | BuildActionBox(); 20 | 21 | /* Destructor */ 22 | 23 | ~BuildActionBox(); 24 | 25 | /* Sets up actions based on the SlackBuild selected */ 26 | 27 | void create(BuildListItem & build, bool limited_actions=false); 28 | }; 29 | -------------------------------------------------------------------------------- /include/BuildListBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ListBox.h" 6 | #include "MouseEvent.h" 7 | 8 | class TagList; 9 | 10 | /******************************************************************************* 11 | 12 | ListBox for SlackBuilds 13 | 14 | *******************************************************************************/ 15 | class BuildListBox: public ListBox { 16 | 17 | protected: 18 | 19 | TagList *_taglist; 20 | 21 | virtual void redrawFrame(); 22 | virtual void redrawSingleItem(unsigned int idx); 23 | 24 | public: 25 | 26 | /* Constructors */ 27 | 28 | BuildListBox(); 29 | BuildListBox(WINDOW *win, const std::string & name); 30 | 31 | /* Tagging */ 32 | 33 | void setTagList(TagList *taglist); 34 | void tagSlackBuild(unsigned int idx); 35 | void tagHighlightedSlackBuild(); 36 | unsigned int tagAll(); 37 | 38 | /* Accessing properties */ 39 | 40 | bool allTagged() const; 41 | 42 | /* User interaction loop */ 43 | 44 | virtual std::string exec(MouseEvent * mevent=NULL); 45 | }; 46 | -------------------------------------------------------------------------------- /include/BuildListItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "IgnoreVersions.h" 6 | #include "ListItem.h" 7 | 8 | /******************************************************************************* 9 | 10 | List item that describes a SlackBuild 11 | 12 | *******************************************************************************/ 13 | class BuildListItem: public ListItem { 14 | 15 | private: 16 | 17 | // Pointer to IgnoreVersions object 18 | 19 | const IgnoreVersions * _ignore_versions; 20 | 21 | // Checks whether a SlackBuild can be upgraded 22 | 23 | bool differsByKernel(const std::string & installed_version, 24 | const std::string & available_version) const; 25 | bool ignoreVersion(const std::string & version) const; 26 | bool upgradable() const; 27 | 28 | public: 29 | 30 | // Constructor 31 | 32 | BuildListItem(); 33 | 34 | // Convert ListItem to BuildListItem 35 | 36 | void operator = (const ListItem & item); 37 | 38 | // Sets IgnoreVersions pointer 39 | 40 | void setIgnoreVersions(IgnoreVersions * ignore_versions); 41 | 42 | // Reads properties from repo 43 | 44 | void readInstalledProps(std::vector & installedpkgs); 45 | int readPropsFromRepo(); 46 | 47 | // Determines BUILD number from last portion of package name 48 | 49 | void parseBuildNum(std::string & build); 50 | 51 | // Build options as string of environment variables 52 | 53 | std::string buildOptionsEnv() const; 54 | }; 55 | -------------------------------------------------------------------------------- /include/BuildOptionsBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "TextInput.h" 6 | #include "Label.h" 7 | #include "BuildListItem.h" 8 | #include "InputBox.h" 9 | #include "MouseEvent.h" 10 | 11 | /******************************************************************************* 12 | 13 | Input box for build options 14 | 15 | *******************************************************************************/ 16 | class BuildOptionsBox: public InputBox { 17 | 18 | private: 19 | 20 | Label _addlbl, _removelbl; 21 | std::vector _entries; 22 | 23 | // Place items 24 | 25 | void setUp(); 26 | 27 | // Add/remove entries 28 | 29 | void addEntry(); 30 | void removeLast(); 31 | 32 | public: 33 | 34 | /* Constructor */ 35 | 36 | BuildOptionsBox(); 37 | 38 | /* Set attributes */ 39 | 40 | void setBuild(const BuildListItem & build); 41 | 42 | /* Get attributes */ 43 | 44 | unsigned int numEntries() const; 45 | std::string entry(unsigned int idx) const; 46 | std::string entries() const; 47 | 48 | /* Write build options to file */ 49 | 50 | int write(const BuildListItem & build) const; 51 | 52 | /* Draws frame, items, etc. as needed */ 53 | 54 | void draw(bool force=false); 55 | 56 | /* User interaction loop */ 57 | 58 | std::string exec(MouseEvent * mevent=NULL); 59 | }; 60 | -------------------------------------------------------------------------------- /include/BuildOrderBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "BuildListItem.h" 7 | #include "BuildListBox.h" 8 | #include "MouseEvent.h" 9 | 10 | /******************************************************************************* 11 | 12 | Displays build order 13 | 14 | *******************************************************************************/ 15 | class BuildOrderBox: public BuildListBox { 16 | 17 | protected: 18 | 19 | /* Drawing */ 20 | 21 | virtual void redrawFrame(); 22 | virtual void redrawSingleItem(unsigned int idx); 23 | 24 | public: 25 | 26 | /* Constructors */ 27 | 28 | BuildOrderBox(); 29 | BuildOrderBox(WINDOW *win, const std::string & name); 30 | 31 | /* Get attributes */ 32 | 33 | virtual void minimumSize(int & height, int & width) const; 34 | virtual void preferredSize(int & height, int & width) const; 35 | 36 | /* Creates list based on SlackBuild selected */ 37 | 38 | int create(BuildListItem & build, 39 | std::vector > & slackbuilds, 40 | const std::string & mode="forward"); 41 | 42 | /* Handles mouse event */ 43 | 44 | std::string handleMouseEvent(MouseEvent * mevent); 45 | }; 46 | -------------------------------------------------------------------------------- /include/CLOParser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /******************************************************************************* 7 | 8 | Class to read and process command-line arguments 9 | 10 | *******************************************************************************/ 11 | class CLOParser { 12 | 13 | private: 14 | 15 | std::vector _argv_str; 16 | std::string _input_file; 17 | bool _sync, _upgrade_all, _upgradable; 18 | 19 | 20 | /* Converts CLOs to vector of strings */ 21 | 22 | void readCLOs(int argc, char *argv[]); 23 | 24 | public: 25 | 26 | /* Constructor */ 27 | 28 | CLOParser(); 29 | 30 | /* Checks CLOs for errors */ 31 | 32 | int checkCLOs(int argc, char *argv[], const std::string & version); 33 | 34 | /* Prints various information messages */ 35 | 36 | void printUsage() const; 37 | void printVersion(const std::string & version) const; 38 | void printHelp() const; 39 | 40 | /* Custom input file information */ 41 | 42 | bool requestInputFile() const; 43 | const std::string & inputFile() const; 44 | 45 | /* Query other possible inputs */ 46 | 47 | bool sync() const; 48 | bool upgradeAll() const; 49 | bool upgradable() const; 50 | }; 51 | -------------------------------------------------------------------------------- /include/CategoryListBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ListBox.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | ListBox for categories 11 | 12 | *******************************************************************************/ 13 | class CategoryListBox: public ListBox { 14 | 15 | private: 16 | 17 | void redrawFrame(); 18 | void redrawSingleItem(unsigned int idx); 19 | 20 | public: 21 | 22 | /* Constructors */ 23 | 24 | CategoryListBox(); 25 | CategoryListBox(WINDOW *win, const std::string & name); 26 | 27 | /* Tagging */ 28 | 29 | void tagCategory(unsigned int idx); 30 | void tagHighlightedCategory(); 31 | 32 | /* User interaction loop */ 33 | 34 | std::string exec(MouseEvent * mevent=NULL); 35 | }; 36 | -------------------------------------------------------------------------------- /include/CategoryListItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ListItem.h" 5 | 6 | /******************************************************************************* 7 | 8 | List item that describes a group of SlackBuilds 9 | 10 | *******************************************************************************/ 11 | class CategoryListItem: public ListItem { 12 | 13 | public: 14 | 15 | // Constructor 16 | 17 | CategoryListItem(); 18 | }; 19 | -------------------------------------------------------------------------------- /include/Color.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | /******************************************************************************* 8 | 9 | Manages colors for ncurses, making color pairs easy to reference by foreground 10 | and background color. 11 | 12 | *******************************************************************************/ 13 | class Color { 14 | 15 | private: 16 | 17 | struct color_entry { 18 | std::string label, name, basename, type; 19 | bool bright; 20 | }; 21 | 22 | struct color_pair { 23 | color_entry fg, bg; 24 | int idx; 25 | bool use_bold, use_blink; 26 | }; 27 | 28 | std::vector _colors; 29 | int _active_pair; 30 | 31 | /* Translate string color (red, green, etc.) into ncurses variable */ 32 | 33 | void baseColorName(const std::string & colorname, std::string & basename, 34 | bool & bright) const; 35 | int ncursesColor(const std::string & basename) const; 36 | 37 | public: 38 | 39 | /* Constructors */ 40 | 41 | Color(); 42 | 43 | /* Create or access color pair by foreground & background colors */ 44 | 45 | void addPair(const std::string & fg_label, const std::string & fg_name, 46 | const std::string & bg_label, const std::string & bg_name); 47 | int getPair(const std::string & fg_label, 48 | const std::string & bg_label) const; 49 | 50 | /* Bold / blink properties */ 51 | 52 | bool pairIsBold(int vec_idx) const; 53 | bool pairBlinks(int vec_idx) const; 54 | 55 | /* Turn color setting on or off in window */ 56 | 57 | int turnOn(WINDOW *win, const std::string & fg_label, 58 | const std::string & bg_label); 59 | int turnOn(WINDOW *win, int vec_idx); 60 | int turnOff(WINDOW *win); 61 | int setBackground(WINDOW *win, const std::string & fg_label, 62 | const std::string & bg_label) const; 63 | int setBackground(WINDOW *win, int vec_idx) const; 64 | 65 | /* Clears all colors */ 66 | 67 | void clear(); 68 | }; 69 | -------------------------------------------------------------------------------- /include/ColorTheme.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "Color.h" 5 | 6 | /******************************************************************************* 7 | 8 | Color theme class 9 | 10 | *******************************************************************************/ 11 | class ColorTheme { 12 | 13 | private: 14 | 15 | std::string _name; 16 | std::string _fg_normal, _bg_normal; 17 | std::string _fg_title, _bg_title; 18 | std::string _fg_info, _bg_info; 19 | std::string _fg_highlight_active, _bg_highlight_active; 20 | std::string _fg_highlight_inactive, _bg_highlight_inactive; 21 | std::string _header, _header_popup; 22 | std::string _tagged; 23 | std::string _fg_popup, _bg_popup; 24 | std::string _fg_warning, _bg_warning; 25 | std::string _hotkey; 26 | std::string _fg_combobox, _bg_combobox; 27 | 28 | public: 29 | 30 | /* Constructor */ 31 | 32 | ColorTheme(); 33 | 34 | /* Set or get name */ 35 | 36 | void setName(const std::string & name); 37 | const std::string & name() const; 38 | 39 | /* Set default colors */ 40 | 41 | void setDefaultColors(); 42 | 43 | /* Read color theme from file */ 44 | 45 | int read(const std::string & color_theme_file); 46 | 47 | /* Set UI colors from theme */ 48 | 49 | void applyTheme(Color & colors) const; 50 | }; 51 | -------------------------------------------------------------------------------- /include/ComboBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ComboBoxList.h" 6 | #include "InputItem.h" 7 | #include "MouseEvent.h" 8 | 9 | class InputBox; 10 | 11 | /******************************************************************************* 12 | 13 | Combo box input item 14 | 15 | *******************************************************************************/ 16 | class ComboBox: public InputItem { 17 | 18 | private: 19 | 20 | WINDOW *_listwin; 21 | ComboBoxList _list; 22 | InputBox *_parent; 23 | 24 | /* Placing and sizing list box */ 25 | 26 | void placeListBox(int y_offset); 27 | 28 | /* User interaction with list */ 29 | 30 | std::string execList(int y_offset, MouseEvent * mevent=NULL); 31 | 32 | public: 33 | 34 | /* Constructor and destructor */ 35 | 36 | ComboBox(); 37 | ComboBox(InputBox *parent); 38 | ~ComboBox(); 39 | 40 | /* Set attributes */ 41 | 42 | void setParent(InputBox *parent); 43 | void addChoice(const std::string & choice); 44 | void setChoice(unsigned int idx); 45 | void setChoice(const std::string & choice); 46 | 47 | /* User interaction */ 48 | 49 | std::string handleMouseEvent(MouseEvent * mevent, int y_offset); 50 | void draw(int y_offset, bool force=false, bool highlight=false); 51 | std::string exec(int y_offset, MouseEvent * mevent=NULL); 52 | 53 | /* Accessing properties */ 54 | 55 | int getIntProp() const; 56 | std::string getStringProp() const; 57 | std::string choice() const; 58 | }; 59 | -------------------------------------------------------------------------------- /include/ComboBoxList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "SelectionBox.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | List displayed by a ComboBox 11 | 12 | *******************************************************************************/ 13 | class ComboBoxList: public SelectionBox { 14 | 15 | protected: 16 | 17 | virtual void redrawFrame(); 18 | virtual void redrawSingleItem(unsigned int idx); 19 | 20 | public: 21 | 22 | /* Constructors */ 23 | 24 | ComboBoxList(); 25 | ComboBoxList(WINDOW *win); 26 | 27 | /* Edit list */ 28 | 29 | void clearList(); 30 | 31 | /* Accessing properties */ 32 | 33 | virtual void preferredSize(int & height, int & width) const; 34 | 35 | /* Drawing */ 36 | 37 | void draw(bool force=false); 38 | 39 | /* Handles mouse event */ 40 | 41 | std::string handleMouseEvent(MouseEvent * mevent); 42 | }; 43 | -------------------------------------------------------------------------------- /include/CursesWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | Abstract class for CursesWidgets. Derived classes must implement sizing rules, 11 | draw, and exec methods. 12 | 13 | *******************************************************************************/ 14 | class CursesWidget { 15 | 16 | protected: 17 | 18 | void printToEol(const std::string & msg, int printable_cols=-1) const; 19 | void printSpaces(int nspaces) const; 20 | void clearWindow () const; 21 | virtual int highlightNextButton(); 22 | virtual int highlightPreviousButton(); 23 | virtual void redrawButtons(); 24 | 25 | std::vector _buttons; // At the bottom, e.g. OK/Cancel 26 | std::vector _button_signals; 27 | std::vector _button_left; // Left edge of each button 28 | std::vector _button_right; // Right edge of each button 29 | 30 | int _highlighted_button; 31 | unsigned int _reserved_rows, _header_rows; 32 | std::string _redraw_type; 33 | std::string _button_fg, _button_bg; 34 | std::string _bg_color, _fg_color; // Default colors 35 | 36 | WINDOW *_win; 37 | 38 | public: 39 | 40 | /* Constructor */ 41 | 42 | CursesWidget(); 43 | 44 | /* Set attributes */ 45 | 46 | virtual void setWindow(WINDOW *win); 47 | void addButton(const std::string & button, const std::string & signal); 48 | void clearButtons(); 49 | void setButtons(const std::vector & buttons, 50 | const std::vector & button_signals); 51 | void setButtonColor(const std::string & button_fg, 52 | const std::string & button_bg); 53 | void setColor(const std::string & fg_color, const std::string & bg_color); 54 | 55 | /* Sets size and position of popup boxes */ 56 | 57 | virtual void popupSize(int & height, int & width, CursesWidget *popup) const; 58 | virtual void placePopup(CursesWidget *popup, WINDOW *win) const; 59 | 60 | /* Hides a popup window by putting it at the center with 0 size */ 61 | 62 | virtual void hideWindow(WINDOW *win) const; 63 | 64 | /* Get attributes */ 65 | 66 | virtual void minimumSize(int & height, int & width) const = 0; 67 | virtual void preferredSize(int & height, int & width) const = 0; 68 | int highlightedButton() const; 69 | const std::string & fgColor() const; 70 | const std::string & bgColor() const; 71 | 72 | /* Mouse interaction */ 73 | 74 | virtual std::string handleMouseEvent(MouseEvent * mevent) = 0; 75 | 76 | /* Draws frame and message */ 77 | 78 | virtual void draw(bool force=false) = 0; 79 | 80 | /* User interaction loop */ 81 | 82 | virtual std::string exec(MouseEvent * mevent=NULL) = 0; 83 | }; 84 | -------------------------------------------------------------------------------- /include/DefaultOptionsBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "TextInput.h" 5 | #include "ToggleInput.h" 6 | #include "InputBox.h" 7 | 8 | /******************************************************************************* 9 | 10 | Dialog to apply default options when the user changes the package manager 11 | 12 | *******************************************************************************/ 13 | class DefaultOptionsBox: public InputBox { 14 | 15 | private: 16 | 17 | std::string _pkg_mgr; 18 | std::string _repo_dir, _sync_cmd, _install_cmd, _upgrade_cmd, 19 | _reinstall_cmd; 20 | ToggleInput _repoitem, _syncitem, _installitem, _upgradeitem, 21 | _reinstallitem; 22 | 23 | public: 24 | 25 | /* Constructor */ 26 | 27 | DefaultOptionsBox(); 28 | 29 | /* Set attributes */ 30 | 31 | int setPackageManager(const std::string & pkg_mgr); 32 | 33 | /* Get attributes */ 34 | 35 | bool setRepoDir() const; 36 | bool setSyncCmd() const; 37 | bool setInstallCmd() const; 38 | bool setUpgradeCmd() const; 39 | bool setReinstallCmd() const; 40 | 41 | const std::string & repoDir() const; 42 | const std::string & syncCmd() const; 43 | const std::string & installCmd() const; 44 | const std::string & upgradeCmd() const; 45 | const std::string & reinstallCmd() const; 46 | }; 47 | -------------------------------------------------------------------------------- /include/DirListBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "DirListing.h" 6 | #include "SelectionBox.h" 7 | #include "MouseEvent.h" 8 | 9 | /******************************************************************************* 10 | 11 | Selection to display and view files in a directory 12 | 13 | *******************************************************************************/ 14 | class DirListBox: public SelectionBox { 15 | 16 | private: 17 | 18 | std::string _topdir, _currentdir; 19 | bool _limit_topdir; 20 | 21 | void redrawSingleItem(unsigned int idx); 22 | int navigateUp(); 23 | void clear(); 24 | 25 | public: 26 | 27 | /* Constructors and destructor */ 28 | 29 | DirListBox(); 30 | DirListBox(WINDOW *win, const std::string & name); 31 | ~DirListBox(); 32 | 33 | /* Setting properties */ 34 | 35 | void limitTopDir(bool limit); 36 | int setDirectory(const std::string & directory, bool reset_topdir=false); 37 | 38 | /* Accessing properties */ 39 | 40 | const std::string & directory() const; 41 | 42 | /* User interaction loop */ 43 | 44 | std::string exec(MouseEvent * mevent=NULL); 45 | }; 46 | -------------------------------------------------------------------------------- /include/DirListing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct direntry { 8 | std::string name; 9 | std::string type; 10 | std::string path; 11 | }; 12 | 13 | /******************************************************************************* 14 | 15 | Stores and operates on data related to directory listings 16 | 17 | *******************************************************************************/ 18 | class DirListing { 19 | 20 | private: 21 | 22 | std::vector _entries; 23 | std::string _path; 24 | 25 | /* Conversions */ 26 | 27 | std::string nameFromDirent(dirent *pent) const; 28 | std::string typeFromDirent(dirent *pent) const; 29 | std::string typeFromStat(const std::string & path) const; 30 | 31 | public: 32 | 33 | static std::string separator; 34 | 35 | /* Constructors */ 36 | 37 | DirListing(); 38 | DirListing(bool sort_listing); 39 | DirListing(bool sort_listing, bool show_hidden); 40 | DirListing(const std::string & path); 41 | DirListing(const std::string & path, bool sort_listing); 42 | DirListing(const std::string & path, bool sort_listing, bool show_hidden); 43 | 44 | /* Create listing */ 45 | 46 | int setFromPath(const std::string & path, bool sort_listing=true, 47 | bool show_hidden=false); 48 | int setFromCwd(bool sort_listing=true, bool show_hidden=false); 49 | int navigateUp(bool sort_listing=true, bool show_hidden=false); 50 | 51 | /* Same as setFromPath, but also creates directory if it doesn't exist */ 52 | 53 | int createFromPath(const std::string & path, bool sort_listing=true, 54 | bool show_hidden=false); 55 | 56 | /* Sorts entries */ 57 | 58 | void sort(); 59 | 60 | /* Returns direntry by index or name */ 61 | 62 | const direntry operator () (unsigned int idx) const; 63 | const direntry operator () (const std::string & name) const; 64 | 65 | /* Returns path */ 66 | 67 | const std::string & path() const; 68 | 69 | /* Returns number of entries */ 70 | 71 | unsigned int size() const; 72 | }; 73 | -------------------------------------------------------------------------------- /include/FilterBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "ListItem.h" 7 | #include "SelectionBox.h" 8 | 9 | /******************************************************************************* 10 | 11 | SelectionBox for filters 12 | 13 | *******************************************************************************/ 14 | class FilterBox: public SelectionBox { 15 | 16 | public: 17 | 18 | /* Constructors and destructor */ 19 | 20 | FilterBox(); 21 | FilterBox(WINDOW *win, const std::string & name); 22 | ~FilterBox(); 23 | }; 24 | -------------------------------------------------------------------------------- /include/HelpItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ListItem.h" 5 | 6 | /******************************************************************************* 7 | 8 | List item for Help window 9 | 10 | *******************************************************************************/ 11 | class HelpItem: public ListItem { 12 | 13 | public: 14 | 15 | // Constructors 16 | 17 | HelpItem(); 18 | HelpItem(const std::string & name, const std::string & shortcut, 19 | bool header=false, bool space=false); 20 | }; 21 | -------------------------------------------------------------------------------- /include/HelpWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "HelpItem.h" 7 | #include "ScrollBox.h" 8 | 9 | /******************************************************************************* 10 | 11 | Help window: lists keyboard shortcuts (abstract version) 12 | 13 | *******************************************************************************/ 14 | class HelpWindow: public ScrollBox { 15 | 16 | protected: 17 | 18 | unsigned int _shortcutwidth; 19 | std::string _leftlabel, _rightlabel; 20 | 21 | /* List of items to display */ 22 | 23 | std::vector _helpitems; 24 | 25 | /* Drawing */ 26 | 27 | void redrawFrame(); 28 | void redrawSingleItem(unsigned int idx); 29 | 30 | /* Width needed for right column */ 31 | 32 | void shortcutWidth(); 33 | 34 | public: 35 | 36 | /* Constructors and destructor */ 37 | 38 | HelpWindow(); 39 | HelpWindow(WINDOW *win, const std::string & name); 40 | ~HelpWindow(); 41 | 42 | /* Set labels (usually 'Action' and 'Shortcut') */ 43 | 44 | void setLabels(const std::string & leftlabel, 45 | const std::string & rightlabel); 46 | 47 | /* Window sizing and placement */ 48 | 49 | void placeWindow() const; 50 | 51 | /* Constructs list to display */ 52 | 53 | virtual void createList() = 0; 54 | }; 55 | -------------------------------------------------------------------------------- /include/IgnoreVersions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /******************************************************************************* 7 | 8 | Reads ignore_versions file and checks SlackBuilds and versions for matches 9 | 10 | *******************************************************************************/ 11 | class IgnoreVersions { 12 | 13 | private: 14 | 15 | std::vector _names; 16 | std::vector _versions; 17 | 18 | public: 19 | 20 | /* Constructor */ 21 | 22 | IgnoreVersions(); 23 | 24 | /* Reads ignore_versions file */ 25 | 26 | void read(const std::string & filename); 27 | 28 | /* Checks SlackBuild for matching version that was listed in the file */ 29 | bool ignoreVersion(const std::string & name, 30 | const::std::string & version) const; 31 | }; 32 | -------------------------------------------------------------------------------- /include/InputBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "CursesWidget.h" 7 | #include "MouseEvent.h" 8 | 9 | class InputItem; 10 | 11 | /******************************************************************************* 12 | 13 | Box containing a number of InputItems 14 | 15 | *******************************************************************************/ 16 | class InputBox: public CursesWidget { 17 | 18 | protected: 19 | 20 | std::string _msg; 21 | std::vector _items; 22 | int _highlight, _prevhighlight, _firstprint; 23 | int _header_rows, _first_selectable, _last_selectable; 24 | int _color_idx; // TODO: use method from CursesWidget 25 | bool _has_scroll_indicator; 26 | 27 | /* Setting item to be highlighted */ 28 | 29 | int highlightFirst(); 30 | int highlightLast(); 31 | int highlightPrevious(); 32 | int highlightNext(); 33 | int highlightPreviousPage(); 34 | int highlightNextPage(); 35 | int highlightFractional(const double & frac); 36 | 37 | /* Determines first line to print (needed for scrolling) */ 38 | 39 | int determineFirstPrint(); 40 | 41 | /* Drawing */ 42 | 43 | virtual void redrawFrame(); 44 | virtual void redrawScrollIndicator() const; 45 | void redrawChangedItems(bool force); 46 | void redrawAllItems(bool force); 47 | 48 | public: 49 | 50 | /* Constructors */ 51 | 52 | InputBox(); 53 | InputBox(WINDOW *win, const std::string & msg); 54 | 55 | /* Add/remove items */ 56 | 57 | void addItem(InputItem *item); 58 | void clear(); 59 | 60 | /* Set attributes */ 61 | 62 | void setWindow(WINDOW *win); 63 | void setMessage(const std::string & msg); 64 | void setHighlight(unsigned int highlight); 65 | void setColor(int color_idx); // TODO: use method from CursesWidget 66 | 67 | /* Get attributes */ 68 | 69 | virtual void minimumSize(int & height, int & width) const; 70 | virtual void preferredSize(int & height, int & width) const; 71 | unsigned int numItems() const; 72 | 73 | /* Mouse interaction */ 74 | 75 | std::string handleMouseEvent(MouseEvent * mevent); 76 | 77 | /* Draws frame, entry, etc. as needed */ 78 | 79 | virtual void draw(bool force=false); 80 | 81 | /* User interaction loop */ 82 | 83 | std::string handleInput(std::string & selection, bool & getting_input, 84 | bool & needs_selection, MouseEvent * mevent=NULL); 85 | virtual std::string exec(MouseEvent * mevent=NULL); 86 | }; 87 | -------------------------------------------------------------------------------- /include/InputItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "MouseEvent.h" 6 | 7 | /******************************************************************************* 8 | 9 | Basic class for an item that goes in an input box, such as text input or 10 | switch. This class serves as a template. 11 | 12 | *******************************************************************************/ 13 | class InputItem { 14 | 15 | protected: 16 | 17 | WINDOW *_win; 18 | int _posx, _posy, _width; 19 | std::string _name, _redraw_type, _item_type; 20 | bool _selectable, _auto_position; 21 | 22 | /* Prints to end of line or specified number of spaces */ 23 | 24 | void printToEol(const std::string & msg) const; 25 | void printSpaces(int nspaces) const; 26 | 27 | public: 28 | 29 | InputItem(); 30 | 31 | // Virtual destructor needed to call delete on base class 32 | // http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors#461224 33 | // (In this case, it's really just to suppress the compiler warning, since 34 | // InputItems don't dynamically allocate any memory.) 35 | 36 | virtual ~InputItem(); 37 | 38 | // Set attributes 39 | 40 | void setName(const std::string & name); 41 | void setPosition(int y, int x); 42 | void setWidth(int width); 43 | void setWindow(WINDOW *win); 44 | void setAutoPosition(bool auto_position); 45 | 46 | // Get attributes 47 | 48 | const std::string & name() const; 49 | int posx() const; 50 | int posy() const; 51 | int width() const; 52 | bool selectable() const; 53 | bool autoPosition() const; 54 | const std::string & itemType() const; 55 | 56 | // User interaction 57 | 58 | virtual std::string handleMouseEvent(MouseEvent * mevent, int y_offset) = 0; 59 | virtual void draw(int y_offset, bool force=false, bool highlight=false) = 0; 60 | virtual std::string exec(int y_offset, MouseEvent * mevent=NULL); 61 | 62 | // Accessing properties of different types. Derived classes should 63 | // reimplement these as needed. 64 | 65 | virtual std::string getStringProp() const; 66 | virtual bool getBoolProp() const; 67 | virtual int getIntProp() const; 68 | virtual double getDoubleProp() const; 69 | }; 70 | -------------------------------------------------------------------------------- /include/InstallBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "BuildListItem.h" 7 | #include "BuildOrderBox.h" 8 | #include "MouseEvent.h" 9 | 10 | /******************************************************************************* 11 | 12 | Allows user to install/upgrade/reinstall/remove SlackBuild and dependencies 13 | 14 | *******************************************************************************/ 15 | class InstallBox: public BuildOrderBox { 16 | 17 | private: 18 | 19 | /* For this class, keep separate copies of the SlackBuilds in the build 20 | order, because it is easier to work with BuildListItems than ListItems 21 | for many of the operations. */ 22 | 23 | std::vector _builds; 24 | int _ndeps, _ninvdeps; 25 | 26 | /* Drawing */ 27 | 28 | void redrawFrame(); 29 | void redrawSingleItem(unsigned int idx); 30 | 31 | public: 32 | 33 | /* Constructors */ 34 | 35 | InstallBox(); 36 | InstallBox(WINDOW *win, const std::string & name); 37 | 38 | /* Get attributes */ 39 | 40 | void minimumSize(int & height, int & width) const; 41 | void preferredSize(int & height, int & width) const; 42 | 43 | int numDeps() const; // See notes in InstallBox.cpp on these two methods 44 | int numInvDeps() const; // ------------------------------------------------ 45 | 46 | bool installingAllDeps() const; 47 | bool installingRequested() const; 48 | 49 | /* Creates list based on SlackBuild selected */ 50 | 51 | int create(BuildListItem & build, 52 | std::vector > & slackbuilds, 53 | const std::string & action, bool resolve_deps=true, 54 | bool batch=false, bool rebuild_inv_deps=false); 55 | 56 | /* Handles mouse event */ 57 | 58 | std::string handleMouseEvent(MouseEvent * mevent); 59 | 60 | /* User interaction loop. Differs from standard BuildListBox exec() in 61 | that the space bar is used to tag (select/unselect) items */ 62 | 63 | std::string exec(MouseEvent * mevent=NULL); 64 | 65 | /* Make a list of packages from a different repo that will be changed */ 66 | 67 | std::vector checkForeign() const; 68 | 69 | /* Install, upgrade, remove, or reinstall SlackBuild and dependencies */ 70 | 71 | int applyChanges(int & ninstalled, int & nupgraded, int & nreinstalled, 72 | int & nremoved); 73 | }; 74 | -------------------------------------------------------------------------------- /include/KeyHelpWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "HelpItem.h" 4 | #include "HelpWindow.h" 5 | 6 | /******************************************************************************* 7 | 8 | Key help window: lists keyboard shortcuts 9 | 10 | *******************************************************************************/ 11 | class KeyHelpWindow: public HelpWindow { 12 | 13 | public: 14 | 15 | /* Constructor */ 16 | 17 | KeyHelpWindow(); 18 | 19 | /* Constructs list to display */ 20 | 21 | void createList(); 22 | }; 23 | -------------------------------------------------------------------------------- /include/Label.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "InputItem.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | Label input item 11 | 12 | *******************************************************************************/ 13 | class Label: public InputItem { 14 | 15 | private: 16 | 17 | int _color_idx; 18 | bool _hline; 19 | bool _bold; 20 | 21 | public: 22 | 23 | /* Constructors and destructor */ 24 | 25 | Label(); 26 | Label(bool selectable); 27 | Label(bool selectable, bool hline); 28 | 29 | /* Set attributes */ 30 | 31 | void setColor(int color_idx); 32 | void setSelectable(bool selectable); 33 | void setHLine(bool hline); 34 | void setBold(bool bold); // Note: if color is available, it is preferred 35 | // to do this with a bold ("bright") fg color 36 | // instead 37 | 38 | /* User interaction */ 39 | 40 | std::string handleMouseEvent(MouseEvent * mevent, int y_offset); 41 | void draw(int y_offset, bool force=false, bool highlight=false); 42 | std::string exec(int y_offset, MouseEvent * mevent=NULL); 43 | }; 44 | -------------------------------------------------------------------------------- /include/ListBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "AbstractListBox.h" 7 | #include "MouseEvent.h" 8 | 9 | class ListItem; 10 | 11 | /******************************************************************************* 12 | 13 | List box with selectable items 14 | 15 | *******************************************************************************/ 16 | class ListBox: public AbstractListBox { 17 | 18 | protected: 19 | 20 | int _highlight, _prevhighlight; 21 | bool _activated; 22 | 23 | /* Setting item to be highlighted */ 24 | 25 | int highlightFirst(); 26 | int highlightLast(); 27 | int highlightPrevious(); 28 | int highlightNext(); 29 | int highlightNextPage(); 30 | int highlightPreviousPage(); 31 | int highlightFractional(const double & frac); 32 | 33 | /* Determines first item to print (needed for scrolling) */ 34 | 35 | int determineFirstPrint(); 36 | 37 | /* Drawing */ 38 | 39 | virtual void redrawSingleItem(unsigned int idx); 40 | virtual void redrawScrollIndicator() const; 41 | void redrawChangedItems(); 42 | 43 | public: 44 | 45 | /* Constructors */ 46 | 47 | ListBox(); 48 | ListBox(WINDOW *win, const std::string & name); 49 | 50 | /* Edit list */ 51 | 52 | void removeItem(unsigned int idx); 53 | virtual void clearList(); 54 | 55 | /* Set attributes */ 56 | 57 | void setActivated(bool activated); 58 | int setHighlight(int highlight); 59 | int setHighlight(const std::string & name); 60 | 61 | /* Get attributes */ 62 | 63 | unsigned int highlight() const; 64 | const std::string & highlightedName() const; 65 | 66 | /* Sets highlight by search for string */ 67 | 68 | int highlightSearch(const std::string & pattern); 69 | 70 | /* Returns pointer to item */ 71 | 72 | ListItem * highlightedItem(); 73 | 74 | /* Handles mouse event */ 75 | 76 | virtual std::string handleMouseEvent(MouseEvent * mevent); 77 | 78 | /* Draws frame, items, etc. as needed */ 79 | 80 | virtual void draw(bool force=false); 81 | 82 | /* User interaction loop */ 83 | 84 | virtual std::string exec(MouseEvent * mevent=NULL); 85 | }; 86 | -------------------------------------------------------------------------------- /include/ListItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /******************************************************************************* 7 | 8 | Basic class for an item that goes in a list box. Each item can have multiple 9 | properties and values, but it must at least have a name. Additional properties 10 | are stored as strings, but helper functions are included to set and get them via 11 | other types; e.g., addBoolProp, setBoolProp, and getBoolProp. 12 | 13 | *******************************************************************************/ 14 | class ListItem { 15 | 16 | protected: 17 | 18 | struct listprop { 19 | std::string propname; 20 | std::string value; 21 | }; 22 | 23 | std::string _name; 24 | std::vector _props; 25 | int _hotkey; 26 | 27 | // Conversions 28 | 29 | std::string bool2String(bool value) const; 30 | bool string2Bool(const std::string & value) const; 31 | 32 | // Accessing props 33 | 34 | int findPropByName(const std::string & propname, int & propidx, 35 | int & lbound, int & rbound) const; 36 | int propIdxByName(const std::string & propname) const; 37 | void setPropByIdx(unsigned int idx, const std::string & value); 38 | 39 | public: 40 | 41 | ListItem(); 42 | ListItem(const std::string & name); 43 | 44 | // Set properties 45 | 46 | void setName(const std::string & name); 47 | 48 | /* HotKey can be used to bold or underline a certain character in the name, 49 | and the caller can use it to perform a certain action when that keystroke 50 | is returned. By default it is set to -1. */ 51 | void setHotKey(int hotkey); 52 | 53 | void addProp(const std::string & propname, const std::string & value); 54 | void addBoolProp(const std::string & propname, bool value); 55 | int setProp(const std::string & propname, const std::string & value); 56 | int setBoolProp(const std::string & propname, bool value); 57 | 58 | // Get properties 59 | 60 | const std::string & name() const; 61 | int hotKey() const; 62 | bool checkProp(const std::string & propname) const; 63 | const std::string & getProp(const std::string & propname) const; 64 | bool getBoolProp(const std::string & propname) const; 65 | }; 66 | -------------------------------------------------------------------------------- /include/MainWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "CursesWidget.h" 7 | #include "AbstractListBox.h" 8 | #include "CategoryListItem.h" 9 | #include "CategoryListBox.h" 10 | #include "BuildListItem.h" 11 | #include "BuildListBox.h" 12 | #include "FilterBox.h" 13 | #include "SearchBox.h" 14 | #include "InputBox.h" 15 | #include "TagList.h" 16 | #include "OptionsWindow.h" 17 | #include "KeyHelpWindow.h" 18 | #include "MouseHelpWindow.h" 19 | #include "Menubar.h" 20 | #include "MouseEvent.h" 21 | 22 | /******************************************************************************* 23 | 24 | Main window 25 | 26 | *******************************************************************************/ 27 | class MainWindow: public CursesWidget { 28 | 29 | private: 30 | 31 | WINDOW *_win1, *_win2; 32 | CategoryListBox _clistbox; 33 | std::vector _blistboxes; 34 | std::vector > _slackbuilds; 35 | std::vector > _displayed_slackbuilds; 36 | std::vector _categories; 37 | std::vector _displayed_categories; 38 | FilterBox _fbox; 39 | SearchBox _searchbox; 40 | TagList _taglist; 41 | OptionsWindow _options; 42 | KeyHelpWindow _help; 43 | MouseHelpWindow _mousehelp; 44 | Menubar _menubar; 45 | std::string _filter, _info, _status, _conf_file; 46 | unsigned int _category_idx, _activated_listbox; 47 | 48 | void printStatus(const std::string & msg, bool bold=false); 49 | void clearStatus(); 50 | void refreshStatus(); 51 | 52 | void redrawHeaderFooter(); 53 | void redrawWindowsHorz(); 54 | void redrawWindowsVert(); 55 | void redrawWindows(bool force=false); 56 | void toggleLayout(); 57 | 58 | /* Clearing and setting up lists, etc. */ 59 | 60 | void clearData(); 61 | int readLists(MouseEvent * mevent=NULL, bool interactive=true); 62 | void clearTags(); 63 | void rebuild(MouseEvent * mevent=NULL); 64 | void resetDisplayedSlackBuilds(); 65 | 66 | /* Asks for confirmation and quits */ 67 | 68 | void quit(); 69 | 70 | /* Filters lists */ 71 | 72 | void filterAll(MouseEvent * mevent=NULL); 73 | void filterInstalled(); 74 | void filterUpgradable(); 75 | void filterTagged(); 76 | void filterBlacklisted(); 77 | void filterNonDeps(); 78 | void filterBuildOptions(); 79 | void filterSearch(const std::string & searchterm, bool case_sensitive=false, 80 | bool whole_whord=false, bool search_readmes=false); 81 | 82 | /* Displays options window */ 83 | 84 | int showOptions(MouseEvent * mevent=NULL); 85 | 86 | /* Displays help window (mouse or keyboard shortcuts) */ 87 | 88 | int showHelp(MouseEvent * mevent=NULL, bool mouse_help=false); 89 | 90 | /* Sets taglist reference in BuildListBoxes */ 91 | 92 | void setTagList(); 93 | 94 | /* Actions for a selected SlackBuild */ 95 | 96 | void browseFiles(const BuildListItem & build, MouseEvent * mevent=NULL); 97 | bool modifyPackage(BuildListItem & build, const std::string & action, 98 | int & ninstalled, int & nupgraded, int & nreinstalled, 99 | int & nremoved, bool & cancel_all, bool batch=false, 100 | MouseEvent * mevent=NULL); 101 | void setBuildOptions(BuildListItem & build, MouseEvent * mevent=NULL); 102 | void showBuildOrder(BuildListItem & build, 103 | const std::string & mode="forward", 104 | MouseEvent * mevent=NULL); 105 | void showPackageInfo(BuildListItem & build, MouseEvent * mevent=NULL); 106 | 107 | /* Sync/update */ 108 | 109 | int syncRepo(MouseEvent * mevent=NULL); 110 | 111 | /* Apply action to tagged SlackBuilds */ 112 | 113 | void applyTags(const std::string & action, MouseEvent * mevent=NULL); 114 | 115 | /* View command line output */ 116 | 117 | void viewCommandLine() const; 118 | 119 | /* Displays an error message */ 120 | 121 | std::string displayError(const std::string & msg, bool centered, 122 | const std::string & name, 123 | const std::string & buttonnames, 124 | MouseEvent * mevent=NULL); 125 | std::string displayMessage(const std::string & msg, bool centered, 126 | const std::string & name, 127 | const std::string & buttonnames, 128 | MouseEvent * mevent=NULL); 129 | 130 | /* Prints package version information as status */ 131 | 132 | void printPackageVersion(const BuildListItem & build); 133 | 134 | /* Shows 'About' dialog */ 135 | 136 | void showAbout(MouseEvent * mevent=NULL); 137 | 138 | /* Menubar */ 139 | 140 | void activateMenubar(); 141 | void deactivateMenubar(); 142 | void menubarActions(MouseEvent * mevent=NULL); 143 | 144 | /* Various operations performed by both exec and handleMouseEvent */ 145 | 146 | void printSelectedPackageVersion(); 147 | void activateListBox(unsigned int list); 148 | void drawSelectedCategory(); 149 | void tagSelectedCategory(); 150 | void tagSelectedSlackBuild(); 151 | void showSelectedBuildActions(bool limited_actions=false, 152 | MouseEvent * mevent=NULL); 153 | 154 | public: 155 | 156 | /* Constructor and destructor */ 157 | 158 | MainWindow(const std::string & version); 159 | ~MainWindow(); 160 | 161 | /* Window setup */ 162 | 163 | int initialize(MouseEvent * mevent=NULL); 164 | 165 | /* Set properties */ 166 | 167 | void setInfo(const std::string & info); 168 | void setConfFile(const std::string & conf_file); 169 | 170 | /* Dialogs */ 171 | 172 | void selectFilter(MouseEvent * mevent=NULL); 173 | void search(MouseEvent * mevent=NULL); 174 | void showBuildActions(BuildListItem & build, bool limited_actions=false, 175 | MouseEvent * mevent=NULL); 176 | 177 | /* Quick search in active list */ 178 | 179 | void quickSearch(); 180 | 181 | /* Upgrade all */ 182 | 183 | void upgradeAll(MouseEvent * mevent=NULL); 184 | 185 | /* List upgradable (non-interactive) */ 186 | 187 | int listUpgradable(); 188 | 189 | /* Not used, but needed for MainWindow to be derived from CursesWidget */ 190 | 191 | void minimumSize(int & height, int & width) const; 192 | void preferredSize(int & height, int & width) const; 193 | 194 | /* Mouse interaction */ 195 | 196 | std::string handleMouseEvent(MouseEvent * mevent); 197 | 198 | /* Redraws the main window */ 199 | 200 | void draw(bool force=false); 201 | 202 | /* Shows the main window */ 203 | 204 | std::string exec(MouseEvent * mevent=NULL); 205 | }; 206 | -------------------------------------------------------------------------------- /include/Menubar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "MouseEvent.h" 7 | #include "MenubarList.h" 8 | #include "CursesWidget.h" 9 | 10 | class MenubarList; 11 | 12 | /******************************************************************************* 13 | 14 | Menubar class 15 | 16 | *******************************************************************************/ 17 | class Menubar: public CursesWidget { 18 | 19 | protected: 20 | 21 | int _highlight, _prevhighlight; 22 | unsigned int _pad, _outerpad, _innerpad; 23 | bool _activated; 24 | std::vector _lists; 25 | std::vector _listwins; 26 | CursesWidget *_parent; 27 | 28 | unsigned int menuColumn(unsigned int lidx) const; 29 | void placeListBox(); 30 | 31 | void highlightFirst(); 32 | void highlightLast(); 33 | void highlightPrevious(); 34 | void highlightNext(); 35 | void setHighlight(int highlight); 36 | 37 | void redrawSingleItem(unsigned int idx); 38 | void redrawChangedItems(); 39 | void redrawAllItems(); 40 | 41 | std::string execList(MouseEvent * mevent=NULL); 42 | 43 | public: 44 | 45 | /* Constructors and destructor */ 46 | 47 | Menubar(); 48 | Menubar(WINDOW *win); 49 | ~Menubar(); 50 | 51 | /* Set attributes */ 52 | 53 | void setActivated(bool activated); 54 | void setParent(CursesWidget * parent); 55 | void setPad(unsigned int pad); 56 | void setListPad(unsigned int outerpad, unsigned int innerpad); 57 | int addList(const std::string & lname, int hotkey=-1); 58 | int addListItem(unsigned int lidx, const std::string & text, 59 | const std::string & shortcut="", int hotkey=-1); 60 | int addListItem(const std::string & lname, const std::string & text, 61 | const std::string & shortcut="", int hotkey=-1); 62 | void clearLists(); 63 | 64 | /* Get attributes */ 65 | 66 | unsigned int numLists() const; 67 | unsigned int highlightedList() const; 68 | std::string highlightedListName() const; 69 | std::string highlightedListItem() const; 70 | void minimumSize(int & height, int & width) const; 71 | void preferredSize(int & height, int & width) const; 72 | void bounds(int & xmin, int & xmax) const; 73 | 74 | /* Handles mouse event */ 75 | 76 | std::string handleMouseEvent(MouseEvent * mevent); 77 | 78 | /* Draws frame, items, etc. as needed */ 79 | 80 | virtual void draw(bool force=false); 81 | 82 | /* User interaction loop */ 83 | 84 | virtual std::string exec(MouseEvent * mevent=NULL); 85 | }; 86 | -------------------------------------------------------------------------------- /include/MenubarList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ComboBoxList.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | List displayed by entries in the Menubar. Differs from ComboBox list only in 11 | that it has a border. 12 | 13 | *******************************************************************************/ 14 | class MenubarList: public ComboBoxList { 15 | 16 | protected: 17 | 18 | unsigned int _outerpad, _innerpad; 19 | int _hotkey; 20 | 21 | void redrawFrame(); 22 | void redrawSingleItem(unsigned int idx); 23 | 24 | public: 25 | 26 | /* Constructors */ 27 | 28 | MenubarList(); 29 | MenubarList(WINDOW *win); 30 | 31 | /* Setting properties */ 32 | 33 | void setPad(unsigned int outerpad, unsigned int innerpad); 34 | void setHotKey(int hotkey); 35 | 36 | /* Accessing properties */ 37 | 38 | int hotKey() const; 39 | void minimumSize(int & height, int & width) const; 40 | void preferredSize(int & height, int & width) const; 41 | }; 42 | -------------------------------------------------------------------------------- /include/MenubarListItem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "ListItem.h" 5 | 6 | /******************************************************************************* 7 | 8 | List item for menubar 9 | 10 | *******************************************************************************/ 11 | class MenubarListItem: public ListItem { 12 | 13 | public: 14 | 15 | // Constructors 16 | 17 | MenubarListItem(); 18 | MenubarListItem(const std::string & name, const std::string & shortcut, 19 | int hotkey); 20 | }; 21 | -------------------------------------------------------------------------------- /include/MessageBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "CursesWidget.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | Header for message box class 11 | 12 | *******************************************************************************/ 13 | class MessageBox: public CursesWidget { 14 | 15 | protected: 16 | 17 | std::string _name, _message; 18 | unsigned int _margin_v, _margin_h; 19 | bool _header_colorize, _centered; 20 | 21 | void redrawFrame(); 22 | virtual void redrawMessage() const; 23 | 24 | public: 25 | 26 | /* Constructors */ 27 | 28 | MessageBox(bool header_colorize=true, bool centered=true); 29 | MessageBox(WINDOW *win, const std::string & name, 30 | bool header_colorize=true, bool centered=true); 31 | 32 | /* Set attributes */ 33 | 34 | void setName(const std::string & name); 35 | void setMessage(const std::string & msg); 36 | 37 | /* Get attributes */ 38 | 39 | virtual void minimumSize(int & height, int & width) const; 40 | virtual void preferredSize(int & height, int & width) const; 41 | 42 | /* Mouse interaction */ 43 | 44 | std::string handleMouseEvent(MouseEvent * mevent); 45 | 46 | /* Draws frame and message */ 47 | 48 | virtual void draw(bool force=false); 49 | 50 | /* User interaction loop */ 51 | 52 | std::string exec(MouseEvent * mevent=NULL); 53 | }; 54 | -------------------------------------------------------------------------------- /include/MouseEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /******************************************************************************* 7 | 8 | Mouse event class. Keeps track of button presses and determines when double 9 | clicks occur. 10 | 11 | *******************************************************************************/ 12 | class MouseEvent { 13 | 14 | protected: 15 | 16 | std::chrono::high_resolution_clock::time_point _tclick; 17 | int _button; 18 | int _x, _y; 19 | bool _doubleclick; 20 | const static int _doubleclick_timeout; 21 | 22 | public: 23 | 24 | /* Constructor */ 25 | 26 | MouseEvent(); 27 | 28 | /* Record click information */ 29 | 30 | void recordClick(const MEVENT & event); 31 | 32 | /* Query click information */ 33 | 34 | int button() const; 35 | int x() const; 36 | int y() const; 37 | bool doubleClick() const; 38 | }; 39 | -------------------------------------------------------------------------------- /include/MouseHelpWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "HelpItem.h" 4 | #include "HelpWindow.h" 5 | 6 | /******************************************************************************* 7 | 8 | Mouse help window: lists mouse bindings 9 | 10 | *******************************************************************************/ 11 | class MouseHelpWindow: public HelpWindow { 12 | 13 | public: 14 | 15 | /* Constructor */ 16 | 17 | MouseHelpWindow(); 18 | 19 | /* Constructs list to display */ 20 | 21 | void createList(); 22 | }; 23 | -------------------------------------------------------------------------------- /include/OptionsWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "TextInput.h" 6 | #include "ToggleInput.h" 7 | #include "Label.h" 8 | #include "ComboBox.h" 9 | #include "InputBox.h" 10 | #include "MouseEvent.h" 11 | 12 | /******************************************************************************* 13 | 14 | Options window 15 | 16 | *******************************************************************************/ 17 | class OptionsWindow: public InputBox { 18 | 19 | private: 20 | 21 | TextInput _iclos_inp, _ivars_inp, _uclos_inp, _uvars_inp; 22 | TextInput _repo_inp, _tag_inp, _sync_inp, _inst_inp, _upgr_inp, _reinst_inp; 23 | ToggleInput _resolve_toggle, _rebuild_toggle, _confirm_toggle, 24 | _buildopts_toggle, _color_toggle, _warninval_toggle, 25 | _cumfilt_toggle; 26 | Label _ui_settings, _color_settings, _pm_settings, _misc_settings; 27 | ComboBox _layout_box, _color_box, _pmgr_box; 28 | 29 | /* Drawing */ 30 | 31 | void redrawFrame(); 32 | 33 | public: 34 | 35 | /* Constructor and destructor */ 36 | 37 | OptionsWindow(); 38 | ~OptionsWindow(); 39 | 40 | /* Read/apply settings */ 41 | 42 | void readSettings(); 43 | void applySettings(int & check_color, int & check_write, 44 | const std::string & conf_file="") const; 45 | 46 | /* Window sizing and placement */ 47 | 48 | void placeWindow(); 49 | 50 | /* User interaction loop */ 51 | 52 | std::string exec(MouseEvent * mevent=NULL); 53 | 54 | /* Automatic defaults dialog when package manager is changed */ 55 | 56 | void askSetDefaults(const std::string & new_pkg_mgr, 57 | MouseEvent * mevent=NULL); 58 | }; 59 | -------------------------------------------------------------------------------- /include/PackageInfoBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "MessageBox.h" 5 | 6 | /******************************************************************************* 7 | 8 | Header for PackageInfoBox class 9 | 10 | *******************************************************************************/ 11 | class PackageInfoBox: public MessageBox { 12 | 13 | private: 14 | 15 | void redrawMessage() const; 16 | 17 | public: 18 | 19 | /* Constructors */ 20 | 21 | PackageInfoBox(); 22 | PackageInfoBox(WINDOW *win); 23 | 24 | /* Get attributes */ 25 | 26 | void minimumSize(int & height, int & width) const; 27 | void preferredSize(int & height, int & width) const; 28 | }; 29 | -------------------------------------------------------------------------------- /include/QuickSearch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "TextInput.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | String input item used for quick search 11 | 12 | *******************************************************************************/ 13 | class QuickSearch: public TextInput { 14 | 15 | public: 16 | 17 | /* User interaction */ 18 | 19 | virtual std::string exec(int y_offset, MouseEvent * mevent=NULL); 20 | }; 21 | -------------------------------------------------------------------------------- /include/ScrollBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "AbstractListBox.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | Same idea as a ListBox, but items are not selectable/highlightable. 11 | 12 | *******************************************************************************/ 13 | class ScrollBox: public AbstractListBox { 14 | 15 | protected: 16 | 17 | /* Scrolling up/down */ 18 | 19 | int scrollFirst(); 20 | int scrollLast(); 21 | int scrollUp(); 22 | int scrollDown(); 23 | int scrollPreviousPage(); 24 | int scrollNextPage(); 25 | int scrollFractional(const double & frac); 26 | 27 | /* Drawing */ 28 | 29 | virtual void redrawSingleItem(unsigned int idx); 30 | virtual void redrawScrollIndicator() const; 31 | 32 | public: 33 | 34 | /* Constructors */ 35 | 36 | ScrollBox(); 37 | ScrollBox(WINDOW *win, const std::string & name); 38 | 39 | /* Mouse interaction */ 40 | 41 | std::string handleMouseEvent(MouseEvent * mevent); 42 | 43 | /* User interaction loop */ 44 | 45 | virtual std::string exec(MouseEvent * mevent=NULL); 46 | }; 47 | -------------------------------------------------------------------------------- /include/SearchBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "TextInput.h" 5 | #include "ToggleInput.h" 6 | #include "InputBox.h" 7 | 8 | /******************************************************************************* 9 | 10 | Search dialog 11 | 12 | *******************************************************************************/ 13 | class SearchBox: public InputBox { 14 | 15 | private: 16 | 17 | TextInput _entryitem; 18 | ToggleInput _caseitem, _wholeitem, _readmeitem, _currentlistitem; 19 | 20 | /* Drawing */ 21 | 22 | void redrawFrame(); 23 | 24 | public: 25 | 26 | /* Constructor and destructor */ 27 | 28 | SearchBox(); 29 | ~SearchBox(); 30 | 31 | /* Set attributes */ 32 | 33 | void clearSearch(); 34 | 35 | /* Get attributes */ 36 | 37 | std::string searchString() const; 38 | bool caseSensitive() const; 39 | bool wholeWord() const; 40 | bool searchREADMEs() const; 41 | bool currentList() const; 42 | }; 43 | -------------------------------------------------------------------------------- /include/SelectionBox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ListBox.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | ListBox for making a selection 11 | 12 | *******************************************************************************/ 13 | class SelectionBox: public ListBox { 14 | 15 | protected: 16 | 17 | bool _modal; // If false, mouse click outside of window will kick out 18 | // of user interaction loop 19 | 20 | std::vector _external_hotkeys; 21 | // Extra hotkeys that can be used to kick out of the loop 22 | 23 | public: 24 | 25 | /* Constructors */ 26 | 27 | SelectionBox(); 28 | SelectionBox(WINDOW *win, const std::string & name); 29 | 30 | /* Set / get attributes */ 31 | 32 | void setModal(bool modal); 33 | bool modal() const; 34 | void addExternalHotKey(char ch); 35 | void setExternalHotKeys(std::vector hotkeys); 36 | 37 | /* User interaction loop */ 38 | 39 | virtual std::string exec(MouseEvent * mevent=NULL); 40 | }; 41 | -------------------------------------------------------------------------------- /include/ShellReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /******************************************************************************* 7 | 8 | Reads shell variables in a file 9 | 10 | *******************************************************************************/ 11 | class ShellReader { 12 | 13 | private: 14 | 15 | std::ifstream _file; 16 | bool _file_open; 17 | 18 | // Check if variable name is found 19 | 20 | bool checkVarname(std::string & line, const std::string & varname) const; 21 | 22 | // Reads value of variable from file 23 | 24 | int readVariable(std::string & line, std::string & value); 25 | int readDefaultVariable(std::string & line, std::string & value); 26 | 27 | public: 28 | 29 | /* Constructor and destructor */ 30 | 31 | ShellReader(); 32 | ~ShellReader(); 33 | 34 | /* Opens or closes a file */ 35 | 36 | int open(const std::string & filename); 37 | int close(); 38 | 39 | /* Reads a variable from the file and stores as string */ 40 | 41 | int read(const std::string & varname, std::string & value, 42 | bool default_var=false); 43 | 44 | /* Rewinds to beginning of the file */ 45 | 46 | int rewind(); 47 | }; 48 | -------------------------------------------------------------------------------- /include/TagList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "SelectionBox.h" 7 | #include "ListItem.h" 8 | #include "BuildListItem.h" 9 | #include "MouseEvent.h" 10 | 11 | /******************************************************************************* 12 | 13 | Manages tagged SlackBuilds 14 | 15 | *******************************************************************************/ 16 | class TagList: public SelectionBox { 17 | 18 | private: 19 | 20 | /* List storing all tagged items. The _items list is a subset of this 21 | showing only what is appropriate for the requested action (install, 22 | upgrade, etc.). */ 23 | 24 | std::vector _tagged; 25 | 26 | /* Drawing */ 27 | 28 | void redrawSingleItem(unsigned int idx); 29 | 30 | public: 31 | 32 | /* Constructors */ 33 | 34 | TagList(); 35 | TagList(WINDOW *win, const std::string & name); 36 | 37 | /* Edit list (redefined to use _tagged instead of _items) */ 38 | 39 | void addItem(ListItem *item); 40 | void removeItem(ListItem *item); 41 | void removeItem(unsigned int idx); 42 | void clearList(); 43 | 44 | /* Get properties */ 45 | 46 | unsigned int numTagged() const; 47 | 48 | /* Create _items list to display based on action */ 49 | 50 | unsigned int getDisplayList(const std::string & action); 51 | 52 | /* Handles mouse event */ 53 | 54 | std::string handleMouseEvent(MouseEvent * mevent); 55 | 56 | /* User interaction loop */ 57 | 58 | std::string exec(MouseEvent * mevent=NULL); 59 | 60 | /* Returns pointer to item by index in _tagged list */ 61 | 62 | ListItem * taggedByIdx(unsigned int idx); 63 | }; 64 | -------------------------------------------------------------------------------- /include/TextInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "InputItem.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | String input item 11 | 12 | *******************************************************************************/ 13 | class TextInput: public InputItem { 14 | 15 | protected: 16 | 17 | std::string _entry, _label; 18 | unsigned int _firsttext, _cursidx, _labellen; 19 | 20 | /* Determines first character to print in input box */ 21 | 22 | unsigned int determineFirstText(); 23 | 24 | /* Drawing */ 25 | 26 | void redrawEntry(int y_offset) const; 27 | 28 | public: 29 | 30 | /* Constructors */ 31 | 32 | TextInput(); 33 | 34 | /* Set properties */ 35 | 36 | void setText(const std::string & text); 37 | void clear(); 38 | void setLabel(const std::string & label); 39 | void removeLabel(); 40 | 41 | /* User interaction */ 42 | 43 | std::string handleMouseEvent(MouseEvent * mevent, int y_offset); 44 | void draw(int y_offset, bool force=false, bool highlight=false); 45 | virtual std::string exec(int y_offset, MouseEvent * mevent=NULL); 46 | 47 | /* Accessing properties */ 48 | 49 | std::string getStringProp() const; 50 | std::string text() const; 51 | }; 52 | -------------------------------------------------------------------------------- /include/ToggleInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "InputItem.h" 6 | #include "MouseEvent.h" 7 | 8 | /******************************************************************************* 9 | 10 | Toggle input item 11 | 12 | *******************************************************************************/ 13 | class ToggleInput: public InputItem { 14 | 15 | private: 16 | 17 | bool _enabled; 18 | 19 | /* Drawing */ 20 | 21 | void redrawEntry(int y_offset) const; 22 | void redrawText(int y_offset) const; 23 | 24 | public: 25 | 26 | /* Constructors */ 27 | 28 | ToggleInput(); 29 | 30 | /* Setting properties */ 31 | 32 | void setEnabled(bool enabled); 33 | void toggle(); 34 | 35 | /* User interaction */ 36 | 37 | std::string handleMouseEvent(MouseEvent * mevent, int y_offset); 38 | void draw(int y_offset, bool force=false, bool highlight=false); 39 | std::string exec(int y_offset, MouseEvent * mevent=NULL); 40 | 41 | /* Accessing properties. */ 42 | 43 | bool getBoolProp() const; 44 | bool enabled() const; 45 | }; 46 | -------------------------------------------------------------------------------- /include/backend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include // floor 6 | #include "BuildListItem.h" 7 | #include "Blacklist.h" 8 | #include "IgnoreVersions.h" 9 | 10 | extern Blacklist blacklist; 11 | extern IgnoreVersions ignore_versions; 12 | 13 | int read_repo(std::vector > & slackbuilds); 14 | int read_buildopts(std::vector > & slackbuilds); 15 | int find_slackbuild(const std::string & name, 16 | std::vector > & slackbuilds, 17 | int & idx0, int & idx1); 18 | int get_pkg_info(const std::string & pkg, std::string & name, 19 | std::string & version, std::string & arch, 20 | std::string & build); 21 | bool check_installed(const BuildListItem & build, 22 | const std::vector & installedpkgs, 23 | std::string & pkg, std::string & version, 24 | std::string & arch, std::string & pkgbuild); 25 | int get_reqs(const BuildListItem & build, std::string & reqs); 26 | int get_repo_info(const BuildListItem & build, std::string & available_version, 27 | std::string & reqs, std::string & available_buildnum); 28 | void determine_installed(std::vector > & slackbuilds, 29 | std::vector & pkg_errors, 30 | std::vector & missing_info); 31 | std::vector list_installed( 32 | std::vector > & slackbuilds); 33 | std::vector list_nondeps( 34 | std::vector > & slackbuilds); 35 | int install_slackbuild(BuildListItem & build); 36 | int upgrade_slackbuild(BuildListItem & build); 37 | int reinstall_slackbuild(BuildListItem & build); 38 | int remove_slackbuild(BuildListItem & build); 39 | int view_readme(const BuildListItem & build); 40 | int view_file(const std::string & path); 41 | int view_notes(const BuildListItem & build); 42 | int sync_repo(bool interactive=true); 43 | 44 | /******************************************************************************* 45 | 46 | Overloaded template functions to turn reference into pointer 47 | http://stackoverflow.com/questions/14466620/c-template-specialization- \ 48 | calling-methods-on-types-that-could-be-pointers-or#14466705 49 | 50 | *******************************************************************************/ 51 | template 52 | T * ptr(T & obj) { return & obj; } 53 | 54 | template 55 | T * ptr(T * obj) { return obj; } 56 | 57 | /******************************************************************************* 58 | 59 | Finds an item by name in a sorted list. If whole_word is set to false, it 60 | will only search the first N characters of items in the list, where N is the 61 | length of the input name. Returns 0 if found, 1 if not found. 62 | 63 | Note: the implementation is placed in the header file to avoid the need for 64 | explicit instantiation of the template. 65 | 66 | *******************************************************************************/ 67 | template 68 | int find_name_in_list(const std::string & name, std::vector & list, 69 | int & idx, int & lbound, int & rbound, 70 | bool whole_word=true) 71 | { 72 | int midbound; 73 | unsigned int namelen; 74 | std::string leftcheck, rightcheck, midcheck; 75 | 76 | if (name == "") { return 1; } 77 | 78 | if (whole_word) 79 | { 80 | leftcheck = ptr(list[lbound])->name(); 81 | rightcheck = ptr(list[rbound])->name(); 82 | } 83 | else 84 | { 85 | namelen = name.size(); 86 | leftcheck = ptr(list[lbound])->name().substr(0,namelen); 87 | rightcheck = ptr(list[rbound])->name().substr(0,namelen); 88 | } 89 | 90 | // Check if outside the bounds 91 | 92 | if ( (name < leftcheck) || (name > rightcheck) ) { return 1; } 93 | 94 | // Check bounds for match 95 | 96 | if (name == leftcheck) 97 | { 98 | if ( (whole_word) || (rbound-lbound == 1) ) 99 | { 100 | idx = lbound; 101 | return 0; 102 | } 103 | } 104 | else if (name == rightcheck) 105 | { 106 | if ( (whole_word) || (rbound-lbound == 1) ) 107 | { 108 | idx = rbound; 109 | return 0; 110 | } 111 | } 112 | else { if (rbound-lbound == 1) { return 1; } } 113 | 114 | // Cut the list in half and try again 115 | 116 | midbound = std::floor(double(lbound+rbound)/2.); 117 | if (whole_word) { midcheck = ptr(list[midbound])->name(); } 118 | else { midcheck = ptr(list[midbound])->name().substr(0,namelen); } 119 | 120 | if (name <= midcheck) { rbound = midbound; } 121 | else { lbound = midbound; } 122 | 123 | return find_name_in_list(name, list, idx, lbound, rbound, whole_word); 124 | } 125 | -------------------------------------------------------------------------------- /include/filters.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "BuildListItem.h" 7 | #include "CategoryListItem.h" 8 | #include "CategoryListBox.h" 9 | #include "BuildListBox.h" 10 | 11 | bool any_build(const BuildListItem & build); 12 | bool build_is_installed(const BuildListItem & build); 13 | bool build_is_upgradable(const BuildListItem & build); 14 | bool build_is_tagged(const BuildListItem & build); 15 | bool build_is_blacklisted(const BuildListItem & build); 16 | bool build_has_buildoptions(const BuildListItem & build); 17 | 18 | void filter_by_func(std::vector > & slackbuilds, 19 | bool (*func)(const BuildListItem &), 20 | std::vector & categories, 21 | WINDOW *blistboxwin, CategoryListBox & clistbox, 22 | std::vector & blistboxes, 23 | unsigned int & nfiltered, bool overwrite=true); 24 | void filter_nondeps(std::vector > & all_slackbuilds, 25 | std::vector > & slackbuilds, 26 | std::vector & categories, 27 | WINDOW *blistboxwin, CategoryListBox & clistbox, 28 | std::vector & blistboxes, 29 | unsigned int & nnondeps, bool overwrite=true); 30 | void filter_search(std::vector > & slackbuilds, 31 | std::vector & categories, 32 | WINDOW *blistboxwin, CategoryListBox & clistbox, 33 | std::vector & blistboxes, 34 | unsigned int & nsearch, const std::string & searchterm, 35 | bool case_sensitive, bool whole_word, bool search_readmes, 36 | bool overwrite=true); 37 | -------------------------------------------------------------------------------- /include/requirements.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "BuildListItem.h" 5 | 6 | int compute_reqs_order(const BuildListItem & build, 7 | std::vector & reqlist, 8 | std::vector > & slackbuilds); 9 | void compute_inv_reqs(const BuildListItem & build, 10 | std::vector & invreqlist, 11 | std::vector > & slackbuilds); 12 | -------------------------------------------------------------------------------- /include/settings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "Color.h" 6 | #include "ColorTheme.h" 7 | 8 | #ifndef PACKAGE_VERSION 9 | #define PACKAGE_VERSION "" 10 | #endif 11 | 12 | namespace settings 13 | { 14 | extern std::string repo_dir, repo_tag; 15 | extern std::string package_manager; 16 | extern std::string sync_cmd, install_cmd, upgrade_cmd, reinstall_cmd; 17 | extern std::string install_clos, install_vars; 18 | extern std::string upgrade_clos, upgrade_vars; 19 | extern std::string editor, viewer; 20 | extern std::string color_theme; 21 | extern std::string layout; 22 | extern bool resolve_deps, confirm_changes, enable_color, rebuild_inv_deps; 23 | extern bool save_buildopts, warn_invalid_pkgnames, cumulative_filters; 24 | } 25 | 26 | extern Color colors; 27 | extern std::vector color_themes; 28 | 29 | int read_config(const std::string & conf_file=""); 30 | int write_config(const std::string & conf_file=""); 31 | int setup_color(); 32 | int apply_color_theme(const std::string & theme); 33 | int activate_color(const std::string & theme); 34 | void deactivate_color(); 35 | -------------------------------------------------------------------------------- /include/signals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace signals 6 | { 7 | extern std::string resize; 8 | extern std::string quit; 9 | extern std::string highlight; 10 | extern std::string highlightFirst; 11 | extern std::string highlightLast; 12 | extern std::string highlightPrev; 13 | extern std::string highlightNext; 14 | extern std::string highlightPrevPage; 15 | extern std::string highlightNextPage; 16 | extern std::string keyTab; 17 | extern std::string keyEnter; 18 | extern std::string scroll; 19 | extern std::string keyRight; 20 | extern std::string keyLeft; 21 | extern std::string keySpace; 22 | extern std::string mouseEvent; 23 | extern std::string nullEvent; 24 | extern std::string tag; 25 | extern std::string keyF9; 26 | } 27 | -------------------------------------------------------------------------------- /include/string_util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | extern std::string int_to_string(int inval); 7 | extern bool is_integer(const std::string & instr); 8 | extern std::string chararray_to_string(char chararray[]); 9 | extern std::string string_to_lower(const std::string & instr); 10 | extern std::string trim(const std::string & instr); 11 | extern std::string remove_leading_whitespace(const std::string & instr); 12 | extern std::string remove_comment(const std::string & instr, 13 | char comment='#'); 14 | extern std::vector split(const std::string & instr, 15 | char delim=' '); 16 | extern std::vector wrap_words(const std::string & instr, 17 | unsigned int width); 18 | extern bool find_in_file(const std::string & pattern, 19 | const std::string & filename, bool whole_word=false, 20 | bool case_sensitive=false); 21 | -------------------------------------------------------------------------------- /man/sboui-backend.8: -------------------------------------------------------------------------------- 1 | .TH SBOUI-BACKEND 8 2 | .SH NAME 3 | sboui-backend \- command-line utility for installing software from SlackBuilds.org 4 | .SH SYNOPSIS 5 | .B sboui-backend 6 | \fBupdate\fR 7 | 8 | .B sboui-backend 9 | \fI[OPTIONS]\fR \fBinstall\fR \fINAME(s)\fR 10 | 11 | .B sboui-backend 12 | \fBinfo\fR \fINAME\fR 13 | 14 | .B sboui-backend 15 | \fB{search|search-readmes} \fIPATTERN\fR 16 | 17 | .B sboui-backend 18 | \fBlist-groups\fR 19 | 20 | .B sboui-backend 21 | \fBbrowse-group\fR \fINAME\fR 22 | 23 | .B sboui-backend 24 | \fB\-\-help\fR, \fB\-h\fR 25 | .SH DESCRIPTION 26 | .B sboui-backend 27 | is a tool to easily install software from SlackBuilds.org. 28 | It is the "built-in" package manager for 29 | .BR sboui , 30 | but it can also be used standalone from the command line. 31 | It is similar to 32 | .B sbopkg 33 | and 34 | .BR sbotools , 35 | but simpler; it is intended to be a minimal SBo package manager for 36 | .BR sboui , 37 | which adds in more advanced features such as automatic forward and inverse dependency resolution. 38 | .B sboui 39 | can function equally well with any of these three package managers (\fBsbopkg\fR, \fBsbotools\fR, or \fBsboui-backend\fR), but 40 | .B sboui-backend 41 | allows 42 | .B sboui 43 | to run without any separate SBo package manager installed. 44 | 45 | .PP 46 | .B Instructions 47 | .PP 48 | Before running 49 | .BR sboui-backend , 50 | select the desired repository and branch in 51 | .IR /etc/sboui/sboui-backend.conf . 52 | .B sboui-backend 53 | uses 54 | .B git 55 | to manage the local SBo repository. 56 | You should select the proper repository to match your Slackware installation. 57 | See 58 | .BR sboui-backend.conf (5) 59 | for more information about the configuration file. 60 | 61 | To create the local repository, run 62 | \fBsboui-backend update\fR 63 | or use the sync command within 64 | .B sboui 65 | with the \fBpackage_manager\fR set to \fBbuilt-in\fR. 66 | This will create the local repository if it does not yet exist or update it if it does. 67 | After that, packages can be built and installed or upgraded using the \fBinstall\fR action. 68 | There are also several commands for searching and browsing the repository, as will be discussed in the next session. 69 | .SH ACTIONS 70 | .TP 71 | .B update 72 | .br 73 | Create or sync the local SBo repository. 74 | .TP 75 | \fBinstall\fR \fI[OPTIONS]\fR \fINAME(s)\fR 76 | .br 77 | Install or upgrade an SBo package, or packages, by name. 78 | If multiple SlackBuild names are listed, the action will be applied to each one. 79 | 80 | .I OPTIONS 81 | 82 | \fB\-f\fR or \fB\-\-force\fR: if a requested package is already installed and up-to-date, reinstall without asking for confirmation first. 83 | 84 | \fBsourcedir\fR=\fIDIRECTORY\fR: instead of downloading source code, copy it from the specified directory. 85 | 86 | .TP 87 | \fBinfo\fR \fINAME\fR 88 | .br 89 | Display the contents of README and README.SLACKWARE / README.Slackware files corresponding to the named SlackBuild. 90 | .TP 91 | \fBsearch\fR \fIPATTERN\fR 92 | .br 93 | Searches for SlackBuilds whose name matches all or part of the given pattern. 94 | For any matches, lists the group it belongs to and whether it is installed. 95 | .TP 96 | \fBsearch-readmes\fR \fIPATTERN\fR 97 | .br 98 | Searches in README files for the given pattern. 99 | For any matches, lists the name of the SlackBuild whose README contains the pattern. 100 | Note that the search READMEs function in 101 | .B sboui 102 | is much faster than this method and finds matches both in the README files and the SlackBuild name. 103 | .TP 104 | \fBlist-groups\fR 105 | .br 106 | Displays a list of all groups (e.g., academic, desktop, libraries, etc.) in the repository. 107 | .TP 108 | \fBbrowse-group\fR \fINAME\fR 109 | .br 110 | Displays a list of all SlackBuilds in a given group. 111 | .TP 112 | \fB-h\fR or \fB--help\fR 113 | .br 114 | Displays a short description of each action in 115 | .BR sboui-backend . 116 | .SH EXIT STATUS 117 | The exit status is 0 if all commands executed as expected. Returns non-zero if: 118 | .IP \(bu 119 | The git clone or git pull commands initiated by the 120 | .B update 121 | action fail. 122 | This can happen if permissions in repo directory are incorrect or if the REPO or BRANCH variables in 123 | .I sboui-backend.conf 124 | are invalid. 125 | .IP \(bu 126 | An invalid option or nonexistent SlackBuild is specified for the 127 | .B install 128 | action. 129 | .IP \(bu 130 | The 131 | \fBsourcedir\fR option is specified for the 132 | .B install 133 | command, but the sources are not found in the specified directory. 134 | .IP \(bu 135 | Source code failed to download or failed the MD5sum check. 136 | .IP \(bu 137 | Building the package failed. 138 | .IP \(bu 139 | Invalid command line options were specified. 140 | .SH ENVIRONMENT 141 | .TP 142 | .B CONF 143 | .br 144 | Configuration file to read. 145 | By default, it is 146 | .IR /etc/sboui/sboui-backend.conf , 147 | but this environment variable can be set to read a different file instead. 148 | .TP 149 | .B OUTPUT 150 | .br 151 | Directory to drop built package. 152 | By default, it is 153 | .IR /tmp . 154 | .TP 155 | .B TMP 156 | .br 157 | Directory where temporary source and package directories are placed. 158 | By default, it is 159 | .IR /tmp/SBo . 160 | .SH FILES 161 | .TP 162 | .I /etc/sboui/sboui-backend.conf 163 | .br 164 | Default configuration file for 165 | .BR sboui-backend . 166 | See 167 | .BR sboui-backend.conf (5) 168 | for more information about the entries in this file. 169 | .SH BUGS 170 | Please report bugs to the email address below or on the issue tracker for sboui's project page, 171 | .IR https://github.com/montagdude/sboui . 172 | .SH SEE ALSO 173 | .BR sboui (8), 174 | .BR sboui-backend (8), 175 | .BR sboui-update-notifier (1), 176 | .BR sbopkg (8), 177 | .BR sboinstall (1) 178 | .SH AUTHORS 179 | Daniel Prosser 180 | -------------------------------------------------------------------------------- /man/sboui-backend.conf.5: -------------------------------------------------------------------------------- 1 | .TH SBOUI-BACKEND.CONF 5 2 | .SH NAME 3 | sboui-backend.conf \- configuration file for sboui-backend 4 | .SH DESCRIPTION 5 | .I sboui-backend.conf 6 | contains settings for 7 | .BR sboui-backend (8), 8 | a command-line utility for installing software from SlackBuilds.org. 9 | This file resides in 10 | .IR /etc/sboui/sboui-backend.conf , 11 | but a different file can be read instead by setting the CONF environment variable. 12 | This manual describes the configuration settings specified in the configuration file. 13 | Variable names, default values, and descriptions are listed below. 14 | .PP 15 | .TP 16 | .B REPO 17 | .br 18 | default: 19 | .B git://git.slackbuilds.org/slackbuilds.git 20 | .IP 21 | Specifies the 22 | .B git 23 | repository to clone and sync locally. 24 | Most users should stick with the default, but if tracking -current, you may want to use 25 | .I git://github.com/Ponce/slackbuilds.git 26 | instead. 27 | .TP 28 | .B BRANCH 29 | .br 30 | default: 31 | .B 15.0 32 | .IP 33 | The branch to clone and sync. 34 | The SBo project creates a new branch for each Slackware release, so use the branch corresponding to the version of Slackware installed. 35 | This input is not relevant for the Ponce -current repo. 36 | .TP 37 | .B REPO_DIR 38 | .br 39 | default: 40 | .I /var/lib/sboui/repo 41 | .IP 42 | Location to store the SBo repository locally. 43 | If you are using 44 | .B sboui 45 | with the built-in 46 | .B package_manager 47 | setting, make sure that this location matches 48 | .B repo_dir 49 | in your 50 | .B sboui 51 | settings. 52 | .TP 53 | .B CLEAN_PACKAGE 54 | .br 55 | default: 56 | .B no 57 | .IP 58 | Whether to delete the package created by the SlackBuild script after installing. 59 | .TP 60 | .B CLEAN_SOURCE 61 | .br 62 | default: 63 | .B yes 64 | .IP 65 | Whether to remove source tarball(s) from the local repo tree after building. 66 | .TP 67 | .B CLEAN_TMP 68 | .br 69 | default: 70 | .B no 71 | .IP 72 | Whether to remove temporary build and source directories after installing the package. 73 | .SH FILES 74 | .TP 75 | .I /etc/sboui/sboui-backend.conf 76 | .br 77 | Default configuration file for 78 | .BR sboui-backend . 79 | .SH SEE ALSO 80 | .BR sboui-backend (8), 81 | .BR sboui (8), 82 | .BR sboui-update-notifier (1) 83 | .SH AUTHORS 84 | Daniel Prosser 85 | -------------------------------------------------------------------------------- /man/sboui-update-notifier.1: -------------------------------------------------------------------------------- 1 | .TH SBOUI-UPDATE-NOTIFIER 1 2 | .SH NAME 3 | sboui-update-notifier \- system tray notifier for SBo package updates 4 | .SH SYNOPSIS 5 | .B sboui-update-notifier 6 | [\fBINTERVAL\fR] 7 | .SH DESCRIPTION 8 | .B sboui-update-notifier 9 | checks whether SBo updates are available, notifies the user via a system tray icon, and optionally launches 10 | .B sboui 11 | to perform the upgrades. 12 | .PP 13 | .B Instructions 14 | .PP 15 | .B sboui-update-notifier 16 | is intended to be run as a startup script for the user's desktop environment or window manager to receive automatic update notifications for SBo packages. 17 | It is only installed when 18 | .B sboui 19 | is configured with 20 | .I INSTALL_SYSTRAY_NOTIFIER 21 | enabled. 22 | In that case, an hourly cronjob is also installed to automatically keep the local SBo repository up-to-date. 23 | .B sboui-update-notifier 24 | checks whether updates are available at a regular interval, and, if so, places the 25 | .B sboui 26 | icon in the system tray. 27 | When clicked, 28 | .B sboui 29 | is launched to perform the upgrades. 30 | .PP 31 | Note that the hourly cronjob uses the RSS feed to detect updates (only downloading the headers to check last modification date), and a full sync is only performed if indicated by the RSS feed. 32 | This procedure ensures that undue load is not placed on the SBo server every hour. 33 | .SH OPTIONS 34 | .B sboui-update-notifier 35 | accepts one optional command-line option: 36 | .TP 37 | .B \fBINTERVAL\fR 38 | .br 39 | Specify the period of time, in seconds, to wait between checks for updates. 40 | The default is 3600 seconds, or 1 hour. 41 | Note that this option does not affect the frequency at which the cronjob runs. 42 | To change that interval, move the cronjob from /etc/cron.hourly to another location, such as /etc/cron.daily. 43 | .SH BUGS 44 | Please report bugs to the email address below or on the issue tracker for sboui's project page, 45 | .IR https://github.com/montagdude/sboui . 46 | .SH SEE ALSO 47 | .BR sboui (8), 48 | .BR sboui-backend (8), 49 | .BR crond (8), 50 | .BR crontab (1) 51 | .SH AUTHORS 52 | Daniel Prosser 53 | -------------------------------------------------------------------------------- /sboui.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | TryExec=${CMAKE_INSTALL_PREFIX}/sbin/sboui 4 | Exec=${GRAPHICAL_SU_CMD} "${TERMINAL_EMULATOR} -e ${CMAKE_INSTALL_PREFIX}/libexec/sboui/sboui_launch" 5 | Name=sboui 6 | GenericName=SBo interactive package manager 7 | Comment=Install, upgrade, or remove SBo packages 8 | Icon=sboui 9 | Terminal=false 10 | Categories=PackageManager;System; 11 | StartupNotify=true 12 | Type=Application 13 | -------------------------------------------------------------------------------- /screenshots/commander.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/montagdude/sboui/eda440d77e7ac11b203c945f31301eabab979908/screenshots/commander.png -------------------------------------------------------------------------------- /screenshots/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/montagdude/sboui/eda440d77e7ac11b203c945f31301eabab979908/screenshots/install.png -------------------------------------------------------------------------------- /screenshots/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/montagdude/sboui/eda440d77e7ac11b203c945f31301eabab979908/screenshots/options.png -------------------------------------------------------------------------------- /screenshots/package_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/montagdude/sboui/eda440d77e7ac11b203c945f31301eabab979908/screenshots/package_info.png -------------------------------------------------------------------------------- /src/Blacklist.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "string_util.h" 6 | #include "backend.h" 7 | #include "Blacklist.h" 8 | 9 | /******************************************************************************* 10 | 11 | Constructor 12 | 13 | *******************************************************************************/ 14 | Blacklist::Blacklist() { _patterns.resize(0); } 15 | 16 | /******************************************************************************* 17 | 18 | Reads and stores patterns from blacklist file 19 | 20 | *******************************************************************************/ 21 | int Blacklist::read(const std::string & filename) 22 | { 23 | std::ifstream file; 24 | std::string line; 25 | 26 | file.open(filename.c_str()); 27 | if (not file.is_open()) { return 1; } 28 | 29 | while (! file.eof()) 30 | { 31 | std::getline(file, line); 32 | line = remove_leading_whitespace(line); 33 | if (line[0] == '#') { continue; } 34 | line = remove_comment(line, '#'); 35 | line = trim(line); 36 | if (line.size() > 0) 37 | { 38 | std::regex reg(line); 39 | _patterns.push_back(reg); 40 | } 41 | } 42 | 43 | file.close(); 44 | 45 | return 0; 46 | } 47 | 48 | /******************************************************************************* 49 | 50 | Checks installed package for matches in name, version, arch, build, and fullname 51 | 52 | *******************************************************************************/ 53 | bool Blacklist::blacklisted(const std::string & pkg) const 54 | { 55 | std::string name, version, arch, build; 56 | unsigned int i, npatterns; 57 | 58 | get_pkg_info(pkg, name, version, arch, build); 59 | 60 | // Check for blacklist pattern matching info in package name 61 | 62 | npatterns = _patterns.size(); 63 | for ( i = 0; i < npatterns; i++ ) 64 | { 65 | if (std::regex_match(name, _patterns[i])) { return true; } 66 | if (std::regex_match(version, _patterns[i])) { return true; } 67 | if (std::regex_match(arch, _patterns[i])) { return true; } 68 | if (std::regex_match(build, _patterns[i])) { return true; } 69 | if (std::regex_match(pkg, _patterns[i])) { return true; } 70 | } 71 | 72 | return false; 73 | } 74 | 75 | bool Blacklist::blacklisted(const std::string & pkg, const std::string & name, 76 | const std::string & version, const std::string & arch, 77 | const std::string & build) const 78 | { 79 | unsigned int i, npatterns; 80 | 81 | // Check for blacklist pattern matching info in package name 82 | 83 | npatterns = _patterns.size(); 84 | for ( i = 0; i < npatterns; i++ ) 85 | { 86 | if (std::regex_match(name, _patterns[i])) { return true; } 87 | if (std::regex_match(version, _patterns[i])) { return true; } 88 | if (std::regex_match(arch, _patterns[i])) { return true; } 89 | if (std::regex_match(build, _patterns[i])) { return true; } 90 | if (std::regex_match(pkg, _patterns[i])) { return true; } 91 | } 92 | 93 | return false; 94 | } 95 | 96 | /******************************************************************************* 97 | 98 | Checks for match by name only (used for not-installed SlackBuilds) 99 | 100 | *******************************************************************************/ 101 | bool Blacklist::nameBlacklisted(const std::string & name) const 102 | { 103 | unsigned int i, npatterns; 104 | 105 | npatterns = _patterns.size(); 106 | for ( i = 0; i < npatterns; i++ ) 107 | { 108 | if (std::regex_match(name, _patterns[i])) { return true; } 109 | } 110 | 111 | return false; 112 | } 113 | -------------------------------------------------------------------------------- /src/BuildActionBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ListItem.h" 4 | #include "BuildListItem.h" 5 | #include "SelectionBox.h" 6 | #include "BuildActionBox.h" 7 | 8 | /******************************************************************************* 9 | 10 | Constructor 11 | 12 | *******************************************************************************/ 13 | BuildActionBox::BuildActionBox() 14 | { 15 | _name = "Select an action"; 16 | } 17 | 18 | /******************************************************************************* 19 | 20 | Destructor 21 | 22 | *******************************************************************************/ 23 | BuildActionBox::~BuildActionBox() 24 | { 25 | unsigned int i, nitems; 26 | 27 | nitems = _items.size(); 28 | for ( i = 0; i < nitems; i++ ) { delete _items[i]; } 29 | _items.resize(0); 30 | } 31 | 32 | /******************************************************************************* 33 | 34 | Creates options using info about SlackBuild 35 | 36 | *******************************************************************************/ 37 | void BuildActionBox::create(BuildListItem & build, bool limited_actions) 38 | { 39 | unsigned int count; 40 | 41 | clearList(); 42 | count = 0; 43 | 44 | addItem(new ListItem("View README")); 45 | _items[count]->setHotKey(0); 46 | count++; 47 | 48 | addItem(new ListItem("Browse files")); 49 | _items[count]->setHotKey(0); 50 | count++; 51 | 52 | addItem(new ListItem("Set build options")); 53 | _items[count]->setHotKey(0); 54 | count++; 55 | 56 | addItem(new ListItem("Show package info")); 57 | _items[count]->setHotKey(1); 58 | count++; 59 | 60 | if (! limited_actions) 61 | { 62 | if (! build.getBoolProp("blacklisted")) 63 | { 64 | if (! build.getBoolProp("installed")) 65 | { 66 | addItem(new ListItem("Install")); 67 | _items[count]->setHotKey(0); 68 | count++; 69 | } 70 | else 71 | { 72 | addItem(new ListItem ("Remove")); 73 | _items[count]->setHotKey(0); 74 | count++; 75 | if (build.getBoolProp("upgradable")) 76 | { 77 | addItem(new ListItem("Upgrade")); 78 | _items[count]->setHotKey(0); 79 | } 80 | else 81 | { 82 | addItem(new ListItem ("Reinstall")); 83 | _items[count]->setHotKey(1); 84 | } 85 | count++; 86 | } 87 | } 88 | 89 | addItem(new ListItem("Compute build order")); 90 | _items[count]->setHotKey(0); 91 | count++; 92 | } 93 | 94 | addItem(new ListItem("List inverse deps")); 95 | _items[count]->setHotKey(0); 96 | count++; 97 | 98 | addItem(new ListItem("View/edit notes")); 99 | _items[count]->setHotKey(3); 100 | count++; 101 | } 102 | -------------------------------------------------------------------------------- /src/CLOParser.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "string_util.h" 5 | #include "CLOParser.h" 6 | 7 | /******************************************************************************* 8 | 9 | Reads command line arguments and saves as vector of strings 10 | 11 | *******************************************************************************/ 12 | void CLOParser::readCLOs(int argc, char *argv[]) 13 | { 14 | int i; 15 | 16 | _argv_str.resize(0); 17 | for ( i = 0; i < argc; i++ ) 18 | { 19 | _argv_str.push_back(chararray_to_string(argv[i])); 20 | } 21 | } 22 | 23 | /******************************************************************************* 24 | 25 | Constructor 26 | 27 | *******************************************************************************/ 28 | CLOParser::CLOParser() 29 | { 30 | _argv_str.resize(0); 31 | _input_file = ""; 32 | _sync = false; 33 | _upgrade_all = false; 34 | _upgradable = false; 35 | } 36 | 37 | /******************************************************************************* 38 | 39 | Checks CLOs for errors. Returns 0 on successful read, 1 if there are errors, or 40 | -1 if the user asked to print help or version info. 41 | 42 | *******************************************************************************/ 43 | int CLOParser::checkCLOs(int argc, char *argv[], const std::string & version) 44 | { 45 | int i; 46 | 47 | // Save CLOs as vector of strings 48 | 49 | readCLOs(argc, argv); 50 | 51 | // Check for errors 52 | 53 | i = 1; 54 | while (i < argc) 55 | { 56 | if ( (_argv_str[i] == "-f") || (_argv_str[i] == "--file") ) 57 | { 58 | if (i < argc-1) 59 | { 60 | _input_file = _argv_str[i+1]; 61 | i += 2; 62 | } 63 | else 64 | { 65 | std::cerr << "Error: must specify a file with " << _argv_str[i] 66 | << " argument." << std::endl; 67 | printUsage(); 68 | return 1; 69 | } 70 | } 71 | else if ( (_argv_str[i] == "-s") || (_argv_str[i] == "--sync") ) 72 | { 73 | _sync = true; 74 | i += 1; 75 | } 76 | else if ( (_argv_str[i] == "-u") || (_argv_str[i] == "--upgrade-all") ) 77 | { 78 | _upgrade_all = true; 79 | i += 1; 80 | } 81 | else if ( (_argv_str[i] == "-p") || (_argv_str[i] == "--upgradable") ) 82 | { 83 | _upgradable = true; 84 | i += 1; 85 | } 86 | else if ( (_argv_str[i] == "-h") || (_argv_str[i] == "--help") ) 87 | { 88 | printHelp(); 89 | return -1; 90 | } 91 | else if ( (_argv_str[i] == "-v") || (_argv_str[i] == "--version") ) 92 | { 93 | printVersion(version); 94 | return -1; 95 | } 96 | else 97 | { 98 | printUsage(); 99 | return 1; 100 | } 101 | } 102 | 103 | return 0; 104 | } 105 | 106 | /******************************************************************************* 107 | 108 | Prints various information messages 109 | 110 | *******************************************************************************/ 111 | void CLOParser::printUsage() const 112 | { 113 | std::cout << "Usage: sboui [OPTION]" << std::endl; 114 | std::cout << "Try 'sboui --help' for more information." << std::endl; 115 | } 116 | 117 | void CLOParser::printVersion(const std::string & version) const 118 | { 119 | std::cout << "sboui " << version << std::endl; 120 | std::cout << "Copyright (C) 2016-2024 Daniel Prosser" << std::endl; 121 | std::cout << "Expat/MIT License: https://opensource.org/licenses/MIT" 122 | << std::endl; 123 | std::cout << "This is free software; you are free to change it and " 124 | << "redistribute it." << std::endl; 125 | std::cout << "This software is presented 'as is', without warranty " 126 | << "of any kind." << std::endl; 127 | } 128 | 129 | void CLOParser::printHelp() const 130 | { 131 | std::cout << "Usage: sboui [OPTION]" << std::endl; 132 | std::cout << std::endl; 133 | std::cout << "Options:" << std::endl; 134 | std::cout << " -f, --file FILE Specify a custom configuration file" 135 | << std::endl; 136 | std::cout << " -s, --sync Sync (update) local SBo repository and exit" 137 | << std::endl; 138 | std::cout << " -u, --upgrade-all Tag and interactively upgrade all packages" 139 | << std::endl; 140 | std::cout << " -p, --upgradable List upgradable SlackBuilds and exit" 141 | << std::endl; 142 | std::cout << " -h, --help Display usage information and exit" 143 | << std::endl; 144 | std::cout << " -v, --version Display version number of sboui and exit" 145 | << std::endl; 146 | std::cout << std::endl; 147 | std::cout << "sboui home page: https://github.com/montagdude/sboui" 148 | << std::endl; 149 | std::cout << "Please report bugs using the GitHub issue tracker." 150 | << std::endl; 151 | } 152 | 153 | /******************************************************************************* 154 | 155 | Custom input file information 156 | 157 | *******************************************************************************/ 158 | bool CLOParser::requestInputFile() const 159 | { 160 | if (_input_file == "") { return false; } 161 | else { return true; } 162 | } 163 | 164 | const std::string & CLOParser::inputFile() const { return _input_file; } 165 | 166 | /******************************************************************************* 167 | 168 | Other possible inputs 169 | 170 | *******************************************************************************/ 171 | bool CLOParser::sync() const { return _sync; } 172 | bool CLOParser::upgradeAll() const { return _upgrade_all; } 173 | bool CLOParser::upgradable() const { return _upgradable; } 174 | -------------------------------------------------------------------------------- /src/CategoryListItem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ListItem.h" 3 | #include "CategoryListItem.h" 4 | 5 | /******************************************************************************* 6 | 7 | Constructor 8 | 9 | *******************************************************************************/ 10 | CategoryListItem::CategoryListItem() 11 | { 12 | _name = ""; 13 | addBoolProp("tagged", false); 14 | addProp("category", ""); 15 | } 16 | -------------------------------------------------------------------------------- /src/ComboBoxList.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // sleep_for 4 | #include // this_thread 5 | #include "Color.h" 6 | #include "settings.h" 7 | #include "signals.h" 8 | #include "ListItem.h" 9 | #include "ComboBoxList.h" 10 | #include "MouseEvent.h" 11 | 12 | /******************************************************************************* 13 | 14 | There is no frame, and scroll arrows are handled by redrawSingleItem, so 15 | do nothing here! 16 | 17 | *******************************************************************************/ 18 | void ComboBoxList::redrawFrame() {} 19 | 20 | /******************************************************************************* 21 | 22 | Redraws a single item. Note: doesn't check if the item is actually on the 23 | screen or not. 24 | 25 | *******************************************************************************/ 26 | void ComboBoxList::redrawSingleItem(unsigned int idx) 27 | { 28 | std::string fg, bg; 29 | int rows, cols, rowsavail, lastrow; 30 | 31 | getmaxyx(_win, rows, cols); 32 | rowsavail = rows-_reserved_rows; 33 | lastrow = _firstprint+rowsavail-1; 34 | 35 | // Go to item location, optionally highlight, and print item 36 | 37 | wmove(_win, idx-_firstprint+_header_rows, 0); 38 | 39 | // Turn on highlight color 40 | 41 | if (int(idx) == _highlight) 42 | { 43 | if (_activated) 44 | { 45 | fg = "fg_highlight_active"; 46 | bg = "bg_highlight_active"; 47 | } 48 | else 49 | { 50 | fg = "fg_highlight_inactive"; 51 | bg = "bg_highlight_inactive"; 52 | } 53 | if (colors.turnOn(_win, fg, bg) != 0) 54 | { 55 | if (_activated) { wattron(_win, A_REVERSE); } 56 | } 57 | } 58 | else { colors.turnOn(_win, "fg_combobox", "bg_combobox"); } 59 | 60 | // Save highlight idx for redrawing later. 61 | // Note: prevents this method from being const. 62 | 63 | if (int(idx) == _highlight) { _prevhighlight = _highlight; } 64 | 65 | // Print item and scroll indicator if needed 66 | 67 | printToEol(_items[idx]->name()); 68 | if ( (_firstprint > 0) && (int(idx) == _firstprint) ) 69 | waddch(_win, ACS_UARROW); 70 | else if ( (lastrow < int(_items.size())-1) && (int(idx) == lastrow) ) 71 | waddch(_win, ACS_DARROW); 72 | else { waddch(_win, ' '); } 73 | 74 | // Turn off highlight color 75 | 76 | if (colors.turnOff(_win) != 0) 77 | { 78 | if ( (int(idx) == _highlight) && _activated ) { wattroff(_win, A_REVERSE); } 79 | } 80 | } 81 | 82 | /******************************************************************************* 83 | 84 | Constructors 85 | 86 | *******************************************************************************/ 87 | ComboBoxList::ComboBoxList() 88 | { 89 | _reserved_rows = 0; 90 | _header_rows = 0; 91 | clearButtons(); 92 | setModal(false); 93 | } 94 | 95 | ComboBoxList::ComboBoxList(WINDOW *win) 96 | { 97 | _win = win; 98 | _reserved_rows = 0; 99 | _header_rows = 0; 100 | clearButtons(); 101 | setModal(false); 102 | } 103 | 104 | /******************************************************************************* 105 | 106 | Edit list 107 | 108 | *******************************************************************************/ 109 | void ComboBoxList::clearList() 110 | { 111 | unsigned int i, nitems; 112 | 113 | nitems = _items.size(); 114 | for ( i = 0; i < nitems; i++ ) { delete _items[i]; } 115 | 116 | _items.resize(0); 117 | _highlight = 0; 118 | _firstprint = 0; 119 | _prevhighlight = 0; 120 | _redraw_type = "all"; 121 | } 122 | 123 | /******************************************************************************* 124 | 125 | Get attributes 126 | 127 | *******************************************************************************/ 128 | void ComboBoxList::preferredSize(int & height, int & width) const 129 | { 130 | int namelen, reserved_cols; 131 | unsigned int i, nitems; 132 | 133 | // Minimum usable height 134 | 135 | nitems = _items.size(); 136 | height = _reserved_rows + nitems; 137 | 138 | // Minimum usable width 139 | 140 | width = 0; 141 | reserved_cols = 4; // For indicator on right 142 | for ( i = 0; i < nitems; i++ ) 143 | { 144 | namelen = _items[i]->name().size(); 145 | if (namelen > width) { width = namelen; } 146 | } 147 | width += reserved_cols; 148 | } 149 | 150 | /******************************************************************************* 151 | 152 | Draws box (frame, items, etc.) as needed 153 | 154 | *******************************************************************************/ 155 | void ComboBoxList::draw(bool force) 156 | { 157 | if (force) { _redraw_type = "all"; } 158 | 159 | // Draw list elements 160 | 161 | if (_redraw_type == "all") 162 | { 163 | clearWindow(); 164 | colors.setBackground(_win, "fg_combobox", "bg_combobox"); 165 | } 166 | if (_redraw_type != "none") { redrawFrame(); } 167 | if ( (_redraw_type == "all") || (_redraw_type == "items") ) { 168 | redrawAllItems(); } 169 | else if (_redraw_type == "changed") { redrawChangedItems(); } 170 | wrefresh(_win); 171 | } 172 | 173 | /******************************************************************************* 174 | 175 | Handles mouse event 176 | 177 | *******************************************************************************/ 178 | std::string ComboBoxList::handleMouseEvent(MouseEvent * mevent) 179 | { 180 | std::string retval; 181 | 182 | // Use method from ListBox, but return keyEnter when item is selected 183 | 184 | retval = ListBox::handleMouseEvent(mevent); 185 | if ( (retval == signals::tag) || (retval == signals::highlight) ) 186 | { 187 | // Redraw and pause for .1 seconds to make button selection visible 188 | 189 | _redraw_type = "all"; 190 | draw(); 191 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); 192 | retval = signals::keyEnter; 193 | } 194 | 195 | return retval; 196 | } 197 | -------------------------------------------------------------------------------- /src/DefaultOptionsBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Color.h" 4 | #include "ToggleInput.h" 5 | #include "DefaultOptionsBox.h" 6 | 7 | /******************************************************************************* 8 | 9 | Constructor 10 | 11 | *******************************************************************************/ 12 | DefaultOptionsBox::DefaultOptionsBox() 13 | { 14 | _firstprint = _header_rows; 15 | setPackageManager("sbopkg"); 16 | 17 | addItem(&_repoitem); 18 | _repoitem.setName("repo_dir"); 19 | _repoitem.setEnabled(true); 20 | _repoitem.setWidth(30); 21 | _repoitem.setPosition(3,1); 22 | 23 | addItem(&_syncitem); 24 | _syncitem.setName("sync_cmd"); 25 | _syncitem.setEnabled(true); 26 | _syncitem.setWidth(30); 27 | _syncitem.setPosition(4,1); 28 | 29 | addItem(&_installitem); 30 | _installitem.setName("install_cmd"); 31 | _installitem.setEnabled(true); 32 | _installitem.setWidth(30); 33 | _installitem.setPosition(5,1); 34 | 35 | addItem(&_upgradeitem); 36 | _upgradeitem.setName("upgrade_cmd"); 37 | _upgradeitem.setEnabled(true); 38 | _upgradeitem.setWidth(30); 39 | _upgradeitem.setPosition(6,1); 40 | 41 | addItem(&_reinstallitem); 42 | _reinstallitem.setName("reinstall_cmd"); 43 | _reinstallitem.setEnabled(true); 44 | _reinstallitem.setWidth(30); 45 | _reinstallitem.setPosition(7,1); 46 | } 47 | 48 | /******************************************************************************* 49 | 50 | Set attributes 51 | 52 | *******************************************************************************/ 53 | int DefaultOptionsBox::setPackageManager(const std::string & pkg_mgr) 54 | { 55 | if (pkg_mgr == "sbopkg") 56 | { 57 | _repo_dir = "/var/lib/sbopkg/SBo/15.0"; 58 | _sync_cmd = "sbopkg -r"; 59 | _install_cmd = "sbopkg -B -i"; 60 | _upgrade_cmd = "sbopkg -B -i"; 61 | _reinstall_cmd = "sbopkg -B -i"; 62 | } 63 | else if (pkg_mgr == "sbotools") 64 | { 65 | _repo_dir = "/usr/sbo/repo"; 66 | _sync_cmd = "sbosnap update"; 67 | _install_cmd = "sboinstall -r"; 68 | _upgrade_cmd = "sboupgrade -r"; 69 | _reinstall_cmd = "sboinstall --reinstall -r"; 70 | } 71 | else if (pkg_mgr == "built-in") 72 | { 73 | _repo_dir = "/var/lib/sboui/repo"; 74 | _sync_cmd = "sboui-backend update"; 75 | _install_cmd = "sboui-backend install -f"; 76 | _upgrade_cmd = "sboui-backend install -f"; 77 | _reinstall_cmd = "sboui-backend install -f"; 78 | } 79 | else if (pkg_mgr == "custom") 80 | { 81 | _repo_dir = ""; 82 | _sync_cmd = ""; 83 | _install_cmd = ""; 84 | _upgrade_cmd = ""; 85 | _reinstall_cmd = ""; 86 | } 87 | else { return 1; } 88 | 89 | _pkg_mgr = pkg_mgr; 90 | _msg = "Apply defaults for " + _pkg_mgr + "?"; 91 | 92 | return 0; 93 | } 94 | 95 | /******************************************************************************* 96 | 97 | Get attributes 98 | 99 | *******************************************************************************/ 100 | bool DefaultOptionsBox::setRepoDir() const { return _repoitem.enabled(); } 101 | bool DefaultOptionsBox::setSyncCmd() const { return _syncitem.enabled(); } 102 | bool DefaultOptionsBox::setInstallCmd() const { return _installitem.enabled(); } 103 | bool DefaultOptionsBox::setUpgradeCmd() const { return _upgradeitem.enabled(); } 104 | bool DefaultOptionsBox::setReinstallCmd() const 105 | { 106 | return _reinstallitem.enabled(); 107 | } 108 | const std::string & DefaultOptionsBox::repoDir() const { return _repo_dir; } 109 | const std::string & DefaultOptionsBox::syncCmd() const { return _sync_cmd; } 110 | const std::string & DefaultOptionsBox::installCmd() const 111 | { 112 | return _install_cmd; 113 | } 114 | const std::string & DefaultOptionsBox::upgradeCmd() const 115 | { 116 | return _upgrade_cmd; 117 | } 118 | const std::string & DefaultOptionsBox::reinstallCmd() const 119 | { 120 | return _reinstall_cmd; 121 | } 122 | -------------------------------------------------------------------------------- /src/FilterBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ListItem.h" 4 | #include "SelectionBox.h" 5 | #include "FilterBox.h" 6 | 7 | /******************************************************************************* 8 | 9 | Constructors and destructor 10 | 11 | *******************************************************************************/ 12 | FilterBox::FilterBox() 13 | { 14 | unsigned int i; 15 | 16 | _name = "Select a filter"; 17 | 18 | addItem(new ListItem("All")); 19 | addItem(new ListItem("Installed")); 20 | addItem(new ListItem("Upgradable")); 21 | addItem(new ListItem("Tagged")); 22 | addItem(new ListItem("Blacklisted")); 23 | addItem(new ListItem("Non-dependencies")); 24 | addItem(new ListItem("Build options set")); 25 | 26 | for ( i = 0; i < 6; i++ ) { _items[i]->setHotKey(0); } 27 | _items[6]->setHotKey(3); 28 | } 29 | 30 | FilterBox::FilterBox(WINDOW *win, const std::string & name) 31 | { 32 | unsigned int i; 33 | 34 | _win = win; 35 | _name = name; 36 | 37 | addItem(new ListItem("All")); 38 | addItem(new ListItem("Installed")); 39 | addItem(new ListItem("Upgradable")); 40 | addItem(new ListItem("Tagged")); 41 | addItem(new ListItem("Blacklisted")); 42 | addItem(new ListItem("Non-dependencies")); 43 | addItem(new ListItem("Build options set")); 44 | 45 | for ( i = 0; i < 6; i++ ) { _items[i]->setHotKey(0); } 46 | _items[6]->setHotKey(3); 47 | } 48 | 49 | FilterBox::~FilterBox() 50 | { 51 | unsigned int i, nitems; 52 | 53 | nitems = _items.size(); 54 | for ( i = 0; i < nitems; i++ ) { delete _items[i]; } 55 | _items.resize(0); 56 | } 57 | -------------------------------------------------------------------------------- /src/HelpItem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ListItem.h" 3 | #include "HelpItem.h" 4 | 5 | /******************************************************************************* 6 | 7 | Constructors 8 | 9 | *******************************************************************************/ 10 | HelpItem::HelpItem() 11 | { 12 | _name = ""; 13 | 14 | // Add props in reverse alphabetical order (should be fastest) 15 | 16 | addBoolProp("space", false); 17 | addProp("shortcut", ""); 18 | addBoolProp("header", false); 19 | } 20 | 21 | HelpItem::HelpItem(const std::string & name, const std::string & shortcut, 22 | bool header, bool space) 23 | { 24 | _name = name; 25 | 26 | // Add props in reverse alphabetical order (should be fastest) 27 | 28 | addBoolProp("space", space); 29 | addProp("shortcut", shortcut); 30 | addBoolProp("header", header); 31 | } 32 | -------------------------------------------------------------------------------- /src/HelpWindow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // floor 4 | #include // min 5 | #include "Color.h" 6 | #include "settings.h" 7 | #include "signals.h" 8 | #include "HelpItem.h" 9 | #include "HelpWindow.h" 10 | 11 | /******************************************************************************* 12 | 13 | Draws window border, title, and header 14 | 15 | *******************************************************************************/ 16 | void HelpWindow::redrawFrame() 17 | { 18 | int rows, cols, namelen, i, nspaces, vlineloc; 19 | double mid, left, right; 20 | 21 | getmaxyx(_win, rows, cols); 22 | 23 | // Title 24 | 25 | namelen = _name.size(); 26 | mid = double(cols)/2.0; 27 | left = std::floor(mid - double(namelen)/2.0); 28 | right = left + namelen; 29 | wmove(_win, 0, left); 30 | wattron(_win, A_BOLD); 31 | wprintw(_win, "%s", _name.c_str()); 32 | wattroff(_win, A_BOLD); 33 | 34 | // Corners 35 | 36 | wmove(_win, 0, 0); 37 | waddch(_win, ACS_ULCORNER); 38 | wmove(_win, rows-1, 0); 39 | waddch(_win, ACS_LLCORNER); 40 | wmove(_win, rows-1, cols-1); 41 | waddch(_win, ACS_LRCORNER); 42 | wmove(_win, 0, cols-1); 43 | waddch(_win, ACS_URCORNER); 44 | 45 | // Top border 46 | 47 | wmove(_win, 0, 1); 48 | for ( i = 1; int(i) < left-1; i++ ) { waddch(_win, ACS_HLINE); } 49 | wmove(_win, 0, right+1); 50 | for ( i = right+1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 51 | 52 | // Left border 53 | 54 | for ( i = 1; i < rows-1; i++ ) { mvwaddch(_win, i, 0, ACS_VLINE); } 55 | 56 | // Right border for header 57 | 58 | mvwaddch(_win, 1, cols-1, ACS_VLINE); 59 | 60 | // Bottom border 61 | 62 | wmove(_win, rows-1, 1); 63 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 64 | 65 | // Draw header 66 | 67 | wmove(_win, 1, 1); 68 | colors.turnOn(_win, "header", "bg_normal"); 69 | wprintw(_win, "%s", _leftlabel.c_str()); 70 | colors.turnOff(_win); 71 | 72 | vlineloc = cols-2 - _shortcutwidth; 73 | nspaces = vlineloc - _leftlabel.size(); 74 | for ( i = 0; i < nspaces; i++ ) { waddch(_win, ' '); } 75 | 76 | colors.turnOn(_win, "header", "bg_normal"); 77 | printToEol(" " + _rightlabel); 78 | wmove(_win, 2, 1); 79 | colors.turnOff(_win); 80 | 81 | // Draw horizontal and then vertical line 82 | 83 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 84 | for ( i = 3; i < rows-3; i++ ) { mvwaddch(_win, i, vlineloc, ACS_VLINE); } 85 | 86 | // Draw connections between horizontal and vertical lines 87 | 88 | mvwaddch(_win, 2, 0, ACS_LTEE); 89 | mvwaddch(_win, 2, cols-1, ACS_RTEE); 90 | mvwaddch(_win, 2, vlineloc, ACS_TTEE); 91 | mvwaddch(_win, rows-3, vlineloc, ACS_BTEE); 92 | 93 | // Button area 94 | 95 | if (_buttons.size() > 0) 96 | { 97 | wmove(_win, rows-3, 1); 98 | for ( i = 1; i < vlineloc; i++ ) { waddch(_win, ACS_HLINE); } 99 | for ( i = vlineloc+1; i < cols-1; i++ ) 100 | { 101 | mvwaddch(_win, rows-3, i, ACS_HLINE); 102 | } 103 | mvwaddch(_win, rows-3, 0, ACS_LTEE); 104 | mvwaddch(_win, rows-3, cols-1, ACS_RTEE); 105 | mvwaddch(_win, rows-2, cols-1, ACS_VLINE); 106 | redrawButtons(); 107 | } 108 | } 109 | 110 | /******************************************************************************* 111 | 112 | Redraws a single item. Note: doesn't check if the item is actually on the 113 | screen or not. 114 | 115 | *******************************************************************************/ 116 | void HelpWindow::redrawSingleItem(unsigned int idx) 117 | { 118 | int ndots, vlineloc, printlen, rows, cols, i; 119 | 120 | getmaxyx(_win, rows, cols); 121 | 122 | // Go to item location 123 | 124 | wmove(_win, idx-_firstprint+_header_rows, 1); 125 | 126 | // Turn on bold for header 127 | 128 | if (_items[idx]->getBoolProp("header")) 129 | wattron(_win, A_BOLD); 130 | 131 | // Print name (if not a 'space' item) 132 | 133 | vlineloc = cols-2 - _shortcutwidth - 1; 134 | printlen = std::min(int(_items[idx]->name().size()), vlineloc); 135 | 136 | if (_items[idx]->getBoolProp("space")) 137 | ndots = vlineloc; 138 | else 139 | { 140 | ndots = vlineloc - _items[idx]->name().size(); 141 | wprintw(_win, "%s", _items[idx]->name().substr(0,printlen).c_str()); 142 | } 143 | 144 | // Turn off bold for header 145 | 146 | if (_items[idx]->getBoolProp("header")) 147 | wattroff(_win, A_BOLD); 148 | 149 | // Print dots and shortcut 150 | 151 | if ( (! _items[idx]->getBoolProp("header")) && 152 | (! _items[idx]->getBoolProp("space")) ) 153 | { 154 | for ( i = 0; int(i) < ndots; i++ ) { waddch(_win, '.'); } 155 | wmove(_win, idx-_firstprint+3, vlineloc+3); 156 | printToEol(_items[idx]->getProp("shortcut")); 157 | } 158 | else 159 | for ( i = 0; int(i) < ndots; i++ ) { waddch(_win, ' '); } 160 | 161 | // Divider 162 | 163 | wmove(_win, idx-_firstprint+3, vlineloc+1); 164 | waddch(_win, ACS_VLINE); 165 | } 166 | 167 | /******************************************************************************* 168 | 169 | Determines width needed for right column 170 | 171 | *******************************************************************************/ 172 | void HelpWindow::shortcutWidth() 173 | { 174 | unsigned int i, nitems; 175 | 176 | nitems = numItems(); 177 | _shortcutwidth = _rightlabel.size(); 178 | for ( i = 0; i < nitems; i++ ) 179 | { 180 | if (_items[i]->getProp("shortcut").size() > _shortcutwidth) 181 | _shortcutwidth = _items[i]->getProp("shortcut").size(); 182 | } 183 | if (std::string("Shortcut").size() > _shortcutwidth) 184 | _shortcutwidth = std::string("Shortcut").size(); 185 | _shortcutwidth += 2; // Margins 186 | } 187 | 188 | /******************************************************************************* 189 | 190 | Constructors and destructor 191 | 192 | *******************************************************************************/ 193 | HelpWindow::HelpWindow() 194 | { 195 | _name = "Keyboard shortcuts"; 196 | _reserved_rows = 4; 197 | _header_rows = 3; 198 | _shortcutwidth = 0; 199 | setLabels("Action", "Shortcut"); 200 | addButton(" Back to main ", signals::quit); 201 | } 202 | 203 | HelpWindow::HelpWindow(WINDOW *win, const std::string & name) 204 | { 205 | _win = win; 206 | _name = name; 207 | _reserved_rows = 4; 208 | _header_rows = 3; 209 | _shortcutwidth = 0; 210 | setLabels("Action", "Shortcut"); 211 | addButton(" Back to main ", signals::quit); 212 | } 213 | 214 | HelpWindow::~HelpWindow() 215 | { 216 | unsigned int i, nitems; 217 | 218 | nitems = numItems(); 219 | for ( i = 0; i < nitems; i++ ) { delete _items[i]; } 220 | _items.resize(0); 221 | } 222 | 223 | /******************************************************************************* 224 | 225 | Set labels 226 | 227 | *******************************************************************************/ 228 | void HelpWindow::setLabels(const std::string & leftlabel, 229 | const std::string & rightlabel) 230 | { 231 | _leftlabel = leftlabel; 232 | _rightlabel = rightlabel; 233 | } 234 | 235 | /******************************************************************************* 236 | 237 | Sizes and places window 238 | 239 | *******************************************************************************/ 240 | void HelpWindow::placeWindow() const 241 | { 242 | int rows, cols; 243 | 244 | getmaxyx(stdscr, rows, cols); 245 | mvwin(_win, 0, 0); 246 | wresize(_win, rows, cols); 247 | } 248 | -------------------------------------------------------------------------------- /src/IgnoreVersions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "string_util.h" 5 | #include "IgnoreVersions.h" 6 | 7 | /******************************************************************************* 8 | 9 | Constructor 10 | 11 | *******************************************************************************/ 12 | IgnoreVersions::IgnoreVersions() 13 | { 14 | _names.resize(0); 15 | _versions.resize(0); 16 | } 17 | 18 | /******************************************************************************* 19 | 20 | Reads and stores SlackBuild:version pairs from file 21 | 22 | *******************************************************************************/ 23 | void IgnoreVersions::read(const std::string & filename) 24 | { 25 | std::ifstream file; 26 | std::string line; 27 | std::vector splitline; 28 | 29 | file.open(filename.c_str()); 30 | if (not file.is_open()) { return; } 31 | 32 | while (! file.eof()) 33 | { 34 | std::getline(file, line); 35 | line = remove_leading_whitespace(line); 36 | if (line[0] == '#') { continue; } 37 | line = remove_comment(line, '#'); 38 | line = trim(line); 39 | splitline = split(line, ':'); 40 | if (splitline.size() < 2) { continue; } 41 | _names.push_back(trim(splitline[0])); 42 | _versions.push_back(trim(splitline[1])); 43 | } 44 | file.close(); 45 | 46 | return; 47 | } 48 | 49 | /******************************************************************************* 50 | 51 | Checks for name:version match in list 52 | 53 | *******************************************************************************/ 54 | bool IgnoreVersions::ignoreVersion(const std::string & name, 55 | const std::string & version) const 56 | { 57 | bool ignore = false; 58 | unsigned int i, nnames; 59 | 60 | nnames = _names.size(); 61 | for ( i = 0; i < nnames; i++ ) 62 | { 63 | if ( (_names[i] == name) && (_versions[i] == version) ) 64 | { 65 | ignore = true; 66 | break; 67 | } 68 | } 69 | 70 | return ignore; 71 | } 72 | -------------------------------------------------------------------------------- /src/InputItem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "InputItem.h" 4 | #include "MouseEvent.h" 5 | 6 | /******************************************************************************* 7 | 8 | Prints to end of line, padding with spaces 9 | 10 | *******************************************************************************/ 11 | void InputItem::printToEol(const std::string & msg) const 12 | { 13 | int i, y, x, rows, cols, rightspace, nspaces, msglen; 14 | 15 | getmaxyx(_win, rows, cols); 16 | getyx(_win, y, x); 17 | 18 | /* Math: Cursor position: x 19 | Number of spaces that can be printed to right = _width-(x-_posx) */ 20 | 21 | msglen = msg.size(); 22 | rightspace = _width - (x - _posx); 23 | if (msglen > rightspace) 24 | wprintw(_win, "%s", msg.substr(0, rightspace).c_str()); 25 | else 26 | { 27 | nspaces = std::max(rightspace-msglen, 0); 28 | wprintw(_win, "%s", msg.c_str()); 29 | for ( i = 0; i < nspaces; i++ ) { wprintw(_win, " "); } 30 | } 31 | } 32 | 33 | /******************************************************************************* 34 | 35 | Prints a given number of spaces 36 | 37 | *******************************************************************************/ 38 | void InputItem::printSpaces(int nspaces) const 39 | { 40 | int i; 41 | 42 | for ( i = 0; i < nspaces; i++ ) { waddch(_win, ' '); } 43 | } 44 | 45 | /******************************************************************************* 46 | 47 | Constructor and destructor. For use of virtual destructor, see: 48 | http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors#461224 49 | 50 | *******************************************************************************/ 51 | InputItem::InputItem() 52 | { 53 | _win = NULL; 54 | _posx = 0; 55 | _posy = 0; 56 | _width = 0; 57 | _name = ""; 58 | _redraw_type = "none"; 59 | _item_type = "none"; 60 | _selectable = true; 61 | _auto_position = true; 62 | } 63 | 64 | InputItem::~InputItem() {} 65 | 66 | /******************************************************************************* 67 | 68 | Set attributes 69 | 70 | *******************************************************************************/ 71 | void InputItem::setWindow(WINDOW *win) { _win = win; } 72 | void InputItem::setName(const std::string & name) { _name = name; } 73 | void InputItem::setWidth(int width) { _width = width; } 74 | void InputItem::setPosition(int y, int x) 75 | { 76 | _posy = y; 77 | _posx = x; 78 | } 79 | 80 | void InputItem::setAutoPosition(bool auto_position) 81 | { 82 | _auto_position = auto_position; 83 | } 84 | 85 | /******************************************************************************* 86 | 87 | Get attributes 88 | 89 | *******************************************************************************/ 90 | const std::string & InputItem::name() const { return _name; } 91 | const std::string & InputItem::itemType() const { return _item_type; } 92 | int InputItem::posx() const { return _posx; } 93 | int InputItem::posy() const { return _posy; } 94 | int InputItem::width() const { return _width; } 95 | bool InputItem::selectable() const { return _selectable; } 96 | bool InputItem::autoPosition() const { return _auto_position; } 97 | 98 | /******************************************************************************* 99 | 100 | User interaction. The base class version just returns an empty string, so that 101 | non-selectable InputItems (e.g., labels) don't have to implement it. Selectable 102 | classes should reimplement this. 103 | 104 | *******************************************************************************/ 105 | std::string InputItem::exec(int y_offset, MouseEvent * mevent) { return ""; } 106 | 107 | /******************************************************************************* 108 | 109 | Accessing properties of different types. Derived classes should reimplement 110 | these as needed. 111 | 112 | *******************************************************************************/ 113 | std::string InputItem::getStringProp() const { return ""; } 114 | bool InputItem::getBoolProp() const { return false; } 115 | int InputItem::getIntProp() const { return 0; } 116 | double InputItem::getDoubleProp() const { return 0.; } 117 | -------------------------------------------------------------------------------- /src/KeyHelpWindow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "HelpItem.h" 3 | #include "KeyHelpWindow.h" 4 | 5 | /******************************************************************************* 6 | 7 | Constructor 8 | 9 | *******************************************************************************/ 10 | KeyHelpWindow::KeyHelpWindow() { createList(); } 11 | 12 | /******************************************************************************* 13 | 14 | Constructs list to display 15 | 16 | *******************************************************************************/ 17 | void KeyHelpWindow::createList() 18 | { 19 | addItem(new HelpItem("Main window", "", true, false)); 20 | addItem(new HelpItem("Activate left/top list", "Left arrow")); 21 | addItem(new HelpItem("Activate menubar", "F9")); 22 | addItem(new HelpItem("Activate right/bottom list", "Right arrow")); 23 | addItem(new HelpItem("Filter", "f")); 24 | addItem(new HelpItem("Show keyboard shortcuts", "?")); 25 | addItem(new HelpItem("Options", "o")); 26 | addItem(new HelpItem("Quick search in active list", "Ctrl-s")); 27 | addItem(new HelpItem("Quit", "q")); 28 | addItem(new HelpItem("Search", "/")); 29 | addItem(new HelpItem("Switch active list", "Tab")); 30 | addItem(new HelpItem("Sync / Update repository", "s")); 31 | addItem(new HelpItem("Toggle vertical/horizontal layout", "l")); 32 | addItem(new HelpItem("Upgrade all", "Ctrl-u")); 33 | addItem(new HelpItem("View command line output", "c")); 34 | 35 | addItem(new HelpItem("space1", "", false, true)); 36 | 37 | addItem(new HelpItem("Lists & input boxes", "", true, false)); 38 | addItem(new HelpItem("Go back / Cancel", "Esc")); 39 | addItem(new HelpItem("Jump to beginning", "Home")); 40 | addItem(new HelpItem("Jump to end", "End")); 41 | addItem(new HelpItem("Next input field", "Tab")); 42 | addItem(new HelpItem("Previous input field", "Shift+Tab")); 43 | addItem(new HelpItem("Pull down combo box", "Space")); 44 | addItem(new HelpItem("Scroll down", "Down arrow")); 45 | addItem(new HelpItem("Scroll up", "Up arrow")); 46 | addItem(new HelpItem("Scroll down a page", "Page down")); 47 | addItem(new HelpItem("Scroll up a page", "Page up")); 48 | addItem(new HelpItem("Select highlighted / Accept selection", "Enter")); 49 | addItem(new HelpItem("Toggle check box", "Space")); 50 | 51 | addItem(new HelpItem("space2", "", false, true)); 52 | 53 | addItem(new HelpItem("Tagging", "", true, false)); 54 | addItem(new HelpItem("Install tagged", "i")); 55 | addItem(new HelpItem("Reinstall tagged", "e")); 56 | addItem(new HelpItem("Remove tagged", "r")); 57 | addItem(new HelpItem("Tag selected", "t")); 58 | addItem(new HelpItem("Upgrade tagged", "u")); 59 | 60 | // Determine width needed to display shortcut 61 | 62 | shortcutWidth(); 63 | } 64 | -------------------------------------------------------------------------------- /src/Label.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Color.h" 4 | #include "settings.h" 5 | #include "signals.h" 6 | #include "InputItem.h" 7 | #include "Label.h" 8 | #include "MouseEvent.h" 9 | 10 | /******************************************************************************* 11 | 12 | Constructors and destructor 13 | 14 | *******************************************************************************/ 15 | Label::Label() 16 | { 17 | _redraw_type = "label"; 18 | _item_type = "Label"; 19 | _color_idx = -1; 20 | _selectable = false; 21 | _hline = false; 22 | _bold = false; 23 | } 24 | 25 | Label::Label(bool selectable) 26 | { 27 | _redraw_type = "label"; 28 | _item_type = "Label"; 29 | _color_idx = -1; 30 | _selectable = selectable; 31 | _hline = false; 32 | _bold = false; 33 | } 34 | 35 | Label::Label(bool selectable, bool hline) 36 | { 37 | _redraw_type = "label"; 38 | _item_type = "Label"; 39 | _color_idx = -1; 40 | _selectable = selectable; 41 | _hline = hline; 42 | _bold = false; 43 | } 44 | 45 | /******************************************************************************* 46 | 47 | Set attributes 48 | 49 | *******************************************************************************/ 50 | void Label::setColor(int color_idx) { _color_idx = color_idx; } 51 | void Label::setSelectable(bool selectable) { _selectable = selectable; } 52 | void Label::setHLine(bool hline) { _hline = hline; } 53 | void Label::setBold(bool bold) { _bold = bold; } 54 | 55 | /******************************************************************************* 56 | 57 | Handles mouse event 58 | 59 | *******************************************************************************/ 60 | std::string Label::handleMouseEvent(MouseEvent * mevent, int y_offset) 61 | { 62 | int begy, begx, ycurs, xcurs; 63 | 64 | getbegyx(_win, begy, begx); 65 | ycurs = mevent->y() - begy; 66 | xcurs = mevent->x() - begx; 67 | 68 | if ( (mevent->button() == 1) || (mevent->button() == 3) ) 69 | { 70 | // Check for clicking in the Label 71 | 72 | if ( (xcurs >= _posx) && (xcurs < _posx+_width) && 73 | (ycurs == _posy-y_offset) ) 74 | { 75 | if (_selectable) 76 | return signals::keySpace; 77 | } 78 | } 79 | 80 | return signals::mouseEvent; // Defer to InputBox to handle event 81 | } 82 | 83 | /******************************************************************************* 84 | 85 | Draws label 86 | 87 | *******************************************************************************/ 88 | void Label::draw(int y_offset, bool force, bool highlight) 89 | { 90 | int i; 91 | 92 | wmove(_win, _posy-y_offset, _posx); 93 | 94 | if (_redraw_type != "label") { return; } 95 | 96 | if (highlight && _selectable) 97 | { 98 | if (colors.turnOn(_win, "fg_highlight_active", "bg_highlight_active") != 0) 99 | wattron(_win, A_REVERSE); 100 | } 101 | else { colors.turnOn(_win, _color_idx); } 102 | 103 | if ( (_bold) && (! colors.pairIsBold(_color_idx)) ) 104 | wattron(_win, A_BOLD); 105 | 106 | if (_hline) 107 | for ( i = 0; i < _width; i++ ) { waddch(_win, ACS_HLINE); } 108 | else 109 | printToEol(_name); 110 | 111 | if (colors.turnOff(_win) != 0) 112 | { 113 | if (highlight && _selectable) { wattroff(_win, A_REVERSE); } 114 | } 115 | 116 | if ( (_bold) && (! colors.pairIsBold(_color_idx)) ) 117 | wattroff(_win, A_BOLD); 118 | 119 | wrefresh(_win); 120 | } 121 | 122 | /******************************************************************************* 123 | 124 | User interaction: returns key stroke 125 | 126 | *******************************************************************************/ 127 | std::string Label::exec(int y_offset, MouseEvent * mevent) 128 | { 129 | int ch; 130 | std::string retval; 131 | MEVENT event; 132 | 133 | const int MY_ESC = 27; 134 | const int MY_TAB = 9; 135 | const int MY_SHIFT_TAB = 353; 136 | 137 | // Redraw 138 | 139 | draw(y_offset, false, true); 140 | 141 | // Get user input 142 | 143 | switch (ch = getch()) { 144 | 145 | // Enter key: return Enter signal 146 | 147 | case '\n': 148 | case '\r': 149 | case KEY_ENTER: 150 | retval = signals::keyEnter; 151 | break; 152 | 153 | // Space: activate item 154 | 155 | case ' ': 156 | retval = signals::keySpace; 157 | break; 158 | 159 | // Navigation keys 160 | 161 | case KEY_HOME: 162 | retval = signals::highlightFirst; 163 | break; 164 | case KEY_END: 165 | retval = signals::highlightLast; 166 | break; 167 | case KEY_PPAGE: 168 | retval = signals::highlightPrevPage; 169 | break; 170 | case KEY_NPAGE: 171 | retval = signals::highlightNextPage; 172 | break; 173 | case KEY_UP: 174 | case MY_SHIFT_TAB: 175 | retval = signals::highlightPrev; 176 | break; 177 | case KEY_DOWN: 178 | case MY_TAB: 179 | retval = signals::highlightNext; 180 | break; 181 | case KEY_RIGHT: 182 | retval = signals::keyRight; 183 | break; 184 | case KEY_LEFT: 185 | retval = signals::keyLeft; 186 | break; 187 | 188 | // Resize signal 189 | 190 | case KEY_RESIZE: 191 | retval = signals::resize; 192 | break; 193 | 194 | // Quit key 195 | 196 | case MY_ESC: 197 | retval = signals::quit; 198 | break; 199 | 200 | // Mouse 201 | 202 | case KEY_MOUSE: 203 | if ( (getmouse(&event) == OK) && mevent ) 204 | { 205 | mevent->recordClick(event); 206 | retval = handleMouseEvent(mevent, y_offset); 207 | } 208 | break; 209 | 210 | default: 211 | retval = char(ch); 212 | break; 213 | } 214 | 215 | return retval; 216 | } 217 | -------------------------------------------------------------------------------- /src/ListItem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // floor 3 | #include "ListItem.h" 4 | 5 | /******************************************************************************* 6 | 7 | Conversions 8 | 9 | *******************************************************************************/ 10 | std::string ListItem::bool2String(bool value) const 11 | { 12 | if (value) { return "true"; } 13 | else { return "false"; } 14 | } 15 | 16 | bool ListItem::string2Bool(const std::string & value) const 17 | { 18 | if (value == "true") { return true; } 19 | else { return false; } 20 | } 21 | 22 | /******************************************************************************* 23 | 24 | Finds prop by name using bisection search 25 | 26 | *******************************************************************************/ 27 | int ListItem::findPropByName(const std::string & propname, int & propidx, 28 | int & lbound, int & rbound) const 29 | { 30 | std::string left, right, mid; 31 | int midbound; 32 | 33 | left = _props[lbound].propname; 34 | right = _props[rbound].propname; 35 | 36 | // Check if outside the bounds 37 | 38 | if ( (propname < left) || (propname > right) ) 39 | return 1; 40 | 41 | // Check bounds for match 42 | 43 | if (propname == left) 44 | { 45 | propidx = lbound; 46 | return 0; 47 | } 48 | else if (propname == right) 49 | { 50 | propidx = rbound; 51 | return 0; 52 | } 53 | 54 | // Cut the list in half and try again 55 | 56 | midbound = std::floor(double(lbound+rbound)/2.); 57 | mid = _props[midbound].propname; 58 | 59 | if (propname <= mid) 60 | rbound = midbound; 61 | else 62 | lbound = midbound; 63 | 64 | return findPropByName(propname, propidx, lbound, rbound); 65 | } 66 | 67 | /******************************************************************************* 68 | 69 | Searches for a property in the list and returns its index. If it does not 70 | exist, returns -1. 71 | 72 | *******************************************************************************/ 73 | int ListItem::propIdxByName(const std::string & propname) const 74 | { 75 | int nprops, propidx, lbound, rbound, check; 76 | 77 | nprops = _props.size(); 78 | if (nprops == 0) 79 | return -1; 80 | 81 | propidx = -1; 82 | lbound = 0; 83 | rbound = nprops-1; 84 | check = findPropByName(propname, propidx, lbound, rbound); 85 | 86 | if (check == 0) 87 | return propidx; 88 | else 89 | return -1; 90 | } 91 | 92 | /******************************************************************************* 93 | 94 | Sets property by index. Warning: does not check for list bounds. 95 | 96 | *******************************************************************************/ 97 | void ListItem::setPropByIdx(unsigned int idx, const std::string & value) 98 | { 99 | _props[idx].value = value; 100 | } 101 | 102 | /******************************************************************************* 103 | 104 | Constructors 105 | 106 | *******************************************************************************/ 107 | ListItem::ListItem() 108 | { 109 | _name = ""; 110 | _props.resize(0); 111 | _hotkey = -1; 112 | } 113 | 114 | ListItem::ListItem(const std::string & name) 115 | { 116 | _name = name; 117 | _props.resize(0); 118 | _hotkey = -1; 119 | } 120 | 121 | /******************************************************************************* 122 | 123 | Set properties. Methods with return value return 0 for success or 1 for failure. 124 | 125 | *******************************************************************************/ 126 | void ListItem::setName(const std::string & name) { _name = name; } 127 | void ListItem::setHotKey(int hotkey) { _hotkey = hotkey; } 128 | void ListItem::addProp(const std::string & propname, const std::string & value) 129 | { 130 | int propidx; 131 | unsigned int i, nprops, propinsert; 132 | listprop prop; 133 | 134 | propidx = propIdxByName(propname); 135 | if (propidx != -1) { setPropByIdx(propidx, value); } 136 | else 137 | { 138 | prop.propname = propname; 139 | prop.value = value; 140 | nprops = _props.size(); 141 | 142 | // Insert in sorted order 143 | 144 | propinsert = nprops; 145 | for ( i = 0; i < nprops; i++ ) 146 | { 147 | if (propname < _props[i].propname) 148 | { 149 | propinsert = i; 150 | break; 151 | } 152 | } 153 | _props.insert(_props.begin()+propinsert, prop); 154 | } 155 | } 156 | 157 | void ListItem::addBoolProp(const std::string & propname, bool value) 158 | { 159 | int propidx; 160 | unsigned int i, nprops, propinsert; 161 | listprop prop; 162 | 163 | propidx = propIdxByName(propname); 164 | if (propidx != -1) { setPropByIdx(propidx, bool2String(value)); } 165 | else 166 | { 167 | prop.propname = propname; 168 | prop.value = bool2String(value); 169 | nprops = _props.size(); 170 | 171 | // Insert in sorted order 172 | 173 | propinsert = nprops; 174 | for ( i = 0; i < nprops; i++ ) 175 | { 176 | if (propname < _props[i].propname) 177 | { 178 | propinsert = i; 179 | break; 180 | } 181 | } 182 | _props.insert(_props.begin()+propinsert, prop); 183 | } 184 | } 185 | 186 | int ListItem::setProp(const std::string & propname, const std::string & value) 187 | { 188 | int propidx; 189 | listprop prop; 190 | 191 | propidx = propIdxByName(propname); 192 | if (propidx == -1) { return 1; } 193 | else 194 | { 195 | setPropByIdx(propidx, value); 196 | return 0; 197 | } 198 | } 199 | 200 | int ListItem::setBoolProp(const std::string & propname, bool value) 201 | { 202 | int propidx; 203 | listprop prop; 204 | 205 | propidx = propIdxByName(propname); 206 | if (propidx == -1) { return 1; } 207 | else 208 | { 209 | setPropByIdx(propidx, bool2String(value)); 210 | return 0; 211 | } 212 | } 213 | 214 | /******************************************************************************* 215 | 216 | Access properties. Warning: getProp methods do not check whether the prop is 217 | actually present, so attempting to access invalid props will result in a 218 | segfault. If you are not sure whether the prop is present, check first with 219 | checkProp. 220 | 221 | *******************************************************************************/ 222 | const std::string & ListItem::name() const { return _name; } 223 | int ListItem::hotKey() const { return _hotkey; } 224 | bool ListItem::checkProp(const std::string & propname) const 225 | { 226 | if ( (propname == "name") || (propIdxByName(propname) != -1) ) 227 | return true; 228 | else { return false; } 229 | } 230 | 231 | const std::string & ListItem::getProp(const std::string & propname) const 232 | { 233 | int propidx; 234 | 235 | if (propname == "name") { return _name; } 236 | else 237 | { 238 | propidx = propIdxByName(propname); 239 | return _props[propidx].value; 240 | } 241 | } 242 | 243 | bool ListItem::getBoolProp(const std::string & propname) const 244 | { 245 | int propidx; 246 | 247 | propidx = propIdxByName(propname); 248 | return string2Bool(_props[propidx].value); 249 | } 250 | -------------------------------------------------------------------------------- /src/MenubarList.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "settings.h" 4 | #include "Color.h" 5 | #include "ListItem.h" 6 | #include "MenubarList.h" 7 | #include "MouseEvent.h" 8 | 9 | /******************************************************************************* 10 | 11 | Draw outer border around box 12 | 13 | *******************************************************************************/ 14 | void MenubarList::redrawFrame() 15 | { 16 | int rows, cols, i; 17 | 18 | getmaxyx(_win, rows, cols); 19 | 20 | // Outside border 21 | 22 | wmove(_win, 0, 1); 23 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 24 | wmove(_win, rows-1, 1); 25 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 26 | 27 | for ( i = 1; i < rows-1; i++ ) { mvwaddch(_win, i, 0, ACS_VLINE); } 28 | for ( i = 1; i < rows-1; i++ ) { mvwaddch(_win, i, cols-1, ACS_VLINE); } 29 | 30 | // Corners 31 | 32 | mvwaddch(_win, 0, 0, ACS_ULCORNER); 33 | mvwaddch(_win, 0, cols-1, ACS_URCORNER); 34 | mvwaddch(_win, rows-1, 0, ACS_LLCORNER); 35 | mvwaddch(_win, rows-1, cols-1, ACS_LRCORNER); 36 | } 37 | 38 | /******************************************************************************* 39 | 40 | Redraws a single item. Note: doesn't check if the item is actually on the 41 | screen or not. 42 | 43 | *******************************************************************************/ 44 | void MenubarList::redrawSingleItem(unsigned int idx) 45 | { 46 | std::string fg, bg; 47 | int rows, cols, rowsavail, lastrow, nspaces, i, hidx, len; 48 | int color_pair1, color_pair2; 49 | 50 | getmaxyx(_win, rows, cols); 51 | rowsavail = rows-_reserved_rows; 52 | lastrow = _firstprint+rowsavail-1; 53 | 54 | // Go to item location, optionally highlight, and print item 55 | 56 | wmove(_win, idx-_firstprint+_header_rows, 1); 57 | 58 | // Turn on highlight color 59 | 60 | if (int(idx) == _highlight) 61 | { 62 | if (_activated) 63 | { 64 | fg = "fg_highlight_active"; 65 | bg = "bg_highlight_active"; 66 | } 67 | else 68 | { 69 | fg = "fg_highlight_inactive"; 70 | bg = "bg_highlight_inactive"; 71 | } 72 | color_pair1 = colors.getPair(fg, bg); 73 | color_pair2 = colors.getPair("hotkey", bg); 74 | if (colors.turnOn(_win, color_pair1) != 0) 75 | { 76 | if (_activated) { wattron(_win, A_REVERSE); } 77 | } 78 | } 79 | else 80 | { 81 | color_pair1 = colors.getPair("fg_combobox", "bg_combobox"); 82 | color_pair2 = colors.getPair("hotkey", "bg_combobox"); 83 | } 84 | 85 | // Save highlight idx for redrawing later. 86 | // Note: prevents this method from being const. 87 | 88 | if (int(idx) == _highlight) { _prevhighlight = _highlight; } 89 | 90 | // Print item and turn off highlight color 91 | 92 | nspaces = cols - 2 - 2*_outerpad - _items[idx]->name().size() 93 | - _items[idx]->getProp("shortcut").size(); 94 | len = _items[idx]->name().size(); 95 | hidx = _items[idx]->hotKey(); 96 | for ( i = 0; i < int(_outerpad); i++ ) { waddch(_win, ' '); } 97 | for ( i = 0; i < len; i++ ) 98 | { 99 | if ( i == hidx ) 100 | { 101 | colors.turnOff(_win); 102 | if (colors.turnOn(_win, color_pair2) != 0) { wattron(_win, A_BOLD); } 103 | wprintw(_win, "%s", _items[idx]->name().substr(i,1).c_str()); 104 | if (colors.turnOff(_win) != 0) { wattroff(_win, A_BOLD); } 105 | colors.turnOn(_win, color_pair1); 106 | } 107 | else { wprintw(_win, "%s", _items[idx]->name().substr(i,1).c_str()); } 108 | } 109 | for ( i = 0; i < nspaces; i++ ) { waddch(_win, ' '); } 110 | printToEol(_items[idx]->getProp("shortcut")); 111 | if (colors.turnOff(_win) != 0) 112 | { 113 | if ( (int(idx) == _highlight) && _activated ) { wattroff(_win, A_REVERSE); } 114 | } 115 | 116 | // Redraw right border or scroll indicator 117 | 118 | if ( (_firstprint > 0) && (int(idx) == _firstprint) ) 119 | waddch(_win, ACS_UARROW); 120 | else if ( (lastrow < int(_items.size())-1) && (int(idx) == lastrow) ) 121 | waddch(_win, ACS_DARROW); 122 | else { waddch(_win, ACS_VLINE); } 123 | } 124 | 125 | /******************************************************************************* 126 | 127 | Constructors 128 | 129 | *******************************************************************************/ 130 | MenubarList::MenubarList() 131 | { 132 | _reserved_rows = 2; 133 | _header_rows = 1; 134 | _outerpad = 0; 135 | _innerpad = 0; 136 | _hotkey = -1; 137 | clearButtons(); 138 | setModal(false); 139 | } 140 | 141 | MenubarList::MenubarList(WINDOW *win) 142 | { 143 | _win = win; 144 | _reserved_rows = 2; 145 | _header_rows = 1; 146 | _outerpad = 0; 147 | _innerpad = 0; 148 | _hotkey = -1; 149 | clearButtons(); 150 | setModal(false); 151 | } 152 | 153 | /******************************************************************************* 154 | 155 | Set attributes 156 | 157 | *******************************************************************************/ 158 | void MenubarList::setPad(unsigned int outerpad, unsigned int innerpad) 159 | { 160 | _outerpad = outerpad; 161 | _innerpad = innerpad; 162 | } 163 | 164 | void MenubarList::setHotKey(int hotkey) { _hotkey = hotkey; } 165 | 166 | /******************************************************************************* 167 | 168 | Get attributes 169 | 170 | *******************************************************************************/ 171 | int MenubarList::hotKey() const { return _hotkey; } 172 | void MenubarList::minimumSize(int & height, int & width) const 173 | { 174 | int namelen, reserved_cols; 175 | unsigned int i, nitems; 176 | std::string shortcut; 177 | 178 | // Minimum usable height 179 | 180 | nitems = _items.size(); 181 | height = _reserved_rows + nitems; 182 | 183 | // Minimum usable width 184 | 185 | width = 0; 186 | reserved_cols = 2 + 2*_outerpad; // 2 for border 187 | 188 | // Width for name + innerpad + shortcut 189 | 190 | for ( i = 0; i < nitems; i++ ) 191 | { 192 | shortcut = _items[i]->getProp("shortcut"); 193 | if (shortcut.size() > 0) 194 | namelen = _items[i]->name().size() + _innerpad 195 | + _items[i]->getProp("shortcut").size(); 196 | else 197 | namelen = _items[i]->name().size(); 198 | if (namelen > width) { width = namelen; } 199 | } 200 | width += reserved_cols; 201 | } 202 | 203 | void MenubarList::preferredSize(int & height, int & width) const 204 | { 205 | minimumSize(height, width); 206 | } 207 | -------------------------------------------------------------------------------- /src/MenubarListItem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ListItem.h" 3 | #include "MenubarListItem.h" 4 | 5 | /******************************************************************************* 6 | 7 | Constructors 8 | 9 | *******************************************************************************/ 10 | MenubarListItem::MenubarListItem() 11 | { 12 | _name = ""; 13 | addProp("shortcut", ""); 14 | } 15 | MenubarListItem::MenubarListItem(const std::string & name, 16 | const std::string & shortcut, int hotkey) 17 | { 18 | _name = name; 19 | addProp("shortcut", shortcut); 20 | setHotKey(hotkey); 21 | } 22 | -------------------------------------------------------------------------------- /src/MouseEvent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MouseEvent.h" 4 | 5 | const int MouseEvent::_doubleclick_timeout = 250; // Milliseconds. Longer than 6 | // this between presses is 7 | // considered a single click 8 | 9 | /******************************************************************************* 10 | 11 | Constructor 12 | 13 | *******************************************************************************/ 14 | MouseEvent::MouseEvent() 15 | { 16 | _tclick = std::chrono::high_resolution_clock::now(); 17 | _button = -1; 18 | _doubleclick = false; 19 | } 20 | 21 | /******************************************************************************* 22 | 23 | Records mouse press information and determines whether double click occurred 24 | 25 | *******************************************************************************/ 26 | void MouseEvent::recordClick(const MEVENT & event) 27 | { 28 | std::chrono::high_resolution_clock::time_point tnew; 29 | int newbutton; 30 | int duration; 31 | 32 | tnew = std::chrono::high_resolution_clock::now(); 33 | 34 | if (event.bstate & BUTTON1_PRESSED) 35 | newbutton = 1; 36 | else if (event.bstate & BUTTON3_PRESSED) 37 | newbutton = 3; 38 | else if (event.bstate & BUTTON4_PRESSED) 39 | newbutton = 4; 40 | #if NCURSES_MOUSE_VERSION > 1 41 | else if (event.bstate & BUTTON5_PRESSED) 42 | #else 43 | // Note: this may not give desired scroll-down behavior with some values of 44 | // TERM. For example, xterm-1003 activates this bit for all mouse movements. 45 | else if (event.bstate & REPORT_MOUSE_POSITION) 46 | #endif 47 | newbutton = 5; 48 | else 49 | return; 50 | 51 | // Determine if a double click occurred 52 | 53 | _doubleclick = false; 54 | if ( (newbutton == 1) && (_button == 1) ) 55 | { 56 | duration = std::chrono::duration_cast 57 | (tnew-_tclick).count(); 58 | if (duration <= MouseEvent::_doubleclick_timeout) 59 | _doubleclick = true; 60 | } 61 | 62 | // Store the rest of the event information 63 | 64 | _tclick = tnew; 65 | _button = newbutton; 66 | _x = event.x; 67 | _y = event.y; 68 | } 69 | 70 | /******************************************************************************* 71 | 72 | Query event information 73 | 74 | *******************************************************************************/ 75 | int MouseEvent::button() const { return _button; } 76 | int MouseEvent::x() const { return _x; } 77 | int MouseEvent::y() const { return _y; } 78 | bool MouseEvent::doubleClick() const { return _doubleclick; } 79 | -------------------------------------------------------------------------------- /src/MouseHelpWindow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "HelpItem.h" 3 | #include "MouseHelpWindow.h" 4 | 5 | /******************************************************************************* 6 | 7 | Constructor 8 | 9 | *******************************************************************************/ 10 | MouseHelpWindow::MouseHelpWindow() 11 | { 12 | _name = "Mouse bindings"; 13 | setLabels("Action", "Binding"); 14 | createList(); 15 | } 16 | 17 | /******************************************************************************* 18 | 19 | Constructs list to display 20 | 21 | *******************************************************************************/ 22 | void MouseHelpWindow::createList() 23 | { 24 | addItem(new HelpItem("Accept selection", "Double left click")); 25 | addItem(new HelpItem("Change selection", "Left click")); 26 | addItem(new HelpItem("Scrolling", "Click arrows / scroll area")); 27 | #if NCURSES_MOUSE_VERSION > 1 28 | addItem(new HelpItem("Scrolling", "Mouse wheel")); 29 | #endif 30 | addItem(new HelpItem("Tag SlackBuild or category", "Right click")); 31 | 32 | // Determine width needed to display shortcuts 33 | 34 | shortcutWidth(); 35 | } 36 | -------------------------------------------------------------------------------- /src/PackageInfoBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include // floor 5 | #include // max 6 | #include "Color.h" 7 | #include "signals.h" 8 | #include "settings.h" 9 | #include "string_util.h" 10 | #include "PackageInfoBox.h" 11 | 12 | /******************************************************************************* 13 | 14 | Prints message in box within defined margins 15 | 16 | *******************************************************************************/ 17 | void PackageInfoBox::redrawMessage() const 18 | { 19 | unsigned int i, max_lines, len; 20 | int rows, cols, left; 21 | double mid; 22 | std::vector splitmsg; 23 | 24 | getmaxyx(_win, rows, cols); 25 | splitmsg = split(_message, '\n'); 26 | 27 | max_lines = splitmsg.size(); 28 | for ( i = 0; i < max_lines; i++ ) 29 | { 30 | len = splitmsg[i].size(); 31 | mid = double(cols-2)/2.0; 32 | left = std::floor(mid - double(len)/2.0) + 1; 33 | wmove(_win, 3+_margin_v+i, 1); 34 | if (_centered) { printSpaces(left-1); } 35 | wprintw(_win, "%s", splitmsg[i].c_str()); 36 | } 37 | } 38 | 39 | /******************************************************************************* 40 | 41 | Constructors 42 | 43 | *******************************************************************************/ 44 | PackageInfoBox::PackageInfoBox() 45 | { 46 | std::vector buttons(1), button_signals(1); 47 | 48 | _name = "Package info"; 49 | buttons[0] = " Ok "; 50 | button_signals[0] = signals::keyEnter; 51 | setButtons(buttons, button_signals); 52 | _centered = false; 53 | setColor("fg_popup", "bg_popup"); 54 | setButtonColor("fg_highlight_active", "bg_highlight_active"); 55 | } 56 | 57 | PackageInfoBox::PackageInfoBox(WINDOW *win) 58 | { 59 | std::vector buttons(1), button_signals(1); 60 | 61 | _win = win; 62 | _name = "Package info"; 63 | buttons[0] = " Ok "; 64 | button_signals[0] = signals::keyEnter; 65 | setButtons(buttons, button_signals); 66 | _centered = false; 67 | setColor("fg_popup", "bg_popup"); 68 | setButtonColor("fg_highlight_active", "bg_highlight_active"); 69 | } 70 | 71 | /******************************************************************************* 72 | 73 | Get attributes 74 | 75 | *******************************************************************************/ 76 | void PackageInfoBox::minimumSize(int & height, int & width) const 77 | { 78 | // Always use the preferred size, or else the displayed info gets squished. 79 | // The user will just have to make their window wider if it's too small. 80 | 81 | preferredSize(height, width); 82 | } 83 | 84 | void PackageInfoBox::preferredSize(int & height, int & width) const 85 | { 86 | int namelen, reserved_rows, reserved_cols, msg_width; 87 | std::vector splitmsg; 88 | unsigned int i, nlines, nbuttons; 89 | 90 | reserved_rows = 6 + 2*_margin_v; 91 | reserved_cols = 2; 92 | 93 | // Preferred width -- pick some reasonable number (message width 50) 94 | 95 | width = _name.size(); 96 | nbuttons = _buttons.size(); 97 | if (nbuttons > 0) 98 | { 99 | namelen = 0; 100 | for ( i = 0; i < nbuttons; i++ ) 101 | { 102 | namelen += _buttons[i].size(); 103 | } 104 | if (namelen > width) { width = namelen; } 105 | } 106 | width += reserved_cols; 107 | width = std::max(width, int(30+2+2*_margin_h)); 108 | msg_width = width-2-2*_margin_h; 109 | 110 | // Required height based on width and message 111 | 112 | splitmsg = split(_message, '\n'); 113 | nlines = splitmsg.size(); 114 | height = reserved_rows + nlines; 115 | 116 | // Check width and adjust height accordingly 117 | 118 | for ( i = 0; i < nlines; i++ ) 119 | { 120 | if (int(splitmsg[i].size()) > msg_width) 121 | msg_width = splitmsg[i].size(); 122 | } 123 | width = msg_width+2+2*_margin_h; 124 | splitmsg = split(_message, '\n'); 125 | nlines = splitmsg.size(); 126 | height = reserved_rows + nlines; 127 | } 128 | -------------------------------------------------------------------------------- /src/QuickSearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "settings.h" 4 | #include "signals.h" 5 | #include "TextInput.h" 6 | #include "QuickSearch.h" 7 | #include "MouseEvent.h" 8 | 9 | /******************************************************************************* 10 | 11 | User interaction: returns key stroke. Unlike regular TextInput, returns whenever 12 | the entry is changed, because the calling function needs to search as the user 13 | types. 14 | 15 | *******************************************************************************/ 16 | std::string QuickSearch::exec(int y_offset, MouseEvent * mevent) 17 | { 18 | int ch; 19 | bool getting_input; 20 | std::string retval; 21 | unsigned int check_redraw; 22 | 23 | const int MY_DELETE = 330; 24 | const int MY_ESC = 27; 25 | const int MY_TAB = 9; 26 | const int MY_SHIFT_TAB = 353; 27 | 28 | curs_set(1); 29 | 30 | getting_input = true; 31 | while (getting_input) 32 | { 33 | // Redraw (do not highlight, like a regular TextInput) 34 | 35 | draw(y_offset, false, false); 36 | _redraw_type = "entry"; 37 | getting_input = false; 38 | 39 | // Get user input 40 | 41 | switch (ch = getch()) { 42 | 43 | // Enter key: return Enter signal 44 | 45 | case '\n': 46 | case '\r': 47 | case KEY_ENTER: 48 | retval = signals::keyEnter; 49 | _redraw_type = "entry"; 50 | break; 51 | 52 | // Backspace key pressed: delete previous character. 53 | // Note: some terminals define it as 8, others as 127 54 | 55 | case 8: 56 | case 127: 57 | case KEY_BACKSPACE: 58 | if (_cursidx > 0) 59 | { 60 | _entry.erase(_cursidx-1,1); 61 | _cursidx--; 62 | if (_cursidx < _firsttext) 63 | { 64 | if (int(_cursidx) > _width-1) { _firsttext = _cursidx-_width+1; } 65 | else { _firsttext = 0; } 66 | } 67 | } 68 | break; 69 | 70 | // Delete key pressed: delete current character 71 | 72 | case MY_DELETE: 73 | if (_cursidx < _entry.size()) { _entry.erase(_cursidx,1); } 74 | break; 75 | 76 | // Navigation keys 77 | 78 | case KEY_LEFT: 79 | getting_input = true; 80 | if (_cursidx > 0) { _cursidx--; } 81 | if (_cursidx < _firsttext) { _firsttext = _cursidx; } 82 | else { _redraw_type = "none"; } 83 | break; 84 | case KEY_RIGHT: 85 | getting_input = true; 86 | if (_cursidx < _entry.size()) { _cursidx++; } 87 | check_redraw = determineFirstText(); 88 | if (check_redraw == 0) { _redraw_type = "none"; } 89 | break; 90 | case KEY_HOME: 91 | getting_input = true; 92 | if (_cursidx == 0) { _redraw_type = "none"; } 93 | _cursidx = 0; 94 | _firsttext = 0; 95 | break; 96 | case KEY_END: 97 | getting_input = true; 98 | _cursidx = _entry.size(); 99 | check_redraw = determineFirstText(); 100 | if (check_redraw == 0) { _redraw_type = "none"; } 101 | break; 102 | case KEY_PPAGE: 103 | retval = "ignore"; 104 | _redraw_type = "entry"; 105 | break; 106 | case KEY_NPAGE: 107 | retval = "ignore"; 108 | _redraw_type = "entry"; 109 | break; 110 | case KEY_UP: 111 | case MY_SHIFT_TAB: 112 | retval = signals::highlightPrev; 113 | _redraw_type = "entry"; 114 | break; 115 | case KEY_DOWN: 116 | case MY_TAB: 117 | retval = signals::highlightNext; 118 | _redraw_type = "entry"; 119 | break; 120 | 121 | // Resize signal 122 | 123 | case KEY_RESIZE: 124 | retval = signals::resize; 125 | _redraw_type = "entry"; 126 | break; 127 | 128 | // Quit key 129 | 130 | case MY_ESC: 131 | retval = signals::quit; 132 | _redraw_type = "entry"; 133 | break; 134 | 135 | // Add character to entry 136 | 137 | default: 138 | _entry.insert(_cursidx, 1, ch); 139 | _cursidx++; 140 | determineFirstText(); 141 | break; 142 | } 143 | } 144 | 145 | // Redraw when exiting, because entry may have changed 146 | 147 | draw(y_offset, false, false); 148 | 149 | curs_set(0); 150 | return retval; 151 | } 152 | -------------------------------------------------------------------------------- /src/SearchBox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // floor 4 | #include "Color.h" 5 | #include "settings.h" 6 | #include "TextInput.h" 7 | #include "ToggleInput.h" 8 | #include "Label.h" 9 | #include "SearchBox.h" 10 | 11 | /******************************************************************************* 12 | 13 | Draws window border, message, and info 14 | 15 | *******************************************************************************/ 16 | void SearchBox::redrawFrame() 17 | { 18 | int rows, cols, msglen, i, left; 19 | double mid; 20 | 21 | getmaxyx(_win, rows, cols); 22 | 23 | // Title 24 | 25 | msglen = _msg.size(); 26 | mid = double(cols-2)/2.0; 27 | left = std::floor(mid - double(msglen)/2.0) + 1; 28 | wmove(_win, 1, 1); 29 | wclrtoeol(_win); 30 | if (colors.turnOn(_win, "fg_title", "bg_title") != 0) 31 | wattron(_win, A_BOLD); 32 | printSpaces(left-1); 33 | printToEol(_msg); 34 | if (colors.turnOff(_win) != 0) 35 | wattroff(_win, A_BOLD); 36 | 37 | // Corners 38 | 39 | wmove(_win, 0, 0); 40 | waddch(_win, ACS_ULCORNER); 41 | wmove(_win, rows-1, 0); 42 | waddch(_win, ACS_LLCORNER); 43 | wmove(_win, rows-1, cols-1); 44 | waddch(_win, ACS_LRCORNER); 45 | wmove(_win, 0, cols-1); 46 | waddch(_win, ACS_URCORNER); 47 | 48 | // Top border 49 | 50 | wmove(_win, 0, 1); 51 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 52 | 53 | // Left border 54 | 55 | for ( i = 1; i < rows-1; i++ ) { mvwaddch(_win, i, 0, ACS_VLINE); } 56 | 57 | // Right border 58 | 59 | for ( i = 1; i < rows-1; i++ ) { mvwaddch(_win, i, cols-1, ACS_VLINE); } 60 | 61 | // Bottom border 62 | 63 | wmove(_win, rows-1, 1); 64 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 65 | 66 | // Horizontal dividers for header and text input 67 | 68 | wmove(_win, 2, 1); 69 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 70 | wmove(_win, 5, 1); 71 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 72 | 73 | // Connections 74 | 75 | mvwaddch(_win, 2, 0, ACS_LTEE); 76 | mvwaddch(_win, 2, cols-1, ACS_RTEE); 77 | mvwaddch(_win, 5, 0, ACS_LTEE); 78 | mvwaddch(_win, 5, cols-1, ACS_RTEE); 79 | 80 | // Button area 81 | 82 | if (_buttons.size() > 0) 83 | { 84 | wmove(_win, rows-3, 1); 85 | for ( i = 1; i < cols-1; i++ ) { waddch(_win, ACS_HLINE); } 86 | mvwaddch(_win, rows-3, 0, ACS_LTEE); 87 | mvwaddch(_win, rows-3, cols-1, ACS_RTEE); 88 | redrawButtons(); 89 | } 90 | } 91 | 92 | /******************************************************************************* 93 | 94 | Constructors and destructor 95 | 96 | *******************************************************************************/ 97 | SearchBox::SearchBox() 98 | { 99 | _firstprint = _header_rows; 100 | _msg = "Search repository"; 101 | _has_scroll_indicator = false; 102 | 103 | addItem(new Label()); 104 | _items[0]->setWidth(30); 105 | _items[0]->setName("Search term:"); 106 | _items[0]->setPosition(3,1); 107 | 108 | addItem(&_entryitem); 109 | _entryitem.setWidth(30); 110 | _entryitem.setPosition(4,1); 111 | 112 | addItem(&_caseitem); 113 | _caseitem.setName("Case sensitive"); 114 | _caseitem.setEnabled(false); 115 | _caseitem.setWidth(30); 116 | _caseitem.setPosition(6,1); 117 | 118 | addItem(&_wholeitem); 119 | _wholeitem.setName("Whole words only"); 120 | _wholeitem.setEnabled(false); 121 | _wholeitem.setWidth(30); 122 | _wholeitem.setPosition(7,1); 123 | 124 | addItem(&_readmeitem); 125 | _readmeitem.setName("Search READMEs"); 126 | _readmeitem.setEnabled(false); 127 | _readmeitem.setWidth(30); 128 | _readmeitem.setPosition(8,1); 129 | 130 | addItem(&_currentlistitem); 131 | _currentlistitem.setName("Current list only"); 132 | _currentlistitem.setEnabled(false); 133 | _currentlistitem.setWidth(30); 134 | _currentlistitem.setPosition(9,1); 135 | } 136 | 137 | SearchBox::~SearchBox() { delete _items[0]; } 138 | 139 | /******************************************************************************* 140 | 141 | Set attributes 142 | 143 | *******************************************************************************/ 144 | void SearchBox::clearSearch() { _entryitem.clear(); } 145 | 146 | /******************************************************************************* 147 | 148 | Get attributes 149 | 150 | *******************************************************************************/ 151 | std::string SearchBox::searchString() const { return _entryitem.text(); } 152 | bool SearchBox::caseSensitive() const { return _caseitem.enabled(); } 153 | bool SearchBox::wholeWord() const { return _wholeitem.enabled(); } 154 | bool SearchBox::searchREADMEs() const { return _readmeitem.enabled(); } 155 | bool SearchBox::currentList() const { return _currentlistitem.enabled(); } 156 | -------------------------------------------------------------------------------- /src/ShellReader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "string_util.h" 5 | #include "ShellReader.h" 6 | 7 | /******************************************************************************* 8 | 9 | Checks variable name and removes 'varname=' if it is found 10 | 11 | *******************************************************************************/ 12 | bool ShellReader::checkVarname(std::string & line, 13 | const std::string & varname) const 14 | { 15 | unsigned int len; 16 | 17 | line = remove_comment(line, '#'); 18 | line = remove_leading_whitespace(line); 19 | 20 | len = varname.size(); 21 | if (line.substr(0, len+1) == varname + "=") 22 | { 23 | line = line.substr(len+1, line.size()-len-1); 24 | return true; 25 | } 26 | else { return false; } 27 | } 28 | 29 | /******************************************************************************* 30 | 31 | Reads the value of a variable given the first line. It is assumed that 32 | checkVarname has been called first so that VARNAME= has already been removed. 33 | 34 | *******************************************************************************/ 35 | int ShellReader::readVariable(std::string & line, std::string & value) 36 | { 37 | bool readnext, endvalue; 38 | unsigned int len; 39 | char quote; 40 | std::size_t quote_pos; 41 | 42 | // Read the first line 43 | 44 | line = trim(line); 45 | len = line.size(); 46 | readnext = false; 47 | if ( (line[0] == '"') || (line[0] == '\'') ) 48 | { 49 | quote = line[0]; // Get quote character 50 | quote_pos = line.substr(1,len-1).find_first_of(quote); 51 | if (quote_pos != std::string::npos) 52 | { 53 | value = line.substr(1,quote_pos); // Value between quotes 54 | return 0; 55 | } 56 | else if (line[len-1] == '\\') 57 | { 58 | value = trim(line.substr(1,len-2)); // Line continuation 59 | readnext = true; 60 | } 61 | else 62 | { 63 | value = trim(line.substr(1,len-1)); // Unclosed quote: go to next line 64 | readnext = true; 65 | } 66 | } 67 | else 68 | { 69 | // Just read the thing right after the equal sign 70 | value = split(line)[0]; 71 | return 0; 72 | } 73 | 74 | // Keep reading subsequent lines until the quote is closed 75 | 76 | if (readnext) 77 | { 78 | endvalue = false; 79 | while (! endvalue) 80 | { 81 | if (_file.eof()) 82 | { 83 | rewind(); 84 | return 1; 85 | } 86 | std::getline(_file, line); 87 | line = remove_leading_whitespace(line); 88 | if (line[0] == '#') { continue; } // Comment line 89 | line = remove_comment(line, '#'); 90 | line = trim(line); 91 | 92 | len = line.size(); 93 | quote_pos = line.substr(1,len-1).find_first_of(quote); 94 | if (quote_pos != std::string::npos) // End value 95 | { 96 | endvalue = true; 97 | value += " " + trim(line.substr(0,quote_pos+1)); 98 | } 99 | else if (line[len-1] == '\\') // Line continuation 100 | { 101 | value += " " + trim(line.substr(0,len-2)); 102 | } 103 | else // Unclosed quote: go to next line 104 | { 105 | value += " " + trim(line); 106 | } 107 | } 108 | } 109 | 110 | return 0; 111 | } 112 | 113 | /******************************************************************************* 114 | 115 | Reads the value of a default variable given the line. Default variables may not 116 | span multiple lines. 117 | 118 | *******************************************************************************/ 119 | int ShellReader::readDefaultVariable(std::string & line, std::string & value) 120 | { 121 | std::size_t dollarpos, brace0pos, colonpos, dashpos, brace1pos; 122 | 123 | line = trim(line); 124 | 125 | // Check to make sure there is a ${VAR:-DEFAULT_VAL} construct 126 | 127 | dollarpos = line.find_first_of('$'); 128 | if (dollarpos == std::string::npos) 129 | return 1; 130 | 131 | brace0pos = line.find_first_of('{'); 132 | if (brace0pos == std::string::npos) 133 | return 1; 134 | 135 | colonpos = line.find_first_of(':'); 136 | if (colonpos == std::string::npos) 137 | return 1; 138 | 139 | dashpos = line.find_first_of('-'); 140 | if (dashpos == std::string::npos) 141 | return 1; 142 | 143 | brace1pos = line.find_first_of('}'); 144 | if (brace1pos == std::string::npos) 145 | return 1; 146 | 147 | if (brace0pos < dollarpos) 148 | return 1; 149 | 150 | if (colonpos < brace0pos) 151 | return 1; 152 | 153 | if (dashpos != colonpos+1) 154 | return 1; 155 | 156 | if (brace1pos < dashpos) 157 | return 1; 158 | 159 | // Pick out the value 160 | 161 | value = line.substr(dashpos+1,brace1pos-dashpos-1); 162 | 163 | return 0; 164 | } 165 | 166 | /******************************************************************************* 167 | 168 | Constructor and destructor 169 | 170 | *******************************************************************************/ 171 | ShellReader::ShellReader() { _file_open = false; } 172 | ShellReader::~ShellReader() { if (_file_open) { _file.close(); } } 173 | 174 | /******************************************************************************* 175 | 176 | Opens or closes a file. Returns 1 on error or 0 on success. 177 | 178 | *******************************************************************************/ 179 | int ShellReader::open(const std::string & filename) 180 | { 181 | _file.open(filename.c_str()); 182 | if (not _file.is_open()) { return 1; } 183 | else { _file_open = true; } 184 | 185 | return 0; 186 | } 187 | 188 | int ShellReader::close() 189 | { 190 | if (! _file_open) { return 1; } 191 | else 192 | { 193 | _file.close(); 194 | _file_open = false; 195 | } 196 | 197 | return 0; 198 | } 199 | 200 | /******************************************************************************* 201 | 202 | Reads a variable from the file and stores as string. If the variable is set as 203 | a default value, set the optional default_var argument = true. 204 | Returns 1 on error or 0 on success. 205 | 206 | *******************************************************************************/ 207 | int ShellReader::read(const std::string & varname, std::string & value, 208 | bool default_var) 209 | { 210 | int check; 211 | bool reading; 212 | std::string line; 213 | 214 | if (! _file_open) { return 1; } 215 | 216 | reading = true; 217 | check = 0; 218 | rewind(); 219 | while (reading) 220 | { 221 | if (_file.eof()) 222 | { 223 | rewind(); 224 | return 1; 225 | } 226 | 227 | std::getline(_file, line); 228 | if (checkVarname(line, varname)) 229 | { 230 | if (default_var) 231 | check = readDefaultVariable(line, value); 232 | else 233 | check = readVariable(line, value); 234 | reading = false; 235 | } 236 | } 237 | 238 | return check; 239 | } 240 | 241 | /******************************************************************************* 242 | 243 | Rewinds to beginning of the file. Returns 1 if the file is not open. 244 | 245 | *******************************************************************************/ 246 | int ShellReader::rewind() 247 | { 248 | if (! _file_open) { return 1; } 249 | 250 | _file.clear(); 251 | _file.seekg(0); 252 | 253 | return 0; 254 | } 255 | -------------------------------------------------------------------------------- /src/requirements.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // reverse, max 4 | #include "BuildListItem.h" 5 | #include "backend.h" // get_reqs, find_slackbuild, list_installed 6 | #include "string_util.h" // split 7 | #include "requirements.h" 8 | 9 | /******************************************************************************* 10 | 11 | Adds required SlackBuild to dependency list, removing any instance already 12 | present in the list 13 | 14 | *******************************************************************************/ 15 | void add_req(BuildListItem * build, 16 | std::vector & reqlist) 17 | { 18 | unsigned int i, nreqs; 19 | 20 | nreqs = reqlist.size(); 21 | for ( i = 0; i < nreqs; i++ ) 22 | { 23 | if (reqlist[i]->name() == build->name()) 24 | { 25 | reqlist.erase(reqlist.begin()+i); 26 | break; 27 | } 28 | } 29 | reqlist.push_back(build); 30 | } 31 | 32 | /******************************************************************************* 33 | 34 | Recursively computes list of requirements for a SlackBuild. List must be 35 | reversed after calling this to get the proper build order. Returns 1 if a 36 | requirement is not found in the list, 2 if a .info file is missing, or 0 37 | otherwise 38 | 39 | *******************************************************************************/ 40 | int get_reqs_recursive(const BuildListItem & build, 41 | std::vector & reqlist, 42 | std::vector > & slackbuilds) 43 | { 44 | unsigned int i, ndeps; 45 | std::vector deplist; 46 | std::string reqs; 47 | int idx0, idx1, check, maxcheck; 48 | 49 | if (build.getBoolProp("installed")) { deplist = 50 | split(build.getProp("requires")); } 51 | else 52 | { 53 | check = get_reqs(build, reqs); 54 | if (check == 0) { deplist = split(reqs); } 55 | else { return 2; } 56 | } 57 | 58 | maxcheck = 0; 59 | check = 0; 60 | ndeps = deplist.size(); 61 | for ( i = 0; i < ndeps; i++ ) 62 | { 63 | if (deplist[i] != "%README%") 64 | { 65 | check = find_slackbuild(deplist[i], slackbuilds, idx0, idx1); 66 | if (check == 0) 67 | { 68 | add_req(&slackbuilds[idx0][idx1], reqlist); 69 | check = get_reqs_recursive(slackbuilds[idx0][idx1], reqlist, slackbuilds); 70 | } 71 | else { check = 1; } 72 | maxcheck = std::max(check, maxcheck); 73 | } 74 | } 75 | 76 | return maxcheck; 77 | } 78 | 79 | /******************************************************************************* 80 | 81 | Computes list of requirements needed for a SlackBuild in the correct build 82 | order. 83 | 84 | *******************************************************************************/ 85 | int compute_reqs_order(const BuildListItem & build, 86 | std::vector & reqlist, 87 | std::vector > & slackbuilds) 88 | { 89 | int check; 90 | 91 | reqlist.resize(0); 92 | check = get_reqs_recursive(build, reqlist, slackbuilds); 93 | std::reverse(reqlist.begin(), reqlist.end()); 94 | 95 | return check; 96 | } 97 | 98 | /******************************************************************************* 99 | 100 | Recursively finds installed SlackBuilds that depend on a given SlackBuild 101 | 102 | *******************************************************************************/ 103 | void get_inverse_reqs_recursive(const BuildListItem & build, 104 | std::vector & invreqlist, 105 | std::vector & installedlist) 106 | { 107 | unsigned int i, j, ninstalled, ndeps; 108 | std::vector deplist; 109 | 110 | ninstalled = installedlist.size(); 111 | for ( i = 0; i < ninstalled; i++ ) 112 | { 113 | deplist = split(installedlist[i]->getProp("requires")); 114 | ndeps = deplist.size(); 115 | for ( j = 0; j < ndeps; j++ ) 116 | { 117 | if (deplist[j] == build.name()) 118 | { 119 | add_req(installedlist[i], invreqlist); 120 | get_inverse_reqs_recursive(*installedlist[i], invreqlist, 121 | installedlist); 122 | break; 123 | } 124 | } 125 | } 126 | } 127 | 128 | /******************************************************************************* 129 | 130 | Computes list of installed SlackBuilds that depend on a given SlackBuild 131 | 132 | *******************************************************************************/ 133 | void compute_inv_reqs(const BuildListItem & build, 134 | std::vector & invreqlist, 135 | std::vector > & slackbuilds) 136 | { 137 | std::vector installedlist; 138 | 139 | invreqlist.resize(0); 140 | installedlist = list_installed(slackbuilds); 141 | get_inverse_reqs_recursive(build, invreqlist, installedlist); 142 | } 143 | -------------------------------------------------------------------------------- /src/sboui-systray.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # System tray notifier for sboui updates. Source code adapted from 4 | # salix-update-notifier by George Vlahavas (gapan). 5 | 6 | import sys 7 | if sys.version_info[0] < 3: 8 | import gtk 9 | else: 10 | import gi 11 | # Note: see deprecation note near the bottom. 12 | gi.require_version('Gtk', '3.0') 13 | from gi.repository import Gtk as gtk 14 | 15 | def accept(data=None): 16 | sys.exit(0) 17 | 18 | def dismiss(data=None): 19 | sys.exit(1) 20 | 21 | def quit(data=None): 22 | sys.exit(2) 23 | 24 | def make_menu(event_button, event_time, data=None): 25 | menu = gtk.Menu() 26 | 27 | accept_image = gtk.Image() 28 | accept_image.set_from_icon_name('system-run', gtk.ICON_SIZE_MENU) 29 | accept_item = gtk.ImageMenuItem('Launch sboui updater') 30 | accept_item.set_image(accept_image) 31 | 32 | dismiss_image = gtk.Image() 33 | dismiss_image.set_from_icon_name('window-close', gtk.ICON_SIZE_MENU) 34 | dismiss_item = gtk.ImageMenuItem('Ignore for now') 35 | dismiss_item.set_image(dismiss_image) 36 | 37 | quit_image = gtk.Image() 38 | quit_image.set_from_icon_name('application-exit', gtk.ICON_SIZE_MENU) 39 | quit_item = gtk.ImageMenuItem('Don\'t remind me again') 40 | quit_item.set_image(quit_image) 41 | 42 | menu.append(accept_item) 43 | menu.append(dismiss_item) 44 | menu.append(quit_item) 45 | accept_item.connect_object("activate", accept, "Accept") 46 | accept_item.show() 47 | dismiss_item.connect_object("activate", dismiss, "Dismiss") 48 | dismiss_item.show() 49 | quit_item.connect_object("activate", quit, "Quit") 50 | quit_item.show() 51 | menu.popup(None, None, None, event_button, event_time) 52 | 53 | def on_right_click(data, event_button, event_time): 54 | make_menu(event_button, event_time) 55 | 56 | def on_left_click(event): 57 | accept() 58 | 59 | if __name__ == '__main__': 60 | if sys.version_info[0] < 3: 61 | icon = gtk.status_icon_new_from_icon_name("sboui") 62 | else: 63 | # Note: this is deprecated in Gtk+3 and removed in Gtk+4. Will 64 | # eventually need to find a replacement. 65 | icon = gtk.StatusIcon().new_from_icon_name("sboui") 66 | icon.set_tooltip_text('SBo updates are available') 67 | icon.connect('popup-menu', on_right_click) 68 | icon.connect('activate', on_left_click) 69 | gtk.main() 70 | -------------------------------------------------------------------------------- /src/sboui-update-notifier.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | from time import sleep 5 | import subprocess 6 | import psutil 7 | import os 8 | import sys 9 | 10 | def sbo_updates_available(): 11 | 12 | proc = subprocess.Popen(['${CMAKE_INSTALL_PREFIX}/sbin/sboui', '-p'], 13 | stdout=subprocess.PIPE) 14 | retval = False 15 | for line in iter(proc.stdout.readline,''): 16 | if sys.version_info[0] < 3: 17 | dcdline = line 18 | else: 19 | dcdline = line.decode() 20 | if dcdline.find("upgradable SlackBuild") != -1: 21 | if dcdline.startswith("No"): 22 | break 23 | else: 24 | retval = True 25 | break 26 | proc.wait() 27 | 28 | return retval 29 | 30 | if __name__ == "__main__": 31 | 32 | # Bail if already running for this user 33 | 34 | username = os.environ['USER'] 35 | this_pid = os.getpid() 36 | for proc in psutil.process_iter(): 37 | cmdline = proc.cmdline() 38 | proc_username = proc.username() 39 | if proc.pid == this_pid: 40 | continue 41 | if proc_username != username: 42 | continue 43 | if len(cmdline) != 2: 44 | continue 45 | if cmdline[0].find('python') != -1 and \ 46 | cmdline[1].find('sboui-update-notifier') != -1: 47 | print('sboui-update-notifier is already running. Exiting.') 48 | sys.exit(0) 49 | 50 | # Sleep time in seconds 51 | 52 | parser = argparse.ArgumentParser(description='System tray notifier for SBo \ 53 | package updates.') 54 | parser.add_argument('interval', nargs='?', default=3600, type=int, 55 | help='seconds of wait time between checks (default 3600)') 56 | args = parser.parse_args() 57 | 58 | # Set update command (kdesu requires -c argument, others like gksu and ktsuss 59 | # don't) 60 | 61 | update_cmd = '${CMAKE_INSTALL_PREFIX}/libexec/sboui/sboui_update_launch' 62 | graphical_su = "${GRAPHICAL_SU}" 63 | if graphical_su == "kdesu": 64 | cmd = [graphical_su, '-c', 65 | '${TERMINAL_EMULATOR} -e {}'.format(update_cmd)] 66 | else: 67 | cmd = [graphical_su, 68 | '${TERMINAL_EMULATOR} -e {}'.format(update_cmd)] 69 | 70 | # Main loop. Show systray icon if updates are available. Quit if requested. 71 | 72 | while True: 73 | 74 | if sbo_updates_available(): 75 | retval = subprocess.call(['${CMAKE_INSTALL_PREFIX}' + 76 | '/libexec/sboui/sboui-systray.py']) 77 | if retval == 0: 78 | subprocess.call(cmd) 79 | elif retval == 2: 80 | break 81 | 82 | sleep(args.interval) 83 | -------------------------------------------------------------------------------- /src/sboui.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "CLOParser.h" 7 | #include "curses.h" 8 | #include "settings.h" 9 | #include "backend.h" 10 | #include "MainWindow.h" 11 | #include "MouseEvent.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | int check; 16 | CLOParser clos; 17 | MouseEvent mevent; 18 | 19 | // Parse command line arguments 20 | 21 | check = clos.checkCLOs(argc, argv, PACKAGE_VERSION); 22 | if (check == 1) { return check; } 23 | else if (check == -1) { return 0; } 24 | 25 | // Read config file 26 | 27 | if (clos.requestInputFile()) { check = read_config(clos.inputFile()); } 28 | else { check = read_config(); } 29 | 30 | // Read blacklist 31 | 32 | blacklist.read("/etc/sboui/blacklist"); 33 | 34 | // Read ignore_versions file 35 | 36 | ignore_versions.read("/etc/sboui/ignore_versions"); 37 | 38 | // Handle non-interactive CLOs 39 | 40 | if (clos.sync()) 41 | return sync_repo(false); 42 | else if (clos.upgradable()) 43 | { 44 | MainWindow mainwindow(PACKAGE_VERSION); 45 | return mainwindow.listUpgradable(); 46 | } 47 | 48 | // Set up ncurses (needed because we set colors while reading config file) 49 | 50 | if (! clos.sync()) 51 | setlocale(LC_ALL, ""); 52 | initscr(); 53 | curs_set(0); 54 | raw(); 55 | noecho(); 56 | set_escdelay(25); 57 | keypad(stdscr, TRUE); 58 | #if NCURSES_MOUSE_VERSION > 1 59 | mousemask(BUTTON1_PRESSED | BUTTON3_PRESSED | BUTTON4_PRESSED | 60 | BUTTON5_PRESSED, NULL); 61 | #else 62 | // Note: in some terminals, REPORT_MOUSE_POSITION can be used to simulate 63 | // button 5, but in others it gives undesired behavior, so to be safe disable 64 | // scroll-down. Button 4 can still be used for scroll up, but I don't think 65 | // it makes sense to have scroll up without scroll down. 66 | mousemask(BUTTON1_PRESSED | BUTTON3_PRESSED, NULL); 67 | #endif 68 | mouseinterval(0); 69 | 70 | // Set up color 71 | 72 | setup_color(); 73 | 74 | // User interaction loop (note: call constructor after setting colors) 75 | 76 | MainWindow mainwindow(PACKAGE_VERSION); 77 | mainwindow.setConfFile(clos.inputFile()); 78 | mainwindow.initialize(&mevent); 79 | if (clos.upgradeAll()) 80 | mainwindow.upgradeAll(&mevent); 81 | mainwindow.exec(&mevent); 82 | 83 | endwin(); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /src/sboui_launch.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash -l 2 | 3 | @CMAKE_INSTALL_PREFIX@/sbin/sboui 4 | -------------------------------------------------------------------------------- /src/sboui_update_launch.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash -l 2 | 3 | @CMAKE_INSTALL_PREFIX@/sbin/sboui -u 4 | -------------------------------------------------------------------------------- /src/signals.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "signals.h" 3 | 4 | namespace signals 5 | { 6 | std::string resize = "__RESIZE__"; 7 | std::string quit = "__QUIT__"; 8 | std::string highlight = "__HIGHLIGHT__"; 9 | std::string highlightFirst = "__HIGHLIGHTFIRST__"; 10 | std::string highlightLast = "__HIGHLIGHTLAST__"; 11 | std::string highlightPrev = "__HIGHLIGHTPREV__"; 12 | std::string highlightNext = "__HIGHLIGHTNEXT__"; 13 | std::string highlightPrevPage = "__HIGHLIGHTPREVPAGE__"; 14 | std::string highlightNextPage = "__HIGHLIGHTNEXTPAGE__"; 15 | std::string keyTab = "__TAB__"; 16 | std::string keyEnter = "__ENTER__"; 17 | std::string scroll = "__SCROLL__"; 18 | std::string keyRight = "__KEYRIGHT__"; 19 | std::string keyLeft = "__KEYLEFT__"; 20 | std::string keySpace = "__KEYSPACE__"; 21 | std::string mouseEvent = "__MOUSEEVENT__"; 22 | std::string nullEvent = "__NULLEVENT__"; 23 | std::string tag = "__TAG__"; 24 | std::string keyF9 = "__KEYF9__"; 25 | } 26 | --------------------------------------------------------------------------------