diff -Nru albert-0.12.0/CMakeLists.txt albert-0.13.1+plugins1/CMakeLists.txt --- albert-0.12.0/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/CMakeLists.txt 2017-09-30 09:43:39.000000000 +0000 @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.3) # Least supporting CMAKE_CXX_STANDARD project(albertlauncher) @@ -7,11 +7,18 @@ # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) + +# Set standard +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) # Set additional compiler flags -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -pedantic") #-Wconversion -Wunused -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DQT_NO_DEBUG_OUTPUT ") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") #-Wconversion -Wunused +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DQT_QML_DEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DQT_NO_DEBUG_OUTPUT") # Color make output SET(CMAKE_COLOR_MAKEFILE ON) @@ -21,7 +28,7 @@ SET(CMAKE_VERBOSE_MAKEFILE ON) else(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(CMAKE_VERBOSE_MAKEFILE OFF) -endif(CMAKE_BUILD_TYPE STREQUAL "Debug") +endif() # Put the binaries in dedicated toplevel directories set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -30,7 +37,7 @@ # Build project add_subdirectory(src/application/) add_subdirectory(src/lib/) -add_subdirectory(src/plugins/) +add_subdirectory(plugins/) # Do platform specific post target stuff if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -39,9 +46,7 @@ install(FILES data/albert.desktop DESTINATION share/applications ) # Install icon - install(FILES src/lib/albert/resources/icons/albert.svg DESTINATION share/icons/hicolor/scalable/apps) + install(FILES src/lib/albertcore/resources/icons/albert.svg DESTINATION share/icons/hicolor/scalable/apps) - # Define where to install the themes - install(DIRECTORY data/themes DESTINATION share/albert COMPONENT config) endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff -Nru albert-0.12.0/data/ArcTemplate.qss albert-0.13.1+plugins1/data/ArcTemplate.qss --- albert-0.12.0/data/ArcTemplate.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/ArcTemplate.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: ubervison - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #%foreground_color%; - background-color: #%background_color%; -} - -#frame { - padding: 4px; - border-radius: 3px; - background-color: #%background_color%; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - border: 1px solid #%border_color%; - font-size: 36px; - selection-color: #%background_color%; - selection-background-color: #%foreground_color%; - background-color: #%inputline_color%; -} - -#settingsButton { - color : #%button_color%; - background-color: #%background_color%; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - selection-color: #%foreground_color%; -} - -QListView::item:selected { - background: #%selection_background_color%; - border: 1px solid #%selection_border_color%; -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #%scroll_color%; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/ArcTemplate.sh albert-0.13.1+plugins1/data/ArcTemplate.sh --- albert-0.12.0/data/ArcTemplate.sh 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/ArcTemplate.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -#!/bin/bash - -TEMPLATE="ArcTemplate.qss" - -function makeStyle(){ - cat "$1" | sed \ - -e "s/%background_color%/$2/g" \ - -e "s/%foreground_color%/$3/g" \ - -e "s/%inputline_color%/$4/g" \ - -e "s/%border_color%/$5/g" \ - -e "s/%button_color%/$6/g" \ - -e "s/%scroll_color%/$7/g" \ - -e "s/%selection_background_color%/$8/g" \ - -e "s/%selection_border_color%/$9/g" > "${10}" -} - -#makeStyle bg fg input border button scrollbar sel_bg sel_border output -makeStyle "$TEMPLATE" "e7e8eb" "727A8F" "fdfdfd" "CFD6E6" "ffffff" "b8babf" "95c4fb" "cfd6e6" "themes/Arc Blue.qss" -makeStyle "$TEMPLATE" "e7e8eb" "727A8F" "fdfdfd" "CFD6E6" "ffffff" "b8babf" "F5F6F7" "4084D6" "themes/Arc Grey.qss" -makeStyle "$TEMPLATE" "383C4A" "AFB8C5" "404552" "21252B" "ffffff" "b8babf" "4084D6" "4084D6" "themes/Arc Dark Blue.qss" -makeStyle "$TEMPLATE" "383C4A" "AFB8C5" "404552" "21252B" "ffffff" "b8babf" "404552" "2B2E39" "themes/Arc Dark Grey.qss" \ No newline at end of file diff -Nru albert-0.12.0/data/SpotlightTemplate.qss albert-0.13.1+plugins1/data/SpotlightTemplate.qss --- albert-0.12.0/data/SpotlightTemplate.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/SpotlightTemplate.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #%foreground_color%; - background-color: #%background_color%; -} - -#frame { - padding: 6px 0px; - border-radius: 8px; - background-color: #%background_color%; - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 0px 8px; - font-size: 36px; - selection-color: #%background_color%; - selection-background-color: #%foreground_color%; - background-color: transparent; -} - -#settingsButton { - margin: 6px 6px 0px 0px; - color: #%button_color%; - background-color: transparent; - padding: 2px; - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -/********** ListViews ************/ - -QListView { - background: transparent; - selection-color: #%selection_foreground_color%; -} - -QListView::item:selected { - background: #%selection_background_color%; -} - -QListView QScrollBar:vertical { - width: 3px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #%scroll_color%; - border-radius: 1px; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 40px; - font-size: 24px; -} - -QListView#proposalList::item{ - padding: 8px 0px 0px 0px; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} diff -Nru albert-0.12.0/data/SpotlightTemplate.sh albert-0.13.1+plugins1/data/SpotlightTemplate.sh --- albert-0.12.0/data/SpotlightTemplate.sh 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/SpotlightTemplate.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -#!/bin/bash - -TEMPLATE="SpotlightTemplate.qss" - -function makeStyle(){ - cat "$1" | sed \ - -e "s/%background_color%/$2/g" \ - -e "s/%foreground_color%/$3/g" \ - -e "s/%button_color%/$4/g" \ - -e "s/%scroll_color%/$5/g" \ - -e "s/%selection_foreground_color%/$6/g"\ - -e "s/%selection_background_color%/$7/g" > "${8}" -} - -#makeStyle bg fg button scroll sel_fg sel_bg output -makeStyle "$TEMPLATE" "fcfcfc" "808080" "e0e0e0" "c0c0c0" "606060" "e0e0e0" "${1}Spotlight.qss" -makeStyle "$TEMPLATE" "030303" "808080" "202020" "404040" "a0a0a0" "202020" "${1}Spotlight Dark.qss" diff -Nru albert-0.12.0/data/StandardThemeTemplate.qss albert-0.13.1+plugins1/data/StandardThemeTemplate.qss --- albert-0.12.0/data/StandardThemeTemplate.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/StandardThemeTemplate.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #%foreground_color%; - background-color: #%background_color%; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #%background_color%; - border: 6px solid #%border_color%; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #%background_color%; - selection-background-color: #%foreground_color%; - background-color: #%inputline_color%; -} - -#settingsButton { - color : #%button_color%; - background-color: #%background_color%; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #%selection_foreground_color%; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20%selection_background_color%, stop:0.5 #10%selection_background_color%, stop:1.0 #20%selection_background_color% ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #%scroll_color%; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/StandardThemeTemplate.sh albert-0.13.1+plugins1/data/StandardThemeTemplate.sh --- albert-0.12.0/data/StandardThemeTemplate.sh 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/StandardThemeTemplate.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -#!/bin/bash - -TEMPLATE="StandardThemeTemplate.qss" - -function makeStyle(){ - cat "${1}" | sed \ - -e "s/%background_color%/${2}/g" \ - -e "s/%foreground_color%/${3}/g" \ - -e "s/%inputline_color%/${4}/g" \ - -e "s/%border_color%/${5}/g" \ - -e "s/%button_color%/${6}/g" \ - -e "s/%scroll_color%/${7}/g" \ - -e "s/%selection_foreground_color%/${8}/g"\ - -e "s/%selection_background_color%/${9}/g" \ - -e "s/%selection_border_color%/${10}/g" > "${11}" -} - -#makeStyle bg fg input border button scroll sel_fg sel_bg sel_bor output -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "808080" "808080" "808080" "808080" "808080" "808080" "${1}Bright.qss" -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "FF8000" "FF8000" "FF8000" "808080" "FF8000" "FF8000" "${1}BrightOrange.qss" -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "FF0080" "FF0080" "FF0080" "808080" "FF0080" "FF0080" "${1}BrightMagenta.qss" -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "00FF80" "00FF80" "00FF80" "808080" "00FF80" "00FF80" "${1}BrightMint.qss" -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "80FF00" "80FF00" "80FF00" "808080" "80FF00" "80FF00" "${1}BrightGreen.qss" -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "0080FF" "0080FF" "0080FF" "808080" "0080FF" "0080FF" "${1}BrightBlue.qss" -makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "8000FF" "8000FF" "8000FF" "808080" "8000FF" "8000FF" "${1}BrightViolet.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "808080" "808080" "808080" "808080" "808080" "808080" "${1}Dark.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "FF8000" "FF8000" "FF8000" "808080" "FF8000" "FF8000" "${1}DarkOrange.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "FF0080" "FF0080" "FF0080" "808080" "FF0080" "FF0080" "${1}DarkMagenta.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "00FF80" "00FF80" "00FF80" "808080" "00FF80" "00FF80" "${1}DarkMint.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "80FF00" "80FF00" "80FF00" "808080" "80FF00" "80FF00" "${1}DarkGreen.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "0080FF" "0080FF" "0080FF" "808080" "0080FF" "0080FF" "${1}DarkBlue.qss" -makeStyle "$TEMPLATE" "404040" "808080" "202020" "8000FF" "8000FF" "8000FF" "808080" "8000FF" "8000FF" "${1}DarkViolet.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "b58900" "b58900" "b58900" "93a1a1" "b58900" "b58900" "${1}SolarizedDarkYellow.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "cb4b16" "cb4b16" "cb4b16" "93a1a1" "cb4b16" "cb4b16" "${1}SolarizedDarkOrange.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "dc322f" "dc322f" "dc322f" "93a1a1" "dc322f" "dc322f" "${1}SolarizedDarkRed.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "d33682" "d33682" "d33682" "93a1a1" "d33682" "d33682" "${1}SolarizedDarkMagenta.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "6c71c4" "6c71c4" "6c71c4" "93a1a1" "6c71c4" "6c71c4" "${1}SolarizedDarkViolet.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "268bd2" "268bd2" "268bd2" "93a1a1" "268bd2" "268bd2" "${1}SolarizedDarkBlue.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "2aa198" "2aa198" "2aa198" "93a1a1" "2aa198" "2aa198" "${1}SolarizedDarkCyan.qss" -makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "859900" "859900" "859900" "93a1a1" "859900" "859900" "${1}SolarizedDarkGreen.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "b58900" "b58900" "b58900" "586e75" "b58900" "b58900" "${1}SolarizedBrightYellow.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "cb4b16" "cb4b16" "cb4b16" "586e75" "cb4b16" "cb4b16" "${1}SolarizedBrightOrange.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "dc322f" "dc322f" "dc322f" "586e75" "dc322f" "dc322f" "${1}SolarizedBrightRed.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "d33682" "d33682" "d33682" "586e75" "d33682" "d33682" "${1}SolarizedBrightMagenta.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "6c71c4" "6c71c4" "6c71c4" "586e75" "6c71c4" "6c71c4" "${1}SolarizedBrightViolet.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "268bd2" "268bd2" "268bd2" "586e75" "268bd2" "268bd2" "${1}SolarizedBrightBlue.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "2aa198" "2aa198" "2aa198" "586e75" "2aa198" "2aa198" "${1}SolarizedBrightCyan.qss" -makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "859900" "859900" "859900" "586e75" "859900" "859900" "${1}SolarizedBrightGreen.qss" diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Blue.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Blue.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Blue.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Blue.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: ubervison - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #727A8F; - background-color: #e7e8eb; -} - -#frame { - padding: 4px; - border-radius: 3px; - background-color: #e7e8eb; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - border: 1px solid #CFD6E6; - font-size: 36px; - selection-color: #e7e8eb; - selection-background-color: #727A8F; - background-color: #fdfdfd; -} - -#settingsButton { - color : #ffffff; - background-color: #e7e8eb; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - selection-color: #727A8F; -} - -QListView::item:selected { - background: #95c4fb; - border: 1px solid #cfd6e6; -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #b8babf; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Dark Blue.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Dark Blue.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Dark Blue.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Dark Blue.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: ubervison - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #AFB8C5; - background-color: #383C4A; -} - -#frame { - padding: 4px; - border-radius: 3px; - background-color: #383C4A; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - border: 1px solid #21252B; - font-size: 36px; - selection-color: #383C4A; - selection-background-color: #AFB8C5; - background-color: #404552; -} - -#settingsButton { - color : #ffffff; - background-color: #383C4A; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - selection-color: #AFB8C5; -} - -QListView::item:selected { - background: #4084D6; - border: 1px solid #4084D6; -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #b8babf; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Dark Grey.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Dark Grey.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Dark Grey.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Dark Grey.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: ubervison - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #AFB8C5; - background-color: #383C4A; -} - -#frame { - padding: 4px; - border-radius: 3px; - background-color: #383C4A; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - border: 1px solid #21252B; - font-size: 36px; - selection-color: #383C4A; - selection-background-color: #AFB8C5; - background-color: #404552; -} - -#settingsButton { - color : #ffffff; - background-color: #383C4A; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - selection-color: #AFB8C5; -} - -QListView::item:selected { - background: #404552; - border: 1px solid #2B2E39; -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #b8babf; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Grey.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Grey.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Arc Grey.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Arc Grey.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: ubervison - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #727A8F; - background-color: #e7e8eb; -} - -#frame { - padding: 4px; - border-radius: 3px; - background-color: #e7e8eb; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - border: 1px solid #CFD6E6; - font-size: 36px; - selection-color: #e7e8eb; - selection-background-color: #727A8F; - background-color: #fdfdfd; -} - -#settingsButton { - color : #ffffff; - background-color: #e7e8eb; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - selection-color: #727A8F; -} - -QListView::item:selected { - background: #F5F6F7; - border: 1px solid #4084D6; -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #b8babf; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/BrightBlue.qss albert-0.13.1+plugins1/data/themes/BrightBlue.qss --- albert-0.12.0/data/themes/BrightBlue.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/BrightBlue.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #0080FF; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #0080FF; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #200080FF, stop:0.5 #100080FF, stop:1.0 #200080FF ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #0080FF; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/BrightGreen.qss albert-0.13.1+plugins1/data/themes/BrightGreen.qss --- albert-0.12.0/data/themes/BrightGreen.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/BrightGreen.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #80FF00; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #80FF00; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #2080FF00, stop:0.5 #1080FF00, stop:1.0 #2080FF00 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #80FF00; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/BrightMagenta.qss albert-0.13.1+plugins1/data/themes/BrightMagenta.qss --- albert-0.12.0/data/themes/BrightMagenta.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/BrightMagenta.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #FF0080; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #FF0080; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF0080, stop:0.5 #10FF0080, stop:1.0 #20FF0080 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #FF0080; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/BrightMint.qss albert-0.13.1+plugins1/data/themes/BrightMint.qss --- albert-0.12.0/data/themes/BrightMint.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/BrightMint.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #00FF80; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #00FF80; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #2000FF80, stop:0.5 #1000FF80, stop:1.0 #2000FF80 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #00FF80; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/BrightOrange.qss albert-0.13.1+plugins1/data/themes/BrightOrange.qss --- albert-0.12.0/data/themes/BrightOrange.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/BrightOrange.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #FF8000; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #FF8000; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF8000, stop:0.5 #10FF8000, stop:1.0 #20FF8000 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #FF8000; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/Bright.qss albert-0.13.1+plugins1/data/themes/Bright.qss --- albert-0.12.0/data/themes/Bright.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/Bright.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #808080; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #808080; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20808080, stop:0.5 #10808080, stop:1.0 #20808080 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #808080; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/BrightViolet.qss albert-0.13.1+plugins1/data/themes/BrightViolet.qss --- albert-0.12.0/data/themes/BrightViolet.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/BrightViolet.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #FFFFFF; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #FFFFFF; - border: 6px solid #8000FF; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #FFFFFF; - selection-background-color: #808080; - background-color: #D0D0D0; -} - -#settingsButton { - color : #8000FF; - background-color: #FFFFFF; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #208000FF, stop:0.5 #108000FF, stop:1.0 #208000FF ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #8000FF; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/DarkBlue.qss albert-0.13.1+plugins1/data/themes/DarkBlue.qss --- albert-0.12.0/data/themes/DarkBlue.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/DarkBlue.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #0080FF; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #0080FF; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #200080FF, stop:0.5 #100080FF, stop:1.0 #200080FF ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #0080FF; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/DarkGreen.qss albert-0.13.1+plugins1/data/themes/DarkGreen.qss --- albert-0.12.0/data/themes/DarkGreen.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/DarkGreen.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #80FF00; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #80FF00; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #2080FF00, stop:0.5 #1080FF00, stop:1.0 #2080FF00 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #80FF00; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/DarkMagenta.qss albert-0.13.1+plugins1/data/themes/DarkMagenta.qss --- albert-0.12.0/data/themes/DarkMagenta.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/DarkMagenta.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #FF0080; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #FF0080; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF0080, stop:0.5 #10FF0080, stop:1.0 #20FF0080 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #FF0080; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/DarkMint.qss albert-0.13.1+plugins1/data/themes/DarkMint.qss --- albert-0.12.0/data/themes/DarkMint.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/DarkMint.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #00FF80; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #00FF80; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #2000FF80, stop:0.5 #1000FF80, stop:1.0 #2000FF80 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #00FF80; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/DarkOrange.qss albert-0.13.1+plugins1/data/themes/DarkOrange.qss --- albert-0.12.0/data/themes/DarkOrange.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/DarkOrange.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #FF8000; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #FF8000; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF8000, stop:0.5 #10FF8000, stop:1.0 #20FF8000 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #FF8000; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/Dark.qss albert-0.13.1+plugins1/data/themes/Dark.qss --- albert-0.12.0/data/themes/Dark.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/Dark.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #808080; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #808080; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20808080, stop:0.5 #10808080, stop:1.0 #20808080 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #808080; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/DarkViolet.qss albert-0.13.1+plugins1/data/themes/DarkViolet.qss --- albert-0.12.0/data/themes/DarkViolet.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/DarkViolet.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #404040; - border: 6px solid #8000FF; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #404040; - selection-background-color: #808080; - background-color: #202020; -} - -#settingsButton { - color : #8000FF; - background-color: #404040; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #808080; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #208000FF, stop:0.5 #108000FF, stop:1.0 #208000FF ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #8000FF; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/Elementary.qss albert-0.13.1+plugins1/data/themes/Elementary.qss --- albert-0.12.0/data/themes/Elementary.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/Elementary.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - * author: Bart Zaalberg - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #404040; - -} - -#frame { - padding: 10px; - border-radius: 4px; - background-color: #F5F5F5; - border: 1px solid #808080; - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 0px; - border-radius: 2px; - border: 1px solid lightblue; - font-size:15px; - selection-color: #404040; - selection-background-color: #FFFFFF; - background-color: #FFFFFF; - padding-left:10px; - margin-right:20px; - color:black; -} - -#settingsButton { - color : #808080; - background-color: #F5F5F5; - padding: 4px; - - /* Respect the frame border */ - margin: 12px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - selection-color: #331; - background-color: #F5F5F5; -} - -QListView::item { - background-color: #F5F5F5; - padding:6px; -} - -QListView::item:selected { - border-radius: 4px; - background-color: #D8D8D8; -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #808080; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: #F5F5F5; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 15px; - color: black; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 35px; - font-size: 13px; - color: #331; - fill: #333; - font-family: "Open Sans"; - src: url("//fonts.googleapis.com/css?family=Open+Sans"); - font-weight: 400; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/Numix.qss albert-0.13.1+plugins1/data/themes/Numix.qss --- albert-0.12.0/data/themes/Numix.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/Numix.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* - * author: - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - - -* { - color : #ccc; - background-color: #2d2d2d; -} - -#frame { - width:640px; - padding: 5px; - background-color: #2d2d2d; - /*border: 1px solid #555;*/ - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - font: 36px "Source Sans Pro Bold"; - selection-color: #fdf6e3; - selection-background-color: #586e75; - border: none; - background-color: #2d2d2d; -} - -#settingsButton { - border: none; - border-radius: 7px; - color : #555; - background-color: transparent; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -#settingsButton:hover { - background-color: #2d2d2d; -} - - -/********** ListViews **********/ - -QListView { - selection-color: #ccc; -} - -QListView::item:selected { - border: none; - background: qlineargradient(x1:0, x2:1, stop:0.0 #3a3a3a, stop:0.5 #3a3a3a, stop:1.0 #3a3a3a ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #AAAAAA; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 36px; - font-size: 26px; - font: 20px "Source Sans Pro Bold"; - background-color: transparent; - border: none; -} - -QListView#proposalList::item{ - height:48px; - padding: 4px; - border-bottom: 1px dotted #555; -} - -QListView#proposalList::item:selected{ - border: none; - background: #3a3a3a; -} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Numix Rounded.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Numix Rounded.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Numix Rounded.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Numix Rounded.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ -/* - * author: Leandro Heck - * based on Manuel Schneider's themes Numix and Yosemite Dark - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - color : #ccc; - background-color: #2d2d2d; -} - -#frame { - width:640px; - padding: 12px; - border-radius: 5px; - background-color: #2d2d2d; - /*border: 1px solid #555;*/ - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - font: 36px "Source Sans Pro Bold"; - selection-color: #fdf6e3; - selection-background-color: #586e75; - border: none; - background-color: #2d2d2d; -} - -#settingsButton { - border: none; - border-radius: 7px; - color : #555; - background-color: transparent; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -#settingsButton:hover { - background-color: #2d2d2d; -} - - -/********** ListViews ************/ - -QListView { - selection-color: #ccc; -} - -QListView::item:selected { - border: none; - background: qlineargradient(x1:0, x2:1, stop:0.0 #3a3a3a, stop:0.5 #3a3a3a, stop:1.0 #3a3a3a ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #AAAAAA; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 36px; - font-size: 26px; - font: 20px "Source Sans Pro Bold"; - background-color: transparent; - border: none; -} - -QListView#proposalList::item{ - height:48px; - padding: 4px; - border-bottom: 1px dotted #555; -} - -QListView#proposalList::item:selected{ - border: none; - background: #3a3a3a; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightBlue.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightBlue.qss --- albert-0.12.0/data/themes/SolarizedBrightBlue.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightBlue.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #268bd2; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #268bd2; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20268bd2, stop:0.5 #10268bd2, stop:1.0 #20268bd2 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #268bd2; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightCyan.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightCyan.qss --- albert-0.12.0/data/themes/SolarizedBrightCyan.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightCyan.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #2aa198; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #2aa198; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #202aa198, stop:0.5 #102aa198, stop:1.0 #202aa198 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #2aa198; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightGreen.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightGreen.qss --- albert-0.12.0/data/themes/SolarizedBrightGreen.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightGreen.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #859900; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #859900; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20859900, stop:0.5 #10859900, stop:1.0 #20859900 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #859900; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightMagenta.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightMagenta.qss --- albert-0.12.0/data/themes/SolarizedBrightMagenta.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightMagenta.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #d33682; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #d33682; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20d33682, stop:0.5 #10d33682, stop:1.0 #20d33682 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #d33682; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightOrange.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightOrange.qss --- albert-0.12.0/data/themes/SolarizedBrightOrange.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightOrange.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #cb4b16; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #cb4b16; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20cb4b16, stop:0.5 #10cb4b16, stop:1.0 #20cb4b16 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #cb4b16; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightRed.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightRed.qss --- albert-0.12.0/data/themes/SolarizedBrightRed.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightRed.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #dc322f; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #dc322f; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20dc322f, stop:0.5 #10dc322f, stop:1.0 #20dc322f ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #dc322f; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightViolet.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightViolet.qss --- albert-0.12.0/data/themes/SolarizedBrightViolet.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightViolet.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #6c71c4; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #6c71c4; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #206c71c4, stop:0.5 #106c71c4, stop:1.0 #206c71c4 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #6c71c4; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedBrightYellow.qss albert-0.13.1+plugins1/data/themes/SolarizedBrightYellow.qss --- albert-0.12.0/data/themes/SolarizedBrightYellow.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedBrightYellow.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #586e75; - background-color: #fdf6e3; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #fdf6e3; - border: 6px solid #b58900; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #fdf6e3; - selection-background-color: #586e75; - background-color: #eee8d5; -} - -#settingsButton { - color : #b58900; - background-color: #fdf6e3; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #586e75; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20b58900, stop:0.5 #10b58900, stop:1.0 #20b58900 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #b58900; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkBlue.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkBlue.qss --- albert-0.12.0/data/themes/SolarizedDarkBlue.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkBlue.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #268bd2; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #268bd2; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20268bd2, stop:0.5 #10268bd2, stop:1.0 #20268bd2 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #268bd2; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkCyan.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkCyan.qss --- albert-0.12.0/data/themes/SolarizedDarkCyan.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkCyan.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #2aa198; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #2aa198; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #202aa198, stop:0.5 #102aa198, stop:1.0 #202aa198 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #2aa198; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkGreen.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkGreen.qss --- albert-0.12.0/data/themes/SolarizedDarkGreen.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkGreen.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #859900; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #859900; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20859900, stop:0.5 #10859900, stop:1.0 #20859900 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #859900; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkMagenta.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkMagenta.qss --- albert-0.12.0/data/themes/SolarizedDarkMagenta.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkMagenta.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #d33682; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #d33682; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20d33682, stop:0.5 #10d33682, stop:1.0 #20d33682 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #d33682; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkOrange.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkOrange.qss --- albert-0.12.0/data/themes/SolarizedDarkOrange.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkOrange.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #cb4b16; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #cb4b16; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20cb4b16, stop:0.5 #10cb4b16, stop:1.0 #20cb4b16 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #cb4b16; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkRed.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkRed.qss --- albert-0.12.0/data/themes/SolarizedDarkRed.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkRed.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #dc322f; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #dc322f; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20dc322f, stop:0.5 #10dc322f, stop:1.0 #20dc322f ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #dc322f; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkViolet.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkViolet.qss --- albert-0.12.0/data/themes/SolarizedDarkViolet.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkViolet.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #6c71c4; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #6c71c4; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #206c71c4, stop:0.5 #106c71c4, stop:1.0 #206c71c4 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #6c71c4; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/SolarizedDarkYellow.qss albert-0.13.1+plugins1/data/themes/SolarizedDarkYellow.qss --- albert-0.12.0/data/themes/SolarizedDarkYellow.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/SolarizedDarkYellow.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #93a1a1; - background-color: #002b36; -} - -#frame { - padding: 6px; - border-radius: 12px; - background-color: #002b36; - border: 6px solid #b58900; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 2px; - border-radius: 2px; - font-size: 36px; - selection-color: #002b36; - selection-background-color: #93a1a1; - background-color: #073642; -} - -#settingsButton { - color : #b58900; - background-color: #002b36; - padding: 4px; - - /* Respect the frame border */ - margin: 6px 6px 0px 0px; - border-top-right-radius: 6px; - border-bottom-left-radius: 10px; - - /* Workaround for Qt to get fixed size button*/ - min-width:13px; - min-height:13px; - max-width:13px; - max-height:13px; -} - -/********** ListViews **********/ - -QListView { - background: transparent; - selection-color: #93a1a1; -} - -QListView::item:selected { - background: qlineargradient(x1:0, x2:1, stop:0.0 #20b58900, stop:0.5 #10b58900, stop:1.0 #20b58900 ); -} - -QListView QScrollBar:vertical { - width: 5px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #b58900; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 44px; - font-size: 26px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Spotlight Dark.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Spotlight Dark.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Spotlight Dark.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Spotlight Dark.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #030303; -} - -#frame { - padding: 6px 0px; - border-radius: 8px; - background-color: #030303; - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 0px 8px; - font-size: 36px; - selection-color: #030303; - selection-background-color: #808080; - background-color: transparent; -} - -#settingsButton { - margin: 6px 6px 0px 0px; - color: #202020; - background-color: transparent; - padding: 2px; - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -/********** ListViews ************/ - -QListView { - background: transparent; - selection-color: #a0a0a0; -} - -QListView::item:selected { - background: #202020; -} - -QListView QScrollBar:vertical { - width: 3px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #404040; - border-radius: 1px; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 40px; - font-size: 24px; -} - -QListView#proposalList::item{ - padding: 8px 0px 0px 0px; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} diff -Nru albert-0.12.0/data/themes/Spotlight.qss albert-0.13.1+plugins1/data/themes/Spotlight.qss --- albert-0.12.0/data/themes/Spotlight.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/Spotlight.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - color : #808080; - background-color: #fcfcfc; -} - -#frame { - padding: 6px 0px; - border-radius: 8px; - background-color: #fcfcfc; - min-width:640px; - max-width:640px; -} - -#inputLine { - padding: 0px 8px; - font-size: 36px; - selection-color: #fcfcfc; - selection-background-color: #808080; - background-color: transparent; -} - -#settingsButton { - margin: 6px 6px 0px 0px; - color: #e0e0e0; - background-color: transparent; - padding: 2px; - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -/********** ListViews ************/ - -QListView { - background: transparent; - selection-color: #606060; -} - -QListView::item:selected { - background: #e0e0e0; -} - -QListView QScrollBar:vertical { - width: 3px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #c0c0c0; - border-radius: 1px; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 40px; - font-size: 24px; -} - -QListView#proposalList::item{ - padding: 8px 0px 0px 0px; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Yosemite Dark.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Yosemite Dark.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/data/themes/Yosemite Dark.qss" 2017-06-09 16:29:43.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/data/themes/Yosemite Dark.qss" 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - font-family:"DejaVu Sans"; - font-weight: 200; - color : #ffffff; - background-color: #f4000000; -} - -#frame { - padding: 12px; - border-radius: 5px; - background-color: #f4000000; - border: 1px solid #20808080; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - font-size: 36px; - selection-color: #f4000000; - selection-background-color: #ffffff; - background-color: transparent; -} - -#settingsButton { - color: #484848; - background-color: transparent; - padding: 8px; - - /* Workaround for Qt to get fixed size button*/ - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -/********** ListViews ************/ - -QListView { - selection-color: #ffffff; -} - -QListView::item:selected { - background: #262626; -} - -QListView QScrollBar:vertical { - width: 2px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #484848; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 40px; - font-size: 22px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/data/themes/Yosemite.qss albert-0.13.1+plugins1/data/themes/Yosemite.qss --- albert-0.12.0/data/themes/Yosemite.qss 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/data/themes/Yosemite.qss 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -/* - * author: Manuel Schneider - * - * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: - * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) - * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) - */ - -* { - border: none; - font-family:"DejaVu Sans"; - font-weight: 200; - color : #000000; - background-color: #fcfcfc; -} - -#frame { - padding: 12px; - border-radius: 5px; - background-color: #fcfcfc; - border: 1px solid #20808080; - - /* Workaround for Qt to get fixed size button*/ - min-width:640px; - max-width:640px; -} - -#inputLine { - font-size: 36px; - selection-color: #fcfcfc; - selection-background-color: #000000; - background-color: transparent; -} - -#settingsButton { - color: #bdbdbd; - background-color: transparent; - padding: 8px; - - /* Workaround for Qt to get fixed size button*/ - min-width:14px; - min-height:14px; - max-width:14px; - max-height:14px; -} - -/********** ListViews ************/ - -QListView { - selection-color: #000000; -} - -QListView::item:selected { - background: #eeeeee; -} - -QListView QScrollBar:vertical { - width: 2px; - background: transparent; -} - -QListView QScrollBar::handle:vertical { - background: #e2e2e2; - min-height: 24px; -} - -QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, -QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, -QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { - border: 0px; - width: 0px; - height: 0px; - background: transparent; -} - -/********** actionList **********/ - -QListView#actionList { - font-size: 20px; -} - -QListView#actionList::item{ - height:28px; -} - -/********** proposalList **********/ - -QListView#proposalList { - icon-size: 40px; - font-size: 22px; -} - -QListView#proposalList::item{ - height:48px; -} diff -Nru albert-0.12.0/debian/changelog albert-0.13.1+plugins1/debian/changelog --- albert-0.12.0/debian/changelog 2017-06-13 10:40:30.000000000 +0000 +++ albert-0.13.1+plugins1/debian/changelog 2017-10-17 11:20:45.000000000 +0000 @@ -1,3 +1,16 @@ +albert (0.13.1+plugins1-1~webupd8~zesty2) zesty; urgency=medium + + * New upstream release + * The plugins are now separate. However, this package ships with the + default plugin pack + * New build-dependency: qtdeclarative5-dev + * Added dont-build-virtualbox-extension.patch + * New recommended dependencies (required only for the QML frontend, + which is not used by default): qml-module-qtquick-controls, + qml-module-qtgraphicaleffects and qml-module-qtquick2 + + -- Alin Andrei Tue, 17 Oct 2017 12:20:45 +0100 + albert (0.12.0-1~webupd8~zesty0) zesty; urgency=medium * New upstream release diff -Nru albert-0.12.0/debian/control albert-0.13.1+plugins1/debian/control --- albert-0.12.0/debian/control 2017-03-20 10:08:12.000000000 +0000 +++ albert-0.13.1+plugins1/debian/control 2017-10-17 11:20:45.000000000 +0000 @@ -3,11 +3,12 @@ Priority: optional Maintainer: Alin Andrei Standards-Version: 3.9.8 -Build-Depends: debhelper (>= 9), cmake, pkg-config, qtbase5-dev, qtbase5-dev-tools, libx11-dev, libqt5x11extras5-dev, libmuparser-dev, libqt5svg5-dev +Build-Depends: debhelper (>= 9), cmake, pkg-config, qtbase5-dev, qtbase5-dev-tools, libx11-dev, libqt5x11extras5-dev, libmuparser-dev, libqt5svg5-dev, qtdeclarative5-dev Homepage: https://github.com/ManuelSchneid3r/albert Package: albert Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libqt5sql5-sqlite, libqt5concurrent5 +Recommends: qml-module-qtquick-controls, qml-module-qtgraphicaleffects, qml-module-qtquick2 Description: Albert Launcher An amazing, desktop environment agnostic omnilauncher. diff -Nru albert-0.12.0/debian/patches/dont-build-virtualbox-extension.patch albert-0.13.1+plugins1/debian/patches/dont-build-virtualbox-extension.patch --- albert-0.12.0/debian/patches/dont-build-virtualbox-extension.patch 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/debian/patches/dont-build-virtualbox-extension.patch 2017-10-17 11:01:31.000000000 +0000 @@ -0,0 +1,19 @@ +The VirtualBox extension brings in a lot of deps, so I'm removing it from building +--- a/plugins/CMakeLists.txt ++++ b/plugins/CMakeLists.txt +@@ -93,10 +93,10 @@ + add_subdirectory(terminal) + endif() + +-option(BUILD_VIRTUALBOX "Build the extension" ON) +-if (BUILD_VIRTUALBOX) +- add_subdirectory(virtualbox) +-endif() ++#option(BUILD_VIRTUALBOX "Build the extension" ON) ++#if (BUILD_VIRTUALBOX) ++# add_subdirectory(virtualbox) ++#endif() + + option(BUILD_WEBSEARCH "Build the extension" ON) + if (BUILD_WEBSEARCH) + diff -Nru albert-0.12.0/debian/patches/series albert-0.13.1+plugins1/debian/patches/series --- albert-0.12.0/debian/patches/series 2017-05-29 09:06:34.000000000 +0000 +++ albert-0.13.1+plugins1/debian/patches/series 2017-10-17 11:01:37.000000000 +0000 @@ -1 +1,2 @@ #fix-gcc-backward-compatibility.patch +dont-build-virtualbox-extension.patch diff -Nru albert-0.12.0/debian/rules albert-0.13.1+plugins1/debian/rules --- albert-0.12.0/debian/rules 2015-01-19 11:09:05.000000000 +0000 +++ albert-0.13.1+plugins1/debian/rules 2017-10-17 11:08:50.000000000 +0000 @@ -4,3 +4,6 @@ %: dh $@ +override_dh_auto_configure: + cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release + make diff -Nru albert-0.12.0/.gitignore albert-0.13.1+plugins1/.gitignore --- albert-0.12.0/.gitignore 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/.gitignore 2017-09-30 09:43:39.000000000 +0000 @@ -4,4 +4,6 @@ packaging design .albertignore +*.qmlc +*.jsc diff -Nru albert-0.12.0/.gitmodules albert-0.13.1+plugins1/.gitmodules --- albert-0.12.0/.gitmodules 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/.gitmodules 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,3 @@ +[submodule "plugins"] + path = plugins + url = ../plugins.git diff -Nru albert-0.12.0/plugins/applications/applications.qrc albert-0.13.1+plugins1/plugins/applications/applications.qrc --- albert-0.12.0/plugins/applications/applications.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/applications.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/application-x-executable.svg + + diff -Nru albert-0.12.0/plugins/applications/CMakeLists.txt albert-0.13.1+plugins1/plugins/applications/CMakeLists.txt --- albert-0.12.0/plugins/applications/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(applications) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Concurrent) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) + diff -Nru albert-0.12.0/plugins/applications/metadata.json albert-0.13.1+plugins1/plugins/applications/metadata.json --- albert-0.12.0/plugins/applications/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.applications", + "name" : "Applications", + "version" : "1.1", + "platform" : "Linux", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : ["gksu"], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/applications/resources/application-x-executable.svg albert-0.13.1+plugins1/plugins/applications/resources/application-x-executable.svg --- albert-0.12.0/plugins/applications/resources/application-x-executable.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/resources/application-x-executable.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/applications/src/configwidget.cpp albert-0.13.1+plugins1/plugins/applications/src/configwidget.cpp --- albert-0.12.0/plugins/applications/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,27 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "configwidget.h" + +/** ***************************************************************************/ +Applications::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); + + // Show the app dirs in the label + QStringList standardPaths = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); + ui.label->setText(ui.label->text().replace("__XDG_DATA_DIRS__", standardPaths.join(", "))); +} diff -Nru albert-0.12.0/plugins/applications/src/configwidget.h albert-0.13.1+plugins1/plugins/applications/src/configwidget.h --- albert-0.12.0/plugins/applications/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace Applications +{ +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/applications/src/configwidget.ui albert-0.13.1+plugins1/plugins/applications/src/configwidget.ui --- albert-0.12.0/plugins/applications/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,97 @@ + + + Applications::ConfigWidget + + + + 0 + 0 + 800 + 600 + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html> +<head> +</head> +<body> +<p>Applications are looked up in the &quot;<span style=" font-style:italic;">applications/&quot;</span> directories in the $XDG_DATA_HOME and $XDG_DATA_DIRS, which are set in the environment variables. Your current environment configuration results in the following applications directories: <span style=" font-weight:600; font-style:italic;">__XDG_DATA_DIRS__</span>. </p> +<p>Every application is represented by a desktop file which has an ID. The desktop file ID is built using the path of the desktop file relative to the applications directory and turning '/' into '-'. If multiple files have the same desktop file ID, the first one in the precedence order given above is used. For more details check the <a href="https://specifications.freedesktop.org/desktop-entry-spec/latest/">desktop entry specification</a>.</p></body></html> + + + true + + + + + + + + + + + + + Ignore OnlyShowIn/NotShowIn keys + + + + + + + Fuzzy + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/applications/src/extension.cpp albert-0.13.1+plugins1/plugins/applications/src/extension.cpp --- albert-0.12.0/plugins/applications/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,657 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "core/query.h" +#include "core/queryhandler.h" +#include "util/offlineindex.h" +#include "util/standardaction.h" +#include "util/standardindexitem.h" +#include "util/shutil.h" +#include "xdg/iconlookup.h" +using std::map; +using std::pair; +using std::vector; +using std::shared_ptr; +using namespace Core; + +extern QString terminalCommand; + + +namespace { + +const char* CFG_FUZZY = "fuzzy"; +const bool DEF_FUZZY = false; +const char* CFG_IGNORESHOWINKEYS = "ignore_show_in_keys"; +const bool DEF_IGNORESHOWINKEYS = false; + +/******************************************************************************/ +QStringList expandedFieldCodes(const QStringList & unexpandedFields, + const QString & icon, + const QString & name, + const QString & path) { + /* + * A number of special field codes have been defined which will be expanded + * by the file manager or program launcher when encountered in the command + * line. Field codes consist of the percentage character ("%") followed by + * an alpha character. Literal percentage characters must be escaped as %%. + * Deprecated field codes should be removed from the command line and + * ignored. Field codes are expanded only once, the string that is used to + * replace the field code should not be checked for field codes itself. + * + * http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html + */ + QStringList expandedFields; + + for (const QString & field : unexpandedFields){ + + if (field == "%i" && !icon.isEmpty()) { + expandedFields.push_back("--icon"); + expandedFields.push_back(icon); + } + + QString tmpstr; + QString::const_iterator it = field.begin(); + + while (it != field.end()) { + if (*it == '%'){ + ++it; + if (it == field.end()) + break; + else if (*it=='%') + tmpstr.push_back("%"); + else if (*it=='c') + tmpstr.push_back(name); + else if (*it=='k') + tmpstr.push_back(path); + // TODO Unhandled f F u U + } + else + tmpstr.push_back(*it); + ++it; + } + if (!tmpstr.isEmpty()) + expandedFields.push_back(std::move(tmpstr)); + } + return expandedFields; +} + +/******************************************************************************/ +QString xdgStringEscape(const QString & unescaped) { + /* + * The escape sequences \s, \n, \t, \r, and \\ are supported for values of + * type string and localestring, meaning ASCII space, newline, tab, carriage + * return, and backslash, respectively. + * + * http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s03.html + */ + QString result; + QString::const_iterator it = unescaped.begin(); + while (it != unescaped.end()) { + if (*it == '\\'){ + ++it; + if (it == unescaped.end()) + break; + else if (*it=='s') + result.append(' '); + else if (*it=='n') + result.append('\n'); + else if (*it=='t') + result.append('\t'); + else if (*it=='r') + result.append('\r'); + else if (*it=='\\') + result.append('\\'); + } + else + result.append(*it); + ++it; + } + return result; +} + +/******************************************************************************/ +QString getLocalizedKey(const QString &key, const map &entries, const QLocale &loc) { + map::const_iterator it; + if ( (it = entries.find(QString("%1[%2]").arg(key, loc.name()))) != entries.end() + || (it = entries.find(QString("%1[%2]").arg(key, loc.name().left(2)))) != entries.end() + || (it = entries.find(key)) != entries.end()) + return it->second; + return QString(); +} + +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +class Applications::Private +{ +public: + Private(Extension *q) : q(q) {} + + Extension *q; + + QPointer widget; + QFileSystemWatcher watcher; + QString graphicalSudoPath; + + vector> index; + OfflineIndex offlineIndex; + + QFutureWatcher>> futureWatcher; + bool rerun = false; + bool ignoreShowInKeys; + + void finishIndexing(); + void startIndexing(); + vector> indexApplications() const; +}; + + + +/** ***************************************************************************/ +void Applications::Private::startIndexing() { + + // Never run concurrent + if ( futureWatcher.future().isRunning() ) { + rerun = true; + return; + } + + // Run finishIndexing when the indexing thread finished + futureWatcher.disconnect(); + QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, + std::bind(&Private::finishIndexing, this)); + + // Run the indexer thread + futureWatcher.setFuture(QtConcurrent::run(this, &Private::indexApplications)); + + // Notification + qInfo() << "Start indexing applications."; + emit q->statusInfo("Indexing applications ..."); +} + + + +/** ***************************************************************************/ +void Applications::Private::finishIndexing() { + + // Get the thread results + index = futureWatcher.future().result(); + + // Rebuild the offline index + offlineIndex.clear(); + for (const auto &item : index) + offlineIndex.add(item); + + // Finally update the watches (maybe folders changed) + if (!watcher.directories().isEmpty()) + watcher.removePaths(watcher.directories()); + QStringList xdgAppDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); + for (const QString &path : xdgAppDirs) { + watcher.addPath(path); + QDirIterator dit(path, QDir::Dirs|QDir::NoDotAndDotDot); + while (dit.hasNext()) + watcher.addPath(dit.next()); + } + + // Notification + qInfo() << qPrintable(QString("Indexed %1 applications.").arg(index.size())); + emit q->statusInfo(QString("%1 applications indexed.").arg(index.size())); + + if ( rerun ) { + startIndexing(); + rerun = false; + } +} + +/** ***************************************************************************/ +vector> Applications::Private::indexApplications() const { + + // Get a new index [O(n)] + vector> desktopEntries; + QStringList xdg_current_desktop = QString(getenv("XDG_CURRENT_DESKTOP")).split(':',QString::SkipEmptyParts); + QLocale loc; + QStringList xdgAppDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); + + // Iterate over all desktop files + for ( const QString &dir : xdgAppDirs ) { + QDirIterator fIt(dir, QStringList("*.desktop"), QDir::Files, + QDirIterator::Subdirectories|QDirIterator::FollowSymlinks); + while (fIt.hasNext()) { + fIt.next(); + + map> sectionMap; + map>::iterator sectionIterator; + + // Build the id + + QString id; + + // If file is in standard path use standard method else filename to build id + if ( std::any_of(xdgAppDirs.begin(), xdgAppDirs.end(), + [&fIt](const QString &dir){ return fIt.filePath().startsWith(dir); }) ) + id = fIt.filePath().remove(QRegularExpression("^.*applications/")).replace("/","-"); + else + id = fIt.fileName(); + + // Skip duplicate ids + if ( std::find_if(desktopEntries.begin(), desktopEntries.end(), + [&id](const shared_ptr & desktopEntry){ + return id == desktopEntry->id(); + }) != desktopEntries.end()) + continue; + + /* + * Get the data from the desktop file + */ + + // Read the file into a map + { + QFile file(fIt.filePath()); + if (!file.open(QIODevice::ReadOnly| QIODevice::Text)) continue; + QTextStream stream(&file); + QString currentGroup; + for (QString line=stream.readLine(); !line.isNull(); line=stream.readLine()) { + line = line.trimmed(); + if (line.startsWith('#') || line.isEmpty()) + continue; + if (line.startsWith("[")){ + currentGroup = line.mid(1,line.size()-2).trimmed(); + continue; + } + sectionMap[currentGroup].emplace(line.section('=', 0,0).trimmed(), + line.section('=', 1, -1).trimmed()); + } + file.close(); + } + + + // Skip if there is no "Desktop Entry" section + if ((sectionIterator = sectionMap.find("Desktop Entry")) == sectionMap.end()) + continue; + + map const &entryMap = sectionIterator->second; + map::const_iterator entryIterator; + + // Skip, if type is not found or not application + if ((entryIterator = entryMap.find("Type")) == entryMap.end() || + entryIterator->second != "Application") + continue; + + // Skip, if this desktop entry must not be shown + if ((entryIterator = entryMap.find("NoDisplay")) != entryMap.end() + && entryIterator->second == "true") + continue; + + if (!ignoreShowInKeys) { + // Skip if the current desktop environment is specified in "NotShowIn" + if ((entryIterator = entryMap.find("NotShowIn")) != entryMap.end()) + for (const QString &str : entryIterator->second.split(';',QString::SkipEmptyParts)) + if (xdg_current_desktop.contains(str)) + continue; + + // Skip if the current desktop environment is not specified in "OnlyShowIn" + if ((entryIterator = entryMap.find("OnlyShowIn")) != entryMap.end()) { + bool found = false; + for (const QString &str : entryIterator->second.split(';',QString::SkipEmptyParts)) + if (xdg_current_desktop.contains(str)){ + found = true; + break; + } + if (!found) + continue; + } + } + + bool term; + QString name; + QString genericName; + QString comment; + QString icon; + QString exec; + QString workingDir; + QStringList keywords; + QStringList actionIdentifiers; + + // Try to get the localized name, skip if empty + name = xdgStringEscape(getLocalizedKey("Name", entryMap, loc)); + if (name.isNull()) + continue; + + // Try to get the exec key, skip if not existant + if ((entryIterator = entryMap.find("Exec")) != entryMap.end()) + exec = xdgStringEscape(entryIterator->second); + else + continue; + + // Try to get the localized icon, skip if empty + icon = xdgStringEscape(getLocalizedKey("Icon", entryMap, loc)); + if (icon.isNull()) + continue; + + // Check if this is a terminal app + term = (entryIterator = entryMap.find("Terminal")) != entryMap.end() + && entryIterator->second=="true"; + + // Try to get the localized genericName + genericName = xdgStringEscape(getLocalizedKey("GenericName", entryMap, loc)); + + // Try to get the localized comment + comment = xdgStringEscape(getLocalizedKey("Comment", entryMap, loc)); + + // Try to get the keywords + keywords = xdgStringEscape(getLocalizedKey("Keywords", entryMap, loc)).split(';',QString::SkipEmptyParts); + + // Try to get the workindir + if ((entryIterator = entryMap.find("Path")) != entryMap.end()) + workingDir = xdgStringEscape(entryIterator->second); + + // Try to get the keywords + if ((entryIterator = entryMap.find("Actions")) != entryMap.end()) + actionIdentifiers = xdgStringEscape(entryIterator->second).split(';',QString::SkipEmptyParts); + +// // Try to get the mimetypes +// if ((valueIterator = entryMap.find("MimeType")) != entryMap.end()) +// keywords = xdgStringEscape(valueIterator->second).split(';',QString::SkipEmptyParts); + + /* + * Default action + */ + + vector> actions; + + // Unquote arguments and expand field codes + QStringList commandline = expandedFieldCodes(Core::ShUtil::split(exec), + icon, + name, + fIt.filePath()); + // Malformed exec line. Constraint (1) + if (commandline.isEmpty()) + continue; + + shared_ptr sa = std::make_shared(); + sa->setText(QString("Run '%1'").arg(name)); + if (term){ + sa->setAction([commandline, workingDir](){ + QStringList arguments = Core::ShUtil::split(terminalCommand); + arguments.append(commandline); + QString command = arguments.takeFirst(); + QProcess::startDetached(command, arguments, workingDir); + }); + } else { + sa->setAction([commandline, workingDir](){ + QStringList arguments = commandline; + QString command = arguments.takeFirst(); + QProcess::startDetached(command, arguments, workingDir); + }); + } + + actions.push_back(sa); + + + /* + * Root action + */ + + if (term){ + sa = std::make_shared(); + sa->setText(QString("Run '%1' as root").arg(name)); + sa->setAction([commandline, workingDir](){ + QStringList arguments = Core::ShUtil::split(terminalCommand); + arguments.append(QString("sudo %1").arg(commandline.join(' '))); + QString command = arguments.takeFirst(); + QProcess::startDetached(command, arguments, workingDir); + }); + actions.push_back(sa); + } + else if ( !graphicalSudoPath.isNull() ) { + sa = std::make_shared(); + sa->setText(QString("Run '%1' as root").arg(name)); + sa->setAction([=](){ + QProcess::startDetached(graphicalSudoPath, commandline, workingDir); + }); + actions.push_back(sa); + } + + + /* + * Desktop Actions + */ + + for (const QString &actionIdentifier: actionIdentifiers){ + + sa = std::make_shared(); + + // Get iterator to action section + if ((sectionIterator = sectionMap.find(QString("Desktop Action %1").arg(actionIdentifier))) == sectionMap.end()) + continue; + map &valueMap = sectionIterator->second; + + // Try to get the localized action name + QString actionName = xdgStringEscape(getLocalizedKey("Name", valueMap, loc)); + if (actionName.isNull()) + continue; + sa->setText(actionName); + + // Get action command + if ((entryIterator = valueMap.find("Exec")) == valueMap.end()) + continue; + + // Unquote arguments and expand field codes + QStringList commandline = expandedFieldCodes(Core::ShUtil::split(entryIterator->second), + icon, + name, + fIt.filePath()); + + if (term){ + sa->setAction([commandline, workingDir](){ + QStringList arguments = Core::ShUtil::split(terminalCommand); + arguments.append(commandline); + QString command = arguments.takeFirst(); + QProcess::startDetached(command, arguments, workingDir); + }); + } else { + sa->setAction([commandline, workingDir](){ + QStringList arguments = commandline; + QString command = arguments.takeFirst(); + QProcess::startDetached(command, arguments, workingDir); + }); + } + actions.push_back(sa); + } + + + /* + * Build the item + */ + + // Finally we got everything, build the item + shared_ptr ssii = std::make_shared(id); + + // Set Name + ssii->setText(name); + + // Set subtext/tootip + if (comment.isEmpty()) + if (genericName.isEmpty()) + ssii->setSubtext(exec); + else + ssii->setSubtext(genericName); + else + ssii->setSubtext(comment); + + // Set icon + icon = XDG::IconLookup::iconPath({icon, "exec"}); + ssii->setIconPath(icon.isEmpty() ? ":application-x-executable" : icon); + + // Set keywords + vector indexStrings; + indexStrings.emplace_back(name, UINT_MAX); + + if ( !exec.startsWith("java ") + && !exec.startsWith("ruby ") + && !exec.startsWith("python ") + && !exec.startsWith("perl ") + && !exec.startsWith("bash ") + && !exec.startsWith("sh ") + && !exec.startsWith("dbus-send ") + && !exec.startsWith("/") ) + indexStrings.emplace_back(commandline[0], UINT_MAX); // safe since (1) + + for (auto & kw : keywords) + indexStrings.emplace_back(kw, UINT_MAX); + + if (!genericName.isEmpty()) + indexStrings.emplace_back(genericName, UINT_MAX*0.7); + + ssii->setIndexKeywords(std::move(indexStrings)); + + // Set actions + ssii->setActions(std::move(actions)); + + desktopEntries.push_back(std::move(ssii)); + } + } + return desktopEntries; +} + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +Applications::Extension::Extension() + : Core::Extension("org.albert.extension.applications"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private(this)) { + + registerQueryHandler(this); + + qunsetenv("DESKTOP_AUTOSTART_ID"); + + d->graphicalSudoPath = QStandardPaths::findExecutable("gksudo"); + + // Load settings + d->offlineIndex.setFuzzy(settings().value(CFG_FUZZY, DEF_FUZZY).toBool()); + d->ignoreShowInKeys = settings().value(CFG_IGNORESHOWINKEYS, DEF_IGNORESHOWINKEYS).toBool(); + + // If the filesystem changed, trigger the scan + connect(&d->watcher, &QFileSystemWatcher::directoryChanged, + std::bind(&Private::startIndexing, d.get())); + + // Trigger initial update + updateIndex(); +} + + + +/** ***************************************************************************/ +Applications::Extension::~Extension() { + d->futureWatcher.waitForFinished(); +} + + + +/** ***************************************************************************/ +QWidget *Applications::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + + // Fuzzy + d->widget->ui.checkBox_fuzzy->setChecked(d->offlineIndex.fuzzy()); + connect(d->widget->ui.checkBox_fuzzy, &QCheckBox::toggled, + this, &Extension::setFuzzy); + + // Ignore onlyshowin notshowin keys + d->widget->ui.checkBox_ignoreShowInKeys->setChecked(d->ignoreShowInKeys); + connect(d->widget->ui.checkBox_ignoreShowInKeys, &QCheckBox::toggled, + this, [this](bool checked){ + settings().setValue(CFG_IGNORESHOWINKEYS, checked); + d->ignoreShowInKeys = checked ; + d->startIndexing(); + }); + + // Status bar + ( d->futureWatcher.isRunning() ) + ? d->widget->ui.label_statusbar->setText("Indexing applications ...") + : d->widget->ui.label_statusbar->setText(QString("%1 applications indexed.").arg(d->index.size())); + connect(this, &Extension::statusInfo, d->widget->ui.label_statusbar, &QLabel::setText); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void Applications::Extension::handleQuery(Core::Query * query) const { + + const vector> &indexables = d->offlineIndex.search(query->string()); + + vector,uint>> results; + for (const shared_ptr &item : indexables) + results.emplace_back(std::static_pointer_cast(item), 1); + + query->addMatches(std::make_move_iterator(results.begin()), + std::make_move_iterator(results.end())); +} + + + +/** ***************************************************************************/ +bool Applications::Extension::fuzzy() { + return d->offlineIndex.fuzzy(); +} + + + +/** ***************************************************************************/ +void Applications::Extension::setFuzzy(bool b) { + settings().setValue(CFG_FUZZY, b); + d->offlineIndex.setFuzzy(b); +} + + + +/** ***************************************************************************/ +void Applications::Extension::updateIndex() { + d->startIndexing(); +} diff -Nru albert-0.12.0/plugins/applications/src/extension.h albert-0.13.1+plugins1/plugins/applications/src/extension.h --- albert-0.12.0/plugins/applications/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/applications/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,57 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace Applications { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Applications"; } + QWidget *widget(QWidget *parent = nullptr) override; + void handleQuery(Core::Query * query) const override; + + bool fuzzy(); + void setFuzzy(bool b = true); + + void updateIndex(); + +private: + + std::unique_ptr d; + +signals: + + void statusInfo(const QString&); + +}; +} diff -Nru albert-0.12.0/plugins/calculator/calculator.qrc albert-0.13.1+plugins1/plugins/calculator/calculator.qrc --- albert-0.12.0/plugins/calculator/calculator.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/calculator.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/calc.svg + + diff -Nru albert-0.12.0/plugins/calculator/CMakeLists.txt albert-0.13.1+plugins1/plugins/calculator/CMakeLists.txt --- albert-0.12.0/plugins/calculator/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(calculator) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore + muparser + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/calculator/metadata.json albert-0.13.1+plugins1/plugins/calculator/metadata.json --- albert-0.12.0/plugins/calculator/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.calculator", + "name" : "Calculator", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : ["libmuparser"], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/calculator/resources/calc.svg albert-0.13.1+plugins1/plugins/calculator/resources/calc.svg --- albert-0.12.0/plugins/calculator/resources/calc.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/resources/calc.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/calculator/src/configwidget.cpp albert-0.13.1+plugins1/plugins/calculator/src/configwidget.cpp --- albert-0.12.0/plugins/calculator/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,23 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +Calculator::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + diff -Nru albert-0.12.0/plugins/calculator/src/configwidget.h albert-0.13.1+plugins1/plugins/calculator/src/configwidget.h --- albert-0.12.0/plugins/calculator/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,31 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace Calculator { + +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + Ui::ConfigWidget ui; +}; + +} diff -Nru albert-0.12.0/plugins/calculator/src/configwidget.ui albert-0.13.1+plugins1/plugins/calculator/src/configwidget.ui --- albert-0.12.0/plugins/calculator/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,40 @@ + + + Calculator::ConfigWidget + + + + + + <html><head/><body><p>This is a simple calculator extension. It lets you evaluate basic math expressions. Check the <a href="https://albertlauncher.github.io/docs/extensions/calculator/"><span style=" text-decoration: underline; color:#0000ff;">docs</span></a> for built-in fuctions and operators.</p></body></html> + + + true + + + + + + + Show group separators + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/calculator/src/extension.cpp albert-0.13.1+plugins1/plugins/calculator/src/extension.cpp --- albert-0.12.0/plugins/calculator/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,145 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "muParser.h" +#include "core/query.h" +#include "util/standarditem.h" +#include "util/standardaction.h" +#include "xdg/iconlookup.h" +using std::vector; +using std::shared_ptr; +using namespace Core; + + + +namespace { +const QString CFG_SEPS = "group_separators"; +const bool CFG_SEPS_DEF = false; +} + + + +class Calculator::Private +{ +public: + QPointer widget; + std::unique_ptr parser; + QLocale locale; + QString iconPath; +}; + + + +/** ***************************************************************************/ +Calculator::Extension::Extension() + : Core::Extension("org.albert.extension.calculator"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private){ + + registerQueryHandler(this); + + // FIXME Qt6 Workaround for https://bugreports.qt.io/browse/QTBUG-58504 + d->locale = QLocale(QLocale::system().name()); + + // Load settings + d->locale.setNumberOptions( + (settings().value(CFG_SEPS, CFG_SEPS_DEF).toBool()) + ? d->locale.numberOptions() & ~QLocale::OmitGroupSeparator + : d->locale.numberOptions() | QLocale::OmitGroupSeparator ); + + QString iconPath = XDG::IconLookup::iconPath("calc"); + d->iconPath = iconPath.isNull() ? ":calc" : iconPath; + + d->parser.reset(new mu::Parser); + d->parser->SetDecSep(d->locale.decimalPoint().toLatin1()); + d->parser->SetThousandsSep(d->locale.groupSeparator().toLatin1()); +} + + + +/** ***************************************************************************/ +Calculator::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *Calculator::Extension::widget(QWidget *parent) { + if (d->widget.isNull()){ + d->widget = new ConfigWidget(parent); + + d->widget->ui.checkBox_groupsep->setChecked(!(d->locale.numberOptions() & QLocale::OmitGroupSeparator)); + connect(d->widget->ui.checkBox_groupsep, &QCheckBox::toggled, [this](bool checked){ + settings().setValue(CFG_SEPS, checked); + d->locale.setNumberOptions( (checked) ? d->locale.numberOptions() & ~QLocale::OmitGroupSeparator + : d->locale.numberOptions() | QLocale::OmitGroupSeparator ); + }); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void Calculator::Extension::handleQuery(Core::Query * query) const { + + d->parser->SetExpr(query->string().toStdString()); + QString result; + + // http://beltoforion.de/article.php?a=muparser&p=errorhandling + try { + result = d->locale.toString(d->parser->Eval(), 'G', 16); + } catch (mu::Parser::exception_type &) { + return; + } + + // Build actions + vector> actions; + shared_ptr action = std::make_shared(); + action->setText(QString("Copy '%1' to clipboard").arg(result)); + action->setAction([=](){ QApplication::clipboard()->setText(result); }); + actions.push_back(action); + + // Make searchterm a lvalue that can be captured by the lambda + QString text = query->string(); + action = std::make_shared(); + action->setText(QString("Copy '%1' to clipboard").arg(text)); + action->setAction([=](){ QApplication::clipboard()->setText(text); }); + actions.push_back(action); + + text = QString("%1 = %2").arg(query->string(), result); + action = std::make_shared(); + action->setText(QString("Copy '%1' to clipboard").arg(text)); + action->setAction([=](){ QApplication::clipboard()->setText(text); }); + actions.push_back(action); + + shared_ptr calcItem = std::make_shared("muparser-eval"); + calcItem->setText(result); + calcItem->setSubtext(QString("Result of '%1'").arg(query->string())); + calcItem->setIconPath(d->iconPath); + calcItem->setActions(std::move(actions)); + + query->addMatch(std::move(calcItem), UINT_MAX); +} diff -Nru albert-0.12.0/plugins/calculator/src/extension.h albert-0.13.1+plugins1/plugins/calculator/src/extension.h --- albert-0.12.0/plugins/calculator/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/calculator/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace Calculator { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Calculator"; } + QWidget *widget(QWidget *parent = nullptr) override; + void handleQuery(Core::Query * query) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/chromebookmarks/chromebookmarks.qrc albert-0.13.1+plugins1/plugins/chromebookmarks/chromebookmarks.qrc --- albert-0.12.0/plugins/chromebookmarks/chromebookmarks.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/chromebookmarks.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/favicon.png + + diff -Nru albert-0.12.0/plugins/chromebookmarks/CMakeLists.txt albert-0.13.1+plugins1/plugins/chromebookmarks/CMakeLists.txt --- albert-0.12.0/plugins/chromebookmarks/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(chromebookmarks) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Concurrent) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/chromebookmarks/metadata.json albert-0.13.1+plugins1/plugins/chromebookmarks/metadata.json --- albert-0.12.0/plugins/chromebookmarks/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.chromebookmarks", + "name" : "Chrome bookmarks", + "version" : "1.0", + "platform" : "Linux", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": false +} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/chromebookmarks/resources/favicon.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/chromebookmarks/resources/favicon.png differ diff -Nru albert-0.12.0/plugins/chromebookmarks/src/configwidget.cpp albert-0.13.1+plugins1/plugins/chromebookmarks/src/configwidget.cpp --- albert-0.12.0/plugins/chromebookmarks/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,39 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "configwidget.h" + +/** ***************************************************************************/ +ChromeBookmarks::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); + + connect(ui.pushButton_editPath, &QPushButton::clicked, + this, &ConfigWidget::onButton_EditPath); +} + +/** ***************************************************************************/ +ChromeBookmarks::ConfigWidget::~ConfigWidget() { + +} + +/** ***************************************************************************/ +void ChromeBookmarks::ConfigWidget::onButton_EditPath() { + QString path = QFileDialog::getOpenFileName(this, tr("Choose path")); + if(path.isEmpty()) return; + emit requestEditPath(path); +} diff -Nru albert-0.12.0/plugins/chromebookmarks/src/configwidget.h albert-0.13.1+plugins1/plugins/chromebookmarks/src/configwidget.h --- albert-0.12.0/plugins/chromebookmarks/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,37 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace ChromeBookmarks { + +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; + +private: + void onButton_EditPath(); + +signals: + void requestEditPath(const QString&); +}; +} diff -Nru albert-0.12.0/plugins/chromebookmarks/src/configwidget.ui albert-0.13.1+plugins1/plugins/chromebookmarks/src/configwidget.ui --- albert-0.12.0/plugins/chromebookmarks/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,95 @@ + + + ChromeBookmarks::ConfigWidget + + + + + + Path to bookmarkfile + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + + + + + Fuzzy + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 50 + 0 + + + + Edit + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/chromebookmarks/src/extension.cpp albert-0.13.1+plugins1/plugins/chromebookmarks/src/extension.cpp --- albert-0.12.0/plugins/chromebookmarks/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,355 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "core/indexable.h" +#include "core/query.h" +#include "util/standardaction.h" +#include "util/standardindexitem.h" +#include "util/offlineindex.h" +#include "xdg/iconlookup.h" +using std::shared_ptr; +using std::vector; +using std::pair; +using namespace Core; + +namespace { + +const char* CFG_PATH = "bookmarkfile"; +const char* CFG_FUZZY = "fuzzy"; +const bool DEF_FUZZY = false; + +/** ***************************************************************************/ +vector> indexChromeBookmarks(const QString &bookmarksPath) { + + // Build a new index + vector> bookmarks; + + // Define a recursive bookmark indexing lambda + std::function rec_bmsearch = + [&rec_bmsearch, &bookmarks](const QJsonObject &json) { + QJsonValue type = json["type"]; + if (type == QJsonValue::Undefined) + return; + if (type.toString() == "folder"){ + QJsonArray jarr = json["children"].toArray(); + for (const QJsonValue &i : jarr) + rec_bmsearch(i.toObject()); + } + if (type.toString() == "url") { + QString name = json["name"].toString(); + QString urlstr = json["url"].toString(); + + shared_ptr ssii = std::make_shared(json["id"].toString()); + ssii->setText(name); + ssii->setSubtext(urlstr); + QString icon = XDG::IconLookup::iconPath({"www", "web-browser", "emblem-web"}); + ssii->setIconPath((icon.isEmpty()) ? ":favicon" : icon); + + vector indexStrings; + QUrl url(urlstr); + QString host = url.host(); + indexStrings.emplace_back(name, UINT_MAX); + indexStrings.emplace_back(host.left(host.size()-url.topLevelDomain().size()), UINT_MAX/2); + ssii->setIndexKeywords(std::move(indexStrings)); + + vector> actions; + shared_ptr action = std::make_shared(); + action->setText("Open URL in your browser"); + action->setAction([urlstr](){ + QDesktopServices::openUrl(QUrl(urlstr)); + }); + actions.push_back(std::move(action)); + + action = std::make_shared(); + action->setText("Copy URL to clipboard"); + action->setAction([urlstr](){ + QApplication::clipboard()->setText(urlstr); + }); + actions.push_back(std::move(action)); + + ssii->setActions(std::move(actions)); + + bookmarks.push_back(std::move(ssii)); + } + }; + + QFile f(bookmarksPath); + if (!f.open(QIODevice::ReadOnly)) { + qWarning() << qPrintable(QString("Could not open Chrome bookmarks file '%1'.").arg(bookmarksPath)); + return vector>(); + } + + QJsonObject json = QJsonDocument::fromJson(f.readAll()).object(); + QJsonObject roots = json.value("roots").toObject(); + for (const QJsonValue &i : roots) + if (i.isObject()) + rec_bmsearch(i.toObject()); + + f.close(); + + return bookmarks; +} + +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +class ChromeBookmarks::Private +{ +public: + Private(Extension *q) : q(q) {} + + Extension *q; + + QPointer widget; + QFileSystemWatcher fileSystemWatcher; + QString bookmarksFile; + + vector> index; + Core::OfflineIndex offlineIndex; + QFutureWatcher>> futureWatcher; + + void finishIndexing(); + void startIndexing(); +}; + + + +/** ***************************************************************************/ +void ChromeBookmarks::Private::startIndexing() { + + // Never run concurrent + if ( futureWatcher.future().isRunning() ) + return; + + // Run finishIndexing when the indexing thread finished + futureWatcher.disconnect(); + QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, + std::bind(&Private::finishIndexing, this)); + + // Run the indexer thread + futureWatcher.setFuture(QtConcurrent::run(indexChromeBookmarks, bookmarksFile)); + + // Notification + qInfo() << "Start indexing Chrome bookmarks."; + emit q->statusInfo("Indexing bookmarks ..."); + +} + + + +/** ***************************************************************************/ +void ChromeBookmarks::Private::finishIndexing() { + + // Get the thread results + index = futureWatcher.future().result(); + + // Rebuild the offline index + offlineIndex.clear(); + for (const auto &item : index) + offlineIndex.add(item); + + /* + * Finally update the watches (maybe folders changed) + * Note that QFileSystemWatcher stops monitoring files once they have been + * renamed or removed from disk, and directories once they have been removed + * from disk. + * Chromium seems to mv the file (inode change). + */ + if ( fileSystemWatcher.files().empty() ) + if( !fileSystemWatcher.addPath(bookmarksFile)) + qWarning() << qPrintable(QString("%1 can not be watched. Changes in this path will not be noticed.").arg(bookmarksFile)); + + // Notification + qInfo() << qPrintable(QString("Indexed %1 Chrome bookmarks.").arg(index.size())); + emit q->statusInfo(QString("%1 bookmarks indexed.").arg(index.size())); +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +ChromeBookmarks::Extension::Extension() + : Core::Extension("org.albert.extension.chromebookmarks"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private(this)) { + + registerQueryHandler(this); + + // Load settings + d->offlineIndex.setFuzzy(settings().value(CFG_FUZZY, DEF_FUZZY).toBool()); + + // Load and set a valid path + QVariant v = settings().value(CFG_PATH); + if (v.isValid() && v.canConvert(QMetaType::QString) && QFileInfo(v.toString()).exists()) + setPath(v.toString()); + else + restorePath(); + + // If the path changed write it to the settings + connect(this, &Extension::pathChanged, [this](const QString& path){ + settings().setValue(CFG_PATH, path); + }); + + // Update index if bookmark file changed + connect(&d->fileSystemWatcher, &QFileSystemWatcher::fileChanged, + this, &Extension::updateIndex); + + // Update index if bookmark file's path changed + connect(this, &Extension::pathChanged, + this, &Extension::updateIndex); + + // Trigger an initial update + updateIndex(); +} + + + +/** ***************************************************************************/ +ChromeBookmarks::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *ChromeBookmarks::Extension::widget(QWidget *parent) { + if (d->widget.isNull()){ + d->widget = new ConfigWidget(parent); + + // Paths + d->widget->ui.lineEdit_path->setText(d->bookmarksFile); + connect(d->widget.data(), &ConfigWidget::requestEditPath, this, &Extension::setPath); + connect(this, &Extension::pathChanged, d->widget->ui.lineEdit_path, &QLineEdit::setText); + + // Fuzzy + d->widget->ui.checkBox_fuzzy->setChecked(fuzzy()); + connect(d->widget->ui.checkBox_fuzzy, &QCheckBox::toggled, this, &Extension::setFuzzy); + + // Status bar + ( d->futureWatcher.isRunning() ) + ? d->widget->ui.label_statusbar->setText("Indexing bookmarks ...") + : d->widget->ui.label_statusbar->setText(QString("%1 bookmarks indexed.").arg(d->index.size())); + connect(this, &Extension::statusInfo, d->widget->ui.label_statusbar, &QLabel::setText); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void ChromeBookmarks::Extension::handleQuery(Core::Query * query) const { + + const vector> &indexables = d->offlineIndex.search(query->string()); + + vector,uint>> results; + for (const shared_ptr &item : indexables) + results.emplace_back(std::static_pointer_cast(item), 0); + + query->addMatches(std::make_move_iterator(results.begin()), + std::make_move_iterator(results.end())); +} + + + +/** ***************************************************************************/ +const QString &ChromeBookmarks::Extension::path() { + return d->bookmarksFile; +} + + + +/** ***************************************************************************/ +void ChromeBookmarks::Extension::setPath(const QString &path) { + + QFileInfo fi(path); + if (!(fi.exists() && fi.isFile())) + return; + + d->bookmarksFile = path; + + emit pathChanged(path); +} + + + +/** ***************************************************************************/ +void ChromeBookmarks::Extension::restorePath() { + // Find a bookmark file (Take first one) + for (const QString &browser : {"chromium","google-chrome"}){ + QString root = QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)).filePath(browser); + QDirIterator it(root, {"Bookmarks"}, QDir::Files, QDirIterator::Subdirectories); + while (it.hasNext()) { + setPath(it.next()); + return; + } + } +} + + + +/** ***************************************************************************/ +bool ChromeBookmarks::Extension::fuzzy() { + return d->offlineIndex.fuzzy(); +} + + + +/** ***************************************************************************/ +void ChromeBookmarks::Extension::updateIndex() { + d->startIndexing(); +} + + + +/** ***************************************************************************/ +void ChromeBookmarks::Extension::setFuzzy(bool b) { + settings().setValue(CFG_FUZZY, b); + d->offlineIndex.setFuzzy(b); +} + diff -Nru albert-0.12.0/plugins/chromebookmarks/src/extension.h albert-0.13.1+plugins1/plugins/chromebookmarks/src/extension.h --- albert-0.12.0/plugins/chromebookmarks/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/chromebookmarks/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,62 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace ChromeBookmarks { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Chrome bookmarks"; } + QWidget *widget(QWidget *parent = nullptr) override; + void handleQuery(Core::Query * query) const override; + + const QString &path(); + void setPath(const QString &path); + void restorePath(); + + bool fuzzy(); + void setFuzzy(bool b = true); + + void updateIndex(); + +private: + + std::unique_ptr d; + +signals: + + void pathChanged(const QString&); + void statusInfo(const QString&); + +}; +} diff -Nru albert-0.12.0/plugins/CMakeLists.txt albert-0.13.1+plugins1/plugins/CMakeLists.txt --- albert-0.12.0/plugins/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,104 @@ +# Do not export symbols by default +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) + +# Set the RPATH for the library lookup +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/albert") + + + +# FrontendPlugins + +option(BUILD_WIDGETBOXMODEL "Build the frontend" ON) +if (BUILD_WIDGETBOXMODEL) + add_subdirectory(widgetboxmodel) +endif() + +option(BUILD_QMLBOXMODEL "Build the frontend" ON) +if (BUILD_QMLBOXMODEL) + add_subdirectory(qmlboxmodel) +endif() + + + +# ExtensionPlugins + +option(BUILD_APPLICATIONS "Build the extension" ON) +if (BUILD_APPLICATIONS) + add_subdirectory(applications) +endif() + +option(BUILD_CALCULATOR "Build the extension" ON) +if (BUILD_CALCULATOR) + add_subdirectory(calculator) +endif() + +option(BUILD_CHROMEBOOKMARKS "Build the extension" ON) +if (BUILD_CHROMEBOOKMARKS) + add_subdirectory(chromebookmarks) +endif() + +option(BUILD_EXTERNALEXTENSIONS "Build the extension" ON) +if (BUILD_EXTERNALEXTENSIONS) + add_subdirectory(externalextensions) +endif() + +option(BUILD_DEBUG "Build the extension" OFF) +if (BUILD_DEBUG) + add_subdirectory(debug) +endif() + +option(BUILD_FILES "Build the extension" ON) +if (BUILD_FILES) + add_subdirectory(files) +endif() + +option(BUILD_FIREFOXBOOKMARKS "Build the extension" ON) +if (BUILD_FIREFOXBOOKMARKS) + add_subdirectory(firefoxbookmarks) +endif() + +option(BUILD_HASHGENERATOR "Build the extension" ON) +if (BUILD_HASHGENERATOR) + add_subdirectory(hashgenerator) +endif() + +option(BUILD_KVSTORE "Build the extension" ON) +if (BUILD_KVSTORE) + add_subdirectory(kvstore) +endif() + +option(BUILD_MPRIS "Build the extension" ON) +if (BUILD_MPRIS) + add_subdirectory(mpris) +endif() + +option(BUILD_SSH "Build the extension" ON) +if (BUILD_SSH) + add_subdirectory(ssh) +endif() + +option(BUILD_SYSTEM "Build the extension" ON) +if (BUILD_SYSTEM) + add_subdirectory(system) +endif() + +option(BUILD_TEMPLATE "Build the extension" OFF) +if (BUILD_TEMPLATE) + add_subdirectory(templateExtension) +endif() + +option(BUILD_TERMINAL "Build the extension" ON) +if (BUILD_TERMINAL) + add_subdirectory(terminal) +endif() + +option(BUILD_VIRTUALBOX "Build the extension" ON) +if (BUILD_VIRTUALBOX) + add_subdirectory(virtualbox) +endif() + +option(BUILD_WEBSEARCH "Build the extension" ON) +if (BUILD_WEBSEARCH) + add_subdirectory(websearch) +endif() diff -Nru albert-0.12.0/plugins/create_plugin.py albert-0.13.1+plugins1/plugins/create_plugin.py --- albert-0.12.0/plugins/create_plugin.py 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/create_plugin.py 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,128 @@ +#!/usr/bin/python + +import os +import re +import sys +import string +from shutil import copyfile + +ID_KEYWORD = "projectid" +NAMESPACE_KEYWORD = "ProjectNamespace" +PRETTYNAME_KEYWORD = "Template" +ID_PATTERN = "^([a-z0-9]+)$" +NAMESPACE_PATTERN = "^([A-Za-z][A-Za-z0-9]+)$" +PRETTYNAME_PATTERN = "^([A-Za-z0-9 _\\-]+)$" +TEMPLATE_EXTENSION_BASE = "templateExtension/" +CMAKE_PATTERN = "^add_subdirectory\(([^\)]+)\)$" + +if len(sys.argv) != 4: + u = "Usage: create_plugin.py \n" + sys.stderr.write(u) + sys.exit(1) + +id_regex = re.compile(ID_PATTERN) +namespace_regex = re.compile(NAMESPACE_PATTERN) +prettyname_regex = re.compile(PRETTYNAME_PATTERN) +cmake_regex = re.compile(CMAKE_PATTERN) + +id_string = sys.argv[1] +namespace_string = sys.argv[2] +prettyname_string = sys.argv[3] + +if not id_regex.match(id_string): + e = "ID has to match " + ID_PATTERN + "\n" + sys.stderr.write(e) + sys.exit(1) + +if not namespace_regex.match(namespace_string): + e = "Namespace has to match " + NAMESPACE_PATTERN + "\n" + sys.stderr.write(e) + sys.exit(1) + +if not prettyname_regex.match(prettyname_string): + e = "Pretty Name has to match " + PRETTYNAME_PATTERN + "\n" + sys.stderr.write(e) + sys.exit(1) + +raw_input("Are we in the src/plugins directory? If not do not proceed because it won't work! ") + +print("Creating directory . . .") +os.mkdir(id_string) +os.chdir(id_string) + +baseDir = os.path.join("..", TEMPLATE_EXTENSION_BASE) +filesToPrepare = [] + +def scanDir(toscan): + global filesToPrepare + global baseDir + if toscan: + template = os.path.join(baseDir, toscan) + else: + template = baseDir + ext = toscan + files = os.listdir(template) + for nextFile in files: + path = os.path.join(template, nextFile) + pathNew = os.path.join(ext, nextFile) + if os.path.isdir(path): + print("Creating directory " + pathNew) + os.mkdir(pathNew) + scanDir(os.path.join(toscan, nextFile)) + else: + print("Copying file " + pathNew) + copyfile(path, pathNew) + filesToPrepare.append(pathNew) + +scanDir("") + +for localFile in filesToPrepare: + print("Preparing file " + localFile) + with open(localFile) as fd: + tmpfile = localFile + ".tmp" + tmp = open(tmpfile, "w") + for line in fd: + tmp.write(re.sub(ID_KEYWORD, id_string, + re.sub(NAMESPACE_KEYWORD, namespace_string, + re.sub(PRETTYNAME_KEYWORD, prettyname_string, line)))) + tmp.close() + os.rename(tmpfile, localFile) + +print("Leaving directory . . .") +os.chdir("..") +print("Updating CMakeLists.txt . . . ") +existingExtensions = [] +preLines = [] +postLines = [] +preSubdir = True +postSubdir = False +with open("CMakeLists.txt", "r") as makelist: + for line in makelist: + match = cmake_regex.match(line) + if match: + preSubdir = False + existingExtensions.append(match.group(1)) + else: + postSubdir = not preSubdir + + if preSubdir: + preLines.append(line) + elif postSubdir: + postLines.append(line) + +existingExtensions.append(id_string) +existingExtensions.sort() + +cmakefile = open("CMakeLists.txt", "w") +for line in preLines: + cmakefile.write(line) # The newline is already in the line, because it didn't get stripped + +for ext in existingExtensions: + cmakefile.write("add_subdirectory(") + cmakefile.write(ext) + cmakefile.write(")\n") + +for line in postLines: + cmakefile.write(line) # The newline is already in the line, because it didn't get stripped + +cmakefile.close() diff -Nru albert-0.12.0/plugins/create_plugin.sh albert-0.13.1+plugins1/plugins/create_plugin.sh --- albert-0.12.0/plugins/create_plugin.sh 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/create_plugin.sh 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,47 @@ +#!/bin/bash + +usage(){ + echo "Usage:" + echo "$0 " +} + +if [ ! $# -eq 3 ]; then + usage + exit 1 +fi + +ID="$1" +NAMESPACE="$2" +PRETTY="$3" + +if [[ ! "$ID" =~ ^[a-z0-9]+$ ]]; then + echo -e "\e[31mid has to be alphanumeric and all lowercase\e[0m" + usage + exit 1 +fi + +if [[ ! "$NAMESPACE" =~ ^[A-Za-z][A-Za-z0-9]+$ ]]; then + echo -e "\e[31mNamespace id has to be alphanumeric and must not begin with a number\e[0m" + usage + exit 1 +fi + + +echo "Clone template" +cp -r "templateExtension" "$ID" + +echo "Adjust metadata.json" +sed -e "s/template/${ID}/" -e "s/Template/${PRETTY}/" "templateExtension/metadata.json" > "${ID}/metadata.json" + +echo "Adjust CMakeListss.txt" +sed -e "s/template/${ID}/" "templateExtension/CMakeLists.txt" > "${ID}/CMakeLists.txt" + +echo "Adjust namespaces" + + +for FILE in $( ls templateExtension | grep -e ".cpp$" -e ".h$" -e ".ui$" ); do + sed \ + -e "s/namespace Template/namespace ${NAMESPACE}/" \ + -e "s/Template::/${NAMESPACE}::/" \ + "templateExtension/${FILE}" > "${ID}/${FILE}" +done diff -Nru albert-0.12.0/plugins/debug/CMakeLists.txt albert-0.13.1+plugins1/plugins/debug/CMakeLists.txt --- albert-0.12.0/plugins/debug/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(debug) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/debug/debug.qrc albert-0.13.1+plugins1/plugins/debug/debug.qrc --- albert-0.12.0/plugins/debug/debug.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/debug.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/debug.png + + diff -Nru albert-0.12.0/plugins/debug/metadata.json albert-0.13.1+plugins1/plugins/debug/metadata.json --- albert-0.12.0/plugins/debug/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.debug", + "name" : "Debug", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": false +} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/debug/resources/debug.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/debug/resources/debug.png differ diff -Nru albert-0.12.0/plugins/debug/src/configwidget.cpp albert-0.13.1+plugins1/plugins/debug/src/configwidget.cpp --- albert-0.12.0/plugins/debug/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,41 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include "configwidget.h" + +Debug::ConfigWidget::ConfigWidget(Extension * extension, QWidget * parent) + : QWidget(parent), extension_(extension) +{ + ui.setupUi(this); + ui.spinBox_delay->setValue(extension_->delay()); + connect(ui.spinBox_delay, static_cast(&QSpinBox::valueChanged), + extension_, &Extension::setDelay); + + ui.spinBox_count->setValue(extension_->count()); + connect(ui.spinBox_count, static_cast(&QSpinBox::valueChanged), + extension_, &Extension::setCount); + + ui.groupBox_async->setChecked(extension_->async()); + connect(ui.groupBox_async, &QGroupBox::toggled, + extension_, &Extension::setAsync); + + ui.lineEdit_trigger->setText(extension_->trigger()); + connect(ui.lineEdit_trigger, &QLineEdit::textChanged, + extension_, &Extension::setTrigger); +} diff -Nru albert-0.12.0/plugins/debug/src/configwidget.h albert-0.13.1+plugins1/plugins/debug/src/configwidget.h --- albert-0.12.0/plugins/debug/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,38 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" +#include "extension.h" + +namespace Debug +{ +class ConfigWidget final : public QWidget +{ + Q_OBJECT + +public: + + explicit ConfigWidget(Extension * extension_, QWidget * parent = 0); + +private: + + Ui::ConfigWidget ui; + Extension * extension_; + +}; +} diff -Nru albert-0.12.0/plugins/debug/src/configwidget.ui albert-0.13.1+plugins1/plugins/debug/src/configwidget.ui --- albert-0.12.0/plugins/debug/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,113 @@ + + + Debug::ConfigWidget + + + + 0 + 0 + 800 + 600 + + + + + + + + + Trigger + + + + + + + dbg + + + + + + + + 0 + 0 + + + + Count of repeats + + + + + + + + 0 + 0 + + + + 1 + + + 1000000 + + + + + + + + + Asyn&chronous + + + true + + + + + + Delay in ms + + + + + + + 50 + + + 1000 + + + 50 + + + 100 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/debug/src/extension.cpp albert-0.13.1+plugins1/plugins/debug/src/extension.cpp --- albert-0.12.0/plugins/debug/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,172 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "core/query.h" +#include "util/standarditem.h" +using Core::StandardItem; + + +class Debug::Private +{ +public: + QPointer widget; + int delay; + int count; + bool async; + QString trigger; +}; + + + + +/** ***************************************************************************/ +Debug::Extension::Extension() + : Core::Extension("org.albert.extension.debug"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + d->delay = settings().value("delay", 50).toInt(); + d->count = settings().value("count", 100).toInt(); + d->async = settings().value("async", true).toBool(); + d->trigger = settings().value("trigger", "dbg").toString(); +} + + + +/** ***************************************************************************/ +Debug::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *Debug::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) + d->widget = new ConfigWidget(this, parent); + return d->widget; +} + + + +/** ***************************************************************************/ +QStringList Debug::Extension::triggers() const { + return {d->trigger}; +} + + + +/** ***************************************************************************/ +const QString& Debug::Extension::trigger() const { + return d->trigger; +} + + + +/** ***************************************************************************/ +void Debug::Extension::handleQuery(Core::Query * query) const { + + // This extension must run only triggered + if ( !query->isTriggered() ) + return; + + for (int i = 0 ; i < d->count; ++i){ + + if (d->async) + std::this_thread::sleep_for(std::chrono::milliseconds(d->delay)); + + if (!query->isValid()) + return; + + std::shared_ptr item = std::make_shared(QString::number(i)); + item->setText(QString("Das Item #%1").arg(i)); + item->setSubtext(QString("Toll, das Item #%1").arg(i)); + item->setIconPath(":debug"); + query->addMatch(std::move(item)); + } +} + + + +/** ***************************************************************************/ +Core::QueryHandler::ExecutionType Debug::Extension::executionType() const { + return ExecutionType::Realtime; +} + + + +/** ***************************************************************************/ +int Debug::Extension::count() const{ + return d->count; +} + + + +/** ***************************************************************************/ +void Debug::Extension::setCount(const int &count){ + settings().setValue("count", count); + d->count = count; +} + + + +/** ***************************************************************************/ +bool Debug::Extension::async() const{ + return d->async; +} + + + +/** ***************************************************************************/ +void Debug::Extension::setAsync(bool async){ + settings().setValue("async", async); + d->async = async; +} + + + +/** ***************************************************************************/ +int Debug::Extension::delay() const { + return d->delay; +} + + + +/** ***************************************************************************/ +void Debug::Extension::setDelay(const int &delay) { + settings().setValue("delay", delay); + d->delay = delay; +} + + + +/** ***************************************************************************/ +void Debug::Extension::setTrigger(const QString &trigger){ + settings().setValue("trigger", trigger); + d->trigger = trigger; +} + + diff -Nru albert-0.12.0/plugins/debug/src/extension.h albert-0.13.1+plugins1/plugins/debug/src/extension.h --- albert-0.12.0/plugins/debug/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/debug/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,62 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace Debug { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Debug"; } + QWidget *widget(QWidget *parent = nullptr) override; + QStringList triggers() const override; + void handleQuery(Core::Query * query) const override; + ExecutionType executionType() const override; + + int count() const; + void setCount(const int &count); + + bool async() const; + void setAsync(bool async); + + int delay() const; + void setDelay(const int &delay); + + const QString& trigger() const; + void setTrigger(const QString &trigger); + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/externalextensions/CMakeLists.txt albert-0.13.1+plugins1/plugins/externalextensions/CMakeLists.txt --- albert-0.12.0/plugins/externalextensions/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(externalextensions) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC}) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/externalextensions/metadata.json albert-0.13.1+plugins1/plugins/externalextensions/metadata.json --- albert-0.12.0/plugins/externalextensions/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.externalextensions", + "name" : "External extensions", + "version" : "0.3", + "platform" : "All", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": false +} diff -Nru albert-0.12.0/plugins/externalextensions/src/configwidget.cpp albert-0.13.1+plugins1/plugins/externalextensions/src/configwidget.cpp --- albert-0.12.0/plugins/externalextensions/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,31 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +ExternalExtensions::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); + ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui.tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); +} + + + +/** ***************************************************************************/ +ExternalExtensions::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/externalextensions/src/configwidget.h albert-0.13.1+plugins1/plugins/externalextensions/src/configwidget.h --- albert-0.12.0/plugins/externalextensions/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,32 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace ExternalExtensions { + +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; + +} diff -Nru albert-0.12.0/plugins/externalextensions/src/configwidget.ui albert-0.13.1+plugins1/plugins/externalextensions/src/configwidget.ui --- albert-0.12.0/plugins/externalextensions/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,57 @@ + + + ExternalExtensions::ConfigWidget + + + + + + <html> +<head/> +<body> +<p>External extensions allow the user to rapidly write custom extensions. External extensions are basically programs that follow a specific communication protocol. For the details see the <a href="https://albertlauncher.github.io/docs/extending/external/v3/">wiki</a>. The list below contains the extensions found on your system. +</p> +</body> +</html> + + + true + + + + + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + Qt::ElideLeft + + + false + + + false + + + false + + + true + + + false + + + + + + + + diff -Nru albert-0.12.0/plugins/externalextensions/src/extension.cpp albert-0.13.1+plugins1/plugins/externalextensions/src/extension.cpp --- albert-0.12.0/plugins/externalextensions/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,146 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "externalextension.h" +#include "externalextensionmodel.h" +using namespace std; + + +class ExternalExtensions::Private +{ +public: + std::vector> externalExtensions; + QFileSystemWatcher fileSystemWatcher; + QPointer widget; +}; + + +/** ***************************************************************************/ +ExternalExtensions::Extension::Extension() + : Core::Extension("org.albert.extension.externalextensions"), + d(new Private) { + + QString oldPath = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)).filePath("external"); + if (QFile::exists(oldPath)) + QFile::rename(oldPath, dataLocation().filePath("extensions")); + + if ( !dataLocation().exists("extensions") ) + dataLocation().mkdir("extensions"); + + connect(&d->fileSystemWatcher, &QFileSystemWatcher::fileChanged, + this, &Extension::reloadExtensions); + + connect(&d->fileSystemWatcher, &QFileSystemWatcher::directoryChanged, + this, &Extension::reloadExtensions); + + reloadExtensions(); +} + + + +/** ***************************************************************************/ +ExternalExtensions::Extension::~Extension() { + // Unregister + for ( auto & script : d->externalExtensions ) + if ( script->state() == ExternalExtension::State::Initialized ) + unregisterQueryHandler(script.get()); +} + + + +/** ***************************************************************************/ +QWidget *ExternalExtensions::Extension::widget(QWidget *parent) { + if (d->widget.isNull()){ + d->widget = new ConfigWidget(parent); + + ExternalExtensionsModel *model = new ExternalExtensionsModel(d->externalExtensions, d->widget->ui.tableView); + d->widget->ui.tableView->setModel(model); + + connect(d->widget->ui.tableView, &QTableView::activated, + model, &ExternalExtensionsModel::onActivated); + +// // Reset the widget when +// connect(this, &Extension::extensionsUpdated, +// d->widget->ui.tableView, &QTableView::reset); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void ExternalExtensions::Extension::reloadExtensions() { + + // Unregister + for ( auto & script : d->externalExtensions ) + if ( script->state() == ExternalExtension::State::Initialized ) + unregisterQueryHandler(script.get()); + + d->externalExtensions.clear(); + + // Remove all watches + if ( !d->fileSystemWatcher.files().isEmpty() ) + d->fileSystemWatcher.removePaths(d->fileSystemWatcher.files()); + if ( !d->fileSystemWatcher.directories().isEmpty() ) + d->fileSystemWatcher.removePaths(d->fileSystemWatcher.directories()); + + // Iterate over all files in the plugindirs + for (const QString &pluginDir : QStandardPaths::locateAll(QStandardPaths::DataLocation, + Core::Plugin::id(), + QStandardPaths::LocateDirectory) ) { + QString extensionDir = QDir(pluginDir).filePath("extensions"); + if ( QFile::exists(extensionDir) ) { + + // Watch this dir + d->fileSystemWatcher.addPath(extensionDir); + + QDirIterator dirIterator(extensionDir, QDir::Files|QDir::Executable, QDirIterator::NoIteratorFlags); + while (dirIterator.hasNext()) { + + QString path = dirIterator.next(); + QString id = dirIterator.fileInfo().fileName(); + + // Skip if this id already exists + auto it = find_if(d->externalExtensions.begin(), d->externalExtensions.end(), + [&id](const unique_ptr & rhs){ + return id == rhs->id(); + }); + + if ( it == d->externalExtensions.end() ) { + d->externalExtensions.emplace_back(new ExternalExtension(path, QString("org.arlbert.extension.external.%1").arg(id))); + d->fileSystemWatcher.addPath(path); + } + } + } + } + + // Register + for ( auto & script : d->externalExtensions ) + if ( script->state() == ExternalExtension::State::Initialized ) + registerQueryHandler(script.get()); + + emit extensionsUpdated(); +} diff -Nru albert-0.12.0/plugins/externalextensions/src/extension.h albert-0.13.1+plugins1/plugins/externalextensions/src/extension.h --- albert-0.12.0/plugins/externalextensions/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "externalextension.h" + +namespace ExternalExtensions { + +class Private; + +class Extension final : + public Core::Extension +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "External extensions"; } + QWidget *widget(QWidget *parent = nullptr) override; + + void reloadExtensions(); + +private: + + std::unique_ptr d; + +signals: + + void extensionsUpdated(); + +}; +} diff -Nru albert-0.12.0/plugins/externalextensions/src/externalextension.cpp albert-0.13.1+plugins1/plugins/externalextensions/src/externalextension.cpp --- albert-0.12.0/plugins/externalextensions/src/externalextension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/externalextension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,399 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "externalextension.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core/query.h" +#include "util/standardaction.h" +#include "util/standarditem.h" +#include "xdg/iconlookup.h" +using namespace std; +using namespace Core; + +#define EXTERNAL_EXTENSION_IID "org.albert.extension.external/v3.0" + +namespace { + +const constexpr char* ALBERT_OP = "ALBERT_OP"; +const constexpr char* ALBERT_QRY = "ALBERT_QUERY"; +const constexpr uint PROC_TIMEOUT = 5000; + +enum Message { + Metadata, + Initialize, + Finalize, + Query +}; + +QString OP_COMMANDS[] = { + "METADATA", + "INITIALIZE", + "FINALIZE", + "QUERY" +}; + + +bool runProcess (QString path, + std::map *variables, + QByteArray *out, + QString *errorString) { + + // Run the process + QProcess process; + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + for ( auto & entry : *variables ) + env.insert(entry.first, entry.second); + process.setProcessEnvironment(env); + process.start(path); + + if ( !process.waitForFinished(PROC_TIMEOUT) ){ + *errorString = "Process timed out."; + process.kill(); + return false; + } + + if ( process.exitStatus() != QProcess::NormalExit ) { + *errorString = "Process crashed."; + return false; + } + + if ( process.exitCode() != 0 ) { + + *errorString = QString("Exit code is %1.").arg(process.exitCode()); + + QByteArray cout = process.readAllStandardOutput(); + QByteArray cerr = process.readAllStandardError(); + + if (!cout.isEmpty()) + errorString->append(QString("\n%1").arg(QString(cout)).trimmed()); + + if (!cerr.isEmpty()) + errorString->append(QString("\n%1").arg(QString(cerr)).trimmed()); + + return false; + } + + *out = process.readAllStandardOutput(); + + return true; +} + + +bool parseJsonObject (const QByteArray &json, + QJsonObject *object, + QString *errorString) { + + // Parse stdout + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(json, &error); + if ( document.isNull() ) { + *errorString = QString("Invalid JSON at %1: %2").arg(error.offset).arg(error.errorString()); + return false; + } + + if ( !document.isObject() ) { + *errorString = "Output does not contain a JSON object."; + return false; + } + + *object = document.object(); + return true; +} + + +bool saveVariables (QJsonObject *object, + std::map *variables, + QString *errorString) { + + variables->clear(); + + if ( !object->contains("variables") ) + return true; + + if ( !object->operator[]("variables").isObject() ) { + *errorString = "'variables' is not a JSON object"; + return false; + } + + QJsonObject vars = object->operator[]("variables").toObject(); + for (auto it = vars.begin(); it != vars.end(); ++it) + if ( it.value().isString() ) + variables->emplace(it.key(), it.value().toString()); + + return true; +} + +} + +/** ***************************************************************************/ +ExternalExtensions::ExternalExtension::ExternalExtension(const QString &path, const QString &id) + : QueryHandler(id), path_(path), id_(id) { + + state_ = State::Error; + name_ = id; // Will be overwritten when available + + /* + * Get the metadata + */ + + QString preparedMessage = QString(OP_COMMANDS[Message::Metadata]).append(": %1 [%2]"); + + // Run the process + QByteArray out; + variables_[ALBERT_OP] = OP_COMMANDS[Message::Metadata]; + if ( !runProcess(path_, &variables_, &out, &errorString_) ){ + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + // Parse stdout + QJsonObject object; + if ( !parseJsonObject(out, &object, &errorString_) ) { + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + // Check for a sane interface ID (IID) + QJsonValue value = object["iid"]; + if (value.isNull()) { + errorString_ = "Metadate does not contain an interface id (iid)."; + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + QString iid = value.toString(); + if (iid != EXTERNAL_EXTENSION_IID) { + errorString_ = QString("Interface id '%1' does not match '%2'.").arg(iid, EXTERNAL_EXTENSION_IID); + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + trigger_ = object["trigger"].toString(); + if ( trigger_.isEmpty() ){ + errorString_ = "No trigger defined in metadata."; + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + // Get opional data + value = object["name"]; + name_ = value.isString() ? value.toString() : id_; + + value = object["version"]; + version_ = value.isString() ? value.toString() : "N/A"; + + value = object["author"]; + author_ = value.isString() ? value.toString() : "N/A"; + + value = object["description"]; + description_ = value.toString(); + + value = object["usage_example"]; + usageExample_ = value.toString(); + + value = object["dependencies"]; + if ( value.isArray() ) + for (const QJsonValue & value : value.toArray()) + dependencies_.append(value.toString()); + + + /* + * Initialize the extension + */ + + preparedMessage = QString(OP_COMMANDS[Message::Initialize]).append(": %1 [%2]"); + + // Run the process + variables_[ALBERT_OP] = OP_COMMANDS[Message::Initialize]; + if ( !runProcess(path_, &variables_, &out, &errorString_) ){ + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + if ( !out.isEmpty() ) { + + // Parse stdout + if ( !parseJsonObject(out, &object, &errorString_) ){ + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + + // Finally save the variables, if any + if ( !saveVariables(&object, &variables_, &errorString_) ){ + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } + } + + state_ = State::Initialized; +} + + +/** ***************************************************************************/ +ExternalExtensions::ExternalExtension::~ExternalExtension() { + + if ( state_ == State::Error ) + return; + + QJsonObject object; + QByteArray out; + + QString preparedMessage = QString(OP_COMMANDS[Message::Finalize]).append(": %1 [%2]"); + + // Run the process + variables_[ALBERT_OP] = OP_COMMANDS[Message::Finalize]; + if ( !runProcess(path_, &variables_, &out, &errorString_) ) { + qWarning() << qPrintable(preparedMessage.arg(errorString_, path_)); + return; + } +} + + +/** ***************************************************************************/ +void ExternalExtensions::ExternalExtension::handleQuery(Core::Query* query) const { + + Q_ASSERT(state_ != State::Error); + + // External extension must run only when triggered, since they are too ressource heavy + if ( query->trigger().isEmpty() ) + return; + + // Never run the extension concurrent + QMutexLocker lock (&processMutex_); + if (!query->isValid()) + return; + + QByteArray out; + QString errorString; + QString preparedMessage = QString(OP_COMMANDS[Message::Query]).append(": %1 [%2]"); + + // Build env + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + variables_[ALBERT_OP] = OP_COMMANDS[Message::Query]; + variables_[ALBERT_QRY] = query->string(); + for ( auto & entry : variables_ ) + env.insert(entry.first, entry.second); + + // Run the process + QProcess process; + process.setProcessEnvironment(env); + process.start(path_); + + while( !process.waitForFinished(10) ) { + if (!query->isValid()) { + process.terminate(); + if ( !process.waitForFinished(PROC_TIMEOUT) ) + process.kill(); + return; + } + } + + if ( process.exitStatus() != QProcess::NormalExit ) { + qWarning() << qPrintable(preparedMessage.arg("Process crashed.", path_)); + return; + } + + if ( process.exitCode() != 0 ) { + errorString = QString("Exit code is %1.").arg(process.exitCode()).append(process.readAllStandardError()); + qWarning() << qPrintable(preparedMessage.arg(errorString, path_)); + return; + } + + out = process.readAllStandardOutput(); + + // Parse stdout + QJsonObject object; + if ( !parseJsonObject(out, &object, &errorString) ) { + qWarning() << qPrintable(preparedMessage.arg(errorString, path_)); + return; + } + + if ( out.isEmpty() ) + return; + + // Save the variables, if any + if ( !saveVariables(&object, &variables_, &errorString) ) { + qWarning() << qPrintable(preparedMessage.arg(errorString, path_)); + return; + } + + // Quit if there are no items + QJsonValue value = object["items"]; + if ( value.isNull() ) + return; + + // Check type of items + if ( !value.isArray() ) { + errorString = "'items' is not an array."; + qWarning() << qPrintable(preparedMessage.arg(errorString, path_)); + return; + } + + // Iterate over the results + shared_ptr item; + shared_ptr action; + vector> actions; + vector,short>> results; + + int i = 0; + for (const QJsonValue & itemValue : value.toArray() ){ + + if ( !itemValue.isObject() ) { + qWarning() << qPrintable(QString("Returned item %1 Item is not a JSON object. (%2)").arg(i).arg(path_)); + return; + } + object = itemValue.toObject(); + + // Build the item from the json object + item = std::make_shared(object["id"].toString()); + item->setText(object["name"].toString()); + item->setSubtext(object["description"].toString()); + item->setCompletionString(object["completion"].toString()); + QString icon = XDG::IconLookup::iconPath({object["icon"].toString(), "unknown"}); + item->setIconPath(icon.isEmpty() ? ":unknown" : icon); + + // Build the actions + actions.clear(); + for (const QJsonValue & value : object["actions"].toArray()){ + object = value.toObject(); + action = std::make_shared(); + action->setText(object["name"].toString()); + QString command = object["command"].toString(); + QStringList arguments; + for (const QJsonValue & value : object["arguments"].toArray()) + arguments.append(value.toString()); + action->setAction(std::bind(static_cast(&QProcess::startDetached), command, arguments)); + actions.push_back(std::move(action)); + } + item->setActions(std::move(actions)); + + results.emplace_back(std::move(item), 0); + } + + query->addMatches(make_move_iterator(results.begin()), + make_move_iterator(results.end())); +} + diff -Nru albert-0.12.0/plugins/externalextensions/src/externalextension.h albert-0.13.1+plugins1/plugins/externalextensions/src/externalextension.h --- albert-0.12.0/plugins/externalextensions/src/externalextension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/externalextension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,82 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include "core/queryhandler.h" + +namespace ExternalExtensions { + +class ExternalExtension final : public Core::QueryHandler +{ +public: + + enum class State { + Initialized, + Error + }; + + + ExternalExtension(const QString &path, const QString &id); + ~ExternalExtension(); + + /* + * Implementation of extension interface + */ + + QStringList triggers() const override { return {trigger_}; } + void handleQuery(Core::Query *query) const override; + + /* + * Extension specific members + */ + + + const QString &path() const { return path_; } + const QString &id() const { return id_; } + const QString &name() const { return name_; } + const QString &author() const { return author_; } + const QString &version() const { return version_; } + const QString &description() const { return description_; } + const QString &usageExample() const { return usageExample_; } + const QString &trigger() const { return trigger_; } + const QStringList &dependencies() const { return dependencies_; } + const State &state() const { return state_; } + const QString &errorString() const { return errorString_; } + +private: + + QString runOperation(const QString &); + + QString path_; + QString id_; + QString name_; + QString author_; + QString version_; + QString trigger_; + QString description_; + QString usageExample_; + QStringList dependencies_; + State state_; + QString errorString_; + mutable std::map variables_; + mutable QMutex processMutex_; +}; + +} diff -Nru albert-0.12.0/plugins/externalextensions/src/externalextensionmodel.cpp albert-0.13.1+plugins1/plugins/externalextensions/src/externalextensionmodel.cpp --- albert-0.12.0/plugins/externalextensions/src/externalextensionmodel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/externalextensionmodel.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,167 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include "externalextensionmodel.h" +#include "externalextension.h" + + +namespace { +enum class Section{Name, Trigger, Path, Count}; +} + + +/** ***************************************************************************/ +int ExternalExtensions::ExternalExtensionsModel::rowCount(const QModelIndex &) const { + return static_cast(externalExtensions_.size()); +} + + + +/** ***************************************************************************/ +int ExternalExtensions::ExternalExtensionsModel::columnCount(const QModelIndex &) const { + return static_cast(Section::Count); +} + + + +/** ***************************************************************************/ +QVariant ExternalExtensions::ExternalExtensionsModel::headerData(int section, Qt::Orientation orientation, int role) const { + // No sanity check necessary since + if ( section<0 || static_cast(Section::Count)<=section ) + return QVariant(); + + + if (orientation == Qt::Horizontal){ + switch (static_cast
(section)) { + case Section::Name:{ + switch (role) { + case Qt::DisplayRole: return "Name"; + case Qt::ToolTipRole: return "The name of the extension."; + default: return QVariant(); + } + + } + case Section::Trigger:{ + switch (role) { + case Qt::DisplayRole: return "Trigger"; + case Qt::ToolTipRole: return "The term that triggers this extension."; + default: return QVariant(); + } + + } + case Section::Path:{ + switch (role) { + case Qt::DisplayRole: return "Path"; + case Qt::ToolTipRole: return "The path of this extension."; + default: return QVariant(); + } + + } + default: return QVariant(); + } + } + return QVariant(); +} + + + +/** ***************************************************************************/ +QVariant ExternalExtensions::ExternalExtensionsModel::data(const QModelIndex &index, int role) const { + if (!index.isValid() + || index.row() >= static_cast(externalExtensions_.size()) + || index.column() >= static_cast(static_cast(Section::Count))) + return QVariant(); + + switch (role) { + case Qt::DecorationRole: { + if ( static_cast
(index.column()) == Section::Name ) { + switch (externalExtensions_[static_cast(index.row())]->state()) { + case ExternalExtension::State::Initialized: + return QIcon(":plugin_loaded"); + case ExternalExtension::State::Error: + return QIcon(":plugin_error"); + } + } + return QVariant(); + } + case Qt::DisplayRole: { + switch (static_cast
(index.column())) { + case Section::Name: return externalExtensions_[static_cast(index.row())]->name(); + case Section::Trigger: return externalExtensions_[static_cast(index.row())]->trigger(); + case Section::Path: return externalExtensions_[static_cast(index.row())]->path(); + default: return QVariant(); + } + } + case Qt::EditRole: { + switch (static_cast
(index.column())) { + case Section::Name: return externalExtensions_[static_cast(index.row())]->name(); + case Section::Trigger: return externalExtensions_[static_cast(index.row())]->trigger(); + case Section::Path: return externalExtensions_[static_cast(index.row())]->path(); + default: return QVariant(); + } + } + case Qt::ToolTipRole: { + QString toolTip; + const ExternalExtension *ext = externalExtensions_[static_cast(index.row())].get(); + + toolTip = QString("ID: %1").arg(ext->id()); + + if (!ext->version().isEmpty()) + toolTip.append(QString("\nVersion: %1").arg(ext->version())); + + if (!ext->author().isEmpty()) + toolTip.append(QString("\nAuthor: %1").arg(ext->author())); + + if (!ext->dependencies().empty()) + toolTip.append(QString("\nDependencies: %1").arg(ext->dependencies().join(", "))); + + toolTip.append(QString("\nPath: %1").arg(ext->path())); + + if (!ext->description().isEmpty()) + toolTip.append(QString("\nDescription: %1").arg(ext->description())); + + if (!ext->usageExample().isEmpty()) + toolTip.append(QString("\nUsage example: '%1'").arg(ext->usageExample())); + + if (ext->state() == ExternalExtension::State::Error && !ext->errorString().isEmpty()) + toolTip.append(QString("\nERROR: %1").arg(ext->errorString())); + + return toolTip; + } + default: + return QVariant(); + } +} + + +/** ***************************************************************************/ +Qt::ItemFlags ExternalExtensions::ExternalExtensionsModel::flags(const QModelIndex &index) const { + if ( !index.isValid() ) + return Qt::NoItemFlags; + return Qt::ItemIsSelectable|Qt::ItemIsEnabled; +} + + +/** ***************************************************************************/ +void ExternalExtensions::ExternalExtensionsModel::onActivated(const QModelIndex &index) { + QDesktopServices::openUrl(QUrl(externalExtensions_[static_cast(index.row())]->path())); +} diff -Nru albert-0.12.0/plugins/externalextensions/src/externalextensionmodel.h albert-0.13.1+plugins1/plugins/externalextensions/src/externalextensionmodel.h --- albert-0.12.0/plugins/externalextensions/src/externalextensionmodel.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/externalextensions/src/externalextensionmodel.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,47 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "externalextension.h" + +namespace ExternalExtensions { + +class ExternalExtensionsModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + + ExternalExtensionsModel(const std::vector> &exts, QObject *parent = Q_NULLPTR) + : QAbstractTableModel(parent), externalExtensions_(exts) {} + + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex & parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex & index) const override; + + void onActivated(const QModelIndex &); + +private: + + const std::vector> &externalExtensions_; +}; + +} diff -Nru albert-0.12.0/plugins/files/CMakeLists.txt albert-0.13.1+plugins1/plugins/files/CMakeLists.txt --- albert-0.12.0/plugins/files/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(files) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Concurrent) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/files/files.qrc albert-0.13.1+plugins1/plugins/files/files.qrc --- albert-0.12.0/plugins/files/files.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/files.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/inode-directory.svg + + diff -Nru albert-0.12.0/plugins/files/metadata.json albert-0.13.1+plugins1/plugins/files/metadata.json --- albert-0.12.0/plugins/files/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.files", + "name" : "Files", + "version" : "1.1", + "platform" : "All", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/files/resources/inode-directory.svg albert-0.13.1+plugins1/plugins/files/resources/inode-directory.svg --- albert-0.12.0/plugins/files/resources/inode-directory.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/resources/inode-directory.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/files/src/configwidget.cpp albert-0.13.1+plugins1/plugins/files/src/configwidget.cpp --- albert-0.12.0/plugins/files/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,241 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "mimetypedialog.h" + +/** ***************************************************************************/ +Files::ConfigWidget::ConfigWidget(Extension *_extension, QWidget *_parent) + : QWidget(_parent), extension(_extension) { + ui.setupUi(this); + + // Paths + QStringListModel *pathsModel = new QStringListModel(this); + pathsModel->setStringList(extension->paths()); + ui.listView_paths->setModel(pathsModel); + connect(extension, &Extension::pathsChanged, + pathsModel, &QStringListModel::setStringList); + + // Buttons + connect(ui.pushButton_add, &QPushButton::clicked, [=](){ + QFileInfo fileInfo(QFileDialog::getExistingDirectory( + this, + tr("Choose directory"), + QStandardPaths::writableLocation(QStandardPaths::HomeLocation))); + if(fileInfo.exists()) + extension->setPaths(QStringList(extension->paths()) << fileInfo.absoluteFilePath()); + }); + + connect(ui.pushButton_remove, &QPushButton::clicked, [this, pathsModel](){ + if ( !ui.listView_paths->currentIndex().isValid() ) + return; + QStringList paths(extension->paths()); + paths.removeAll(pathsModel->stringList()[ui.listView_paths->currentIndex().row()]); + extension->setPaths(paths); + }); + + connect(ui.pushButton_restore, &QPushButton::clicked, + extension, &Extension::restorePaths); + + connect(ui.pushButton_update, &QPushButton::clicked, + extension, &Extension::updateIndex); + + /* + * Initialize the indexing options + */ + + ui.checkBox_hidden->setChecked(extension->indexHidden()); + connect(ui.checkBox_hidden, &QCheckBox::toggled, extension, &Extension::setIndexHidden); + + ui.checkBox_followSymlinks->setChecked(extension->followSymlinks()); + connect(ui.checkBox_followSymlinks, &QCheckBox::toggled, extension, &Extension::setFollowSymlinks); + + ui.checkBox_fuzzy->setChecked(extension->fuzzy()); + connect(ui.checkBox_fuzzy, &QCheckBox::toggled, extension, &Extension::setFuzzy); + + ui.spinBox_interval->setValue(static_cast(extension->scanInterval())); + connect(ui.spinBox_interval, static_cast(&QSpinBox::valueChanged), + extension, &Extension::setScanInterval); + + /* + * Initialize the mime options + */ + + QStringList filters = extension->filters(); + + if (filters.contains("audio/*")) + ui.checkBox_audio->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("audio/"); })) + ui.checkBox_audio->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_audio->setCheckState(Qt::Unchecked); + + if (filters.contains("video/*")) + ui.checkBox_video->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("video/"); })) + ui.checkBox_video->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_video->setCheckState(Qt::Unchecked); + + if (filters.contains("image/*")) + ui.checkBox_image->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("image/"); })) + ui.checkBox_image->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_image->setCheckState(Qt::Unchecked); + + if (filters.contains("application/*")) + ui.checkBox_docs->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("application/"); })) + ui.checkBox_docs->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_docs->setCheckState(Qt::Unchecked); + + if (filters.contains("inode/directory")) + ui.checkBox_dirs->setCheckState(Qt::Checked); + else + ui.checkBox_dirs->setCheckState(Qt::Unchecked); + + /* + * Set the actions for checking the mime options + */ + + connect(ui.checkBox_audio, &QCheckBox::clicked, extension, [this]() { + ui.checkBox_audio->setTristate(false); + QStringList filters = extension->filters(); + filters.erase(std::remove_if(filters.begin(), filters.end(), + [](const QString &str){ return str.startsWith("audio/"); }), + filters.end()); + if (ui.checkBox_audio->checkState() == Qt::Checked) + filters.push_back("audio/*"); + extension->setFilters(filters); + }); + + connect(ui.checkBox_video, &QCheckBox::clicked, extension, [this]() { + ui.checkBox_video->setTristate(false); + QStringList filters = extension->filters(); + filters.erase(std::remove_if(filters.begin(), filters.end(), + [](const QString &str){ return str.startsWith("video/"); }), + filters.end()); + if (ui.checkBox_video->checkState() == Qt::Checked) + filters.push_back("video/*"); + extension->setFilters(filters); + }); + + connect(ui.checkBox_image, &QCheckBox::clicked, extension, [this]() { + ui.checkBox_image->setTristate(false); + QStringList filters = extension->filters(); + filters.erase(std::remove_if(filters.begin(), filters.end(), + [](const QString &str){ return str.startsWith("image/"); }), + filters.end()); + if (ui.checkBox_image->checkState() == Qt::Checked) + filters.push_back("image/*"); + extension->setFilters(filters); + }); + + connect(ui.checkBox_docs, &QCheckBox::clicked, extension, [this]() { + ui.checkBox_docs->setTristate(false); + QStringList filters = extension->filters(); + filters.erase(std::remove_if(filters.begin(), filters.end(), + [](const QString &str){ return str.startsWith("application/"); }), + filters.end()); + if (ui.checkBox_docs->checkState() == Qt::Checked) + filters.push_back("application/*"); + extension->setFilters(filters); + }); + + connect(ui.checkBox_dirs, &QCheckBox::toggled, extension, [=](bool checked){ + QStringList filters = extension->filters(); + filters.removeAll("inode/directory"); + if (checked) + filters.push_back("inode/directory"); + extension->setFilters(filters); + }); + + // The advanced button action + connect(ui.pushButton_advanced, &QPushButton::clicked, [=](){ + + MimeTypeDialog dialog(extension->filters(), this); + dialog.setWindowModality(Qt::WindowModal); + if ( dialog.exec() ) { + + // If the dialog has been accepted, update extension and checkboxes + extension->setFilters(dialog.filters()); + + // Set the shortcuts + QStringList filters = extension->filters(); + + if (filters.contains("audio/*")) + ui.checkBox_audio->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("audio/"); })) + ui.checkBox_audio->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_audio->setCheckState(Qt::Unchecked); + + if (filters.contains("video/*")) + ui.checkBox_video->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("video/"); })) + ui.checkBox_video->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_video->setCheckState(Qt::Unchecked); + + if (filters.contains("image/*")) + ui.checkBox_image->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("image/"); })) + ui.checkBox_image->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_image->setCheckState(Qt::Unchecked); + + if (filters.contains("application/*")) + ui.checkBox_docs->setCheckState(Qt::Checked); + else if (std::any_of(filters.begin(), filters.end(), + [](const QString & str){ return str.startsWith("application/"); })) + ui.checkBox_docs->setCheckState(Qt::PartiallyChecked); + else + ui.checkBox_docs->setCheckState(Qt::Unchecked); + + if (filters.contains("inode/directory")) + ui.checkBox_dirs->setCheckState(Qt::Checked); + else + ui.checkBox_dirs->setCheckState(Qt::Unchecked); + } + }); + + // Status bar + connect(extension, &Extension::statusInfo, this, [this](const QString& text){ + QFontMetrics metrics(ui.label_statusbar->font()); + QString elidedText = metrics.elidedText(text, Qt::ElideMiddle, ui.label_statusbar->width()-5); + ui.label_statusbar->setText(elidedText); + }); +} + + + +/** ***************************************************************************/ +Files::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/files/src/configwidget.h albert-0.13.1+plugins1/plugins/files/src/configwidget.h --- albert-0.12.0/plugins/files/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ + +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "ui_configwidget.h" + +namespace Files { + +class Extension; + +class ConfigWidget final : public QWidget +{ + Q_OBJECT + +public: + + explicit ConfigWidget(Extension *ext, QWidget *parent = 0); + ~ConfigWidget(); + +private: + + Extension *extension; + Ui::ConfigWidget ui; + +signals: + + void requestAddPath(const QString&); + void requestRemovePath(const QString&); + +}; + +} diff -Nru albert-0.12.0/plugins/files/src/configwidget.ui albert-0.13.1+plugins1/plugins/files/src/configwidget.ui --- albert-0.12.0/plugins/files/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,240 @@ + + + Files::ConfigWidget + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Paths + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + + + + + + + + 0 + 0 + + + + + .. + + + + + + + + 0 + 0 + + + + + .. + + + + + + + Restore + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + + + + Indexed MIME types + + + + + + Documents + + + + + + + Folders + + + + + + + Images + + + + + + + Video + + + + + + + Audio + + + + + + + Advanced + + + + + + + + + + Misc settings + + + + + + Fuzzy Search + + + + + + + Index hidden files + + + + + + + Follow symlinks + + + + + + + + + + Scan interval + + + + + + Start scan + + + + + + + mins + + + 0 + + + 1440 + + + 5 + + + 60 + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/files/src/extension.cpp albert-0.13.1+plugins1/plugins/files/src/extension.cpp --- albert-0.12.0/plugins/files/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,523 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "file.h" +#include "standardfile.h" +#include "extension.h" +#include "indextreenode.h" +#include "core/query.h" +#include "util/offlineindex.h" +#include "util/standarditem.h" +#include "util/standardaction.h" +using namespace Core; +using namespace std; + + +namespace { + +const char* CFG_PATHS = "paths"; +const char* CFG_FILTERS = "filters"; +const QStringList DEF_FILTERS = { "inode/directory", "application/*" }; +const char* CFG_FUZZY = "fuzzy"; +const bool DEF_FUZZY = false; +const char* CFG_INDEX_HIDDEN = "indexhidden"; +const bool DEF_INDEX_HIDDEN = false; +const char* CFG_FOLLOW_SYMLINKS = "follow_symlinks"; +const bool DEF_FOLLOW_SYMLINKS = false; +const char* CFG_SCAN_INTERVAL = "scan_interval"; +const uint DEF_SCAN_INTERVAL = 15; + + + +class OfflineIndexBuilderVisitor : public Files::Visitor { + Core::OfflineIndex &offlineIndex; +public: + OfflineIndexBuilderVisitor(Core::OfflineIndex &offlineIndex) + : offlineIndex(offlineIndex) { } + + void visit(Files::IndexTreeNode *node) override { + for ( const shared_ptr &item : node->items() ) + offlineIndex.add(item); + } +}; + + +class CounterVisitor : public Files::Visitor { +public: + uint itemCount = 0; + uint dirCount = 0; + void visit(Files::IndexTreeNode *node) override { + ++dirCount; + itemCount += node->items().size(); + } +}; + +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +class Files::Private +{ +public: + Private(Extension *q) : q(q), abort(false), rerun(false) {} + + Extension *q; + + QPointer widget; + + QStringList indexRootDirs; + IndexSettings indexSettings; + vector> indexTrees; + unique_ptr> futureWatcher; + Core::OfflineIndex offlineIndex; + QTimer indexIntervalTimer; + bool abort; + bool rerun; + + + void finishIndexing(); + void startIndexing(); + Core::OfflineIndex *indexFiles(); +}; + + + +/** ***************************************************************************/ +void Files::Private::startIndexing() { + + // Abort and rerun + if ( futureWatcher ) { + emit q->statusInfo("Waiting for indexer to shut down ..."); + abort = true; + rerun = true; + return; + } + + // Run finishIndexing when the indexing thread finished + futureWatcher.reset(new QFutureWatcher); + QObject::connect(futureWatcher.get(), &QFutureWatcher::finished, + [this](){ this->finishIndexing(); }); + + // Restart the timer (Index update may have been started manually) + if (indexIntervalTimer.interval() != 0) + indexIntervalTimer.start(); + + // Run the indexer thread + qInfo() << "Start indexing files."; + futureWatcher->setFuture(QtConcurrent::run(this, &Private::indexFiles)); + + // Notification + emit q->statusInfo("Indexing files ..."); +} + + + +/** ***************************************************************************/ +void Files::Private::finishIndexing() { + + // In case of abortion the returned data is invalid + if ( !abort ) { + OfflineIndex *retval = futureWatcher->future().result(); + if (retval) { + offlineIndex = std::move(*retval); + delete retval; + } + + // Notification + CounterVisitor counterVisitor; + for (const auto & tree : indexTrees ) + tree->accept(counterVisitor); + qInfo() << qPrintable(QString("Indexed %1 files in %2 directories.") + .arg(counterVisitor.itemCount).arg(counterVisitor.dirCount)); + emit q->statusInfo(QString("Indexed %1 files in %2 directories.") + .arg(counterVisitor.itemCount).arg(counterVisitor.dirCount)); + } + + futureWatcher.reset(); + abort = false; + + if ( rerun ) { + rerun = false; + startIndexing(); + } +} + + + +/** ***************************************************************************/ +OfflineIndex* Files::Private::indexFiles() { + + // Remove the subtrees not wanted anymore + auto it = indexTrees.begin(); + while ( it != indexTrees.end() ) { + if ( indexRootDirs.contains((*it)->path()) ) + ++it; + else { + (*it)->removeDownlinks(); + it = indexTrees.erase(it); + } + } + + // Start the indexing + for ( const QString &rootDir : indexRootDirs ) { + + qDebug() << qPrintable(QString("Indexing %1…").arg(rootDir)); + emit q->statusInfo(QString("Indexing %1…").arg(rootDir)); + + // If this root dir does not exist create it + auto it = find_if(indexTrees.begin(), indexTrees.end(), + [&rootDir](const shared_ptr& tree){ return tree->path() == rootDir; }); + if ( it == indexTrees.end() ) { + indexTrees.push_back(make_shared(rootDir)); + indexTrees.back()->update(abort, indexSettings); + } + else + (*it)->update(abort, indexSettings); + + + if ( abort ) + return nullptr; + } + + indexSettings.setForceUpdate(true); + + // Serialize data + qDebug() << "Serializing index data…"; + emit q->statusInfo("Serializing index data…"); + QFile file(q->cacheLocation().filePath("fileindex.json")); + if (file.open(QIODevice::WriteOnly)) { + QJsonArray array; + for (auto& tree : this->indexTrees) + array.push_back(tree->serialize()); + QJsonDocument doc(array); + file.write(doc.toJson(QJsonDocument::Compact)); + file.close(); + } + else + qWarning() << "Couldn't write to file:" << file.fileName(); + + + // Build offline index + qDebug() << "Building offline index…"; + emit q->statusInfo("Building offline index…"); + Core::OfflineIndex *offline = new Core::OfflineIndex; + OfflineIndexBuilderVisitor visitor(*offline); + for (auto& tree : this->indexTrees) + tree->accept(visitor); + return offline; +} + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +Files::Extension::Extension() + : Core::Extension("org.albert.extension.files"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private(this)) { + + registerQueryHandler(this); + + // Load settings + d->indexSettings.setFilters(settings().value(CFG_FILTERS, DEF_FILTERS).toStringList()); + d->indexSettings.setIndexHidden(settings().value(CFG_INDEX_HIDDEN, DEF_INDEX_HIDDEN).toBool()); + d->indexSettings.setFollowSymlinks(settings().value(CFG_FOLLOW_SYMLINKS, DEF_FOLLOW_SYMLINKS).toBool()); + d->indexSettings.setForceUpdate(false); + d->offlineIndex.setFuzzy(settings().value(CFG_FUZZY, DEF_FUZZY).toBool()); + d->indexIntervalTimer.setInterval(settings().value(CFG_SCAN_INTERVAL, DEF_SCAN_INTERVAL).toInt()*60000); // Will be started in the initial index update + d->indexRootDirs = settings().value(CFG_PATHS, QDir::homePath()).toStringList(); + + // Index timer + connect(&d->indexIntervalTimer, &QTimer::timeout, this, &Extension::updateIndex); + + // If the root dirs change write it to the settings + connect(this, &Extension::pathsChanged, [this](const QStringList& dirs){ + settings().setValue(CFG_PATHS, dirs); + }); + + // Deserialize data + qDebug() << "Deserializing index data…"; + QFile file(cacheLocation().filePath("fileindex.json")); + if ( file.exists() ) { + if (file.open(QIODevice::ReadOnly)) { + QJsonDocument loadDoc{QJsonDocument::fromJson(file.readAll())}; + for ( const QJsonValueRef value : loadDoc.array()){ + d->indexTrees.push_back(make_shared()); // Invalid node + d->indexTrees.back()->deserialize(value.toObject()); + } + file.close(); + } + else + qWarning() << "Couldn't read from file:" << file.fileName(); + } + + // Trigger an initial update + updateIndex(); +} + + + +/** ***************************************************************************/ +Files::Extension::~Extension() { + + // The indexer thread has sideeffects wait for termination + d->abort = true; + d->rerun = false; + if ( d->futureWatcher ){ + disconnect(d->futureWatcher.get(), 0, 0, 0); + d->futureWatcher->waitForFinished(); + } +} + + + +/** ***************************************************************************/ +QWidget *Files::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) + d->widget = new ConfigWidget(this, parent); + return d->widget; +} + + + +/** ***************************************************************************/ +void Files::Extension::handleQuery(Core::Query * query) const { + + if ( query->trigger()=="/" || query->trigger()=="~" ) { + + QFileInfo queryFileInfo(query->rawString()); + + // Substitute tilde + if ( query->rawString()[0] == '~' ) + queryFileInfo.setFile(QDir::homePath()+query->string()); + + // Get all matching files + QFileInfo pathInfo(queryFileInfo.path()); + if ( pathInfo.exists() && pathInfo.isDir() ) { + QMimeDatabase mimeDatabase; + QDir dir(pathInfo.filePath()); + for (const QFileInfo& fileinfo : dir.entryInfoList(QDir::AllEntries|QDir::Hidden|QDir::NoDotAndDotDot, + QDir::DirsFirst|QDir::Name|QDir::IgnoreCase) ) { + if ( fileinfo.fileName().startsWith(queryFileInfo.fileName()) ) { + QMimeType mimetype = mimeDatabase.mimeTypeForFile(fileinfo.filePath()); + query->addMatch(make_shared(fileinfo.filePath(), mimetype), + static_cast(UINT_MAX * static_cast(queryFileInfo.fileName().size()) / fileinfo.fileName().size())); + } + } + } + } + else + { + if ( query->string().isEmpty() ) + return; + + if ( QString("albert scan files").startsWith(query->string()) ) { + + shared_ptr standardAction = make_shared(); + standardAction->setText("Update the file index"); + // Const cast is fine since the action will not be called here + standardAction->setAction([this](){ const_cast(this)->updateIndex(); }); + + shared_ptr standardItem = make_shared("org.albert.extension.files.action.index"); + standardItem->setText("albert scan files"); + standardItem->setSubtext("Update the file index"); + standardItem->setIconPath(":app_icon"); + standardItem->setActions({standardAction}); + + query->addMatch(move(standardItem)); + } + + // Search for matches + const vector> &indexables = d->offlineIndex.search(query->string()); + + // Add results to query + vector,uint>> results; + for (const shared_ptr &item : indexables) + // TODO `Search` has to determine the relevance. Set to 0 for now + results.emplace_back(static_pointer_cast(item), 0); + + query->addMatches(make_move_iterator(results.begin()), + make_move_iterator(results.end())); + } +} + + + +/** ***************************************************************************/ +const QStringList &Files::Extension::paths() const { + return d->indexRootDirs; +} + + + +/** ***************************************************************************/ +void Files::Extension::setPaths(const QStringList &paths) { + + if (d->indexRootDirs == paths) + return; + + d->indexRootDirs.clear(); + + // Check sanity and add path + for ( const QString& path : paths ) { + + QFileInfo fileInfo(path); + QString absPath = fileInfo.absoluteFilePath(); + + if (d->indexRootDirs.contains(absPath)) { + qWarning() << QString("Duplicate paths: %1.").arg(path); + continue; + } + + if (!fileInfo.exists()) { + qWarning() << QString("Path does not exist: %1.").arg(path); + continue; + } + + if(!fileInfo.isDir()) { + qWarning() << QString("Path is not a directory: %1.").arg(path); + continue; + } + + d->indexRootDirs << absPath; + } + + sort(d->indexRootDirs.begin(), d->indexRootDirs.end()); + + emit pathsChanged(d->indexRootDirs); + + // Store to settings + settings().setValue(CFG_PATHS, d->indexRootDirs); + +} + + + +/** ***************************************************************************/ +void Files::Extension::restorePaths() { + // Add standard path + d->indexRootDirs.clear(); + d->indexRootDirs << QStandardPaths::writableLocation(QStandardPaths::HomeLocation); + emit pathsChanged(d->indexRootDirs); +} + + + +/** ***************************************************************************/ +void Files::Extension::updateIndex() { + d->startIndexing(); +} + + + +/** ***************************************************************************/ +bool Files::Extension::indexHidden() const { + return d->indexSettings.indexHidden(); +} + + + +/** ***************************************************************************/ +void Files::Extension::setIndexHidden(bool b) { + settings().setValue(CFG_INDEX_HIDDEN, b); + d->indexSettings.setIndexHidden(b); +} + + + +/** ***************************************************************************/ +bool Files::Extension::followSymlinks() const { + return d->indexSettings.followSymlinks(); +} + + + +/** ***************************************************************************/ +void Files::Extension::setFollowSymlinks(bool b) { + settings().setValue(CFG_FOLLOW_SYMLINKS, b); + d->indexSettings.setFollowSymlinks(b); +} + + + +/** ***************************************************************************/ +unsigned int Files::Extension::scanInterval() const { + return static_cast(d->indexIntervalTimer.interval()/60000); +} + + + +/** ***************************************************************************/ +void Files::Extension::setScanInterval(uint minutes) { + settings().setValue(CFG_SCAN_INTERVAL, minutes); + (minutes == 0) ? d->indexIntervalTimer.stop() + : d->indexIntervalTimer.start(static_cast(minutes*60000)); +} + + + +/** ***************************************************************************/ +bool Files::Extension::fuzzy() const { + return d->offlineIndex.fuzzy(); +} + + + +/** ***************************************************************************/ +void Files::Extension::setFuzzy(bool b) { + settings().setValue(CFG_FUZZY, b); + d->offlineIndex.setFuzzy(b); +} + + + +/** ***************************************************************************/ +QStringList Files::Extension::filters() const { + QStringList retval; + for ( auto const & regex : d->indexSettings.filters() ) + retval.push_back(regex.pattern()); + return retval; +} + + + +/** ***************************************************************************/ +void Files::Extension::setFilters(const QStringList &filters) { + settings().setValue(CFG_FILTERS, filters); + d->indexSettings.setFilters(filters); +} diff -Nru albert-0.12.0/plugins/files/src/extension.h albert-0.13.1+plugins1/plugins/files/src/extension.h --- albert-0.12.0/plugins/files/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,77 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace Files { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + + Q_PROPERTY(QStringList paths READ paths WRITE setPaths NOTIFY pathsChanged) + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Files"; } + QStringList triggers() const override { return {"/", "~"}; } + QWidget *widget(QWidget *parent = nullptr) override; + void handleQuery(Core::Query * query) const override; + + const QStringList &paths() const; + void setPaths(const QStringList &); + void restorePaths(); + + bool indexHidden() const; + void setIndexHidden(bool b = true); + + bool followSymlinks() const; + void setFollowSymlinks(bool b = true); + + uint scanInterval() const; + void setScanInterval(uint minutes); + + bool fuzzy() const; + void setFuzzy(bool b = true); + + QStringList filters() const; + void setFilters(const QStringList &); + + void updateIndex(); + +private: + + std::unique_ptr d; + +signals: + + void pathsChanged(const QStringList&); + void statusInfo(const QString&); + +}; +} diff -Nru albert-0.12.0/plugins/files/src/fileactions.cpp albert-0.13.1+plugins1/plugins/files/src/fileactions.cpp --- albert-0.12.0/plugins/files/src/fileactions.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/fileactions.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,146 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "fileactions.h" + +/******************************************************************************/ + +Files::FileAction::FileAction(Files::File *file) : file_(file) { + +} + +Files::FileAction::~FileAction() { + +} + +/******************************************************************************/ + +Files::OpenFileAction::OpenFileAction(Files::File *file) : FileAction(file) { + +} + +QString Files::OpenFileAction::text() const { + return "Open with default application"; +} +#include +void Files::OpenFileAction::activate() { + qDebug() << QUrl::fromLocalFile(file_->filePath()).toEncoded(); + QDesktopServices::openUrl(QUrl::fromLocalFile(file_->filePath())); +} + +/******************************************************************************/ + +Files::RevealFileAction::RevealFileAction(Files::File *file) : FileAction(file) { + +} + +QString Files::RevealFileAction::text() const { + return "Reveal in file browser"; +} + +void Files::RevealFileAction::activate() { + QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(file_->filePath()).path())); +} + +/******************************************************************************/ + +extern QString terminalCommand; + +Files::TerminalFileAction::TerminalFileAction(Files::File *file) + : FileAction(file) { +} + +QString Files::TerminalFileAction::text() const { + return "Open terminal at this path"; + +} + +void Files::TerminalFileAction::activate() { + QFileInfo fileInfo(file_->filePath()); + QStringList commandLine = terminalCommand.trimmed().split(' '); + if ( commandLine.size() == 0 ) + return; + if ( fileInfo.isDir() ) + QProcess::startDetached(commandLine[0], {}, fileInfo.filePath()); + else + QProcess::startDetached(commandLine[0], {}, fileInfo.path()); +} + +/******************************************************************************/ + +Files::ExecuteFileAction::ExecuteFileAction(Files::File *file) : FileAction(file) { + +} + +QString Files::ExecuteFileAction::text() const { + return "Execute file"; +} + +void Files::ExecuteFileAction::activate() { + QProcess::startDetached(file_->filePath()); +} + +/******************************************************************************/ + +Files::CopyFileAction::CopyFileAction(Files::File *file) : FileAction(file) { + +} + +QString Files::CopyFileAction::text() const { + return "Copy file to clipboard"; +} + +void Files::CopyFileAction::activate() { + // Get clipboard + QClipboard *cb = QApplication::clipboard(); + + // Ownership of the new data is transferred to the clipboard. + QMimeData* newMimeData = new QMimeData(); + + // Copy old mimedata + const QMimeData* oldMimeData = cb->mimeData(); + for (const QString &f : oldMimeData->formats()) + newMimeData->setData(f, oldMimeData->data(f)); + + // Copy path of file + QString filePath = file_->filePath(); + newMimeData->setText(filePath); + + // Copy file + newMimeData->setUrls({QUrl::fromLocalFile(filePath)}); + + // Copy file (f*** you gnome) + QByteArray gnomeFormat = QByteArray("copy\n").append(QUrl::fromLocalFile(filePath).toEncoded()); + newMimeData->setData("x-special/gnome-copied-files", gnomeFormat); + + // Set the mimedata + cb->setMimeData(newMimeData); +} + +/******************************************************************************/ + +Files::CopyPathAction::CopyPathAction(Files::File *file) + : FileAction(file) { +} + +QString Files::CopyPathAction::text() const { + return "Copy path to clipboard"; +} + +void Files::CopyPathAction::activate() { + QApplication::clipboard()->setText(file_->filePath()); +} diff -Nru albert-0.12.0/plugins/files/src/fileactions.h albert-0.13.1+plugins1/plugins/files/src/fileactions.h --- albert-0.12.0/plugins/files/src/fileactions.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/fileactions.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,98 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include +#include "core/action.h" +#include "file.h" + +namespace Files { + +/** ***************************************************************************/ +struct FileAction : public Core::Action +{ + FileAction(File *file); + ~FileAction(); + File const * const file_; +}; + + + +/** ***************************************************************************/ +struct OpenFileAction final : public FileAction +{ + OpenFileAction(File *file); + QString text() const override; + void activate() override; +}; + + + +/** ***************************************************************************/ +struct RevealFileAction final : public FileAction +{ + RevealFileAction(File *file); + QString text() const override; + void activate() override; +}; + + + +/** ***************************************************************************/ +struct TerminalFileAction final : public FileAction +{ + TerminalFileAction(File *file); + QString text() const override; + void activate() override; +}; + + + +/** ***************************************************************************/ +struct ExecuteFileAction final : public FileAction +{ + ExecuteFileAction(File *file); + QString text() const override; + void activate() override; +}; + + + +/** ***************************************************************************/ +struct CopyFileAction final : public FileAction +{ + CopyFileAction(File *file); + QString text() const override; + void activate() override; +}; + + + +/** ***************************************************************************/ +struct CopyPathAction final : public FileAction +{ + CopyPathAction(File *file); + QString text() const override; + void activate() override; +}; + + +} diff -Nru albert-0.12.0/plugins/files/src/file.cpp albert-0.13.1+plugins1/plugins/files/src/file.cpp --- albert-0.12.0/plugins/files/src/file.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/file.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,108 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "file.h" +#include +#include +#include "xdg/iconlookup.h" +#include "fileactions.h" +using namespace std; + + +std::map Files::File::iconCache_; + + +/** ***************************************************************************/ +QString Files::File::id() const { + return filePath(); +} + + +/** ***************************************************************************/ +QString Files::File::text() const { + return name(); +} + + +/** ***************************************************************************/ +QString Files::File::subtext() const { + return path(); +} + + +/** ***************************************************************************/ +QString Files::File::completionString() const { + const QString &path = filePath(); + QString result = ( QFileInfo(path).isDir() ) ? QString("%1/").arg(path) : path; +#ifdef __linux__ + if ( result.startsWith(QDir::homePath()) ) + result.replace(QDir::homePath(), "~"); +#endif + return result; +} + + +/** ***************************************************************************/ +QString Files::File::iconPath() const { + + const QString xdgIconName = mimetype().iconName(); + + // First check if icon exists + auto search = iconCache_.find(xdgIconName); + if(search != iconCache_.end()) + return search->second; + + QString icon = XDG::IconLookup::iconPath({xdgIconName, mimetype().genericIconName(), "unknown"}); + if ( !icon.isEmpty() ) { + iconCache_.emplace(xdgIconName, icon); + return icon; + } + + // Nothing found, return a fallback icon + if ( xdgIconName == "inode-directory" ) { + icon = ":directory"; + iconCache_.emplace(xdgIconName, icon); + } else { + icon = ":unknown"; + iconCache_.emplace(xdgIconName, icon); + } + return icon; +} + + +/** ***************************************************************************/ +vector> Files::File::actions() { + vector> actions; + actions.push_back(std::make_shared(this)); + QFileInfo fileInfo(filePath()); + if ( fileInfo.isFile() && fileInfo.isExecutable() ) + actions.push_back(std::make_shared(this)); + actions.push_back(std::make_shared(this)); + actions.push_back(std::make_shared(this)); + actions.push_back(std::make_shared(this)); + actions.push_back(std::make_shared(this)); + return actions; +} + + + +/** ***************************************************************************/ +vector Files::File::indexStrings() const { + std::vector res; + res.emplace_back(name(), UINT_MAX); + // TODO ADD PATH + return res; +} diff -Nru albert-0.12.0/plugins/files/src/file.h albert-0.13.1+plugins1/plugins/files/src/file.h --- albert-0.12.0/plugins/files/src/file.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/file.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,56 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include "core/indexable.h" + +namespace Files { + +class File : public Core::IndexableItem +{ +public: + + QString id() const override; + QString text() const override; + QString subtext() const override; + QString completionString() const override; + QString iconPath() const override; + std::vector indexStrings() const override; + std::vector> actions() override; + + /** Return the filename of the file */ + virtual QString name() const = 0; + + /** Return the path exclusive the filename of the file */ + virtual QString path() const = 0; + + /** Return the path inclusive the filename of the file */ + virtual QString filePath() const = 0; + + /** Return the mimetype of the file */ + virtual const QMimeType &mimetype() const = 0; + +private: + + static std::map iconCache_; + +}; + +} diff -Nru albert-0.12.0/plugins/files/src/indexfile.cpp albert-0.13.1+plugins1/plugins/files/src/indexfile.cpp --- albert-0.12.0/plugins/files/src/indexfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/indexfile.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,50 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "indexfile.h" +#include "indextreenode.h" +using namespace std; + + + +/** ***************************************************************************/ +Files::IndexFile::IndexFile(QString name, const shared_ptr &pathNode, QMimeType mimetype) + : name_(name), pathNode_(pathNode), mimetype_(mimetype) { } + + +/** ***************************************************************************/ +QString Files::IndexFile::name() const { + return name_; +} + + +/** ***************************************************************************/ +QString Files::IndexFile::path() const { + return pathNode_->path(); +} + + +/** ***************************************************************************/ +QString Files::IndexFile::filePath() const { + return QDir(pathNode_->path()).filePath(name_); +} + +/** ***************************************************************************/ +const QMimeType &Files::IndexFile::mimetype() const { + return mimetype_; +} diff -Nru albert-0.12.0/plugins/files/src/indexfile.h albert-0.13.1+plugins1/plugins/files/src/indexfile.h --- albert-0.12.0/plugins/files/src/indexfile.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/indexfile.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include "file.h" + +namespace Files { + +class IndexTreeNode; + +class IndexFile : public File +{ +public: + + IndexFile(QString name, const std::shared_ptr &pathNode, QMimeType mimetype); + + QString name() const override; + QString path() const override; + QString filePath() const override; + const QMimeType &mimetype() const override; + +protected: + + + QString name_; + std::shared_ptr pathNode_; + QMimeType mimetype_; + +}; + +} diff -Nru albert-0.12.0/plugins/files/src/indextreenode.cpp albert-0.13.1+plugins1/plugins/files/src/indextreenode.cpp --- albert-0.12.0/plugins/files/src/indextreenode.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/indextreenode.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,320 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "indextreenode.h" +#include "indexfile.h" +using namespace std; + + +/**************************************************************************************************/ +Files::IndexTreeNode::IndexTreeNode() { } + + + +/**************************************************************************************************/ +Files::IndexTreeNode::IndexTreeNode(QString name, QDateTime lastModified, shared_ptr parent) + : enable_shared_from_this(), parent(parent), name(name), lastModified(lastModified) { } + + +/**************************************************************************************************/ +Files::IndexTreeNode::IndexTreeNode(QString name, shared_ptr parent) + : IndexTreeNode(name, QDateTime::fromMSecsSinceEpoch(0), parent) { } + + +/**************************************************************************************************/ +Files::IndexTreeNode::IndexTreeNode(const IndexTreeNode &other) + : enable_shared_from_this(), + children(other.children), + name(other.name), + lastModified(other.lastModified), + items_(other.items_) { } + + +/**************************************************************************************************/ +Files::IndexTreeNode::~IndexTreeNode() { + removeDownlinks(); +} + + +/**************************************************************************************************/ +void Files::IndexTreeNode::accept(Visitor &visitor) { + visitor.visit(this); + for ( auto & child : children ) + child->accept(visitor); +} + + +/**************************************************************************************************/ +void Files::IndexTreeNode::removeDownlinks() { + for ( shared_ptr & child : children ) + child->removeDownlinks(); + children.clear(); + items_.clear(); +} + + +/**************************************************************************************************/ +QString Files::IndexTreeNode::path() const { + return ( parent ) ? QDir(parent->path()).filePath(name) : name; +} + + +/**************************************************************************************************/ +void Files::IndexTreeNode::update(const bool &abort, IndexSettings indexSettings) { + + set indexedDirs; + QMimeDatabase mimeDatabase; + // ignore ignorefile by default + vector ignoreEntries = {IgnoreEntry( + QRegularExpression(QString("%1$").arg(IGNOREFILE)), + PatternType::Exclude)}; + // Start the indexing + updateRecursion(abort, mimeDatabase, indexSettings, indexedDirs, ignoreEntries); +} + + +/**************************************************************************************************/ +QJsonObject Files::IndexTreeNode::serialize(){ + + QJsonObject jsonNode; + + jsonNode.insert("name", this->name); + jsonNode.insert("lastmodified", this->lastModified.toString()); + + QJsonArray itemArray; + for ( const shared_ptr &file : items_ ) { + QJsonObject jsonFile; + jsonFile.insert("name", file->name()); + jsonFile.insert("mimetype", file->mimetype().name()); + itemArray.push_back(jsonFile); + } + jsonNode.insert("items", itemArray); + + QJsonArray nodeArray; + for ( const shared_ptr &childNode : children ) + nodeArray.push_back(childNode->serialize()); + jsonNode.insert("children", nodeArray); + + return jsonNode; +} + + +/**************************************************************************************************/ +void Files::IndexTreeNode::deserialize(const QJsonObject &object, shared_ptr parent) { + + this->parent = parent; + name = object["name"].toString(); + lastModified = QDateTime::fromString(object["lastmodified"].toString()); + + for (const QJsonValueRef child : object["children"].toArray()) { + children.push_back(make_shared()); // Invalid node + children.back()->deserialize(child.toObject(), shared_from_this()); + } + + for (const QJsonValueRef item : object["items"].toArray()){ + const QJsonObject &object = item.toObject(); + items_.push_back(make_shared( + object["name"].toString(), + shared_from_this(), + QMimeDatabase().mimeTypeForName(object["mimetype"].toString()))); + } +} + + +/**************************************************************************************************/ +const std::vector > &Files::IndexTreeNode::items() const { + return items_; +} + + +/**************************************************************************************************/ +void Files::IndexTreeNode::updateRecursion(const bool &abort, + const QMimeDatabase &mimeDatabase, + const IndexSettings &indexSettings, + set &indexedDirs, + const vector &ignoreEntries){ + + if (abort) return; + + const QFileInfo fileInfo(path()); + + // Skip if this dir has already been indexed (loop detection) + if ( indexedDirs.count(fileInfo.canonicalFilePath()) ) + return; + + + // Read the ignore file, see http://doc.qt.io/qt-5/qregexp.html#wildcard-matching + vector localIgnoreEntries = ignoreEntries; + QFile file(QDir(fileInfo.filePath()).filePath(IGNOREFILE)); + if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { + QTextStream in(&file); + while ( !in.atEnd() ) { + QString pattern = QDir::cleanPath(in.readLine()); + + if ( pattern.isEmpty() || pattern.startsWith("#") ) + continue; + + // Replace ** and * by their regex analogons + pattern.replace(QRegularExpression("(?path()) ) { + (*childIt)->removeDownlinks(); + childIt = children.erase(childIt); + } else + ++childIt; + + + // Handle the directory contents + // Prepare the iterator properties + QDir::Filters entryListFilters = QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden; + const QFileInfoList &fil = QDir(fileInfo.filePath()).entryInfoList(entryListFilters, QDir::Name); + for ( const QFileInfo &fileInfo : fil ){ + + bool isValid = true; + + // Skip check if this file should be excluded + PatternType patternType = PatternType::Include; + for ( const IgnoreEntry &ignoreEntry : localIgnoreEntries ) + if ( ignoreEntry.regex.match(fileInfo.filePath()).hasMatch() ) + patternType = ignoreEntry.type; + if ( patternType == PatternType::Exclude ) + isValid &= false; + + // Invalidate if this file is a symlink and we should skip symlinks + if ( fileInfo.isSymLink() && !indexSettings.followSymlinks() ) + isValid &= false; + + // Invalidate if this file is hidden we should skip hidden files + if ( fileInfo.isHidden() && !indexSettings.indexHidden() ) + isValid &= false; + + // Add directories as nodes + if ( fileInfo.isDir() ) { + + // Get the place where the item were if would exist in log(n) time + decltype(children)::iterator lb = lower_bound( + children.begin(), children.end(), fileInfo.fileName(), + [&](const shared_ptr & child, QString name) { + return child->name < name; + }); + + // If does not exist and is valid insert + if ( lb == children.end() || (*lb)->name != fileInfo.fileName() ) { + if (isValid) + children.insert(lb, make_shared(fileInfo.fileName(), shared_from_this())); + // If does exist and is invalid remove node + } else if (!isValid){ + (*lb)->removeDownlinks(); + children.erase(lb); + } + } + + // Add entries as items + const QMimeType mimetype = mimeDatabase.mimeTypeForFile(fileInfo.filePath()); + const QString mimeName = mimetype.name(); + + // If the entry is valid and a mime filter matches add it to the items + if (isValid && any_of(indexSettings.filters().begin(), indexSettings.filters().end(), + [&](const QRegExp &re){ return re.exactMatch(mimeName); }) ) + items_.push_back(make_shared(fileInfo.fileName(), + shared_from_this(), + mimetype)); + } + } + + // Recursively check all childnodes too + for ( const shared_ptr &child : children ) + child->updateRecursion(abort, mimeDatabase, indexSettings, indexedDirs, localIgnoreEntries); + +} + + +/**************************************************************************************************/ +/**************************************************************************************************/ + + +const std::vector &Files::IndexSettings::filters() const { + return mimefilters_; +} +void Files::IndexSettings::setFilters(std::vector value) { + forceUpdate_= true; + mimefilters_= value; +} +void Files::IndexSettings::setFilters(QStringList value) { + forceUpdate_= true; + mimefilters_.clear(); + for ( const QString &re : value ) + mimefilters_.emplace_back(re, Qt::CaseInsensitive, QRegExp::Wildcard); +} +bool Files::IndexSettings::indexHidden() const { + return indexHidden_; +} +void Files::IndexSettings::setIndexHidden(bool value) { + forceUpdate_= true; + indexHidden_= value; +} +bool Files::IndexSettings::followSymlinks() const { + return followSymlinks_; +} +void Files::IndexSettings::setFollowSymlinks(bool value) { + forceUpdate_= true; + followSymlinks_= value; +} +bool Files::IndexSettings::forceUpdate() const { + return forceUpdate_; +} +void Files::IndexSettings::setForceUpdate(bool value) { + forceUpdate_= value; +} + + +/**************************************************************************************************/ +/**************************************************************************************************/ diff -Nru albert-0.12.0/plugins/files/src/indextreenode.h albert-0.13.1+plugins1/plugins/files/src/indextreenode.h --- albert-0.12.0/plugins/files/src/indextreenode.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/indextreenode.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,121 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "indexfile.h" + +namespace Files { + +class Visitor; +class IndexSettings; + +enum class PatternType { + Include, + Exclude +}; + +struct IgnoreEntry { + IgnoreEntry(QRegularExpression regex, PatternType type) : regex(regex), type(type) {} + QRegularExpression regex; + PatternType type; +}; + +class IndexTreeNode final : public std::enable_shared_from_this +{ +public: + + IndexTreeNode(); + IndexTreeNode(const IndexTreeNode & other); + IndexTreeNode(QString name, QDateTime lastModified, std::shared_ptr parent = std::shared_ptr()); + IndexTreeNode(QString name, std::shared_ptr parent = std::shared_ptr()); + ~IndexTreeNode(); + + void accept(Visitor &visitor); + + void removeDownlinks(); + + QString path() const; + + void update(const bool &abort, IndexSettings indexSettings); + + QJsonObject serialize(); + void deserialize(const QJsonObject &, std::shared_ptr parent = std::shared_ptr()); + + const std::vector > &items() const; + +private: + + void updateRecursion(const bool &abort, + const QMimeDatabase &mimeDatabase, + const IndexSettings &indexSettings, + std::set &indexedDirs, + const std::vector &ignoreEntries); + + std::shared_ptr parent; + std::vector> children; + QString name; + QDateTime lastModified; + std::vector> items_; + + static constexpr const char* IGNOREFILE = ".albertignore"; + +}; + + +/** ***********************************************************************************************/ +class IndexSettings +{ +public: + const std::vector &filters() const; + void setFilters(std::vector value); + void setFilters(QStringList value); + + bool indexHidden() const; + void setIndexHidden(bool value); + + bool followSymlinks() const; + void setFollowSymlinks(bool value); + + bool forceUpdate() const; + void setForceUpdate(bool value); + +private: + + std::vector mimefilters_; + bool indexHidden_ = false; + bool followSymlinks_ = false; + bool forceUpdate_ = false; // Ignore lastModified, force update + +}; + + +/** ***********************************************************************************************/ +class Visitor { +public: + virtual ~Visitor() { } + virtual void visit(IndexTreeNode *) = 0; +}; + +} diff -Nru albert-0.12.0/plugins/files/src/mimetypedialog.cpp albert-0.13.1+plugins1/plugins/files/src/mimetypedialog.cpp --- albert-0.12.0/plugins/files/src/mimetypedialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/mimetypedialog.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,134 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include "mimetypedialog.h" +#include "ui_mimetypedialog.h" + + +/** ***************************************************************************/ +Files::MimeTypeDialog::MimeTypeDialog(const QStringList &filters, QWidget *parent) : + QDialog(parent), ui(new Ui::MimeTypeDialog) { + ui->setupUi(this); + + // Populate a standard itemmodel with mime types + QStandardItemModel *standardItemModel = new QStandardItemModel(this); + for (QMimeType mimeType : QMimeDatabase().allMimeTypes()) { + QStandardItem *item = new QStandardItem; + item->setText(mimeType.name()); + item->setToolTip(mimeType.filterString()); + standardItemModel->appendRow(item); + } + standardItemModel->sort(0); + + // Add a proxy model for mimtype filtering + QSortFilterProxyModel *mimeFilterModel = new QSortFilterProxyModel(this); + mimeFilterModel->setSourceModel(standardItemModel); + ui->listView_mimeTypes->setModel(mimeFilterModel); + + // Add a stinglist model to the filter model + filtersModel = new QStringListModel(filters, this); + ui->listView_filters->setModel(filtersModel); + + // Set the filter for the proxymodel if the users typed something + connect(ui->lineEdit, &QLineEdit::textChanged, + mimeFilterModel, &QSortFilterProxyModel::setFilterFixedString); + + // On mimetype list activation add the mimetype to the filter list + connect(ui->listView_mimeTypes, &QListView::activated, [this](const QModelIndex &index){ + filtersModel->insertRow(filtersModel->rowCount()); + filtersModel->setData(filtersModel->index(filtersModel->rowCount()-1,0), index.data()); + }); + + // On ">" button click add the mimetype to the filter list + connect(ui->toolButton_copyMimetype, &QToolButton::clicked, [this](){ + QModelIndex index = ui->listView_mimeTypes->currentIndex(); + filtersModel->insertRow(filtersModel->rowCount()); + filtersModel->setData(filtersModel->index(filtersModel->rowCount()-1,0), index.data()); + }); + + // Add a new line on "+" + connect(ui->toolButton_add, &QToolButton::clicked, [this](){ + int row = filtersModel->rowCount(); + filtersModel->insertRow(row); + ui->listView_filters->setCurrentIndex(filtersModel->index(row, 0)); + ui->listView_filters->edit(filtersModel->index(row, 0)); + }); + + // Remove the selected line on "-" + connect(ui->toolButton_remove, &QToolButton::clicked, [this](){ + QModelIndex index = ui->listView_filters->currentIndex(); + if ( index.isValid() ) + filtersModel->removeRow(index.row()); + }); + + // Let the listview intercept the input of the filter line edit (for navigation and activation) + ui->lineEdit->installEventFilter(this); +} + + + +/** ***************************************************************************/ +Files::MimeTypeDialog::~MimeTypeDialog() { + delete ui; +} + + + +/** ***************************************************************************/ +QStringList Files::MimeTypeDialog::filters() const { + return filtersModel->stringList(); +} + + + +/** ***************************************************************************/ +bool Files::MimeTypeDialog::eventFilter(QObject * /*theres only the linedit*/, QEvent *event) { + + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + switch (keyEvent->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Enter: + case Qt::Key_Return: + QApplication::sendEvent(ui->listView_mimeTypes, keyEvent); + return true; + default: + return false; + } + } + return false; +} + + + +/** ***************************************************************************/ +void Files::MimeTypeDialog::keyPressEvent(QKeyEvent *evt) { + // Eat keys for desired behaviour + switch ( evt->key() ) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + return; + } + QDialog::keyPressEvent(evt); +} diff -Nru albert-0.12.0/plugins/files/src/mimetypedialog.h albert-0.13.1+plugins1/plugins/files/src/mimetypedialog.h --- albert-0.12.0/plugins/files/src/mimetypedialog.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/mimetypedialog.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,46 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include + +namespace Files{ +namespace Ui { +class MimeTypeDialog; +} + +class MimeTypeDialog : public QDialog +{ + Q_OBJECT + +public: + + explicit MimeTypeDialog(const QStringList &filters, QWidget *parent = 0); + ~MimeTypeDialog(); + + QStringList filters() const; + +protected: + + bool eventFilter(QObject *watched, QEvent *event) override; + void keyPressEvent(QKeyEvent *evt) override; + + QStringListModel *filtersModel; + Ui::MimeTypeDialog *ui; + +}; +} diff -Nru albert-0.12.0/plugins/files/src/mimetypedialog.ui albert-0.13.1+plugins1/plugins/files/src/mimetypedialog.ui --- albert-0.12.0/plugins/files/src/mimetypedialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/mimetypedialog.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,165 @@ + + + Files::MimeTypeDialog + + + + 0 + 0 + 512 + 380 + + + + MIME filters + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + <html><head/><body><p style=" color:#808080;"> +Choose the MIME types you want to be indexed by the files extension. The left box contains the known MIME types. Use it to find your desired MIME types. The right box contains the list of patterns that is used to filter the indexed files by matching their MIME type. The patterns support wildcard matching. Check the <a href="https://albertlauncher.github.io/docs/extensions/files/#mime-filters">docs</a> for more details and examples. +</p></body></html> + + + true + + + + + + + + + + + Qt::ScrollBarAlwaysOn + + + QAbstractItemView::EditKeyPressed + + + QAbstractItemView::DropOnly + + + true + + + + + + + Filter for the mimetypes… + + + + + + + + + + + > + + + + .. + + + + + + + + + + + Drop files into the list to add their mimetypes or choose a mimetype from the complete list using the "Add mimetype" button. + + + Qt::ScrollBarAlwaysOn + + + + + + + + + + .. + + + + + + + + .. + + + + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Files::MimeTypeDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Files::MimeTypeDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff -Nru albert-0.12.0/plugins/files/src/standardfile.cpp albert-0.13.1+plugins1/plugins/files/src/standardfile.cpp --- albert-0.12.0/plugins/files/src/standardfile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/standardfile.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "standardfile.h" +using namespace std; + + +/** ***************************************************************************/ +Files::StandardFile::StandardFile(QString path, QMimeType mimetype) + : mimetype_(mimetype){ + QFileInfo fileInfo(path); + name_ = fileInfo.fileName(); + path_ = fileInfo.canonicalPath(); +} + + +/** ***************************************************************************/ +QString Files::StandardFile::name() const { + return name_; +} + + +/** ***************************************************************************/ +QString Files::StandardFile::path() const { + return path_; +} + + +/** ***************************************************************************/ +QString Files::StandardFile::filePath() const { + return QDir(path_).filePath(name_); +} + +/** ***************************************************************************/ +const QMimeType &Files::StandardFile::mimetype() const { + return mimetype_; +} diff -Nru albert-0.12.0/plugins/files/src/standardfile.h albert-0.13.1+plugins1/plugins/files/src/standardfile.h --- albert-0.12.0/plugins/files/src/standardfile.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/files/src/standardfile.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,45 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include "file.h" + +namespace Files { + +class StandardFile : public File +{ +public: + + StandardFile(QString path, QMimeType mimetype); + + QString name() const override; + QString path() const override; + QString filePath() const override; + const QMimeType &mimetype() const override; + +protected: + + QString name_; + QString path_; + QMimeType mimetype_; + +}; + +} diff -Nru albert-0.12.0/plugins/firefoxbookmarks/CMakeLists.txt albert-0.13.1+plugins1/plugins/firefoxbookmarks/CMakeLists.txt --- albert-0.12.0/plugins/firefoxbookmarks/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(firefoxbookmarks) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Concurrent Sql) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + ${Qt5Sql_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/firefoxbookmarks/firefoxbookmarks.qrc albert-0.13.1+plugins1/plugins/firefoxbookmarks/firefoxbookmarks.qrc --- albert-0.12.0/plugins/firefoxbookmarks/firefoxbookmarks.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/firefoxbookmarks.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/favicon.png + + diff -Nru albert-0.12.0/plugins/firefoxbookmarks/metadata.json albert-0.13.1+plugins1/plugins/firefoxbookmarks/metadata.json --- albert-0.12.0/plugins/firefoxbookmarks/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.firefoxbookmarks", + "name" : "Firefox bookmarks", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "Martin Buergmann, Manuel Schneider", + "dependencies" : ["firefox"], + "enabledbydefault": false +} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/firefoxbookmarks/resources/favicon.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/firefoxbookmarks/resources/favicon.png differ diff -Nru albert-0.12.0/plugins/firefoxbookmarks/src/configwidget.cpp albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/configwidget.cpp --- albert-0.12.0/plugins/firefoxbookmarks/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +FirefoxBookmarks::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +FirefoxBookmarks::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/firefoxbookmarks/src/configwidget.h albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/configwidget.h --- albert-0.12.0/plugins/firefoxbookmarks/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace FirefoxBookmarks { +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/firefoxbookmarks/src/configwidget.ui albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/configwidget.ui --- albert-0.12.0/plugins/firefoxbookmarks/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,68 @@ + + + FirefoxBookmarks::ConfigWidget + + + + 0 + 0 + 480 + 320 + + + + + + + Select your firefox profile: + + + + + + + + + + Fuzzy Search + + + true + + + + + + + Open with firefox by default + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/firefoxbookmarks/src/extension.cpp albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/extension.cpp --- albert-0.12.0/plugins/firefoxbookmarks/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,455 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extension.h" +#include "configwidget.h" +#include "core/extension.h" +#include "core/item.h" +#include "core/query.h" +#include "util/offlineindex.h" +#include "util/standardaction.h" +#include "util/standardindexitem.h" +#include "xdg/iconlookup.h" +using std::pair; +using std::shared_ptr; +using std::vector; +using namespace Core; + +namespace { +const QString CFG_PROFILE = "profile"; +const QString CFG_FUZZY = "fuzzy"; +const bool DEF_FUZZY = false; +const QString CFG_USE_FIREFOX = "openWithFirefox"; +const bool DEF_USE_FIREFOX = false; +const uint UPDATE_DELAY = 60000; +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +class FirefoxBookmarks::Private +{ +public: + Private(Extension *q) : q(q) {} + + Extension *q; + + bool openWithFirefox; + QPointer widget; + QString firefoxExecutable; + QString profilesIniPath; + QString currentProfileId; + QFileSystemWatcher databaseWatcher; + + vector> index; + Core::OfflineIndex offlineIndex; + + QTimer updateDelayTimer; + void startIndexing(); + void finishIndexing(); + QFutureWatcher>> futureWatcher; + std::vector> indexFirefoxBookmarks() const; +}; + + +/** ***************************************************************************/ +void FirefoxBookmarks::Private::startIndexing() { + + // Never run concurrent + if ( futureWatcher.future().isRunning() ) + return; + + // Run finishIndexing when the indexing thread finished + futureWatcher.disconnect(); + QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, + std::bind(&Private::finishIndexing, this)); + + // Run the indexer thread + futureWatcher.setFuture(QtConcurrent::run(this, &Private::indexFirefoxBookmarks)); + + // Notification + qInfo() << "Start indexing Firefox bookmarks."; + emit q->statusInfo("Indexing bookmarks ..."); +} + + +/** ***************************************************************************/ +void FirefoxBookmarks::Private::finishIndexing() { + + // Get the thread results + index = futureWatcher.future().result(); + + // Rebuild the offline index + offlineIndex.clear(); + for (const auto &item : index) + offlineIndex.add(item); + + // Notification + qInfo() << qPrintable(QString("Indexed %1 Firefox bookmarks.").arg(index.size())); + emit q->statusInfo(QString("%1 bookmarks indexed.").arg(index.size())); +} + + + +/** ***************************************************************************/ +vector> +FirefoxBookmarks::Private::indexFirefoxBookmarks() const { + + QSqlDatabase database = QSqlDatabase::database(q->Core::Plugin::id()); + + if (!database.open()) { + qWarning() << qPrintable(QString("Could not open Firefox database: %1").arg(database.databaseName())); + return vector>(); + } + + // Build a new index + vector> bookmarks; + + QSqlQuery result(database); + + if ( !result.exec("SELECT b.guid, b.title, p.url " + "FROM moz_bookmarks b " + "JOIN moz_places p ON b.fk = p.id " // attach place (which has the url) + "WHERE p.url NOT LIKE 'place%'") ) { // Those with place:... will not work with xdg-open + qWarning() << qPrintable(QString("Querying Firefox bookmarks failed: %1").arg(result.lastError().text())); + return vector>(); + } + + // Find an appropriate icon + QString icon = XDG::IconLookup::iconPath({"www", "web-browser", "emblem-web"}); + icon = icon.isEmpty() ? ":favicon" : icon; + + while (result.next()) { + + // Url will be used more often + QString urlstr = result.value(2).toString(); + + // Create item + shared_ptr ssii = std::make_shared(result.value(0).toString()); + ssii->setText(result.value(1).toString()); + ssii->setSubtext(urlstr); + ssii->setIconPath(icon); + + // Add severeal secondary index keywords + vector indexStrings; + QUrl url(urlstr); + QString host = url.host(); + indexStrings.emplace_back(ssii->text(), UINT_MAX); + indexStrings.emplace_back(host.left(host.size()-url.topLevelDomain().size()), UINT_MAX/2); + indexStrings.emplace_back(result.value(2).toString(), UINT_MAX/4); // parent dirname + ssii->setIndexKeywords(std::move(indexStrings)); + + // Add actions + vector> actions; + + shared_ptr actionDefault = std::make_shared(); + actionDefault->setText("Open URL in your default browser"); + actionDefault->setAction([urlstr](){ + QDesktopServices::openUrl(QUrl(urlstr)); + }); + + shared_ptr actionFirefox = std::make_shared(); + actionFirefox->setText("Open URL in Firefox"); + actionFirefox->setAction([urlstr, this](){ + QProcess::startDetached(firefoxExecutable, {urlstr}); + }); + + shared_ptr actionNewFirefox = std::make_shared(); + actionNewFirefox->setText("Open URL in new Firefox window"); + actionNewFirefox->setAction([urlstr, this](){ + QProcess::startDetached(firefoxExecutable, {"--new-window", urlstr}); + }); + + shared_ptr action = std::make_shared(); + action->setText("Copy url to clipboard"); + action->setAction([urlstr](){ QApplication::clipboard()->setText(urlstr); }); + + // Set the order of the actions + if ( openWithFirefox ) { + actions.push_back(std::move(actionFirefox)); + actions.push_back(std::move(actionNewFirefox)); + actions.push_back(std::move(actionDefault)); + } else { + actions.push_back(std::move(actionDefault)); + actions.push_back(std::move(actionFirefox)); + actions.push_back(std::move(actionNewFirefox)); + } + actions.push_back(std::move(action)); + + ssii->setActions(std::move(actions)); + + bookmarks.push_back(std::move(ssii)); + } + + return bookmarks; +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +FirefoxBookmarks::Extension::Extension() + : Core::Extension("org.albert.extension.firefoxbookmarks"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private(this)){ + + registerQueryHandler(this); + + // Add a sqlite database connection for this extension, check requirements + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", Core::Plugin::id()); + if ( !db.isValid() ) + throw "Firefox executable not found."; + if (!db.driver()->hasFeature(QSqlDriver::Transactions)) + throw "Firefox executable not found."; + + // Find firefox executable + d->firefoxExecutable = QStandardPaths::findExecutable("firefox"); + if (d->firefoxExecutable.isEmpty()) + throw "Firefox executable not found."; + + // Locate profiles ini + d->profilesIniPath = QStandardPaths::locate(QStandardPaths::HomeLocation, + ".mozilla/firefox/profiles.ini", + QStandardPaths::LocateFile); + if (d->profilesIniPath.isEmpty()) // Try a windowsy approach + d->profilesIniPath = QStandardPaths::locate(QStandardPaths::DataLocation, + "Mozilla/firefox/profiles.ini", + QStandardPaths::LocateFile); + if (d->profilesIniPath.isEmpty()) + throw "Could not locate profiles.ini."; + + // Load the settings + d->currentProfileId = settings().value(CFG_PROFILE).toString(); + d->offlineIndex.setFuzzy(settings().value(CFG_FUZZY, DEF_FUZZY).toBool()); + d->openWithFirefox = settings().value(CFG_USE_FIREFOX, DEF_USE_FIREFOX).toBool(); + + // If the id does not exist find a proper default + QSettings profilesIni(d->profilesIniPath, QSettings::IniFormat); + if ( !profilesIni.contains(d->currentProfileId) ){ + + d->currentProfileId = QString(); + + QStringList ids = profilesIni.childGroups(); + if ( ids.isEmpty() ) + qWarning() << "No Firefox profiles found."; + else { + + // Use the last used profile + if ( d->currentProfileId.isNull() ) { + for (QString &id : ids) { + profilesIni.beginGroup(id); + if ( profilesIni.contains("Default") + && profilesIni.value("Default").toBool() ) { + d->currentProfileId = id; + } + profilesIni.endGroup(); + } + } + + // Use the default profile + if ( d->currentProfileId.isNull() && ids.contains("default")) { + d->currentProfileId = "default"; + } + + // Use the first + d->currentProfileId = ids[0]; + } + } + + // Set the profile + setProfile(d->currentProfileId); + + // Delay the indexing to avoid excessice resource consumption + d->updateDelayTimer.setInterval(UPDATE_DELAY); + d->updateDelayTimer.setSingleShot(true); + + // If the database changed, trigger the update delay + connect(&d->databaseWatcher, &QFileSystemWatcher::fileChanged, + &d->updateDelayTimer, static_cast(&QTimer::start)); + + // If the update delay passed, update the index + connect(&d->updateDelayTimer, &QTimer::timeout, + std::bind(&Private::startIndexing, d.get())); +} + + + +/** ***************************************************************************/ +FirefoxBookmarks::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *FirefoxBookmarks::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + + // Get the profiles keys + QSettings profilesIni(d->profilesIniPath, QSettings::IniFormat); + QStringList groups = profilesIni.childGroups(); + + // Extract all profiles and names and put it in the checkbox + QComboBox *cmb = d->widget->ui.comboBox; + for (QString &profileId : groups) { + profilesIni.beginGroup(profileId); + + // Use name if available else id + if ( profilesIni.contains("Name") ) + cmb->addItem( QString("%1 (%2)").arg(profilesIni.value("Name").toString(), profileId), profileId); + else { + cmb->addItem(profileId, profileId); + qWarning() << qPrintable(QString("Firefox profile '%1' does not contain a name.").arg(profileId)); + } + + // If the profileId match set the current item of the checkbox + if (profileId == d->currentProfileId) + cmb->setCurrentIndex(cmb->count() - 1); + + profilesIni.endGroup(); + } + + connect(cmb, static_cast(&QComboBox::currentIndexChanged), + this, &Extension::setProfile); + + // Fuzzy + QCheckBox *ckb = d->widget->ui.fuzzy; + ckb->setChecked(d->offlineIndex.fuzzy()); + connect(ckb, &QCheckBox::clicked, this, &Extension::changeFuzzyness); + + // Which app to use + ckb = d->widget->ui.openWithFirefox; + ckb->setChecked(d->openWithFirefox); + connect(ckb, &QCheckBox::clicked, this, &Extension::changeOpenPolicy); + + // Status bar + ( d->futureWatcher.isRunning() ) + ? d->widget->ui.label_statusbar->setText("Indexing bookmarks ...") + : d->widget->ui.label_statusbar->setText(QString("%1 bookmarks indexed.").arg(d->index.size())); + connect(this, &Extension::statusInfo, d->widget->ui.label_statusbar, &QLabel::setText); + + } + return d->widget; +} + + + +/** ***************************************************************************/ +void FirefoxBookmarks::Extension::handleQuery(Core::Query *query) const { + + const vector> &indexables = d->offlineIndex.search(query->string()); + + vector,uint>> results; + for (const shared_ptr &item : indexables) + results.emplace_back(std::static_pointer_cast(item), 0); + + query->addMatches(std::make_move_iterator(results.begin()), + std::make_move_iterator(results.end())); +} + + + +/** ***************************************************************************/ +void FirefoxBookmarks::Extension::setProfile(const QString& profile) { + + d->currentProfileId = profile; + + QSettings profilesIni(d->profilesIniPath, QSettings::IniFormat); + + // Check if profile id is in profiles file + if ( !profilesIni.childGroups().contains(d->currentProfileId) ){ + qWarning() << qPrintable(QString("Firefox user profile '%2' not found.").arg(d->currentProfileId)); + return; + } + + // Enter the group + profilesIni.beginGroup(d->currentProfileId); + + // Check if the profile contains a path key + if ( !profilesIni.contains("Path") ){ + qWarning() << qPrintable(QString("Firefox profile '%2' does not contain a path.").arg(d->currentProfileId)); + return; + } + + // Get the correct absolute profile path + QString profilePath = ( profilesIni.contains("IsRelative") && profilesIni.value("IsRelative").toBool()) + ? QFileInfo(d->profilesIniPath).dir().absoluteFilePath(profilesIni.value("Path").toString()) + : profilesIni.value("Path").toString(); + + // Build the database path + QString dbPath = QString("%1/places.sqlite").arg(profilePath); + + // Set the databases path + QSqlDatabase db = QSqlDatabase::database(Core::Plugin::id()); + db.setDatabaseName(dbPath); + + // Set a file system watcher on the database monitoring changes + if (!d->databaseWatcher.files().isEmpty()) + d->databaseWatcher.removePaths(d->databaseWatcher.files()); + d->databaseWatcher.addPath(dbPath); + + d->startIndexing(); + + settings().setValue(CFG_PROFILE, d->currentProfileId); +} + + + +/** ***************************************************************************/ +void FirefoxBookmarks::Extension::changeFuzzyness(bool fuzzy) { + d->offlineIndex.setFuzzy(fuzzy); + settings().setValue(CFG_FUZZY, fuzzy); +} + + + +/** ***************************************************************************/ +void FirefoxBookmarks::Extension::changeOpenPolicy(bool useFirefox) { + d->openWithFirefox = useFirefox; + settings().setValue(CFG_USE_FIREFOX, useFirefox); + d->startIndexing(); +} diff -Nru albert-0.12.0/plugins/firefoxbookmarks/src/extension.h albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/extension.h --- albert-0.12.0/plugins/firefoxbookmarks/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/firefoxbookmarks/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,55 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "core/extension.h" +#include "core/queryhandler.h" +#include + +namespace FirefoxBookmarks { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Firefox bookmarks"; } + QWidget *widget(QWidget *parent = nullptr) override; + void handleQuery(Core::Query * query) const override; + + void setProfile(const QString &profile); + void changeFuzzyness(bool fuzzy); + void changeOpenPolicy(bool withFirefox); + +private: + + std::unique_ptr d; + +signals: + + void statusInfo(const QString&); +}; +} diff -Nru albert-0.12.0/plugins/hashgenerator/CMakeLists.txt albert-0.13.1+plugins1/plugins/hashgenerator/CMakeLists.txt --- albert-0.12.0/plugins/hashgenerator/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(hashgenerator) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/hashgenerator/hashgenerator.qrc albert-0.13.1+plugins1/plugins/hashgenerator/hashgenerator.qrc --- albert-0.12.0/plugins/hashgenerator/hashgenerator.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/hashgenerator.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/hash.svg + + diff -Nru albert-0.12.0/plugins/hashgenerator/metadata.json albert-0.13.1+plugins1/plugins/hashgenerator/metadata.json --- albert-0.12.0/plugins/hashgenerator/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,9 @@ +{ + "id" : "org.albert.extension.hashgenerator", + "name" : "Hash Generator", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "manuelschneid3r", + "dependencies" : [] +} diff -Nru albert-0.12.0/plugins/hashgenerator/resources/hash.svg albert-0.13.1+plugins1/plugins/hashgenerator/resources/hash.svg --- albert-0.12.0/plugins/hashgenerator/resources/hash.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/resources/hash.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ +Width: 2pxBlur: 12Opacity: 60 \ No newline at end of file diff -Nru albert-0.12.0/plugins/hashgenerator/src/configwidget.cpp albert-0.13.1+plugins1/plugins/hashgenerator/src/configwidget.cpp --- albert-0.12.0/plugins/hashgenerator/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +HashGenerator::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +HashGenerator::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/hashgenerator/src/configwidget.h albert-0.13.1+plugins1/plugins/hashgenerator/src/configwidget.h --- albert-0.12.0/plugins/hashgenerator/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace HashGenerator { +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/hashgenerator/src/configwidget.ui albert-0.13.1+plugins1/plugins/hashgenerator/src/configwidget.ui --- albert-0.12.0/plugins/hashgenerator/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,46 @@ + + + HashGenerator::ConfigWidget + + + + 0 + 0 + 480 + 320 + + + + + + + <html> +<head/> +<body> +<p>This is a simple hashing extension. Just type &quot;hash &quot; and the string you would like to hash. You will get a list of items containing the hash value of your string generated with the state of the art hashing algorithms. You can also compute the hash you want directly by using the hash name as prefix, e.g. &quot;md5 Hello world&quot;.</p> +</body> +</html> + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/hashgenerator/src/extension.cpp albert-0.13.1+plugins1/plugins/hashgenerator/src/extension.cpp --- albert-0.12.0/plugins/hashgenerator/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,135 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "core/item.h" +#include "core/query.h" +#include "util/standarditem.h" +#include "util/standardaction.h" +#include "extension.h" +using namespace std; +using namespace Core; + +namespace { +const QStringList algorithmNames = { + "MD4", + "MD5", + "SHA1", + "SHA224", + "SHA256", + "SHA384", + "SHA512", + "SHA3_224", + "SHA3_256", + "SHA3_384", + "SHA3_512" +}; +} + + +class HashGenerator::Private +{ +public: + QPointer widget; +}; + + + +/** ***************************************************************************/ +HashGenerator::Extension::Extension() + : Core::Extension("org.albert.extension.hashgenerator"), // Must match the id in metadata + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + registerQueryHandler(this); +} + + + +/** ***************************************************************************/ +HashGenerator::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *HashGenerator::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + } + return d->widget; +} + + + +/** ***************************************************************************/ +QStringList HashGenerator::Extension::triggers() const { + return { + "hash ", + "md4 ", + "md5 ", + "sha1 ", + "sha224 ", + "sha256 ", + "sha384 ", + "sha512 ", + "sha3_224 ", + "sha3_256 ", + "sha3_384 ", + "sha3_512 " + }; +} + + +/** ***************************************************************************/ +void HashGenerator::Extension::handleQuery(Core::Query * query) const { + + auto buildItem = [](int algorithm, QString string){ + QCryptographicHash hash(static_cast(algorithm)); + hash.addData(string.toUtf8()); + QByteArray hashString = hash.result().toHex(); + + shared_ptr item = std::make_shared(algorithmNames[algorithm]); + item->setText(QString("%1 of '%2'").arg(algorithmNames[algorithm], string)); + item->setSubtext(hashString); + item->setIconPath(":hash"); + item->setCompletionString(QString("%1 %2").arg(algorithmNames[algorithm].toLower(), string)); + item->setActions({std::make_shared( + QString("Copy hash value to clipboard"), + [=](){QApplication::clipboard()->setText(QString(hashString));})}); + return item; + }; + + if ( query->trigger() == "hash " ) { + // Output all hashes + for (int algorithm = 0; algorithm < 11; ++algorithm) + query->addMatch(buildItem(algorithm, query->string())); + } else { + // Output particular hash if name matches + auto it = std::find(algorithmNames.begin(), algorithmNames.end(), + query->trigger().trimmed().toUpper()); + if (it != algorithmNames.end()) { + int algorithm = static_cast(std::distance(algorithmNames.begin(), it)); + query->addMatch(buildItem(algorithm, query->string())); + } + } +} + diff -Nru albert-0.12.0/plugins/hashgenerator/src/extension.h albert-0.13.1+plugins1/plugins/hashgenerator/src/extension.h --- albert-0.12.0/plugins/hashgenerator/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/hashgenerator/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,49 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace HashGenerator { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Hash Generator"; } + QWidget *widget(QWidget *parent = nullptr) override; + QStringList triggers() const override; + void handleQuery(Core::Query * query) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/kvstore/CMakeLists.txt albert-0.13.1+plugins1/plugins/kvstore/CMakeLists.txt --- albert-0.12.0/plugins/kvstore/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(kvstore) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Sql) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Sql_LIBRARIES} + albertcore +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/kvstore/kvstore.qrc albert-0.13.1+plugins1/plugins/kvstore/kvstore.qrc --- albert-0.12.0/plugins/kvstore/kvstore.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/kvstore.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/kv.svg + + diff -Nru albert-0.12.0/plugins/kvstore/metadata.json albert-0.13.1+plugins1/plugins/kvstore/metadata.json --- albert-0.12.0/plugins/kvstore/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,9 @@ +{ + "id" : "org.albert.extension.kvstore", + "name" : "Key Value Store", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "manuelschneid3r", + "dependencies" : [] +} diff -Nru albert-0.12.0/plugins/kvstore/resources/kv.svg albert-0.13.1+plugins1/plugins/kvstore/resources/kv.svg --- albert-0.12.0/plugins/kvstore/resources/kv.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/resources/kv.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + battery + apm + acpi + power management + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/kvstore/src/configwidget.cpp albert-0.13.1+plugins1/plugins/kvstore/src/configwidget.cpp --- albert-0.12.0/plugins/kvstore/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,47 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +KeyValueStore::ConfigWidget::ConfigWidget(QSqlDatabase *db, QWidget *parent) : QWidget(parent) { + ui.setupUi(this); + + model = new QSqlTableModel(this, *db); + model->setTable("kv"); + model->setEditStrategy(QSqlTableModel::OnFieldChange); + model->setHeaderData(0, Qt::Horizontal, tr("Key")); + model->setHeaderData(1, Qt::Horizontal, tr("Value")); + model->setSort(0, Qt::SortOrder::AscendingOrder); + model->select(); + + ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui.tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui.tableView->setModel(model); + +} + + +/** ***************************************************************************/ +KeyValueStore::ConfigWidget::~ConfigWidget() { + +} + + +/** ***************************************************************************/ +void KeyValueStore::ConfigWidget::updateTable() { + model->select(); +} diff -Nru albert-0.12.0/plugins/kvstore/src/configwidget.h albert-0.13.1+plugins1/plugins/kvstore/src/configwidget.h --- albert-0.12.0/plugins/kvstore/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,41 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "ui_configwidget.h" + +namespace KeyValueStore { +class ConfigWidget final : public QWidget +{ + Q_OBJECT + +public: + + explicit ConfigWidget(QSqlDatabase *db, QWidget *parent = nullptr); + ~ConfigWidget(); + Ui::ConfigWidget ui; + + void updateTable(); + +private: + + QSqlTableModel *model; + +}; +} diff -Nru albert-0.12.0/plugins/kvstore/src/configwidget.ui albert-0.13.1+plugins1/plugins/kvstore/src/configwidget.ui --- albert-0.12.0/plugins/kvstore/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,58 @@ + + + KeyValueStore::ConfigWidget + + + + 0 + 0 + 274 + 342 + + + + + + + <html> +<head/> +<body> +<p>This extension lets you store values by key and look them up by the key. Trigger the extension by typing &quot;kv &quot; to show the entries. Further characters act as a filter on the keys. Note that the lookup works without the trigger too. Type &quot;kv set &lt;key&gt; &lt;value&gt;&quot; or &quot;kv unset &lt;key&gt;&quot; to set and unset mappings.</p> +</body> +</html> + + + true + + + + + + + true + + + QAbstractItemView::SingleSelection + + + false + + + false + + + false + + + true + + + false + + + + + + + + diff -Nru albert-0.12.0/plugins/kvstore/src/extension.cpp albert-0.13.1+plugins1/plugins/kvstore/src/extension.cpp --- albert-0.12.0/plugins/kvstore/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,182 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "core/item.h" +#include "core/query.h" +#include "util/standarditem.h" +#include "util/standardaction.h" +#include "extension.h" +using namespace std; +using namespace Core; + +namespace { +const QString insertStmt = "INSERT OR REPLACE INTO kv (key, value) VALUES (:key, :value);"; +const QString removeStmt = "DELETE FROM kv WHERE key=:key;"; +} + + +class KeyValueStore::Private +{ +public: + QPointer widget; + QSqlDatabase db; +}; + + +/** ***************************************************************************/ +KeyValueStore::Extension::Extension() + : Core::Extension("org.albert.extension.kvstore"), // Must match the id in metadata + Core::QueryHandler(Plugin::id()), + d(new Private) { + + d->db = QSqlDatabase::addDatabase("QSQLITE", Plugin::id()); + if ( !d->db.isValid() ) + throw("No SQLite driver available"); + + d->db.setDatabaseName(configLocation().filePath("kvstore.db")); + if (!d->db.open()) + throw("Unable to establish a database connection."); + + d->db.transaction(); + + // Create tables + QSqlQuery q(d->db); + if (!q.exec("CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value NOT NULL);")) + throw("Unable to create table."); + + d->db.commit(); + + + registerQueryHandler(this); +} + + +/** ***************************************************************************/ +KeyValueStore::Extension::~Extension() { + +} + + +/** ***************************************************************************/ +QWidget *KeyValueStore::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(&d->db, parent); + } + return d->widget; +} + + +/** ***************************************************************************/ +void KeyValueStore::Extension::handleQuery(Core::Query * query) const { + + if ( query->isTriggered() ) { + + QString sec1 = query->string().section(' ', 0, 0, QString::SectionSkipEmpty); + + // SETTING + if ( sec1 == "set" ){ + QString key = query->string().section(' ', 1, 1, QString::SectionSkipEmpty); + QString value = query->string().section(' ', 2, -1, QString::SectionSkipEmpty); + + if ( key.isEmpty() || value.isEmpty() ) + return; + + shared_ptr item = std::make_shared(); + item->setText(QString("Set '%1': '%2'").arg(key, value)); + item->setSubtext(QString("Store this mapping in the database.")); + item->setIconPath(":kv"); + item->setCompletionString(query->string()); + item->setActions({std::make_shared( + QString("Add mapping to the database"), + [this, key, value](){ + QSqlQuery q(d->db); + q.prepare(insertStmt); + q.bindValue(":key", key); + q.bindValue(":value", value); + q.exec(); + if (this->d->widget) + this->d->widget->updateTable(); + }) + }); + query->addMatch(move(item)); + } + + // UNSETTING + else if ( sec1 == "unset" ){ + QString searchterm = query->string().section(' ', 1, -1, QString::SectionSkipEmpty); + QSqlQuery q(d->db); + q.exec(QString("SELECT key, value FROM kv WHERE key LIKE '%1%'").arg(searchterm)); + while ( q.next() ){ + QString key = q.value(0).toString(); + + shared_ptr action = std::make_shared(); + action->setText("Remove mapping from database"); + action->setAction([this, key](){ + QSqlQuery q(d->db); + q.prepare(removeStmt); + q.bindValue(":key", key); + q.exec(); + if (this->d->widget) + this->d->widget->updateTable(); + }); + + shared_ptr item = std::make_shared(); + item->setText(QString("Unset '%1': '%2'").arg(key, q.value(1).toString())); + item->setSubtext(QString("Remove this mapping from the database.")); + item->setIconPath(":kv"); + item->setCompletionString(QString("kv unset %1").arg(key)); + item->setActions({action}); + query->addMatch(move(item), static_cast(1.0/key.length()*searchterm.length())); + } + } + } + + // LOOKUP + + // Allow empty lookup (getting everything) only for triggered queries + if (query->string().isEmpty() && query->trigger().isEmpty()) + return; + + QSqlQuery q(d->db); + q.exec(QString("SELECT key, value FROM kv WHERE key LIKE '%1%'").arg(query->string())); + while ( q.next() ){ + QString key = q.value(0).toString(); + QString value = q.value(1).toString(); + + shared_ptr action = std::make_shared(); + action->setText("Copy value to clipboard"); + action->setAction([=](){ QApplication::clipboard()->setText(value); }); + + shared_ptr item = std::make_shared(QString("kv_%1").arg(key)); + item->setText(value); + item->setSubtext(QString("Value of '%1'").arg(key)); + item->setIconPath(":kv"); + item->setCompletionString(QString("kv %1").arg(key)); + item->setActions({action}); + query->addMatch(move(item), static_cast(1.0/key.length()*query->string().length())); + } +} + diff -Nru albert-0.12.0/plugins/kvstore/src/extension.h albert-0.13.1+plugins1/plugins/kvstore/src/extension.h --- albert-0.12.0/plugins/kvstore/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/kvstore/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,49 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace KeyValueStore { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Key Value Store"; } + QWidget *widget(QWidget *parent = nullptr) override; + QStringList triggers() const override { return {"kv "}; } + void handleQuery(Core::Query * query) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/mpris/CMakeLists.txt albert-0.13.1+plugins1/plugins/mpris/CMakeLists.txt --- albert-0.12.0/plugins/mpris/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(mpris) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets DBus) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5DBus_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/mpris/metadata.json albert-0.13.1+plugins1/plugins/mpris/metadata.json --- albert-0.12.0/plugins/mpris/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,9 @@ +{ + "id" : "org.albert.extension.mpris", + "name" : "MPRIS Control", + "version" : "1.0", + "platform" : "Linux", + "group" : "Extensions", + "author" : "Martin Buergmann", + "dependencies" : ["dbus-daemon"] +} diff -Nru albert-0.12.0/plugins/mpris/mpris.qrc albert-0.13.1+plugins1/plugins/mpris/mpris.qrc --- albert-0.12.0/plugins/mpris/mpris.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/mpris.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,9 @@ + + + resources/1485099680_playback-play.svg + resources/1485099683_playback-fast-forward.svg + resources/1485099687_playback-rewind.svg + resources/1485099690_playback-pause.svg + resources/1485100510_primitive-square.svg + + diff -Nru albert-0.12.0/plugins/mpris/resources/1485099680_playback-play.svg albert-0.13.1+plugins1/plugins/mpris/resources/1485099680_playback-play.svg --- albert-0.12.0/plugins/mpris/resources/1485099680_playback-play.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/resources/1485099680_playback-play.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/mpris/resources/1485099683_playback-fast-forward.svg albert-0.13.1+plugins1/plugins/mpris/resources/1485099683_playback-fast-forward.svg --- albert-0.12.0/plugins/mpris/resources/1485099683_playback-fast-forward.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/resources/1485099683_playback-fast-forward.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/mpris/resources/1485099687_playback-rewind.svg albert-0.13.1+plugins1/plugins/mpris/resources/1485099687_playback-rewind.svg --- albert-0.12.0/plugins/mpris/resources/1485099687_playback-rewind.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/resources/1485099687_playback-rewind.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/mpris/resources/1485099690_playback-pause.svg albert-0.13.1+plugins1/plugins/mpris/resources/1485099690_playback-pause.svg --- albert-0.12.0/plugins/mpris/resources/1485099690_playback-pause.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/resources/1485099690_playback-pause.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/mpris/resources/1485100510_primitive-square.svg albert-0.13.1+plugins1/plugins/mpris/resources/1485100510_primitive-square.svg --- albert-0.12.0/plugins/mpris/resources/1485100510_primitive-square.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/resources/1485100510_primitive-square.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/mpris/src/command.cpp albert-0.13.1+plugins1/plugins/mpris/src/command.cpp --- albert-0.12.0/plugins/mpris/src/command.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/command.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,119 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "command.h" +#include +#include +#include +#include +#include "item.h" + +/** ***************************************************************************/ +MPRIS::Command::Command(const QString &label, const QString &title, const QString &subtext, const QString &method, QString iconpath) + : label_(label), title_(title), subtext_(subtext), method_(method), iconpath_(iconpath) { +} + + + +/** ***************************************************************************/ +QString& MPRIS::Command::getIconPath() { + return iconpath_; +} + + + +/** ***************************************************************************/ +MPRIS::Command &MPRIS::Command::applicableWhen(const char* path, const char *property, const QVariant expectedValue, bool positivity) { + path_ = path; + property_ = property; + expectedValue_ = expectedValue; + positivity_ = positivity; + applicableCheck_ = true; + return *this; +} + + + +/** ***************************************************************************/ +SharedItem MPRIS::Command::produceAlbertItem(Player &player) const { + QDBusMessage msg = QDBusMessage::createMethodCall(player.busId(), "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", method_); + SharedItem ptr(new MPRIS::Item(player, title_, subtext_, iconpath_, msg)); + return ptr; +} + + + +/** ***************************************************************************/ +bool MPRIS::Command::isApplicable(Player &p) const { + // Check the applicable-option if given + if (!applicableCheck_) + return true; + + // split DBus interface and property into seperate strings + int splitAt = property_.lastIndexOf('.'); + QString ifaceName = property_.left(splitAt); + QString propertyName = property_.right(property_.length() - splitAt -1); + + // Compose Get-Property-Message + QDBusMessage mesg = QDBusMessage::createMethodCall( + p.busId(), //"org.mpris.MediaPlayer2.rhythmbox", + path_, //"/org/mpris/MediaPlayer2", + "org.freedesktop.DBus.Properties", + "Get"); + QList args; + // Specify DBus interface to get the property from and the property-name + args.append(ifaceName); //"org.mpris.MediaPlayer2.Player"); + args.append(propertyName); //"CanGoNext"); + mesg.setArguments(args); + + // Query the property + QDBusMessage reply = QDBusConnection::sessionBus().call(mesg); + + // Check if the result is as expected + if ( reply.type() != QDBusMessage::ReplyMessage ){ + qWarning() << "Error while querying the property 'PlaybackStatus'"; + return true; + } + + if ( reply.arguments().empty() ) { + qWarning() << "Reply query 'PlaybackStatus' is empty"; + return true; + } + + return (reply.arguments().at(0).value().variant() == expectedValue_) == positivity_; +} + + + +/** ***************************************************************************/ +QString& MPRIS::Command::getLabel() { + return label_; +} + + + +/** ***************************************************************************/ +QString& MPRIS::Command::getMethod() { + return method_; +} + + + +/** ***************************************************************************/ +QString& MPRIS::Command::getTitle() { + return title_; +} + diff -Nru albert-0.12.0/plugins/mpris/src/command.h albert-0.13.1+plugins1/plugins/mpris/src/command.h --- albert-0.12.0/plugins/mpris/src/command.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/command.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,78 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include +#include +#include "core/query.h" +#include "player.h" +using std::function; +typedef std::shared_ptr SharedItem; + +namespace MPRIS { + +class Command +{ +public: + /** + * @brief Command Constructs a DBus command to launch from albert with the given parameters. + * @param label An internal variable to query at a later point. Not needed for the DBus query. + * @param title The title of the StandardItem which will be created. + * @param subtext The subtext of the StandardItem which will be created. + * @param method The DBus method to invoke when this command is performed. + * @param iconpath The path to the icon which the StandardItem will get. + */ + Command(const QString& label, const QString& title, const QString& subtext, const QString& method, QString iconpath); + + QString& getLabel(); + QString& getTitle(); + QString& getMethod(); + QString& getIconPath(); + + /** + * @brief applicableWhen Configure this command to be only appicable under a certian (given) conditions. + * @param path The path to query the property from. + * @param property The name of the property. This property will be checked as condition. + * @param expectedValue The value of the property. + * @param positivity The result of the equality-check (queriedValue == expectedValue). Here you can negate the result. + * @return Returns itself, but now configured for applicability-check + */ + Command& applicableWhen(const char *path, const char* property, const QVariant expectedValue, bool positivity); + + /** + * @brief produceStandardItem Produces an instance of AlbertItem for this command to invoke on a given Player. + * @return Returns a shared_ptr on this AlbertItem. + */ + SharedItem produceAlbertItem(Player &) const; + + /** + * @brief isApplicable If configured, checks if the given property meets the expected criteria. + * @return True if not configured or match, false if the property is different than expected. + */ + bool isApplicable(Player&) const; + +private: + QString label_, title_, subtext_, method_, iconpath_; + bool applicableCheck_; + QString path_; + QString property_; + QVariant expectedValue_; + bool positivity_; +}; + +} // namespace MPRIS diff -Nru albert-0.12.0/plugins/mpris/src/configwidget.cpp albert-0.13.1+plugins1/plugins/mpris/src/configwidget.cpp --- albert-0.12.0/plugins/mpris/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +MPRIS::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +MPRIS::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/mpris/src/configwidget.h albert-0.13.1+plugins1/plugins/mpris/src/configwidget.h --- albert-0.12.0/plugins/mpris/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace MPRIS { +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/mpris/src/configwidget.ui albert-0.13.1+plugins1/plugins/mpris/src/configwidget.ui --- albert-0.12.0/plugins/mpris/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,46 @@ + + + MPRIS::ConfigWidget + + + + 0 + 0 + 480 + 320 + + + + + + + <html> +<head/> +<body> +<p>If you have MPRIS-capable media players running (like Rhythmbox, VLC, ...) just type any of &quot;play&quot;, &quot;pause&quot;, &quot;stop&quot;, &quot;next&quot;, &quot;previous&quot; and you can send these commands directly to your player from albert.</p> +</body> +</html> + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/mpris/src/extension.cpp albert-0.13.1+plugins1/plugins/mpris/src/extension.cpp --- albert-0.12.0/plugins/mpris/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,286 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "extension.h" +#include +#include +#include +#include +#include +#include +#include +#include "core/query.h" +#include "xdg/iconlookup.h" +#include "command.h" +#include "configwidget.h" +#include "player.h" + +#define themeOr(name, fallbk) XDG::IconLookup::iconPath(name).isEmpty() ? fallbk : XDG::IconLookup::iconPath(name) + +namespace { +static const int DBUS_TIMEOUT = 25 /* ms */; +} + +class MPRIS::Private +{ +public: + ~Private(); + + const char* name = "MPRIS Control"; + static QDBusMessage findPlayerMsg; + QPointer widget; + QList mediaPlayers; + QStringList commands; + QMap commandObjects; + + + QDBusMessage call(QDBusMessage &toDispatch); + +}; + + +QDBusMessage MPRIS::Private::findPlayerMsg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames"); + + + +/** ***************************************************************************/ +MPRIS::Private::~Private() { + // If there are still media player objects, delete them + qDeleteAll(mediaPlayers); + // Don't need to destruct the command objects. + // This is done by the destructor of QMap +} + + + +/** ***************************************************************************/ +QDBusMessage MPRIS::Private::call(QDBusMessage &toDispatch) { + return QDBusConnection::sessionBus().call(toDispatch, QDBus::Block, DBUS_TIMEOUT); +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +MPRIS::Extension::Extension() + : Core::Extension("org.albert.extension.mpris"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + QString icon; + + // Setup the DBus commands + icon = themeOr("media-playback-start", ":play"); + Command* nextToAdd = new Command( + "play", // Label + "Play", // Title + "Start playing on %1", // Subtext + "Play", // DBus Method + icon + ); + nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.PlaybackStatus", "Playing", false); + d->commands.append("play"); + d->commandObjects.insert("play", *nextToAdd); + + icon = themeOr("media-playback-pause", ":pause"); + nextToAdd = new Command( + "pause", + "Pause", + "Pause %1", + "Pause", + icon + ); + nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.PlaybackStatus", "Playing", true); + d->commands.append("pause"); + d->commandObjects.insert("pause", *nextToAdd); + + icon = themeOr("media-playback-stop", ":stop"); + nextToAdd = new Command( + "stop", + "Stop", + "Stop %1", + "Stop", + icon + ); + nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.PlaybackStatus", "Playing", true); + d->commands.append("stop"); + d->commandObjects.insert("stop", *nextToAdd); + + icon = themeOr("media-skip-forward", ":next"); + nextToAdd = new Command( + "next track", + "Next track", + "Play next track on %1", + "Next", + icon + ); + nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.CanGoNext", true, true); + //.fireCallback([](){qInfo("NEXT");}) + d->commands.append("next track"); + d->commandObjects.insert("next track", *nextToAdd); + + icon = themeOr("media-skip-backward", ":prev"); + nextToAdd = new Command( + "previous track", + "Previous track", + "Play previous track on %1", + "Previous", + icon + ); + nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.CanGoPrevious", true, true); + d->commands.append("previous track"); + d->commandObjects.insert("previous track", *nextToAdd); +} + + + +/** ***************************************************************************/ +MPRIS::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *MPRIS::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void MPRIS::Extension::setupSession() { + + // Clean the memory + qDeleteAll(d->mediaPlayers); + d->mediaPlayers.clear(); + + // If there is no session bus, abort + if (!QDBusConnection::sessionBus().isConnected()) + return; + + // Querying the DBus to list all available services + QDBusMessage response = d->call(Private::findPlayerMsg); + + // Do some error checking + if (response.type() == QDBusMessage::ReplyMessage) { + QList args = response.arguments(); + if (args.length() == 1) { + QVariant arg = args.at(0); + if (!arg.isNull() && arg.isValid()) { + QStringList runningBusEndpoints = arg.toStringList(); + if (!runningBusEndpoints.isEmpty()) { + // No errors + + // Filter all mpris capable + //names = names.filter(filterRegex); + QStringList busids; + for (QString& id: runningBusEndpoints) { + if (id.startsWith("org.mpris.MediaPlayer2.")) + busids.append(id); + } + + for (QString& busId : busids) { + + // Query the name of the media player of which we have the bus id. + QDBusInterface iface(busId, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2"); + iface.setTimeout(DBUS_TIMEOUT); + + QString name = busId; + QVariant prop = iface.property("Identity"); + if (prop.isValid() && !prop.isNull() && prop.canConvert(QVariant::String)) { + name = prop.toString(); + } else { + qWarning("DBus: Name is either invalid, null or not instanceof string"); + } + + bool canRaise = false; + prop = iface.property("CanRaise"); + if (prop.isValid() && !prop.isNull() && prop.canConvert(QVariant::Bool)) { + canRaise = prop.toBool(); + } else { + qWarning("DBus: CanRaise is either invalid, null or not instanceof bool"); + } + + // And add their player object to the list + d->mediaPlayers.push_back(new Player{busId, name, canRaise}); + + } + + + } else { + qCritical("[%s] DBus error: Argument is either not type of QStringList or is empty!", d->name); + } + } else { + qCritical("[%s] DBus error: Reply argument not valid or null!", d->name); + } + } else { + qCritical("[%s] DBus error: Expected 1 argument for DBus reply. Got %d", d->name, args.length()); + } + } else { + qCritical("[%s] DBus error: %s", d->name, response.errorMessage().toStdString().c_str()); + } +} + + + +/** ***************************************************************************/ +void MPRIS::Extension::handleQuery(Core::Query *query) const { + + const QString& q = query->string().trimmed().toLower(); + + if ( q.isEmpty() ) + return; + + // Do not proceed if there are no players running. Why would you even? + if (d->mediaPlayers.isEmpty()) + return; + + // Filter applicable commands + QStringList cmds; + for (QString& cmd : d->commands) { + if (cmd.startsWith(q)) + cmds.append(cmd); + } + + + // For every option create entries for every player + for (QString& cmd: cmds) { + // Get the command + Command& toExec = d->commandObjects.find(cmd).value(); + // For every player: + for (Player *p : d->mediaPlayers) { + // See if it's applicable for this player + if (toExec.isApplicable(*p)) + // And add a match if so + query->addMatch(toExec.produceAlbertItem(*p), + static_cast(1.0*q.length()/cmd.length())*UINT_MAX); + } + } +} + + + +/** ***************************************************************************/ +QString MPRIS::Extension::name() const { + return d->name; +} diff -Nru albert-0.12.0/plugins/mpris/src/extension.h albert-0.13.1+plugins1/plugins/mpris/src/extension.h --- albert-0.12.0/plugins/mpris/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace MPRIS { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + Extension(); + ~Extension(); + + QString name() const override; + QWidget *widget(QWidget *parent = nullptr) override; + void setupSession() override; + void handleQuery(Core::Query *query) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/mpris/src/item.cpp albert-0.13.1+plugins1/plugins/mpris/src/item.cpp --- albert-0.12.0/plugins/mpris/src/item.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/item.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,65 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "item.h" +#include +#include "util/standardaction.h" +using Core::StandardAction; + + +/** ***************************************************************************/ +MPRIS::Item::Item(Player &p, const QString &title, const QString &subtext, const QString &iconPath, const QDBusMessage &msg) + : iconPath_(iconPath), message_(msg) { + if (title.contains("%1")) + text_ = title.arg(p.name()); + else + text_ = title; + if (subtext.contains("%1")) + subtext_ = subtext.arg(p.name()); + else + subtext_ = subtext; + actions_.push_back(shared_ptr(new StandardAction(subtext_, [this](){ + QDBusConnection::sessionBus().send(message_); +// flags->hideWidget = hideAfter_; +// flags->clearInput = hideAfter_; + }))); + if (p.canRaise()) { + actions_.push_back(shared_ptr(new StandardAction("Raise Window", [&p](){ + QString busid = p.busId(); + QDBusMessage raise = QDBusMessage::createMethodCall(busid, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Raise"); + if (!QDBusConnection::sessionBus().send(raise)) { + qWarning("Error calling raise method on dbus://%s", busid.toStdString().c_str()); + } + }))); + } + id_ = "extension.mpris.item:%1.%2"; + id_ = id_.arg(p.busId()).arg(msg.member()); +} + + + +/** ***************************************************************************/ +MPRIS::Item::~Item() { + +} + + + +/** ***************************************************************************/ +vector> MPRIS::Item::actions() { + return actions_; +} + diff -Nru albert-0.12.0/plugins/mpris/src/item.h albert-0.13.1+plugins1/plugins/mpris/src/item.h --- albert-0.12.0/plugins/mpris/src/item.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/item.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,53 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "util/standarditem.h" +#include "player.h" +using std::vector; +using std::shared_ptr; +using Core::Action; + +namespace MPRIS { + +class Item final : public Core::Item +{ +public: + + Item(Player &p, const QString& title, const QString& subtext, const QString& iconPath, const QDBusMessage& msg); + ~Item(); + + QString id() const override { return id_; } + QString text() const override { return text_; } + QString subtext() const override { return subtext_; } + QString iconPath() const override { return iconPath_; } + vector> actions() override; + +private: + + QString id_; + QString text_; + QString subtext_; + QString iconPath_; + QDBusMessage message_; + vector> actions_; + +}; + +} diff -Nru albert-0.12.0/plugins/mpris/src/player.h albert-0.13.1+plugins1/plugins/mpris/src/player.h --- albert-0.12.0/plugins/mpris/src/player.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/mpris/src/player.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,40 @@ +// albert extension mpris - a mpris interface plugin for albert +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include + +namespace MPRIS { + +class Player +{ +public: + Player(const QString& busid, const QString& name, bool canRaise) + : busId_(busid), name_(name), canRaise_(canRaise) {} + + const QString& name() const { return name_; } + const QString& busId() const { return busId_; } + bool canRaise() const { return canRaise_; } + +private: + + QString busId_; + QString name_; + bool canRaise_; +}; + +} // namespace MPRIS diff -Nru albert-0.12.0/plugins/qmlboxmodel/CMakeLists.txt albert-0.13.1+plugins1/plugins/qmlboxmodel/CMakeLists.txt --- albert-0.12.0/plugins/qmlboxmodel/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(qmlboxmodel) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Qml Quick) + +add_library(${PROJECT_NAME} SHARED ${SRC}) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Qml_LIBRARIES} + ${Qt5Quick_LIBRARIES} + albertcore +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) +install(DIRECTORY "share/" DESTINATION "share/albert/org.albert.frontend.boxmodel.qml") diff -Nru albert-0.12.0/plugins/qmlboxmodel/metadata.json albert-0.13.1+plugins1/plugins/qmlboxmodel/metadata.json --- albert-0.12.0/plugins/qmlboxmodel/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,6 @@ +{ + "id" : "org.albert.frontend.boxmodel.qml", + "name" : "QML Box Model", + "version" : "1.0", + "author" : "Manuel Schneider" +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/qmlboxmodel.qrc albert-0.13.1+plugins1/plugins/qmlboxmodel/qmlboxmodel.qrc --- albert-0.12.0/plugins/qmlboxmodel/qmlboxmodel.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/qmlboxmodel.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,7 @@ + + + resources/gear.svg + resources/HistoryTextInput.qml + resources/MainComponent.qml + + diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/DesktopListView.qml albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/DesktopListView.qml --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/DesktopListView.qml 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/DesktopListView.qml 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +ListView { + + property int itemCount: 5 + + width: parent.width + height: (count === 0) ? 0 : Math.min(itemCount, count)*(itemAt(0,0).height+spacing)-spacing + snapMode: ListView.SnapToItem + clip: true + keyNavigationWraps: false + boundsBehavior: Flickable.StopAtBounds + highlightMoveDuration : 250 + highlightMoveVelocity : 100 + + Connections { + target: model + onModelReset: currentIndex = -1 + } + + Keys.onPressed: { + event.accepted = true + if ( event.key === Qt.Key_Up && event.modifiers === Qt.NoModifier && count > 0 ) + decrementCurrentIndex() + else if ( event.key === Qt.Key_Down && event.modifiers === Qt.NoModifier && count > 0 ) + if (currentIndex === -1) + currentIndex = Math.min(1, count-1) + else + incrementCurrentIndex() + else if ( event.key === Qt.Key_PageUp && event.modifiers === Qt.NoModifier && count > 0 ) + currentIndex = Math.max(currentIndex - itemCount, 0) + else if ( event.key === Qt.Key_PageDown && event.modifiers === Qt.NoModifier && count > 0 ) + currentIndex = Math.min(currentIndex + itemCount, count-1) + else if ( event.key === Qt.Key_Home && event.modifiers === Qt.ControlModifier && count > 0 ) + currentIndex = 0 + else if ( event.key === Qt.Key_End && event.modifiers === Qt.ControlModifier && count > 0 ) + currentIndex = count-1 + else + event.accepted = false + } +} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/fonts/Roboto-Thin.ttf and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/fonts/Roboto-Thin.ttf differ diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/gear.svg albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/gear.svg --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/gear.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/gear.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,38 @@ + + + +image/svg+xml \ No newline at end of file diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/HistoryTextInput.qml albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/HistoryTextInput.qml --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/HistoryTextInput.qml 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/HistoryTextInput.qml 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +TextInput { + + function clearLine() { + text = "" + } + + function pushTextToHistory() { + history.add(text) + clearLine() + clearIterator() + } + + function clearIterator() { + return history.resetIterator() + } + + function nextIteration() { + var entry = history.next() + if ( entry.length !== 0 ){ + textChanged.disconnect(clearIterator) + text = entry + textChanged.connect(clearIterator) + } + } + + function prevIteration() { + var entry = history.prev() + if (entry.length!==0) { + textChanged.disconnect(clearIterator) + text = entry + textChanged.connect(clearIterator) + } + } + + Component.onCompleted: { + textChanged.connect(clearIterator) + } + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/ItemViewDelegate.qml albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/ItemViewDelegate.qml --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/ItemViewDelegate.qml 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/ItemViewDelegate.qml 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,129 @@ +import QtQuick 2.5 +import QtGraphicalEffects 1.0 + +Item { + + id: listItem + + property int iconSize + property int spacing + property int textSize + property int descriptionSize + property color textColor + property color highlightColor + property string fontName + property int animationDuration: 150 + + width: parent.width + height: Math.max(listItemIcon.height, listItemTextArea.height) + + MouseArea { + anchors.fill: parent + onClicked: resultsList.currentIndex = index + onDoubleClicked: (mouse.modifiers===Qt.NoModifier) ? root.activate() : root.activate(-mouse.modifiers) + } + + Image { + id: listItemIcon + asynchronous: true + source: { + var path = itemDecorationRole + return ( path[0] === ":" ) ? "qrc"+path : path + } + width: listItem.iconSize + height: listItem.iconSize + sourceSize.width: listItem.iconSize*2 + sourceSize.height: listItem.iconSize*2 + cache: true + fillMode: Image.PreserveAspectFit + visible: false + } + InnerShadow { + id: sunkenListItemIcon + width: source.width + height: source.height + horizontalOffset: listItem.ListView.isCurrentItem ? 0 : 2 + verticalOffset: listItem.ListView.isCurrentItem ? 0 : 2 + radius: listItem.ListView.isCurrentItem ? 0 : 4 + samples: 8 + color: "#80000000" + visible: false + Behavior on verticalOffset { NumberAnimation{ duration: animationDuration } } + Behavior on horizontalOffset { NumberAnimation{ duration: animationDuration } } + Behavior on radius { NumberAnimation{ duration: animationDuration } } + source: listItemIcon + } + Desaturate { + id: desaturatedSunkenListItemIcon + anchors.verticalCenter: parent.verticalCenter + width: source.width + height: source.height + desaturation: listItem.ListView.isCurrentItem ? 0 : 0.25 + Behavior on desaturation { NumberAnimation{ duration: animationDuration } } + source: sunkenListItemIcon + } + + + Column { + id: listItemTextArea + anchors { + left: desaturatedSunkenListItemIcon.right + leftMargin: listItem.spacing + right: parent.right + verticalCenter: parent.verticalCenter + } + Text { + id: textId + width: parent.width + text: itemTextRole + textFormat: Text.PlainText + elide: Text.ElideRight + color: listItem.ListView.isCurrentItem ? listItem.highlightColor : listItem.textColor + font.family: listItem.fontName + font.pixelSize: listItem.textSize + Behavior on color { ColorAnimation{ duration: animationDuration } } + } + Text { + id: subTextId + width: parent.width + text: (listItem.ListView.isCurrentItem && root.state==="fallback") ? itemFallbackRole : itemToolTipRole + textFormat: Text.PlainText + elide: Text.ElideRight + color: listItem.ListView.isCurrentItem ? listItem.highlightColor : listItem.textColor + font.family: listItem.fontName + font.pixelSize: listItem.descriptionSize + Behavior on color { ColorAnimation{ duration: animationDuration } } + Behavior on text { + SequentialAnimation { + NumberAnimation { target: subTextId; property: "opacity"; from:1; to: 0; duration: animationDuration/2 } + PropertyAction { } + NumberAnimation { target: subTextId; property: "opacity"; from:0; to: 1; duration: animationDuration/2 } + } + } + } + } // listItemTextArea (Column) + + + /* + * The function to activate an item + * Currently work as follows: + * action is undefined -> default action + * action 0<= are the alternative actions + * action 0> activation while modifier is pressed (-action is the number of the modifier) + * currently only Meta is supported + */ + function activate(/*optional*/ action){ + if (typeof action === 'undefined') + itemActionRole = 0 + else + if (action < 0 && -action==Qt.MetaModifier) + itemFallbackRole = 0 + else + itemAltActionsRole = action + } + + function actionsList() { + return itemAltActionsRole + } + +} // listItem (MouseArea) diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/MainComponent.qml albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/MainComponent.qml --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/MainComponent.qml 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/MainComponent.qml 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,304 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.0 +import QtGraphicalEffects 1.0 +import "themes.js" as Themes + +Item { + + id: root + width: frame.width+2*preferences.shadow_size + height: frame.height+2*preferences.shadow_size + + layer.enabled: true + layer.effect: DropShadow { + transparentBorder: true + verticalOffset: preferences.shadow_size/3 + radius: preferences.shadow_size + samples: preferences.shadow_size*2 + color: preferences.shadow_color + } + + Preferences { + id: preferences + objectName: "preferences" + } + + FontLoader { + source: "fonts/Roboto-Thin.ttf" + onStatusChanged: if (loader.status === FontLoader.Ready) preferences.font_name = fontname + } + + Rectangle { + + id: frame + objectName: "frame" // for C++ + x: preferences.shadow_size; + y: preferences.shadow_size + width: preferences.window_width + height: content.height+2*content.anchors.margins + radius: preferences.radius + color: preferences.background_color + Behavior on color { ColorAnimation { duration: preferences.animation_duration; easing.type: Easing.OutCubic } } + Behavior on border.color { ColorAnimation { duration: preferences.animation_duration; easing.type: Easing.OutCubic } } + border.color: preferences.border_color + border.width: preferences.border_size + + Column { + + id: content + anchors { + top: parent.top + left: parent.left + right: parent.right + margins: preferences.border_size+preferences.padding + } + spacing: preferences.spacing + + HistoryTextInput { + id: historyTextInput + anchors { + left: parent.left; + right: parent.right; + } + clip: true + color: preferences.input_color + focus: true + font.pixelSize: preferences.input_fontsize + font.family: preferences.font_name + selectByMouse: true + selectedTextColor: preferences.background_color + selectionColor: preferences.selection_color + Keys.forwardTo: [root, resultsList] + cursorDelegate : Item { + id: cursor + Rectangle { width: 1 + height: parent.height + color: preferences.cursor_color + } + SequentialAnimation on opacity { + loops: Animation.Infinite; + NumberAnimation { to: 0; duration: 500; easing.type: Easing.InOutExpo } + NumberAnimation { to: 1; duration: 500; easing.type: Easing.InOutExpo } + } + } + onTextChanged: { root.state="" } + } // historyTextInput + + DesktopListView { + id: resultsList + width: parent.width + model: resultsModel + itemCount: preferences.max_items + spacing: preferences.spacing + delegate: Component { + ItemViewDelegate{ + iconSize: preferences.icon_size + spacing: preferences.spacing + textSize: preferences.item_title_fontsize + descriptionSize: preferences.item_description_fontsize + textColor: preferences.foreground_color + highlightColor: preferences.highlight_color + fontName: preferences.font_name + animationDuration: preferences.animation_duration + } + } + Keys.onEnterPressed: (event.modifiers===Qt.NoModifier) ? activate() : activate(-event.modifiers) + Keys.onReturnPressed: (event.modifiers===Qt.NoModifier) ? activate() : activate(-event.modifiers) + onCurrentIndexChanged: if (root.state==="detailsView") root.state="" + } // resultsList (ListView) + + DesktopListView { + id: actionsListView + width: parent.width + model: ListModel { id: actionsModel } + itemCount: actionsModel.count + spacing: preferences.spacing + Behavior on visible { + SequentialAnimation { + PropertyAction { } + NumberAnimation { target: actionsListView; property: "opacity"; from:0; to: 1; duration: preferences.animation_duration } + } + } + delegate: Text { + horizontalAlignment: Text.AlignHCenter + width: parent.width + text: name + textFormat: Text.PlainText + font.family: preferences.font_name + elide: Text.ElideRight + font.pixelSize: (preferences.item_description_fontsize+preferences.item_title_fontsize)/2 + color: ListView.isCurrentItem ? preferences.highlight_color : preferences.foreground_color + Behavior on color { ColorAnimation{ duration: preferences.animation_duration } } + MouseArea { + anchors.fill: parent + onClicked: actionsListView.currentIndex = index + onDoubleClicked: activate(index) + } + } + visible: false + Keys.onEnterPressed: activate(currentIndex) + Keys.onReturnPressed: activate(currentIndex) + } // actionsListView (ListView) + } // content (Column) + + + SettingsButton { + id: settingsButton + size: preferences.settingsbutton_size + color: preferences.settingsbutton_color + hoverColor: preferences.settingsbutton_hover_color + onLeftClicked: settingsWidgetRequested() + onRightClicked: menu.popup() + anchors { + top: parent.top + right: parent.right + topMargin: preferences.padding+preferences.border_size + rightMargin: preferences.padding+preferences.border_size + } + + Menu { + id: menu + MenuItem { + text: "Preferences" + shortcut: "Alt+," + onTriggered: settingsWidgetRequested() + } + MenuItem { + text: "Quit" + shortcut: "Alt+F4" + onTriggered: Qt.quit() + + } + } + } + } // frame (Rectangle) + + onActiveFocusChanged: state="" + + // Key handling + Keys.onPressed: { + event.accepted = true + if ( event.key === Qt.Key_Up && state === "" && resultsList.currentIndex === -1 ) { + historyTextInput.nextIteration() + } + else if ( event.key === Qt.Key_Up && event.modifiers === Qt.ControlModifier ) { + state == "" + historyTextInput.nextIteration() + } + else if ( event.key === Qt.Key_Down && event.modifiers === Qt.ControlModifier ) { + state == "" + historyTextInput.prevIteration() + } + else if ( event.key === Qt.Key_Meta ) { + if (resultsList.currentIndex === -1) + resultsList.currentIndex = 0 + state="fallback" + } + else if ( event.key === Qt.Key_Comma && event.modifiers === Qt.AltModifier ) { + settingsWidgetRequested() + } + else if ( event.key === Qt.Key_Alt && resultsList.count > 0 ) { + if (resultsList.currentIndex === -1) + resultsList.currentIndex = 0 + state = "detailsView" + } + else if ( event.key === Qt.Key_Tab && resultsList.count > 0 ) { + if ( resultsList.currentIndex === -1 ) + resultsList.currentIndex = 0 + historyTextInput.text = resultsList.model.data(resultsList.model.index(resultsList.currentIndex, 0),3) // OMG magic numbers hacked in + } else event.accepted = false + } + Keys.onReleased: { + event.accepted = true + if ( event.key === Qt.Key_Meta ) + state="" + else if ( event.key === Qt.Key_Alt ) + state="" + else event.accepted = false + + } + + states : [ + State { + name: "" + }, + State { + name: "fallback" + }, + State { + name: "detailsView" + PropertyChanges { target: actionsListView; visible: true } + PropertyChanges { target: historyTextInput; Keys.forwardTo: [root, actionsListView] } + StateChangeScript { + name: "actionLoaderScript" + script: { + actionsModel.clear() + var actionTexts = resultsList.currentItem.actionsList(); + for ( var i = 0; i < actionTexts.length; i++ ) + actionsModel.append({"name": actionTexts[i]}); + actionsListView.currentIndex = 0 + } + } + } + ] + + Connections { + target: mainWindow + onVisibilityChanged: { + state="" + historyTextInput.selectAll() + historyTextInput.clearIterator() + } + } + + Component.onCompleted: setTheme("Bright") + + + // ▼ ▼ ▼ ▼ ▼ DO NOT CHANGE THIS UNLESS YOU KNOW WHAT YOU ARE DOING ▼ ▼ ▼ ▼ ▼ + + /* + * Currently the interface with the program logic comprises the following: + * + * These context properties are set: + * - mainWindow + * - resultsModel + * - history + * + * These properties must exist in root: + * - inputText (string, including the implicitly genreated signal) + * + * These functions must extist in root: + * - availableThemes() + * - setTheme(str) + * + * These signals must exist in root: + * - inputChanged(str) + * - settingsWidgetRequested() + * + * These object names with must exist somewhere: + * - frame (the visual root frame, i.e. withouth shadow) + * - preferences (QtObject containing only preference propterties) + */ + property string interfaceVersion: "1.0-alpha" // Will not change until beta + + property alias inputText: historyTextInput.text + signal settingsWidgetRequested() + + function activate(/*optional*/ action) { + if ( resultsList.count > 0 ) { + if ( resultsList.currentIndex === -1 ) + resultsList.currentIndex = 0 + resultsList.currentItem.activate(action) + historyTextInput.pushTextToHistory() + mainWindow.hide() + } + } + + function availableThemes() { return Object.keys(Themes.themes()) } + function setTheme(themeName) { + var themeObject = Themes.themes()[themeName] + for (var property in themeObject) + if (themeObject.hasOwnProperty(property)) + preferences[property] = themeObject[property] + } +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/metadata.json albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/metadata.json --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ +{ + "name" : "BoxModel", + "version" : "1.0-alpha", + "author" : "Manuel Schneider" +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/Preferences.qml albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/Preferences.qml --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/Preferences.qml 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/Preferences.qml 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +import QtQuick 2.5 + +QtObject { + + property color background_color + property color foreground_color + property color input_color + property color cursor_color + property color selection_color + property color highlight_color + property color border_color + property color settingsbutton_color + property color settingsbutton_hover_color + property color shadow_color + property int border_size + property int settingsbutton_size + property int input_fontsize + property int icon_size + property int shadow_size + property int item_title_fontsize + property int item_description_fontsize + property int max_items + property int spacing + property int padding + property int radius + property int window_width + property string font_name + property int animation_duration + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/SettingsButton.qml albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/SettingsButton.qml --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/SettingsButton.qml 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/SettingsButton.qml 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,63 @@ +import QtQuick 2.5 +import QtGraphicalEffects 1.0 + +Item { + id: root + property color color + property color hoverColor + property int size + signal rightClicked() + signal leftClicked() + + width: size + height: size + + Rectangle { + id: gearcolor + anchors.fill: gearmask + color: root.color + Behavior on color { ColorAnimation { duration: 3000; easing.type: Easing.OutExpo } } + visible: false + } + Image { + id: gearmask + source: "gear.svg" + anchors.fill: gear + sourceSize.width: width*2 + sourceSize.height: height*2 + smooth: true + visible: false + } + OpacityMask { + id: gear + anchors.fill: parent + source: gearcolor + maskSource: gearmask + RotationAnimation on rotation { + duration : 10000 + easing.type: Easing.Linear + loops: Animation.Infinite + from: 0 + to: 360 + } + } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if ( mouse.button === Qt.LeftButton ) + leftClicked() + else if ( mouse.button === Qt.RightButton ) + rightClicked() + } + } + + states: State { + name: "hovered" + when: mouseArea.containsMouse + PropertyChanges { target: gearcolor; color: root.hoverColor } + } + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/themes.js albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/themes.js --- albert-0.12.0/plugins/qmlboxmodel/share/styles/BoxModel/themes.js 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/share/styles/BoxModel/themes.js 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,198 @@ + +function themes() { + + var themes = {} + + themes.Bright = {} + themes.Bright.input_fontsize = 36 + themes.Bright.item_title_fontsize = 26 + themes.Bright.item_description_fontsize = 12 + themes.Bright.icon_size = 48 + themes.Bright.max_items = 5 + themes.Bright.spacing = 6 + themes.Bright.padding = 6 + themes.Bright.radius = 16 + themes.Bright.border_size = 6 + themes.Bright.settingsbutton_size = 16 + themes.Bright.animation_duration = 200 + themes.Bright.window_width = 640 + themes.Bright.font_name = "Roboto" + themes.Bright.shadow_size = 30 + themes.Bright.shadow_color = "#40000000" + themes.Bright.foreground_color = "#a0a0a0" + themes.Bright.background_color = "#FFFFFF" + themes.Bright.highlight_color = "#606060" + themes.Bright.border_color = themes.Bright.foreground_color + themes.Bright.input_color = themes.Bright.foreground_color + themes.Bright.cursor_color = themes.Bright.foreground_color + themes.Bright.selection_color = themes.Bright.highlight_color + themes.Bright.settingsbutton_hover_color = themes.Bright.highlight_color + themes.Bright.settingsbutton_color = themes.Bright.background_color + + var highlights = {} + highlights.BrightOrange = "#ff9f3f" + highlights.BrightMagenta = "#ff3f9f" + highlights.BrightMint = "#3fff9f" + highlights.BrightGreen = "#9fff3f" + highlights.BrightBlue = "#3f9fff" + highlights.BrightViolet = "#9f3fff" + + for (var name in highlights){ + if (highlights.hasOwnProperty(name)){ + themes[name] = JSON.parse(JSON.stringify(themes.Bright)) + themes[name].highlight_color = highlights[name] + themes[name].selection_color = highlights[name] + themes[name].border_color = highlights[name] + themes[name].settingsbutton_hover_color = highlights[name] + } + } + + themes.Dark = JSON.parse(JSON.stringify(themes.Bright)) + themes.Dark.foreground_color = "#808080" + themes.Dark.background_color = "#404040" + themes.Dark.highlight_color = "#E0E0E0" + themes.Dark.border_color = themes.Dark.foreground_color + themes.Dark.input_color = themes.Dark.foreground_color + themes.Dark.cursor_color = themes.Dark.foreground_color + themes.Dark.settingsbutton_color = themes.Dark.background_color + themes.Dark.settingsbutton_hover_color = themes.Dark.highlight_color + themes.Dark.selection_color = themes.Dark.highlight_color + + highlights = {} + highlights.DarkOrange = "#FF9020" + highlights.DarkMagenta = "#FF2090" + highlights.DarkMint = "#20FF90" + highlights.DarkGreen = "#90FF20" + highlights.DarkBlue = "#2090FF" + highlights.DarkViolet = "#9020FF" + + for (name in highlights){ + if (highlights.hasOwnProperty(name)){ + themes[name] = JSON.parse(JSON.stringify(themes.Dark)) + themes[name].highlight_color = highlights[name] + themes[name].selection_color = highlights[name] + themes[name].border_color = highlights[name] + themes[name].settingsbutton_hover_color = highlights[name] + } + } + + themes.SolarizedBrightYellow = JSON.parse(JSON.stringify(themes.Dark)) + themes.SolarizedBrightYellow.background_color = "#fdf6e3" + themes.SolarizedBrightYellow.foreground_color = "#839496" + themes.SolarizedBrightYellow.highlight_color = "#b58900" + themes.SolarizedBrightYellow.input_color = themes.SolarizedBrightYellow.foreground_color + themes.SolarizedBrightYellow.cursor_color = themes.SolarizedBrightYellow.foreground_color + themes.SolarizedBrightYellow.settingsbutton_color = themes.SolarizedBrightYellow.background_color + themes.SolarizedBrightYellow.settingsbutton_hover_color = themes.SolarizedBrightYellow.highlight_color + themes.SolarizedBrightYellow.selection_color = themes.SolarizedBrightYellow.highlight_color + themes.SolarizedBrightYellow.border_color = themes.SolarizedBrightYellow.highlight_color + + highlights = {} + highlights.SolarizedBrightOrange = "#cb4b16" + highlights.SolarizedBrightRed = "#dc322f" + highlights.SolarizedBrightMagenta = "#d33682" + highlights.SolarizedBrightCyan = "#2aa198" + highlights.SolarizedBrightViolet = "#6c71c4" + highlights.SolarizedBrightBlue = "#268bd2" + highlights.SolarizedBrightGreen = "#859900" + + for (name in highlights){ + if (highlights.hasOwnProperty(name)){ + themes[name] = JSON.parse(JSON.stringify(themes.SolarizedBrightYellow)) + themes[name].highlight_color = highlights[name] + themes[name].selection_color = highlights[name] + themes[name].border_color = highlights[name] + themes[name].settingsbutton_hover_color = highlights[name] + } + } + + themes.SolarizedDarkYellow = JSON.parse(JSON.stringify(themes.SolarizedBrightYellow)) + themes.SolarizedDarkYellow.background_color = "#002b36" + themes.SolarizedDarkYellow.highlight_color = "#b58900" + themes.SolarizedDarkYellow.input_color = themes.SolarizedDarkYellow.foreground_color + themes.SolarizedDarkYellow.cursor_color = themes.SolarizedDarkYellow.foreground_color + themes.SolarizedDarkYellow.settingsbutton_color = themes.SolarizedDarkYellow.background_color + themes.SolarizedDarkYellow.settingsbutton_hover_color = themes.SolarizedDarkYellow.highlight_color + themes.SolarizedDarkYellow.selection_color = themes.SolarizedDarkYellow.highlight_color + themes.SolarizedDarkYellow.border_color = themes.SolarizedDarkYellow.highlight_color + + highlights = {} + highlights.SolarizedDarkOrange = "#cb4b16" + highlights.SolarizedDarkRed = "#dc322f" + highlights.SolarizedDarkMagenta = "#d33682" + highlights.SolarizedDarkCyan = "#2aa198" + highlights.SolarizedDarkViolet = "#6c71c4" + highlights.SolarizedDarkBlue = "#268bd2" + highlights.SolarizedDarkGreen = "#859900" + + for (name in highlights){ + if (highlights.hasOwnProperty(name)){ + themes[name] = JSON.parse(JSON.stringify(themes.SolarizedDarkYellow)) + themes[name].highlight_color = highlights[name] + themes[name].selection_color = highlights[name] + themes[name].border_color = highlights[name] + themes[name].settingsbutton_hover_color = highlights[name] + } + } + + themes.Tiffany = JSON.parse(JSON.stringify(themes.Bright)) + themes.Tiffany.background_color = "#e2f2fa" + themes.Tiffany.foreground_color = "#73BDE4" + themes.Tiffany.highlight_color = "#a47a51" + themes.Tiffany.border_color = "#1d6a87" + themes.Tiffany.input_color = themes.Tiffany.foreground_color + themes.Tiffany.cursor_color = themes.Tiffany.foreground_color + themes.Tiffany.settingsbutton_color = themes.Tiffany.background_color + themes.Tiffany.settingsbutton_hover_color = themes.Tiffany.highlight_color + themes.Tiffany.selection_color = themes.Tiffany.highlight_color + + themes.Nerdy = JSON.parse(JSON.stringify(themes.Bright)) + themes.Nerdy.icon_size = 36 + themes.Nerdy.input_fontsize = 26 + themes.Nerdy.item_title_fontsize = 18 + themes.Nerdy.item_description_fontsize = 11 + themes.Nerdy.max_items = 8 + themes.Nerdy.spacing = 6 + themes.Nerdy.radius = 6 + themes.Nerdy.border_size = 1 + themes.Nerdy.settingsbutton_size = 14 + themes.Nerdy.window_width = 600 + themes.Nerdy.font_name = "monospace" + themes.Nerdy.background_color = "#202020" + themes.Nerdy.foreground_color = "#808080" + themes.Nerdy.highlight_color = "#00FF00" + themes.Nerdy.border_color = "#404040" + themes.Nerdy.cursor_color = themes.Nerdy.highlight_color + themes.Nerdy.input_color = themes.Nerdy.highlight_color + themes.Nerdy.selection_color = themes.Nerdy.foreground_color + themes.Nerdy.settingsbutton_color = "#303030" + themes.Nerdy.settingsbutton_hover_color = themes.Nerdy.highlight_color + + themes.Spotlight = {} + themes.Spotlight.icon_size = 38 + themes.Spotlight.input_fontsize = 28 + themes.Spotlight.item_title_fontsize = 20 + themes.Spotlight.item_description_fontsize = 12 + themes.Spotlight.max_items = 5 + themes.Spotlight.spacing = 6 + themes.Spotlight.shadow_size = 30 + themes.Spotlight.radius = 8 + themes.Spotlight.padding = 8 + themes.Spotlight.border_size = 0 + themes.Spotlight.settingsbutton_size = 15 + themes.Spotlight.window_width = 600 + themes.Spotlight.animation_duration = 200 + themes.Spotlight.font_name = "Roboto" + themes.Spotlight.background_color = "#ffffff" + themes.Spotlight.foreground_color = "#808080" + themes.Spotlight.highlight_color = "#303030" + themes.Spotlight.border_color = "#ffffff" + themes.Spotlight.input_color = "#303030" + themes.Spotlight.cursor_color = "#303030" + themes.Spotlight.selection_color = "#c0c0c0" + themes.Spotlight.settingsbutton_color = "#ffffff" + themes.Spotlight.settingsbutton_hover_color = "#a0a0a0" + themes.Spotlight.shadow_color = "#70000000" + + return themes +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/colordialog.hpp albert-0.13.1+plugins1/plugins/qmlboxmodel/src/colordialog.hpp --- albert-0.12.0/plugins/qmlboxmodel/src/colordialog.hpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/colordialog.hpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,39 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2016 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace QmlBoxModel { + +class ColorDialog : public QColorDialog +{ + Q_OBJECT + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged USER true) +public: + ColorDialog(QWidget * parent = 0) : QColorDialog(parent){ + setOptions(QColorDialog::ShowAlphaChannel); + connect(this, &QColorDialog::currentColorChanged, + this, &ColorDialog::colorChanged); + } + + QColor color(){ return currentColor(); } + void setColor(const QColor& c){ setCurrentColor(c); } +signals: + void colorChanged(const QColor &color); +}; + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/configwidget.cpp albert-0.13.1+plugins1/plugins/qmlboxmodel/src/configwidget.cpp --- albert-0.12.0/plugins/qmlboxmodel/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,124 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "mainwindow.h" +#include "propertyeditor.h" + +/** ***************************************************************************/ +QmlBoxModel::ConfigWidget::ConfigWidget(MainWindow *mainWindow, QWidget *parent, Qt::WindowFlags f) + : QWidget(parent, f), mainWindow_(mainWindow) { + + ui.setupUi(this); + + // ALWAYS ON TOP + ui.checkBox_onTop->setChecked(mainWindow_->alwaysOnTop()); + connect(ui.checkBox_onTop, &QCheckBox::toggled, mainWindow_, + &MainWindow::setAlwaysOnTop); + + // HIDE ON FOCUS OUT + ui.checkBox_hideOnFocusOut->setChecked(mainWindow_->hideOnFocusLoss()); + connect(ui.checkBox_hideOnFocusOut, &QCheckBox::toggled, + mainWindow_, &MainWindow::setHideOnFocusLoss); + + // ALWAYS CENTER + ui.checkBox_center->setChecked(mainWindow_->showCentered()); + connect(ui.checkBox_center, &QCheckBox::toggled, + mainWindow_, &MainWindow::setShowCentered); + + // HIDE ON CLOSE + ui.checkBox_hideOnClose->setChecked(mainWindow_->hideOnClose()); + connect(ui.checkBox_hideOnClose, &QCheckBox::toggled, + mainWindow_, &MainWindow::setHideOnClose); + + + /* + * STYLES + */ + + // Fill the combobox + for ( const QmlStyleSpec &style : mainWindow_->availableStyles() ) { + ui.comboBox_style->addItem(style.name, style.mainComponent); + + // Add tooltip + ui.comboBox_style->setItemData(ui.comboBox_style->count()-1, + QString("%1\nVersion: %2\nAuthor: %3") + .arg(style.name, style.version, style.author), + Qt::ToolTipRole); + + if ( style.mainComponent == mainWindow_->source().toString() ) + ui.comboBox_style->setCurrentIndex(ui.comboBox_style->count()-1); + } + updateThemes(); + + connect(ui.comboBox_style, static_cast(&QComboBox::currentIndexChanged), + this, &ConfigWidget::onStyleChanged); + + connect(ui.comboBox_themes, static_cast(&QComboBox::currentIndexChanged), + this, &ConfigWidget::onThemeChanged); + + // PROPERTY EDITOR + connect(ui.toolButton_propertyEditor, &QToolButton::clicked, mainWindow_, [this](){ + PropertyEditor *pe = new PropertyEditor(mainWindow_, this); + pe->setWindowModality(Qt::WindowModality::WindowModal); + pe->show(); + }); +} + + +/** ***************************************************************************/ +void QmlBoxModel::ConfigWidget::onStyleChanged(int i) { + // Apply the style + mainWindow_->setSource(mainWindow_->availableStyles()[static_cast(i)].mainComponent); + updateThemes(); +} + + +/** ***************************************************************************/ +void QmlBoxModel::ConfigWidget::onThemeChanged(const QString &text) { + mainWindow_->setTheme(text); +} + + +/** ***************************************************************************/ +void QmlBoxModel::ConfigWidget::updateThemes() { + + ui.comboBox_themes->blockSignals(true); + + ui.comboBox_themes->clear(); + + // Add disabled placeholder item + ui.comboBox_themes->addItem("Choose theme..."); + const QStandardItemModel* model = qobject_cast(ui.comboBox_themes->model()); + QStandardItem* item = model->item(0); + item->setEnabled(false); + ui.comboBox_themes->insertSeparator(1); + + // Add themes + ui.comboBox_themes->addItems(mainWindow_->availableThemes()); + + ui.comboBox_themes->blockSignals(false); + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/configwidget.h albert-0.13.1+plugins1/plugins/qmlboxmodel/src/configwidget.h --- albert-0.12.0/plugins/qmlboxmodel/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,42 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include "ui_configwidget.h" + +namespace QmlBoxModel { + +class MainWindow; + +class ConfigWidget final : public QWidget +{ + Q_OBJECT + +public: + + ConfigWidget(MainWindow *mainWindow, QWidget * parent = 0, Qt::WindowFlags f = 0); + +private: + + void onStyleChanged(int); + void onThemeChanged(const QString &text); + void updateThemes(); + + MainWindow *mainWindow_; + Ui::SettingsDialog ui; +}; + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/configwidget.ui albert-0.13.1+plugins1/plugins/qmlboxmodel/src/configwidget.ui --- albert-0.12.0/plugins/qmlboxmodel/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,134 @@ + + + QmlBoxModel::SettingsDialog + + + + 0 + 0 + + + + + + + User Interface + + + + + + Style: + + + comboBox_style + + + + + + + + + + + + + .. + + + + + + + + + Apply theme: + + + + + + + + + + Hide on focus out: + + + checkBox_hideOnFocusOut + + + + + + + + + + + + + + Always center Albert: + + + checkBox_center + + + + + + + + + + + + + + Always on top: + + + checkBox_onTop + + + + + + + + + + + + + + Hide on close: + + + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/frontendplugin.cpp albert-0.13.1+plugins1/plugins/qmlboxmodel/src/frontendplugin.cpp --- albert-0.12.0/plugins/qmlboxmodel/src/frontendplugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/frontendplugin.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,83 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "frontendplugin.h" +#include "configwidget.h" +#include "mainwindow.h" + + +/** ***************************************************************************/ +QmlBoxModel::FrontendPlugin::FrontendPlugin() + : Frontend("org.albert.frontend.boxmodel.qml"), + mainWindow(new MainWindow(this)){ + + connect(mainWindow.get(), &MainWindow::inputChanged, [this](){ + emit inputChanged(input()); + }); + + connect(mainWindow.get(), &MainWindow::settingsWidgetRequested, + this, &Frontend::settingsWidgetRequested); + + connect(mainWindow.get(), &MainWindow::visibilityChanged, + this, [this](QWindow::Visibility visibility){ + emit ( visibility == QWindow::Visibility::Hidden ) ? widgetHidden() : widgetShown(); + }); +} + + +/** ***************************************************************************/ +QmlBoxModel::FrontendPlugin::~FrontendPlugin() { + +} + + +/** ***************************************************************************/ +bool QmlBoxModel::FrontendPlugin::isVisible() { + return mainWindow->isVisible(); +} + + +/** ***************************************************************************/ +void QmlBoxModel::FrontendPlugin::setVisible(bool visible) { + mainWindow->setVisible(visible); + mainWindow->raise(); + mainWindow->requestActivate(); +} + + +/** ***************************************************************************/ +QString QmlBoxModel::FrontendPlugin::input() { + return mainWindow->input(); +} + + +/** ***************************************************************************/ +void QmlBoxModel::FrontendPlugin::setInput(const QString &input) { + mainWindow->setInput(input); +} + + +/** ***************************************************************************/ +void QmlBoxModel::FrontendPlugin::setModel(QAbstractItemModel *m) { + mainWindow->setModel(m); +} + + +/** ***************************************************************************/ +QWidget *QmlBoxModel::FrontendPlugin::widget(QWidget *parent) { + return new ConfigWidget(mainWindow.get(), parent); +} + diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/frontendplugin.h albert-0.13.1+plugins1/plugins/qmlboxmodel/src/frontendplugin.h --- albert-0.12.0/plugins/qmlboxmodel/src/frontendplugin.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/frontendplugin.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core_globals.h" +#include "core/frontend.h" + +namespace QmlBoxModel { + +class MainWindow; + +class FrontendPlugin final : public Core::Frontend +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_FRONTEND_IID FILE "metadata.json") + +public: + + FrontendPlugin(); + ~FrontendPlugin(); + + bool isVisible() override; + void setVisible(bool visible) override; + + QString input() override; + void setInput(const QString&) override; + + void setModel(QAbstractItemModel *) override; + + QWidget* widget(QWidget *parent = nullptr) override; + +private: + + std::unique_ptr mainWindow; +}; + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/mainwindow.cpp albert-0.13.1+plugins1/plugins/qmlboxmodel/src/mainwindow.cpp --- albert-0.12.0/plugins/qmlboxmodel/src/mainwindow.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/mainwindow.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,573 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mainwindow.h" +#include "frontendplugin.h" +#ifdef __unix__ +#include "xcb/xcb.h" +#include +#undef KeyPress +#undef KeyRelease +#undef FocusOut +#undef Status +#include +#endif + +namespace { +const QString CFG_CENTERED = "showCentered"; +const bool DEF_CENTERED = true; +const QString CFG_HIDEONFOCUSLOSS = "hideOnFocusLoss"; +const bool DEF_HIDEONFOCUSLOSS = true; +const QString CFG_ALWAYS_ON_TOP = "alwaysOnTop"; +const bool DEF_ALWAYS_ON_TOP = true; +const char* CFG_HIDE_ON_CLOSE = "hideOnClose"; +const bool DEF_HIDE_ON_CLOSE = false; +const QString CFG_STYLEPATH = "stylePath"; +const QString CFG_WND_POS = "windowPosition"; +const QString PLUGIN_ID = "org.albert.frontend.boxmodel.qml"; +const QString STYLE_MAIN_NAME = "MainComponent.qml"; +const QString STYLE_CONFIG_NAME = "style_properties.ini"; +const QString PREF_OBJ_NAME = "preferences"; +const QString FRAME_OBJ_NAME = "frame"; +} + +/** ***************************************************************************/ +QmlBoxModel::MainWindow::MainWindow(FrontendPlugin *plugin, QWindow *parent) : QQuickView(parent) { + setColor(Qt::transparent); + setFlags(Qt::Tool + | Qt::WindowStaysOnTopHint + | Qt::FramelessWindowHint + | Qt::WindowCloseButtonHint // No close event w/o this + ); + + plugin_ = plugin; + + // Set qml environment + rootContext()->setContextProperty("mainWindow", this); + rootContext()->setContextProperty("history", &history_); + rootContext()->setContextProperty("resultsModel", &model_); + + // Quit application when qml signals quit + connect(engine(), SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); + + // When component is ready load the saved properties + connect(this, &QQuickView::statusChanged, this, [this](QQuickView::Status status){ + if ( status == QQuickView::Status::Ready ){ + + // Get root object + if (!rootObject()){ + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return; + } + + // Forward signals + connect(rootObject(), SIGNAL(inputTextChanged()), + this, SIGNAL(inputChanged())); + + connect(rootObject(), SIGNAL(settingsWidgetRequested()), + this, SIGNAL(settingsWidgetRequested())); + + connect(rootObject(), SIGNAL(settingsWidgetRequested()), + this, SLOT(hide())); + + // Get preferences object + QObject *preferencesObject = rootObject()->findChild(PREF_OBJ_NAME); + if (!preferencesObject){ + qWarning() << qPrintable(QString("Could not retrieve settableProperties: " + "There is no object named '%1'.").arg(PREF_OBJ_NAME)); + return; + } + + // Load the style properties in the group of this style id + QSettings s(plugin_->configLocation().filePath(STYLE_CONFIG_NAME), QSettings::Format::IniFormat); + s.beginGroup(QFileInfo(source().toString()).dir().dirName()); + for (const QString &prop : settableProperties()) + if (s.contains(prop)) + preferencesObject->setProperty(prop.toLatin1().data(), s.value(prop)); + } + }); + + // Reload if source file changed + connect(&watcher_, &QFileSystemWatcher::fileChanged, + [this](){ + qDebug() << "QML file reloaded."; + QUrl url = source(); + setSource(QUrl()); + engine()->clearComponentCache(); + setSource(url); + watcher_.addPath(url.toString()); + }); + + // Center window between each hide and show + connect(this, &QQuickView::visibilityChanged, [this](QWindow::Visibility visibility){ + if ( visibility == QWindow::Visibility::Hidden ) + if ( showCentered_ ){ + QDesktopWidget *dw = QApplication::desktop(); + setPosition(dw->availableGeometry(dw->screenNumber(QCursor::pos())) + .center()-QPoint(width()/2,256)); + } + }); + + QStringList pluginDataPaths = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, + "org.albert.frontend.boxmodel.qml", + QStandardPaths::LocateDirectory); + +// // Add the shared modules to the lookup path +// for (const QString &pluginDataPath : pluginDataPaths){ +// QDir pluginDataDir = QDir(pluginDataPath); +// if ( pluginDataDir.exists("shared") ) +// engine()->addImportPath(pluginDataDir.filePath("shared")); +// } + + // Get style files + QFileInfoList styles; + for (const QString &pluginDataPath : pluginDataPaths) { + QDirIterator it(QString("%1/styles").arg(pluginDataPath), QDir::Dirs|QDir::NoDotAndDotDot); + while ( it.hasNext() ) { + QDir root = QDir(it.next()); + if ( root.exists(STYLE_MAIN_NAME) ){ + QmlStyleSpec style; + style.mainComponent = root.filePath(STYLE_MAIN_NAME); + style.name = root.dirName(); + style.author = "N/A"; + style.version = "N/A"; + if ( root.exists("metadata.json") ) { + QFile file(root.filePath("metadata.json")); + if (file.open(QIODevice::ReadOnly)) { + QJsonObject metadata = QJsonDocument::fromJson(file.readAll()).object(); + if (metadata.contains("name")) + style.name = metadata["name"].toString(); + if (metadata.contains("author")) + style.author = metadata["author"].toString(); + if (metadata.contains("version")) + style.version = metadata["version"].toString(); + } + } + styles_.push_back(style); + } + } + } + + if (styles_.empty()) + throw "No styles found."; + + + auto storeWinPos = [this](){ + plugin_->settings().setValue(CFG_WND_POS, position()); + }; + connect(this, &MainWindow::xChanged, storeWinPos); + connect(this, &MainWindow::yChanged, storeWinPos); + + // Load window settings + setPosition(plugin_->settings().value(CFG_WND_POS).toPoint()); + setShowCentered(plugin_->settings().value(CFG_CENTERED, DEF_CENTERED).toBool()); + setHideOnFocusLoss(plugin_->settings().value(CFG_HIDEONFOCUSLOSS, DEF_HIDEONFOCUSLOSS).toBool()); + setAlwaysOnTop(plugin_->settings().value(CFG_ALWAYS_ON_TOP, DEF_ALWAYS_ON_TOP).toBool()); + setHideOnClose(plugin_->settings().value(CFG_HIDE_ON_CLOSE, DEF_HIDE_ON_CLOSE).toBool()); + if ( plugin_->settings().contains(CFG_STYLEPATH) && QFile::exists(plugin_->settings().value(CFG_STYLEPATH).toString()) ) + setSource(plugin_->settings().value(CFG_STYLEPATH).toString()); + else { + setSource(styles_[0].mainComponent); + plugin_->settings().setValue(CFG_STYLEPATH, styles_[0].mainComponent); + } + +} + + +/** ***************************************************************************/ +QmlBoxModel::MainWindow::~MainWindow() { + +} + + +/** ***************************************************************************/ +QString QmlBoxModel::MainWindow::input() { + + // Get root object + QObject *rootObj = rootObject(); + if (!rootObj){ + qWarning() << "Could not retrieve input: There is no root object."; + return QString(); + } + return rootObj->property("inputText").toString(); +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setInput(const QString &input) { + + // Get root object + QObject *rootObj = rootObject(); + if (!rootObj){ + qWarning() << "Could not retrieve input: There is no root object."; + return; + } + rootObj->setProperty("inputText", input); +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setSource(const QUrl &url) { + + // Apply the source + QQuickView::setSource(url); + + if ( url.isEmpty() ) + return; + + // Save the theme + plugin_->settings().setValue(CFG_STYLEPATH, source().toString()); + + // Watch this source file for modifications + if ( !watcher_.files().isEmpty() ) + watcher_.removePaths(watcher_.files()); + watcher_.addPath(url.toString()); +} + + +/** ***************************************************************************/ +const std::vector &QmlBoxModel::MainWindow::availableStyles() const { + return styles_; +} + + +/** ***************************************************************************/ +QStringList QmlBoxModel::MainWindow::settableProperties() { + + // Get root object + if (!rootObject()){ + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return QStringList(); + } + + // Get preferences object + const QObject *preferencesObject = rootObject()->findChild(PREF_OBJ_NAME); + if (!preferencesObject){ + qWarning() << qPrintable(QString("Could not retrieve settableProperties: " + "There is no object named '%1'.").arg(PREF_OBJ_NAME)); + return QStringList(); + } + + // Get preferences object's meta object (Reflection yieh…) + const QMetaObject *preferencesMetaObject = preferencesObject->metaObject(); + if (!preferencesMetaObject){ + qWarning() << "Could not retrieve settableProperties: Fetching MetaObject failed."; + return QStringList(); + } + + // Get all properties of the object + QStringList settableProperties; + for (int i = 0; i < preferencesMetaObject->propertyCount(); i++) + settableProperties.append(preferencesMetaObject->property(i).name()); + + // QtObject type has a single property "objectName". Remove it. + settableProperties.removeAll("objectName"); + + return settableProperties; +} + + +/** ***************************************************************************/ +QVariant QmlBoxModel::MainWindow::property(const char *name) const { + + // Get root object + if (!rootObject()){ + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return QVariant(); + } + + // Get preferences object + const QObject *preferencesObject = rootObject()->findChild(PREF_OBJ_NAME); + if (!preferencesObject){ + qWarning() << qPrintable(QString("Could not retrieve settableProperties: " + "There is no object named '%1'.").arg(PREF_OBJ_NAME)); + return QVariant(); + } + + return preferencesObject->property(name); +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setProperty(const char *attribute, const QVariant &value) { + + // Create the settings instance of the decicated file in config location + QSettings s(plugin_->configLocation().filePath(STYLE_CONFIG_NAME), QSettings::Format::IniFormat); + s.beginGroup(QFileInfo(source().toString()).dir().dirName()); + s.setValue(attribute, value); + + // Get root object + if (!rootObject()) { + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return; + } + + // Get preferences object + QObject *preferencesObject = rootObject()->findChild(PREF_OBJ_NAME); + if (!preferencesObject) { + qWarning() << qPrintable(QString("Could not retrieve settableProperties: " + "There is no object named '%1'.").arg(PREF_OBJ_NAME)); + return; + } + + // Set the property + preferencesObject->setProperty(attribute, value); +} + + +/** ***************************************************************************/ +QStringList QmlBoxModel::MainWindow::availableThemes() { + + // Get root object + if (!rootObject()){ + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return QStringList(); + } + + QVariant returnedValue; + QMetaObject::invokeMethod(rootObject(), "availableThemes", Q_RETURN_ARG(QVariant, returnedValue)); + return returnedValue.toStringList(); +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setTheme(const QString &name){ + + // Get root object + if (!rootObject()) { + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return; + } + + // Let qml apply the theme + QMetaObject::invokeMethod(rootObject(), "setTheme", Q_ARG(QVariant, QVariant::fromValue(name))); + + // Save all current poperties in the group with this style id + QSettings s(plugin_->configLocation().filePath(STYLE_CONFIG_NAME), QSettings::Format::IniFormat); + QString styleId = QFileInfo(source().toString()).dir().dirName(); + s.beginGroup(styleId); + for (const QString &prop : settableProperties()) + s.setValue(prop, property(prop.toLatin1().data())); +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setModel(QAbstractItemModel *model) { + model_.setSourceModel(model); +} + + +/** ***************************************************************************/ +bool QmlBoxModel::MainWindow::event(QEvent *event) { + switch (event->type()) + { + // Quit on Alt+F4 + case QEvent::Close: + ( hideOnClose_ ) ? setVisible(false) : qApp->quit(); + return true; + + // Hide window on escape key + case QEvent::KeyPress: + if ( static_cast(event)->modifiers() == Qt::NoModifier + && static_cast(event)->key() == Qt::Key_Escape ){ + hide(); + return true; + } + break; + default:break; + } + return QQuickView::event(event); +} + + +#ifdef Q_OS_LINUX +/** **************************************************************************** + * @brief MainWidget::nativeEvent + * + * The purpose of this function is to hide in special casesonly. + */ +bool QmlBoxModel::MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *) +{ + if (eventType == "xcb_generic_event_t") + { + xcb_generic_event_t* event = static_cast(message); + switch (event->response_type & 127) + { + case XCB_FOCUS_OUT: { + /* This is a horribly hackish but working solution. + + A triggered key grab on X11 steals the focus of the window for short + period of time. This may result in the following annoying behaviour: + When the hotkey is pressed and X11 steals the focus there arises a + race condition between the hotkey event and the focus out event. + When the app is visible and the focus out event is delivered the app + gets hidden. Finally when the hotkey is received the app gets shown + again although the user intended to hide the app with the hotkey. + + Solutions: + Although X11 differs between the two focus out events, qt does not. + One might install a native event filter and use the XCB structs to + decide which type of event is delivered, but this approach is not + platform independent (unless designed so explicitely, but its a + hassle). The behaviour was expected when the app hides on: + + (mode==XCB_NOTIFY_MODE_GRAB && detail==XCB_NOTIFY_DETAIL_NONLINEAR)|| + (mode==XCB_NOTIFY_MODE_NORMAL && detail==XCB_NOTIFY_DETAIL_NONLINEAR) + (Check Xlib Programming Manual) + + Another much simpler but less elegant solution is to delay the + hiding a few milliseconds, so that the hotkey event will always be + handled first. */ + + xcb_focus_out_event_t *fe = reinterpret_cast(event); +// qDebug() << "MainWidget::nativeEvent::XCB_FOCUS_OUT\t"; +// switch (fe->mode) { +// case XCB_NOTIFY_MODE_NORMAL: qDebug() << "XCB_NOTIFY_MODE_NORMAL";break; +// case XCB_NOTIFY_MODE_GRAB: qDebug() << "XCB_NOTIFY_MODE_GRAB";break; +// case XCB_NOTIFY_MODE_UNGRAB: qDebug() << "XCB_NOTIFY_MODE_UNGRAB";break; +// case XCB_NOTIFY_MODE_WHILE_GRABBED: qDebug() << "XCB_NOTIFY_MODE_WHILE_GRABBED";break; +// } +// switch (fe->detail) { +// case XCB_NOTIFY_DETAIL_ANCESTOR: qDebug() << "ANCESTOR";break; +// case XCB_NOTIFY_DETAIL_INFERIOR: qDebug() << "INFERIOR";break; +// case XCB_NOTIFY_DETAIL_NONE: qDebug() << "NONE";break; +// case XCB_NOTIFY_DETAIL_NONLINEAR: qDebug() << "NONLINEAR";break; +// case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: qDebug() << "NONLINEAR_VIRTUAL";break; +// case XCB_NOTIFY_DETAIL_POINTER: qDebug() << "POINTER";break;break; +// case XCB_NOTIFY_DETAIL_POINTER_ROOT: qDebug() << "POINTER_ROOT"; +// case XCB_NOTIFY_DETAIL_VIRTUAL: qDebug() << "VIRTUAL";break; +// } + if ((/*(fe->mode==XCB_NOTIFY_MODE_GRAB && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR) ||*/ + (fe->mode==XCB_NOTIFY_MODE_NORMAL && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR )) && + hideOnFocusLoss_) + hide(); + return true; + } + } + } + return false; +} +#endif + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::resizeEvent(QResizeEvent *event) { + + QQuickView::resizeEvent(event); + +#ifdef __unix__ + + // Get root object + if (!rootObject()) { + qWarning() << "Could not retrieve settableProperties: There is no root object."; + return; + } + + // Get preferences object + QObject *frameObject = rootObject()->findChild(FRAME_OBJ_NAME, Qt::FindChildrenRecursively); + if (frameObject) { + // Keep the input shape consistent + int shape_event_base, shape_error_base; + if (XShapeQueryExtension(QX11Info::display(), &shape_event_base, &shape_error_base)) { + + Region region = XCreateRegion(); + XRectangle rectangle; + rectangle.x = static_cast(frameObject->property("x").toUInt()); + rectangle.y = static_cast(frameObject->property("y").toUInt()); + rectangle.width = static_cast(frameObject->property("width").toUInt()); + rectangle.height = static_cast(frameObject->property("height").toUInt()); + XUnionRectWithRegion(&rectangle, region, region); + XShapeCombineRegion(QX11Info::display(), winId(), ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); + } + } else + qWarning() << qPrintable(QString("Could not retrieve settableProperties: " + "There is no object named '%1'.").arg(FRAME_OBJ_NAME)); +#endif + +} + + +/** ***************************************************************************/ +bool QmlBoxModel::MainWindow::alwaysOnTop() const { + return flags() & Qt::WindowStaysOnTopHint; +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setAlwaysOnTop(bool alwaysOnTop) { + + plugin_->settings().setValue(CFG_ALWAYS_ON_TOP, alwaysOnTop); + + alwaysOnTop + ? setFlags(flags() | Qt::WindowStaysOnTopHint) + : setFlags(flags() & ~Qt::WindowStaysOnTopHint); + // Flags changed. Update + QQuickView::hide(); +} + + +/** ***************************************************************************/ +bool QmlBoxModel::MainWindow::hideOnFocusLoss() const { + return hideOnFocusLoss_; +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setHideOnFocusLoss(bool hideOnFocusLoss) { + plugin_->settings().setValue(CFG_HIDEONFOCUSLOSS, hideOnFocusLoss); + hideOnFocusLoss_ = hideOnFocusLoss; +} + + +/** ***************************************************************************/ +bool QmlBoxModel::MainWindow::showCentered() const { + return showCentered_; +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setShowCentered(bool showCentered) { + plugin_->settings().setValue(CFG_CENTERED, showCentered); + showCentered_ = showCentered; +} + + +/** ***************************************************************************/ +bool QmlBoxModel::MainWindow::hideOnClose() const { + return hideOnClose_; +} + + +/** ***************************************************************************/ +void QmlBoxModel::MainWindow::setHideOnClose(bool hideOnClose) { + plugin_->settings().setValue(CFG_HIDE_ON_CLOSE, hideOnClose); + hideOnClose_ = hideOnClose; +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/mainwindow.h albert-0.13.1+plugins1/plugins/qmlboxmodel/src/mainwindow.h --- albert-0.12.0/plugins/qmlboxmodel/src/mainwindow.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/mainwindow.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,94 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include "core/history.h" + +namespace QmlBoxModel { + +struct QmlStyleSpec { + QString name; + QString version; + QString author; + QString mainComponent; +}; + +class FrontendPlugin; + +class MainWindow final : public QQuickView +{ + Q_OBJECT + +public: + + MainWindow(FrontendPlugin *plugin, QWindow *parent = 0); + ~MainWindow(); + + QString input(); + void setInput(const QString&); + void setModel(QAbstractItemModel* model); + + const std::vector &availableStyles() const; + QStringList settableProperties(); + + QVariant property(const char *name) const; + void setProperty(const char *attribute, const QVariant &value); + + QStringList availableThemes(); + void setTheme(const QString& name); + + void setSource(const QUrl & url); + + bool showCentered() const; + void setShowCentered(bool showCentered); + + bool hideOnFocusLoss() const; + void setHideOnFocusLoss(bool hideOnFocusLoss); + + bool alwaysOnTop() const; + void setAlwaysOnTop(bool alwaysOnTop); + + bool hideOnClose() const; + void setHideOnClose(bool b = true); + +protected: + + bool event(QEvent *event) override; + bool nativeEvent(const QByteArray &eventType, void *message, long *) override; + void resizeEvent(QResizeEvent *event) override; + + bool showCentered_; + bool hideOnFocusLoss_; + bool hideOnClose_; + Core::History history_; + QIdentityProxyModel model_; + std::vector styles_; + QFileSystemWatcher watcher_; + FrontendPlugin *plugin_; + +signals: + + void inputChanged(); + void settingsWidgetRequested(); + +}; + +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/propertyeditor.cpp albert-0.13.1+plugins1/plugins/qmlboxmodel/src/propertyeditor.cpp --- albert-0.12.0/plugins/qmlboxmodel/src/propertyeditor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/propertyeditor.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,123 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2016 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "propertyeditor.h" +#include "mainwindow.h" +#include "colordialog.hpp" +#include +#include +#include +#include +#include +#include + +namespace QmlBoxModel { + +class PropertyModel final : public QAbstractTableModel +{ +public: + PropertyModel(MainWindow *mainWindow, QObject * parent = 0) + : QAbstractTableModel(parent), mainWindow_(mainWindow){ + properties_ = mainWindow_->settableProperties(); + } + + ~PropertyModel() { + + } + + int rowCount(const QModelIndex & parent = QModelIndex()) const override { + Q_UNUSED(parent) + return properties_.count(); + } + + int columnCount(const QModelIndex & parent = QModelIndex()) const override { + Q_UNUSED(parent) + return 2; + } + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override { + if (role == Qt::DisplayRole || role == Qt::EditRole) { + if ( index.column() == 0 ) + return properties_[index.row()]; + else if (index.column()==1) + return mainWindow_->property(properties_.at(index.row()).toLatin1().data()); + } + return QVariant(); + } + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override { + if (orientation == Qt::Horizontal && role == Qt::DisplayRole){ + if (section==0) + return "Property"; + if (section==1) + return "Value"; + } + return QVariant(); + } + + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override { + if (role == Qt::EditRole){ + mainWindow_->setProperty(properties_[index.row()].toLatin1().data(), value); + return true; + } + return true; + } + + Qt::ItemFlags flags(const QModelIndex & index) const override { + if (index.column()==0) + return Qt::NoItemFlags|Qt::ItemIsEnabled; + if (index.column()==1) + return Qt::ItemIsEditable|Qt::ItemIsEnabled; + return Qt::NoItemFlags; + } + +private: + MainWindow *mainWindow_; + QStringList properties_; +}; + +} + + + +///****************************************************************************/ +QmlBoxModel::PropertyEditor::PropertyEditor(MainWindow *mainWindow, QWidget *parent) + : QDialog (parent){ + + resize(320, 480); + setWindowTitle("PropertyEditor"); + + QTableView *tableView = new QTableView(this); + tableView->setObjectName(QStringLiteral("tableView")); + tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setStretchLastSection(true); + tableView->setAlternatingRowColors(true); + tableView->setShowGrid(false); + tableView->horizontalHeader()->setMinimumSectionSize(16); + tableView->setModel(new PropertyModel(mainWindow, tableView)); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(tableView); + + QItemEditorFactory *editorFactory = new QItemEditorFactory; + editorFactory->registerEditor(QVariant::Color, new QStandardItemEditorCreator()); + + // Create a delgate using the factory + QStyledItemDelegate *delegate = new QStyledItemDelegate(this); + delegate->setItemEditorFactory(editorFactory); + tableView->setItemDelegate(delegate); +} diff -Nru albert-0.12.0/plugins/qmlboxmodel/src/propertyeditor.h albert-0.13.1+plugins1/plugins/qmlboxmodel/src/propertyeditor.h --- albert-0.12.0/plugins/qmlboxmodel/src/propertyeditor.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/qmlboxmodel/src/propertyeditor.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,32 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2016 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace QmlBoxModel { + +class MainWindow; + +class PropertyEditor : public QDialog +{ + Q_OBJECT + +public: + explicit PropertyEditor(MainWindow *mainWindow, QWidget *parent = 0); +}; + +} diff -Nru albert-0.12.0/plugins/ssh/CMakeLists.txt albert-0.13.1+plugins1/plugins/ssh/CMakeLists.txt --- albert-0.12.0/plugins/ssh/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(ssh) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/ssh/metadata.json albert-0.13.1+plugins1/plugins/ssh/metadata.json --- albert-0.12.0/plugins/ssh/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.ssh", + "name" : "Secure Shell", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/ssh/resources/ssh.svg albert-0.13.1+plugins1/plugins/ssh/resources/ssh.svg --- albert-0.12.0/plugins/ssh/resources/ssh.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/resources/ssh.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,741 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/ssh/src/configwidget.cpp albert-0.13.1+plugins1/plugins/ssh/src/configwidget.cpp --- albert-0.12.0/plugins/ssh/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +Ssh::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +Ssh::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/ssh/src/configwidget.h albert-0.13.1+plugins1/plugins/ssh/src/configwidget.h --- albert-0.12.0/plugins/ssh/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,32 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace Ssh { + +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; + +} diff -Nru albert-0.12.0/plugins/ssh/src/configwidget.ui albert-0.13.1+plugins1/plugins/ssh/src/configwidget.ui --- albert-0.12.0/plugins/ssh/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,53 @@ + + + Ssh::ConfigWidget + + + + + + This extension scans your /etc/ssh/config and ~/.ssh/config and makes your ssh hosts accessible by Albert. This is a pure convenience extension. If you want to use ssh to the full extend consider using it directly via the Terminal extension. + + + true + + + + + + + Use 'known_hosts' + + + + + + + + 0 + 0 + + + + Rescan + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/ssh/src/extension.cpp albert-0.13.1+plugins1/plugins/ssh/src/extension.cpp --- albert-0.12.0/plugins/ssh/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,268 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extension.h" +#include "configwidget.h" +#include "core/query.h" +#include "util/standardaction.h" +#include "util/standarditem.h" +#include "util/shutil.h" +#include "xdg/iconlookup.h" +using std::shared_ptr; +using std::vector; +using namespace Core; + +extern QString terminalCommand; + +namespace { + +const char* CFG_USE_KNOWN_HOSTS = "use_known_hosts"; +const bool DEF_USE_KNOWN_HOSTS = true; + +// Function to extract the hosts of a ssh config file +std::set getSshHostsFromConfig(const QString& path) { + std::set hosts; + QFile file(path); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + while ( !in.atEnd() ) { + QStringList fields = in.readLine().split(QRegularExpression("\\s+"), QString::SkipEmptyParts); + if ( fields.size() > 1 && fields[0] == "Host") + for ( int i = 1; i < fields.size(); ++i ){ + if ( !(fields[i].contains('*') || fields[i].contains('?')) ) + hosts.insert(fields[i]); + } + } + file.close(); + } + return hosts; +} + +// Function to extract the hosts of a ssh known_hosts file +std::set getSshHostsFromKnownHosts(const QString& path) { + std::set hosts; + QFile file(path); + if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { + QRegularExpression re ("^[a-zA-Z0-9\\.]*(?=(,.*)*\\s)"); + QTextStream in(&file); + while ( !in.atEnd() ) { + QString line = in.readLine(); + QRegularExpressionMatch match = re.match(line); + if ( match.hasMatch() ) + hosts.insert(match.captured(0)); + } + file.close(); + } + return hosts; +} + +} + + + +class Ssh::Private +{ +public: + QString icon; + QPointer widget; + QFileSystemWatcher fileSystemWatcher; + vector> hosts; + QString shell; + bool useKnownHosts; +}; + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +Ssh::Extension::Extension() + : Core::Extension("org.albert.extension.ssh"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + // passwd must not be freed + passwd *pwd = getpwuid(geteuid()); + if (pwd == NULL) + throw "Could not retrieve user shell"; + d->shell = pwd->pw_shell; + + // Load settings + d->useKnownHosts = settings().value(CFG_USE_KNOWN_HOSTS, DEF_USE_KNOWN_HOSTS).toBool(); + + // Find ssh + if (QStandardPaths::findExecutable("ssh").isNull()) + throw QString("[%s] ssh not found.").arg(Core::Plugin::id()); + + // Find an appropriate icon + d->icon = XDG::IconLookup::iconPath({"ssh", "terminal"}); + if (d->icon.isEmpty()) + d->icon = ":ssh"; // Fallback + + rescan(); +} + + + +/** ***************************************************************************/ +Ssh::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *Ssh::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + + // Checkboxes + d->widget->ui.checkBox_knownhosts->setChecked(useKnownHosts()); + connect(d->widget->ui.checkBox_knownhosts, &QCheckBox::toggled, + this, &Extension::setUseKnownHosts); + + connect(d->widget->ui.pushButton_rescan, &QPushButton::clicked, + this, &Extension::rescan); + + } + return d->widget; +} + + + +/** ***************************************************************************/ +void Ssh::Extension::handleQuery(Core::Query * query) const { + + if ( query->isTriggered() ){ + + // Add all hosts that the query is a prefix of + for ( shared_ptr& host : d->hosts ) + if ( host->text().startsWith(query->string()) ) + query->addMatch(host, static_cast(1.0*query->string().size()/host->text().size()* UINT_MAX)); + + if (!query->string().trimmed().isEmpty()) { + // Add the quick connect item + QString trimmed = query->string().trimmed(); + shared_ptr action = std::make_shared(); + action->setText(QString("Connect to '%1' using ssh").arg(trimmed)); + action->setAction([trimmed, this](){ + QStringList tokens; + tokens << Core::ShUtil::split(terminalCommand) << d->shell << "-c" + << QString(" ssh %1 || read -rsp $'\nPress enter to close the terminal.\n'").arg(trimmed); + QProcess::startDetached(tokens.takeFirst(), tokens); + }); + + std::shared_ptr item = std::make_shared(""); + item->setText(trimmed); + item->setSubtext(QString("Quick connect to '%1' using ssh").arg(trimmed)); + item->setCompletionString(QString("ssh %1").arg(trimmed)); + item->setIconPath(d->icon); + item->setActions({action}); + + query->addMatch(std::move(item)); + } + + } else { + + // Add all hosts that the query is a prefix of + if ( !query->string().isEmpty()) + for ( shared_ptr& host : d->hosts ) + if ( host->text().startsWith(query->string()) ) + query->addMatch(host, static_cast(1.0*query->string().size()/host->text().size()* UINT_MAX)); + + } +} + + + +/** ***************************************************************************/ +void Ssh::Extension::rescan() { + + // Build a new index + vector> sshHosts; + + // Get the hosts in config + std::set hosts; + for ( const QString& path : {QString("/etc/ssh/config"), QDir::home().filePath(".ssh/config")} ) + if ( QFile::exists(path) ) + for ( const QString& host : getSshHostsFromConfig(path) ) + hosts.insert(host); + + // Get the hosts in known_hosts + if ( d->useKnownHosts ) { + const QString& path = QDir::home().filePath(".ssh/known_hosts"); + if ( QFile::exists(path) ) + for ( const QString& host : getSshHostsFromKnownHosts(path) ) + hosts.insert(host); + } + + + for ( const QString& host : hosts ){ + + // Create item + std::shared_ptr si = std::make_shared(host); + si->setText(host); + si->setSubtext(QString("Connect to '%1' using ssh").arg(host)); + si->setCompletionString(QString("ssh %1").arg(host)); + si->setIconPath(d->icon); + + shared_ptr sa = std::make_shared(); + sa->setText(QString("Connect to '%1' using ssh").arg(host)); + sa->setAction([host, this](){ + QStringList tokens; + tokens << Core::ShUtil::split(terminalCommand) + << d->shell << "-c" + << QString(" ssh %1 || read -rsp $'\nPress enter to close the terminal.\n'").arg(host); + QProcess::startDetached(tokens.takeFirst(), tokens); + }); + si->setActions({sa}); + + sshHosts.push_back(std::move(si)); + } + + d->hosts = std::move(sshHosts); +} + + + +/** ***************************************************************************/ +bool Ssh::Extension::useKnownHosts() { + return d->useKnownHosts; +} + + + +/** ***************************************************************************/ +void Ssh::Extension::setUseKnownHosts(bool b) { + settings().setValue(CFG_USE_KNOWN_HOSTS, b); + d->useKnownHosts = b; + rescan(); +} diff -Nru albert-0.12.0/plugins/ssh/src/extension.h albert-0.13.1+plugins1/plugins/ssh/src/extension.h --- albert-0.12.0/plugins/ssh/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,54 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace Ssh { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "SecureShell"; } + QWidget *widget(QWidget *parent = nullptr) override; + QStringList triggers() const override { return {"ssh "}; } + void handleQuery(Core::Query * query) const override; + + void rescan(); + + bool useKnownHosts(); + void setUseKnownHosts(bool b = true); + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/ssh/ssh.qrc albert-0.13.1+plugins1/plugins/ssh/ssh.qrc --- albert-0.12.0/plugins/ssh/ssh.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/ssh/ssh.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/ssh.svg + + diff -Nru albert-0.12.0/plugins/system/CMakeLists.txt albert-0.13.1+plugins1/plugins/system/CMakeLists.txt --- albert-0.12.0/plugins/system/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(system) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/system/metadata.json albert-0.13.1+plugins1/plugins/system/metadata.json --- albert-0.12.0/plugins/system/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.system", + "name" : "System", + "version" : "1.0", + "platform" : "Linux", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/system/resources/hibernate.svg albert-0.13.1+plugins1/plugins/system/resources/hibernate.svg --- albert-0.12.0/plugins/system/resources/hibernate.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/resources/hibernate.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/system/resources/lock.svg albert-0.13.1+plugins1/plugins/system/resources/lock.svg --- albert-0.12.0/plugins/system/resources/lock.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/resources/lock.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/system/resources/logout.svg albert-0.13.1+plugins1/plugins/system/resources/logout.svg --- albert-0.12.0/plugins/system/resources/logout.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/resources/logout.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/system/resources/poweroff.svg albert-0.13.1+plugins1/plugins/system/resources/poweroff.svg --- albert-0.12.0/plugins/system/resources/poweroff.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/resources/poweroff.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/system/resources/reboot.svg albert-0.13.1+plugins1/plugins/system/resources/reboot.svg --- albert-0.12.0/plugins/system/resources/reboot.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/resources/reboot.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/system/resources/suspend.svg albert-0.13.1+plugins1/plugins/system/resources/suspend.svg --- albert-0.12.0/plugins/system/resources/suspend.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/resources/suspend.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/system/src/configwidget.cpp albert-0.13.1+plugins1/plugins/system/src/configwidget.cpp --- albert-0.12.0/plugins/system/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +System::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +System::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/system/src/configwidget.h albert-0.13.1+plugins1/plugins/system/src/configwidget.h --- albert-0.12.0/plugins/system/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace System { +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/system/src/configwidget.ui albert-0.13.1+plugins1/plugins/system/src/configwidget.ui --- albert-0.12.0/plugins/system/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,115 @@ + + + System::ConfigWidget + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Suspend: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Lock: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Log out: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Shut down: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Restart: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + <html><head/><body><p><span style=" color:#808080;">Be aware that on most distributions the standard commands to control your systems state (e.g. reboot, shutdown, systemctl etc) do not shutdown your desktop session gracefully. Try to use your desktop session managers interface. If you think you know good defaults for your desktop environment, please suggest it on </span><a href="https://github.com/ManuelSchneid3r/albert/issues"><span style=" text-decoration: underline; color:#0000ff;">github</span></a><span style=" color:#808080;">.</span></p></body></html> + + + true + + + + + + + Hibernate: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + diff -Nru albert-0.12.0/plugins/system/src/extension.cpp albert-0.13.1+plugins1/plugins/system/src/extension.cpp --- albert-0.12.0/plugins/system/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,276 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "extension.h" +#include "core/query.h" +#include "util/standardaction.h" +#include "util/standarditem.h" +#include "xdg/iconlookup.h" +using std::vector; + + +namespace { + +enum SupportedCommands { + LOCK, + LOGOUT, + SUSPEND, + HIBERNATE, + REBOOT, + POWEROFF, + NUMCOMMANDS +}; + +vector configNames = { + "lock", + "logout", + "suspend", + "hibernate", + "reboot", + "shutdown" +}; + +vector itemTitles = { + "Lock", + "Log out", + "Suspend", + "Hibernate", + "Restart", + "Shut down" +}; + +vector itemDescriptions = { + "Lock the session.", + "Quit the session.", + "Suspend the machine.", + "Hibernate the machine.", + "Reboot the machine.", + "Shutdown the machine.", +}; + +vector iconNames = { + "system-lock-screen", + "system-log-out", + "system-suspend", + "system-suspend-hibernate", + "system-reboot", + "system-shutdown" +}; + + +QString defaultCommand(SupportedCommands command){ + + QString de = getenv("XDG_CURRENT_DESKTOP"); + + switch (command) { + case LOCK: + if (de == "Unity" || de == "Pantheon" || de == "GNOME") + return "gnome-screensaver-command --lock"; + else if (de == "kde-plasma" || de == "KDE") + return "dbus-send --dest=org.freedesktop.ScreenSaver --type=method_call /ScreenSaver org.freedesktop.ScreenSaver.Lock"; + else if (de == "XFCE") + return "xflock4"; + else if (de == "X-Cinnamon" || de == "Cinnamon") + return "cinnamon-screensaver-command --lock"; + else if (de == "MATE") + return "mate-screensaver-command --lock"; + else + return "xdg-screensaver lock"; + + case LOGOUT: + if (de == "Unity" || de == "Pantheon" || de == "GNOME") + return "gnome-session-quit --logout"; + else if (de == "kde-plasma" || de == "KDE") + return "qdbus org.kde.ksmserver /KSMServer logout 0 0 0"; + else if (de == "X-Cinnamon") + return "cinnamon-session-quit --logout"; + else if (de == "XFCE") + return "xfce4-session-logout --logout"; + else if (de == "MATE") + return "mate-session-save --logout"; + else + return "notify-send \"Error.\" \"Logout command is not set.\" --icon=system-log-out"; + + case SUSPEND: + if (de == "XFCE") + return "xfce4-session-logout --suspend"; + else if (de == "MATE") + return "sh -c \"mate-screensaver-command --lock && systemctl suspend -i\""; + else + return "systemctl suspend -i"; + + case HIBERNATE: + if (de == "XFCE") + return "xfce4-session-logout --hibernate"; + else if (de == "MATE") + return "sh -c \"mate-screensaver-command --lock && systemctl hibernate -i\""; + else + return "systemctl hibernate -i"; + + case REBOOT: + if (de == "Unity" || de == "Pantheon" || de == "GNOME") + return "gnome-session-quit --reboot"; + else if (de == "kde-plasma" || de == "KDE") + return "qdbus org.kde.ksmserver /KSMServer logout 0 1 0"; + else if (de == "X-Cinnamon") + return "cinnamon-session-quit --reboot"; + else if (de == "XFCE") + return "xfce4-session-logout --reboot"; + else if (de == "MATE") + return "mate-session-save --shutdown-dialog"; + else + return "notify-send \"Error.\" \"Reboot command is not set.\" --icon=system-reboot"; + + case POWEROFF: + if (de == "Unity" || de == "Pantheon" || de == "GNOME") + return "gnome-session-quit --power-off"; + else if (de == "kde-plasma" || de == "KDE") + return "qdbus org.kde.ksmserver /KSMServer logout 0 2 0"; + else if (de == "X-Cinnamon") + return "cinnamon-session-quit --power-off"; + else if (de == "XFCE") + return "xfce4-session-logout --halt"; + else if (de == "MATE") + return "mate-session-save --shutdown-dialog"; + else + return "notify-send \"Error.\" \"Poweroff command is not set.\" --icon=system-shutdown"; + + case NUMCOMMANDS: + // NEVER REACHED; + return ""; + } + + // NEVER REACHED; + return ""; +} + +} + + + +class System::Private +{ +public: + QPointer widget; + vector iconPaths; + vector commands; +}; + + + +/** ***************************************************************************/ +System::Extension::Extension() + : Core::Extension("org.albert.extension.system"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + // Load settings + for (size_t i = 0; i < NUMCOMMANDS; ++i) { + d->iconPaths.push_back(XDG::IconLookup::iconPath(iconNames[i])); + d->commands.push_back(settings().value(configNames[i], defaultCommand(static_cast(i))).toString()); + } +} + + + +/** ***************************************************************************/ +System::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *System::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + + // Initialize the content and connect the signals + + d->widget->ui.lineEdit_lock->setText(d->commands[LOCK]); + connect(d->widget->ui.lineEdit_lock, &QLineEdit::textEdited, [this](const QString &s){ + d->commands[LOCK]= s; + settings().setValue(configNames[LOCK], s); + }); + + d->widget->ui.lineEdit_logout->setText(d->commands[LOGOUT]); + connect(d->widget->ui.lineEdit_logout, &QLineEdit::textEdited, [this](const QString &s){ + d->commands[LOGOUT]= s; + settings().setValue(configNames[LOGOUT], s); + }); + + d->widget->ui.lineEdit_suspend->setText(d->commands[SUSPEND]); + connect(d->widget->ui.lineEdit_suspend, &QLineEdit::textEdited, [this](const QString &s){ + d->commands[SUSPEND]= s; + settings().setValue(configNames[SUSPEND], s); + }); + + d->widget->ui.lineEdit_hibernate->setText(d->commands[HIBERNATE]); + connect(d->widget->ui.lineEdit_hibernate, &QLineEdit::textEdited, [this](const QString &s){ + d->commands[HIBERNATE]= s; + settings().setValue(configNames[HIBERNATE], s); + }); + + d->widget->ui.lineEdit_reboot->setText(d->commands[REBOOT]); + connect(d->widget->ui.lineEdit_reboot, &QLineEdit::textEdited, [this](const QString &s){ + d->commands[REBOOT]= s; + settings().setValue(configNames[REBOOT], s); + }); + + d->widget->ui.lineEdit_shutdown->setText(d->commands[POWEROFF]); + connect(d->widget->ui.lineEdit_shutdown, &QLineEdit::textEdited, [this](const QString &s){ + d->commands[POWEROFF]= s; + settings().setValue(configNames[POWEROFF], s); + }); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void System::Extension::handleQuery(Core::Query * query) const { + + if ( query->string().isEmpty()) + return; + + for (size_t i = 0; i < NUMCOMMANDS; ++i) { + if ( itemTitles[i].startsWith(query->string(), Qt::CaseInsensitive) ) { + + QString cmd = d->commands[i]; + std::shared_ptr action = std::make_shared(); + action->setText(itemDescriptions[i]); + action->setAction([=](){ QProcess::startDetached(cmd); }); + + std::shared_ptr item = std::make_shared(configNames[i]); + item->setText(itemTitles[i]); + item->setSubtext(itemDescriptions[i]); + item->setIconPath(d->iconPaths[i]); + item->setActions({move(action)}); + + query->addMatch(std::move(item), static_cast(static_cast(query->string().size())/itemTitles[i].size()*UINT_MAX)); + } + } +} + diff -Nru albert-0.12.0/plugins/system/src/extension.h albert-0.13.1+plugins1/plugins/system/src/extension.h --- albert-0.12.0/plugins/system/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace System { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "System"; } + QWidget *widget(QWidget *parent = nullptr) override; + void handleQuery(Core::Query * query) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/system/system.qrc albert-0.13.1+plugins1/plugins/system/system.qrc --- albert-0.12.0/plugins/system/system.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/system/system.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ + + + resources/poweroff.svg + resources/reboot.svg + resources/suspend.svg + resources/hibernate.svg + resources/lock.svg + resources/logout.svg + + diff -Nru albert-0.12.0/plugins/templateExtension/CMakeLists.txt albert-0.13.1+plugins1/plugins/templateExtension/CMakeLists.txt --- albert-0.12.0/plugins/templateExtension/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(projectid) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC}) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/templateExtension/metadata.json albert-0.13.1+plugins1/plugins/templateExtension/metadata.json --- albert-0.12.0/plugins/templateExtension/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.projectid", + "name" : "Template", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "Author missing", + "dependencies" : [], + "enabledbydefault": false +} diff -Nru albert-0.12.0/plugins/templateExtension/src/configwidget.cpp albert-0.13.1+plugins1/plugins/templateExtension/src/configwidget.cpp --- albert-0.12.0/plugins/templateExtension/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +ProjectNamespace::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +ProjectNamespace::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/templateExtension/src/configwidget.h albert-0.13.1+plugins1/plugins/templateExtension/src/configwidget.h --- albert-0.12.0/plugins/templateExtension/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace ProjectNamespace { +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/templateExtension/src/configwidget.ui albert-0.13.1+plugins1/plugins/templateExtension/src/configwidget.ui --- albert-0.12.0/plugins/templateExtension/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,51 @@ + + + ProjectNamespace::ConfigWidget + + + + 0 + 0 + 480 + 320 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p align="center"><span style=" color:#808080;">This is a simple template extension.</span></p></body></html> + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/templateExtension/src/extension.cpp albert-0.13.1+plugins1/plugins/templateExtension/src/extension.cpp --- albert-0.12.0/plugins/templateExtension/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,141 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include "core/item.h" +#include "core/query.h" +#include "util/standardaction.h" +#include "util/standarditem.h" +#include "xdg/iconlookup.h" +#include "configwidget.h" +#include "extension.h" +using namespace Core; +using namespace std; + + + +class ProjectNamespace::Private +{ +public: + QPointer widget; +}; + + + +/** ***************************************************************************/ +ProjectNamespace::Extension::Extension() + : Core::Extension("org.albert.extension.projectid"), // Must match the id in metadata + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + /* + * Check the Extension and Plugin header to see the members in this scope + */ + + // You can throw in the constructor if something fatal happened + throw std::runtime_error( "Description of error." ); + throw std::string( "Description of error." ); + throw QString( "Description of error." ); + throw "Description of error."; + throw; // Whatever prints "unknown error" +} + + + +/** ***************************************************************************/ +ProjectNamespace::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *ProjectNamespace::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void ProjectNamespace::Extension::setupSession() { + +} + + + +/** ***************************************************************************/ +void ProjectNamespace::Extension::teardownSession() { + +} + + + +/** ***************************************************************************/ +void ProjectNamespace::Extension::handleQuery(Core::Query * query) const { + + // Queries can be empty + if ( query->string().isEmpty() ) + return; + + // They can also contain only spaces + if ( query->string().trimmed().isEmpty() ) + return; + + // If you registered a trigger and it matches trigger will contain it + if ( !query->trigger().isNull() ) { + + /* + * Use + * + * query->addMatch(my_item) + * + * to add matches. If you created a throw away item MOVE it instead of + * copying e.g.: + * + * query->addMatch(std::move(my_tmp_item)) + * + * The relevance factor is optional. (Defaults to 0) its a usigned integer depicting the + * relevance of the item 0 mean not relevant UINT_MAX is totally relevant (exact match). + * E.g. it the query is "it" and your items name is "item" + * + * my_item.name().startswith(query->string) + * + * is a naive match criterion and + * + * UINT_MAX / ( query.searchterm().size() / my_item.name().size() ) + * + * a naive match factor. + * + * If you have a lot of items use the iterator versions addMatches, e.g. like that + * + * query->addMatches(my_items.begin(), my_items.end()); + * + * If the items in the container are temporary object move them to avoid uneccesary + * reference counting: + * + * query->addMatches(std::make_move_iterator(my_tmp_items.begin()), + * std::make_move_iterator(my_tmp_items.end())); + */ + } +} + diff -Nru albert-0.12.0/plugins/templateExtension/src/extension.h albert-0.13.1+plugins1/plugins/templateExtension/src/extension.h --- albert-0.12.0/plugins/templateExtension/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/templateExtension/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,50 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace ProjectNamespace { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Template"; } + QWidget *widget(QWidget *parent = nullptr) override; + void setupSession() override; + void teardownSession() override; + void handleQuery(Core::Query * query) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/terminal/CMakeLists.txt albert-0.13.1+plugins1/plugins/terminal/CMakeLists.txt --- albert-0.12.0/plugins/terminal/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(terminal) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Concurrent) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/terminal/metadata.json albert-0.13.1+plugins1/plugins/terminal/metadata.json --- albert-0.12.0/plugins/terminal/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.terminal", + "name" : "Terminal", + "version" : "1.0", + "platform" : "Linux", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/terminal/resources/terminal.svg albert-0.13.1+plugins1/plugins/terminal/resources/terminal.svg --- albert-0.12.0/plugins/terminal/resources/terminal.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/resources/terminal.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/terminal/src/configwidget.cpp albert-0.13.1+plugins1/plugins/terminal/src/configwidget.cpp --- albert-0.12.0/plugins/terminal/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,17 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" diff -Nru albert-0.12.0/plugins/terminal/src/configwidget.h albert-0.13.1+plugins1/plugins/terminal/src/configwidget.h --- albert-0.12.0/plugins/terminal/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,37 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace Terminal { + +class ConfigWidget final : public QWidget +{ + Q_OBJECT + +public: + + ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); + } + + Ui::ConfigWidget ui; + +}; + +} diff -Nru albert-0.12.0/plugins/terminal/src/configwidget.ui albert-0.13.1+plugins1/plugins/terminal/src/configwidget.ui --- albert-0.12.0/plugins/terminal/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,33 @@ + + + Terminal::ConfigWidget + + + + + + The terminal extension allows you to run commands in a terminal or a shell directly. Theres not much more about it but convenience. Just invoke the extension using the trigger '>'. + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff -Nru albert-0.12.0/plugins/terminal/src/extension.cpp albert-0.13.1+plugins1/plugins/terminal/src/extension.cpp --- albert-0.12.0/plugins/terminal/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,232 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extension.h" +#include "configwidget.h" +#include "core/query.h" +#include "util/shutil.h" +#include "util/standarditem.h" +#include "util/standardaction.h" +#include "xdg/iconlookup.h" +using namespace std; +using Core::Action; +using Core::StandardAction; +using Core::StandardItem; + +extern QString terminalCommand; + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +class Terminal::Private +{ +public: + QPointer widget; + QString iconPath; + QString shell; + QFileSystemWatcher watcher; + set index; + QFutureWatcher> futureWatcher; +}; + + + +/** ***************************************************************************/ +Terminal::Extension::Extension() + : Core::Extension("org.albert.extension.terminal"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + QString iconPath = XDG::IconLookup::iconPath("terminal"); + d->iconPath = iconPath.isNull() ? ":terminal" : iconPath; + + d->watcher.addPaths(QString(::getenv("PATH")).split(':', QString::SkipEmptyParts)); + connect(&d->watcher, &QFileSystemWatcher::directoryChanged, + this, &Extension::rebuildIndex); + + // passwd must not be freed + passwd *pwd = getpwuid(geteuid()); + if (pwd == nullptr) + throw "Could not retrieve user shell"; + d->shell = pwd->pw_shell; + + rebuildIndex(); +} + + + +/** ***************************************************************************/ +Terminal::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *Terminal::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) + d->widget = new ConfigWidget(parent); + return d->widget; +} + + + +/** ***************************************************************************/ +void Terminal::Extension::handleQuery(Core::Query * query) const { + + if ( !query->isTriggered() || query->string().trimmed().isEmpty() ) + return; + + vector,short>> results; + + // Extract data from input string: [0] program. The rest: args + QString potentialProgram = query->string().section(' ', 0, 0, QString::SectionSkipEmpty); + QString argsString = query->string().section(' ', 1, -1, QString::SectionSkipEmpty); + + // Iterate over matches + set::iterator it = lower_bound(d->index.begin(), d->index.end(), potentialProgram); + + // Get the + QString commonPrefix; + if ( it != d->index.end() ) + commonPrefix = *it; + + while (it != d->index.end() && it->startsWith(potentialProgram)){ + + // Update common prefix + auto mismatchindexes = std::mismatch(it->begin()+potentialProgram.size()-1, it->end(), + commonPrefix.begin()+potentialProgram.size()-1); + commonPrefix.resize(std::distance(it->begin(), mismatchindexes.first)); + + QString commandlineString = QString("%1 %2").arg(*it, argsString); + + shared_ptr runAction = make_shared(); + runAction->setText("Run"); + runAction->setAction([commandlineString](){ + QProcess::startDetached(commandlineString); + }); + + shared_ptr shellAction = make_shared(); + shellAction->setText("Run in a shell"); + shellAction->setAction([this, commandlineString](){ + QProcess::startDetached(d->shell, {"-ic", commandlineString}); + }); + + shared_ptr termAction = make_shared(); + termAction->setText("Run in a terminal"); + termAction->setAction([this, commandlineString](){ + QStringList tokens = Core::ShUtil::split(terminalCommand); + tokens << d->shell << "-ic" << QString("%1; exec %2").arg(commandlineString, d->shell); + QProcess::startDetached(tokens.takeFirst(), tokens); + }); + + shared_ptr item = make_shared(*it); + item->setText(commandlineString); + item->setSubtext(QString("Run '%1'").arg(commandlineString)); + item->setIconPath(d->iconPath); + item->setActions({ move(runAction), move(shellAction), move(termAction) }); + + results.emplace_back(item, 0); + ++it; + } + + // Apply completion string to items + QString completion = QString(">%1").arg(commonPrefix); + for (pair,short> &match: results) + std::static_pointer_cast(match.first)->setCompletionString(completion); + + // Build general item + QString commandline = query->string(); + + shared_ptr runAction = make_shared(); + runAction->setText("Run"); + runAction->setAction([commandline](){ + QProcess::startDetached(commandline); + }); + + shared_ptr shellAction = make_shared(); + shellAction->setText("Run in a shell"); + shellAction->setAction([this, commandline](){ + QProcess::startDetached(d->shell, {"-ic", commandline}); + }); + + shared_ptr termAction = make_shared(); + termAction->setText("Run in a terminal"); + termAction->setAction([this, commandline](){ + QStringList tokens = Core::ShUtil::split(terminalCommand); + tokens << d->shell << "-ic" << QString("%1; exec %2").arg(commandline, d->shell); + QProcess::startDetached(tokens.takeFirst(), tokens); + }); + + shared_ptr item = make_shared(); + item->setText(QString("I'm Feeling Lucky").arg(commandline)); + item->setSubtext(QString("Try running '%1'").arg(commandline)); + item->setCompletionString(query->rawString()); + item->setIconPath(d->iconPath); + item->setActions({ move(runAction), move(shellAction), move(termAction) }); + + results.emplace_back(item, 0); + + // Add results to query + query->addMatches(results.begin(), results.end()); +} + + +/** ***************************************************************************/ +void Terminal::Extension::rebuildIndex() { + + if ( d->futureWatcher.isRunning() ) + return; + + auto index = [](){ + qDebug() << "Building $PATH index."; + set index; + QStringList paths = QString(::getenv("PATH")).split(':', QString::SkipEmptyParts); + for (const QString &path : paths) { + QDirIterator dirIt(path); + while (dirIt.hasNext()) { + QFileInfo file(dirIt.next()); + if ( file.isExecutable() ) + index.insert(file.fileName()); + } + } + qDebug() << "Building $PATH index done."; + return index; + }; + + connect(&d->futureWatcher, &QFutureWatcher>::finished, this, [this](){ + d->index = d->futureWatcher.future().result(); + disconnect(&d->futureWatcher, nullptr, nullptr, nullptr); + }); + + d->futureWatcher.setFuture(QtConcurrent::run(index)); +} diff -Nru albert-0.12.0/plugins/terminal/src/extension.h albert-0.13.1+plugins1/plugins/terminal/src/extension.h --- albert-0.12.0/plugins/terminal/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,51 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace Terminal { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Terminal"; } + QWidget *widget(QWidget *parent = nullptr) override; + QStringList triggers() const override { return {">"}; } + void handleQuery(Core::Query * query) const override; + +private: + + void rebuildIndex(); + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/terminal/terminal.qrc albert-0.13.1+plugins1/plugins/terminal/terminal.qrc --- albert-0.12.0/plugins/terminal/terminal.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/terminal/terminal.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/terminal.svg + + diff -Nru albert-0.12.0/plugins/virtualbox/CMakeLists.txt albert-0.13.1+plugins1/plugins/virtualbox/CMakeLists.txt --- albert-0.12.0/plugins/virtualbox/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(virtualbox) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Xml) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +add_definitions(-DRT_OS_LINUX) +add_definitions(-DVBOX_WITH_XPCOM_NAMESPACE_CLEANUP) +set(PATH_XPCOM /usr/lib/virtualbox/sdk/bindings/xpcom) +set(PATH_BIN /usr/lib/virtualbox) + +if(NOT EXISTS ${PATH_XPCOM}/include/VirtualBox_XPCOM.h) + message("${PATH_XPCOM}/include/VirtualBox_XPCOM.h not found. Build will fail!") +endif() + +set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "${PATH_BIN}") + +target_include_directories(${PROJECT_NAME} + PRIVATE + src/ + ${PATH_XPCOM}/include + ${PATH_XPCOM}/include/nsprpub + ${PATH_XPCOM}/include/string + ${PATH_XPCOM}/include/xpcom + ${PATH_XPCOM}/include/ipcd +) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Xml_LIBRARIES} + albertcore + ${PATH_BIN}/VBoxXPCOM.so + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/virtualbox/metadata.json albert-0.13.1+plugins1/plugins/virtualbox/metadata.json --- albert-0.12.0/plugins/virtualbox/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.virtualbox", + "name" : "VirtualBox", + "version" : "3.0", + "platform" : "Linux", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : ["virtualbox"], + "enabledbydefault": false +} diff -Nru albert-0.12.0/plugins/virtualbox/resources/virtualbox.svg albert-0.13.1+plugins1/plugins/virtualbox/resources/virtualbox.svg --- albert-0.12.0/plugins/virtualbox/resources/virtualbox.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/resources/virtualbox.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/virtualbox/src/configwidget.cpp albert-0.13.1+plugins1/plugins/virtualbox/src/configwidget.cpp --- albert-0.12.0/plugins/virtualbox/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,29 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "configwidget.h" + +/** ***************************************************************************/ +VirtualBox::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { + ui.setupUi(this); +} + + + +/** ***************************************************************************/ +VirtualBox::ConfigWidget::~ConfigWidget() { + +} diff -Nru albert-0.12.0/plugins/virtualbox/src/configwidget.h albert-0.13.1+plugins1/plugins/virtualbox/src/configwidget.h --- albert-0.12.0/plugins/virtualbox/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace VirtualBox { +class ConfigWidget final : public QWidget +{ + Q_OBJECT +public: + explicit ConfigWidget(QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; +}; +} diff -Nru albert-0.12.0/plugins/virtualbox/src/configwidget.ui albert-0.13.1+plugins1/plugins/virtualbox/src/configwidget.ui --- albert-0.12.0/plugins/virtualbox/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,35 @@ + + + VirtualBox::ConfigWidget + + + + 0 + 0 + 480 + 320 + + + + + + + Found VMs: + + + + + + + + + + Refresh + + + + + + + + diff -Nru albert-0.12.0/plugins/virtualbox/src/extension.cpp albert-0.13.1+plugins1/plugins/virtualbox/src/extension.cpp --- albert-0.12.0/plugins/virtualbox/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,244 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// Contributed to by 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extension.h" +#include "vm.h" +#include "core/query.h" +#include "util/standarditem.h" +#include "util/standardaction.h" +#include "xdg/iconlookup.h" +using Core::Action; +using Core::StandardAction; +using Core::StandardItem; + +#include +#include +#include "VirtualBox_XPCOM.h" + +#include "configwidget.h" + + +class VirtualBox::Private +{ +public: + + QPointer widget; + QList vms; + QFileSystemWatcher vboxWatcher; + + nsCOMPtr manager; + nsCOMPtr virtualBox; + + + //void rescanVBoxConfig(QString path); + void pollMachines(); + void reload(); + +}; + + + +/** *************************************************************************** +void VirtualBox::Private::rescanVBoxConfig(QString path) { + + qInfo() << "Start indexing VirtualBox images."; + + QFile vboxConfigFile(path); + if (!vboxConfigFile.exists()) + return; + if (!vboxConfigFile.open(QFile::ReadOnly)) { + qCritical() << "Could not open VirtualBox config file for read operation!"; + return; + } + + QDomDocument vboxConfig; + QString errMsg = ""; + int errLine = 0, errCol = 0; + if (!vboxConfig.setContent(&vboxConfigFile, &errMsg, &errLine, &errCol)) { + qWarning() << qPrintable(QString("Parsing VBox config failed because %s in line %d col %d").arg(errMsg).arg(errLine, errCol)); + vboxConfigFile.close(); + return; + } + vboxConfigFile.close(); + + QDomElement root = vboxConfig.documentElement(); + if (root.isNull()) { + qCritical() << "In VBox config file: Root element is null."; + return; + } + + QDomElement global = root.firstChildElement("Global"); + if (global.isNull()) { + qCritical() << "In VBox config file: Global element is null."; + return; + } + + QDomElement machines = global.firstChildElement("MachineRegistry"); // List of MachineEntry + if (machines.isNull()) { + qCritical() << "In VBox config file: Machine registry element is null."; + return; + } + + // With this we iterate over the machine entries + QDomElement machine = machines.firstChildElement(); + + // And we count how many entries we find for information reasons + int found = 0; + + qDeleteAll(vms); + vms.clear(); + + while (!machine.isNull()) { + + vms.append(new VM(machine.attribute("src"))); + + machine = machine.nextSiblingElement(); + found++; + } + + qInfo() << qPrintable(QString("Indexed %2 VirtualBox images.").arg(found)); +}*/ + + + +/** ***************************************************************************/ +void VirtualBox::Private::pollMachines() { + + qDeleteAll(vms); + vms.clear(); + + nsresult rc; + IMachine **machines = NULL; + PRUint32 machineCnt = 0; + + rc = virtualBox->GetMachines(&machineCnt, &machines); + if (NS_SUCCEEDED(rc)) { + for (PRUint32 i = 0; i < machineCnt; ++ i) { + IMachine *machine = machines[i]; + if (machine) { + vms.append(new VM(machine)); + } + } + } + +} + + + +/** ***************************************************************************/ +void VirtualBox::Private::reload() { + pollMachines(); + widget->ui.listWidget->clear(); + + for (VM* vm : vms) { + widget->ui.listWidget->addItem(vm->name()); + } +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +VirtualBox::Extension::Extension() + : Core::Extension("org.albert.extension.virtualbox"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + + nsresult rc; + + rc = NS_GetComponentManager(getter_AddRefs(d->manager)); + if (NS_FAILED(rc)) + throw("Error: could not get component manager."); + + rc = d->manager->CreateInstanceByContractID(NS_VIRTUALBOX_CONTRACTID, nsnull, + NS_GET_IID(IVirtualBox), + getter_AddRefs(d->virtualBox)); + if (NS_FAILED(rc)) + throw("Error, could not instantiate VirtualBox object."); + + VMItem::iconPath_ = XDG::IconLookup::iconPath("virtualbox"); + if ( VMItem::iconPath_.isNull() ) + VMItem::iconPath_ = ":vbox"; + + /*QString vboxConfigPath = QStandardPaths::locate(QStandardPaths::ConfigLocation, "VirtualBox/VirtualBox.xml"); + if (vboxConfigPath.isEmpty()) + throw "VirtualBox was not detected!"; + + d->rescanVBoxConfig(vboxConfigPath); + d->vboxWatcher.addPath(vboxConfigPath); + connect(&d->vboxWatcher, &QFileSystemWatcher::fileChanged, + std::bind(&Private::rescanVBoxConfig, d.get(), std::placeholders::_1));*/ +} + + + +/** ***************************************************************************/ +VirtualBox::Extension::~Extension() { + d->virtualBox = nsnull; + NS_ShutdownXPCOM(nsnull); +} + + + +/** ***************************************************************************/ +QWidget *VirtualBox::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) { + d->widget = new ConfigWidget(parent); + + d->reload(); + + connect(d->widget->ui.pushButton, &QPushButton::clicked, [=]() {d->reload();}); + } + return d->widget; +} + + + +/** ***************************************************************************/ +void VirtualBox::Extension::setupSession() { + d->pollMachines(); +} + + + +/** ***************************************************************************/ +void VirtualBox::Extension::handleQuery(Core::Query * query) const { + + if ( query->string().isEmpty() ) + return; + + for (VM* vm : d->vms) { + if (vm->startsWith(query->string())) + query->addMatch(std::shared_ptr(vm->produceItem())); // Implicit move + } +} diff -Nru albert-0.12.0/plugins/virtualbox/src/extension.h albert-0.13.1+plugins1/plugins/virtualbox/src/extension.h --- albert-0.12.0/plugins/virtualbox/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,50 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2015 Manuel Schneider +// Contributed to by 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/extension.h" +#include "core/queryhandler.h" + +namespace VirtualBox { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return tr("VirtualBox"); } + QWidget *widget(QWidget *parent = nullptr) override; + void setupSession() override; + void handleQuery(Core::Query *) const override; + +private: + + std::unique_ptr d; + +}; +} diff -Nru albert-0.12.0/plugins/virtualbox/src/vm.cpp albert-0.13.1+plugins1/plugins/virtualbox/src/vm.cpp --- albert-0.12.0/plugins/virtualbox/src/vm.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/vm.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,174 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "vm.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "util/standardaction.h" +using Core::StandardAction; + + +/** ***************************************************************************/ +VirtualBox::VM::VM(IMachine *machine) : machine_(machine) { + PRBool isAccessible = PR_FALSE; + machine->GetAccessible(&isAccessible); + + if (isAccessible) { + nsXPIDLString machineName; + machine->GetName(getter_Copies(machineName)); + char *machineNameAscii = ToNewCString(machineName); + name_ = machineNameAscii; + free(machineNameAscii); + } else { + name_ = ""; + } + + nsXPIDLString iid; + machine->GetId(getter_Copies(iid)); + const char *uuidString = ToNewCString(iid); + uuid_ = uuidString; + free((void*)uuidString); +} + + + +/** ***************************************************************************/ +VirtualBox::VM::~VM() { + /* don't forget to release the objects in the array... */ + machine_->Release(); +} + + + +/* + + A state diagram of the VBox VMStates + + +---------[powerDown()] <- Stuck <--[failure]-+ + V | + +-> PoweredOff --+-->[powerUp()]--> Starting --+ | +-----[resume()]-----+ + | | | | V | + | Aborted -----+ +--> Running --[pause()]--> Paused + | | ^ | ^ | + | Saved -----------[powerUp()]--> Restoring -+ | | | | + | ^ | | | | + | | +-----------------------------------------+-|-------------------+ + + | | | | | + | | +- OnlineSnapshotting <--[takeSnapshot()]<--+---------------------+ + | | | | + | +-------- Saving <--------[saveState()]<----------+---------------------+ + | | | + +-------------- Stopping -------[powerDown()]<----------+---------------------+ + + */ +/** ***************************************************************************/ +VirtualBox::VMItem *VirtualBox::VM::produceItem() const { + + QString pauseCmd = "VBoxManage controlvm %1 pause"; + QString startCmd = "VBoxManage startvm %1"; + QString saveCmd = "VBoxManage controlvm %1 savestate"; + QString stopCmd = "VBoxManage controlvm %1 poweroff"; + QString resetCmd = "VBoxManage controlvm %1 reset"; + QString resumeCmd = "VBoxManage controlvm %1 resume"; + pauseCmd = pauseCmd.arg(uuid_); + startCmd = startCmd.arg(uuid_); + saveCmd = saveCmd.arg(uuid_); + stopCmd = stopCmd.arg(uuid_); + resetCmd = resetCmd.arg(uuid_); + resumeCmd = resumeCmd.arg(uuid_); + ActionSPtrVec actions; + int mainAction = 0; + + PRUint32 state; + machine_->GetState(&state); + switch (state) { + case MachineState::Starting: + case MachineState::Restoring: + case MachineState::Saving: + case MachineState::Stopping: + mainAction = VMItem::VM_STATE_CHANGING; + actions.push_back(std::shared_ptr( new StandardAction("Controls are disabled", [](){}) )); + break; + case MachineState::PoweredOff: + case MachineState::Aborted: + mainAction = VMItem::VM_START; + actions.push_back(std::shared_ptr( new StandardAction("Start", [startCmd](){ QProcess::startDetached(startCmd); }) )); + break; + case MachineState::Saved: + mainAction = VMItem::VM_START; + actions.push_back(std::shared_ptr( new StandardAction("Start", [startCmd](){ QProcess::startDetached(startCmd); }) )); + break; + case MachineState::Running: + mainAction = VMItem::VM_PAUSE; + actions.push_back(std::shared_ptr( new StandardAction("Pause", [pauseCmd](){ QProcess::startDetached(pauseCmd); }) )); + actions.push_back(std::shared_ptr( new StandardAction("Save State", [saveCmd](){ QProcess::startDetached(saveCmd); }) )); + actions.push_back(std::shared_ptr( new StandardAction("Stop", [stopCmd](){ QProcess::startDetached(stopCmd); }) )); + break; + case MachineState::Paused: + mainAction = VMItem::VM_RESUME; + actions.push_back(std::shared_ptr( new StandardAction("Resume", [resumeCmd](){ QProcess::startDetached(resumeCmd); }) )); + actions.push_back(std::shared_ptr( new StandardAction("Save State", [saveCmd](){ QProcess::startDetached(saveCmd); }) )); + actions.push_back(std::shared_ptr( new StandardAction("Reset", [resetCmd](){ QProcess::startDetached(resetCmd); }) )); + break; + default: + mainAction = VMItem::VM_DIFFERENT; + actions.push_back(std::shared_ptr( new StandardAction("Controls are disabled", [](){}) )); + } + + return new VMItem(name_, uuid_, mainAction, actions, state_); +} + + + +/** ***************************************************************************/ +bool VirtualBox::VM::startsWith(QString other) const { + return name_.startsWith(other, Qt::CaseInsensitive); +} + + + +/** *************************************************************************** +void VirtualBox::VM::probeState() const { + QProcess *process = new QProcess; + process->setReadChannel(QProcess::StandardOutput); + process->start("VBoxManage", {"showvminfo", uuid_, "--machinereadable"}); + QObject::connect(process, static_cast(&QProcess::finished), + [this, process](int exitCode, QProcess::ExitStatus exitStatus){ + if (exitStatus == QProcess::NormalExit && exitCode == 0){ + while (process->canReadLine()) { + QString line = QString::fromLocal8Bit(process->readLine()); + if (line.startsWith("VMState=")) { + QRegularExpression regex("VMState=\"(.*)\""); + QRegularExpressionMatch match = regex.match(line); + state_ = match.captured(1).toLower(); + break; + } + } + } + process->deleteLater(); + }); + QObject::connect(process, static_cast(&QProcess::error), [process](QProcess::ProcessError){ + process->deleteLater(); + }); +}*/ + diff -Nru albert-0.12.0/plugins/virtualbox/src/vm.h albert-0.13.1+plugins1/plugins/virtualbox/src/vm.h --- albert-0.12.0/plugins/virtualbox/src/vm.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/vm.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,43 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include +#include "vmitem.h" +#include "VirtualBox_XPCOM.h" + +namespace VirtualBox { + +class VM +{ +public: + VM(IMachine *machine); + virtual ~VM(); + VMItem* produceItem() const; + bool startsWith(QString other) const; + const QString &uuid() const { return uuid_; } + const QString &name() const { return name_; } + +private: + IMachine* machine_; + QString name_; + QString uuid_; + mutable QString state_; +}; + +} // namespace VirtualBox + diff -Nru albert-0.12.0/plugins/virtualbox/src/vmitem.cpp albert-0.13.1+plugins1/plugins/virtualbox/src/vmitem.cpp --- albert-0.12.0/plugins/virtualbox/src/vmitem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/vmitem.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,80 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "vmitem.h" + +#include + +/** ***************************************************************************/ +QString VirtualBox::VMItem::iconPath_; +const int VirtualBox::VMItem::VM_START = 1; +const int VirtualBox::VMItem::VM_PAUSE = 2; +const int VirtualBox::VMItem::VM_RESUME = 3; +const int VirtualBox::VMItem::VM_STATE_CHANGING = -1; +const int VirtualBox::VMItem::VM_DIFFERENT = -2; + +VirtualBox::VMItem::VMItem(const QString &name, const QString &uuid, int &mainAction, const ActionSPtrVec actions, const QString &state) : name_(name), uuid_(uuid), actions_(actions), mainAction_(mainAction) { + idstring_ = QString("extension.virtualbox.item:%1.%2").arg(uuid).arg(state); +} + +QString VirtualBox::VMItem::subtext() const { + QString toreturn; + switch (mainAction_) { + case VM_START: + toreturn = "Start %1"; + break; + case VM_PAUSE: + toreturn = "Pause %1"; + break; + case VM_RESUME: + toreturn = "Resume %1"; + break; + case VM_STATE_CHANGING: + toreturn = "The VM %1 is currently in action. Controls are disabled!"; + break; + case VM_DIFFERENT: + toreturn = "The VM %1 is currently in in unhandled state. Controls are disabled!"; + break; + default: + toreturn = "Start %1"; + break; + } + return toreturn.arg(name_); +} + +/* +void VirtualBox::VMItem::activate(Action::ExecutionFlags *) { + QString executionCommand; + switch (mainAction_) { + case VM_START: + executionCommand = "vboxmanage startvm %1"; + break; + case VM_PAUSE: + executionCommand = "vboxmanage controlvm %1 pause"; + break; + case VM_RESUME: + executionCommand = "vboxmanage controlvm %1 resume"; + break; + case VM_STATE_CHANGING: + break; + default: + executionCommand = "vboxmanage startvm %1"; + break; + } + if (!executionCommand.isEmpty()) + QProcess::startDetached(executionCommand.arg(uuid_)); +} +*/ diff -Nru albert-0.12.0/plugins/virtualbox/src/vmitem.h albert-0.13.1+plugins1/plugins/virtualbox/src/vmitem.h --- albert-0.12.0/plugins/virtualbox/src/vmitem.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/src/vmitem.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,64 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2016-2017 Martin Buergmann +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include "core/item.h" +using std::vector; +using std::shared_ptr; +using Core::Action; +using Core::Item; + +namespace VirtualBox { + +typedef vector> ActionSPtrVec; + +class VMItem : public Item +{ +public: + VMItem(const QString &name, const QString &uuid, int &mainAction, const ActionSPtrVec actions, const QString &state); + + + /* + * Implementation of AlbertItem interface + */ + + QString id() const override { return idstring_; } + QString text() const override { return name_; } + QString subtext() const override; + QString iconPath() const override { return iconPath_; } + ActionSPtrVec actions() override { return actions_; } + + /* + * Item specific members + */ + + static QString iconPath_; + static const int VM_START; + static const int VM_PAUSE; + static const int VM_RESUME; + static const int VM_STATE_CHANGING; + static const int VM_DIFFERENT; + +private: + QString name_; + QString uuid_; + QString idstring_; + ActionSPtrVec actions_; + int mainAction_; +}; + +} // namespace VirtualBox diff -Nru albert-0.12.0/plugins/virtualbox/virtualbox.qrc albert-0.13.1+plugins1/plugins/virtualbox/virtualbox.qrc --- albert-0.12.0/plugins/virtualbox/virtualbox.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/virtualbox/virtualbox.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,5 @@ + + + resources/virtualbox.svg + + diff -Nru albert-0.12.0/plugins/websearch/CMakeLists.txt albert-0.13.1+plugins1/plugins/websearch/CMakeLists.txt --- albert-0.12.0/plugins/websearch/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(websearch) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets) + +add_library(${PROJECT_NAME} SHARED ${SRC} ${PROJECT_NAME}.qrc) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + albertcore + xdg +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/plugins/websearch/metadata.json albert-0.13.1+plugins1/plugins/websearch/metadata.json --- albert-0.12.0/plugins/websearch/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,10 @@ +{ + "id" : "org.albert.extension.websearch", + "name" : "WebSearch", + "version" : "1.0", + "platform" : "All", + "group" : "Extensions", + "author" : "Manuel Schneider", + "dependencies" : [], + "enabledbydefault": true +} diff -Nru albert-0.12.0/plugins/websearch/resources/amazon.svg albert-0.13.1+plugins1/plugins/websearch/resources/amazon.svg --- albert-0.12.0/plugins/websearch/resources/amazon.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/amazon.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/default.svg albert-0.13.1+plugins1/plugins/websearch/resources/default.svg --- albert-0.12.0/plugins/websearch/resources/default.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/default.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/duckduckgo.svg albert-0.13.1+plugins1/plugins/websearch/resources/duckduckgo.svg --- albert-0.12.0/plugins/websearch/resources/duckduckgo.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/duckduckgo.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,14 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/ebay.svg albert-0.13.1+plugins1/plugins/websearch/resources/ebay.svg --- albert-0.12.0/plugins/websearch/resources/ebay.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/ebay.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/google.svg albert-0.13.1+plugins1/plugins/websearch/resources/google.svg --- albert-0.12.0/plugins/websearch/resources/google.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/google.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/octocat.svg albert-0.13.1+plugins1/plugins/websearch/resources/octocat.svg --- albert-0.12.0/plugins/websearch/resources/octocat.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/octocat.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/wikipedia.svg albert-0.13.1+plugins1/plugins/websearch/resources/wikipedia.svg --- albert-0.12.0/plugins/websearch/resources/wikipedia.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/wikipedia.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,4 @@ + + + + \ No newline at end of file Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/websearch/resources/wolfram.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/websearch/resources/wolfram.png differ diff -Nru albert-0.12.0/plugins/websearch/resources/wolfram.svg albert-0.13.1+plugins1/plugins/websearch/resources/wolfram.svg --- albert-0.12.0/plugins/websearch/resources/wolfram.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/wolfram.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/resources/youtube.svg albert-0.13.1+plugins1/plugins/websearch/resources/youtube.svg --- albert-0.12.0/plugins/websearch/resources/youtube.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/resources/youtube.svg 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/plugins/websearch/src/configwidget.cpp albert-0.13.1+plugins1/plugins/websearch/src/configwidget.cpp --- albert-0.12.0/plugins/websearch/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,135 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include "configwidget.h" +#include "enginesmodel.h" +#include "extension.h" +#include "searchengineeditor.h" + +/** ***************************************************************************/ +Websearch::ConfigWidget::ConfigWidget(Extension *extension, QWidget *parent) + : QWidget(parent), extension_(extension) { + + ui.setupUi(this); + + enginesModel_ = new EnginesModel(extension, ui.tableView_searches); + ui.tableView_searches->setModel(enginesModel_); + + ui.tableView_searches->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui.tableView_searches->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + + // Initialize connections + connect(ui.pushButton_new, &QPushButton::clicked, + this, &ConfigWidget::onButton_new); + + connect(ui.pushButton_remove, &QPushButton::clicked, + this, &ConfigWidget::onButton_remove); + + connect(ui.pushButton_restoreDefaults, &QPushButton::clicked, + this, &ConfigWidget::onButton_restoreDefaults); + + connect(ui.tableView_searches, &QTableView::activated, + this, &ConfigWidget::onActivated); +} + + + +/** ***************************************************************************/ +Websearch::ConfigWidget::~ConfigWidget() { +} + + + +/** ***************************************************************************/ +void Websearch::ConfigWidget::onActivated(QModelIndex index) { + int row = index.row(); + SearchEngineEditor searchEngineEditor(extension_->engines()[static_cast(row)], this); + + if (searchEngineEditor.exec()){ + // Set the new engine + const SearchEngine & searchEngine = searchEngineEditor.searchEngine(); + enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.name, Qt::DisplayRole); + enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.iconPath, Qt::DecorationRole); + enginesModel_->setData(enginesModel_->index(row, 1), searchEngine.trigger, Qt::DisplayRole); + enginesModel_->setData(enginesModel_->index(row, 2), searchEngine.url, Qt::DisplayRole); + } + ui.tableView_searches->reset(); +} + + + +/** ***************************************************************************/ +void Websearch::ConfigWidget::onButton_new() { + + // Open search engine editor + SearchEngine searchEngine; + searchEngine.iconPath = ":default"; + SearchEngineEditor searchEngineEditor(searchEngine, this); + + if (searchEngineEditor.exec()){ + + // Insert new row in model + int row = (ui.tableView_searches->currentIndex().isValid()) + ? ui.tableView_searches->currentIndex().row() + : ui.tableView_searches->model()->rowCount(); + enginesModel_->insertRow(row); + + // Set the new engine + searchEngine = searchEngineEditor.searchEngine(); + enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.name, Qt::DisplayRole); + enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.iconPath, Qt::DecorationRole); + enginesModel_->setData(enginesModel_->index(row, 1), searchEngine.trigger, Qt::DisplayRole); + enginesModel_->setData(enginesModel_->index(row, 2), searchEngine.url, Qt::DisplayRole); + + // Set current + QModelIndex index = ui.tableView_searches->model()->index(row, 0, QModelIndex()); + ui.tableView_searches->setCurrentIndex(index); + } +} + + + +/** ***************************************************************************/ +void Websearch::ConfigWidget::onButton_remove() { + // Ask if sure + int row = ui.tableView_searches->currentIndex().row(); + QString engineName = ui.tableView_searches->model() + ->data(ui.tableView_searches->model()->index(row, 1)).toString(); + QMessageBox::StandardButton reply = + QMessageBox::question(this, "Sure?", + QString("Do you really want to remove '%1' from the search engines?") + .arg(engineName), + QMessageBox::Yes|QMessageBox::No); + // Remove if sure + if (reply == QMessageBox::Yes) + ui.tableView_searches->model()->removeRow(ui.tableView_searches->currentIndex().row()); +} + + + +/** ***************************************************************************/ +void Websearch::ConfigWidget::onButton_restoreDefaults() { + QMessageBox::StandardButton reply = + QMessageBox::question(this, "Sure?", + QString("Do you really want to restore the default search engines?"), + QMessageBox::Yes|QMessageBox::No); + // Remove if sure + if (reply == QMessageBox::Yes) + enginesModel_->restoreDefaults(); +} diff -Nru albert-0.12.0/plugins/websearch/src/configwidget.h albert-0.13.1+plugins1/plugins/websearch/src/configwidget.h --- albert-0.12.0/plugins/websearch/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,47 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_configwidget.h" + +namespace Websearch { + +class Extension; +class EnginesModel; + +class ConfigWidget final : public QWidget +{ + Q_OBJECT + +public: + + explicit ConfigWidget(Extension *extension, QWidget *parent = 0); + ~ConfigWidget(); + Ui::ConfigWidget ui; + +private: + + void onActivated(QModelIndex index); + void onButton_new(); + void onButton_remove(); + void onButton_restoreDefaults(); + + Extension *extension_; + EnginesModel *enginesModel_; +}; + +} diff -Nru albert-0.12.0/plugins/websearch/src/configwidget.ui albert-0.13.1+plugins1/plugins/websearch/src/configwidget.ui --- albert-0.12.0/plugins/websearch/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,90 @@ + + + Websearch::ConfigWidget + + + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::InternalMove + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + false + + + true + + + false + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + .. + + + + + + + + .. + + + + + + + Restore + + + + + + + + + + diff -Nru albert-0.12.0/plugins/websearch/src/enginesmodel.cpp albert-0.13.1+plugins1/plugins/websearch/src/enginesmodel.cpp --- albert-0.12.0/plugins/websearch/src/enginesmodel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/enginesmodel.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,326 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +#include +#include +#include +#include +#include +#include +#include +#include "enginesmodel.h" +#include "extension.h" +#include "searchengine.h" + +namespace { + +enum class Section{ Name, Trigger, URL} ; +const int sectionCount = 3; + +std::map iconCache; + +} + + +/** ***************************************************************************/ +Websearch::EnginesModel::EnginesModel(Extension *extension, QObject *parent) + : QAbstractTableModel(parent), extension_(extension) { +} + + +/** ***************************************************************************/ +int Websearch::EnginesModel::rowCount(const QModelIndex &) const { + return static_cast(extension_->engines().size()); +} + + + +/** ***************************************************************************/ +int Websearch::EnginesModel::columnCount(const QModelIndex &) const { + return sectionCount; +} + + + +/** ***************************************************************************/ +QVariant Websearch::EnginesModel::headerData(int section, Qt::Orientation orientation, int role) const { + // No sanity check necessary since + if ( section < 0 || sectionCount <= section ) + return QVariant(); + + + if (orientation == Qt::Horizontal){ + switch (static_cast
(section)) { + case Section::Name:{ + switch (role) { + case Qt::DisplayRole: return "Name"; + case Qt::ToolTipRole: return "The name of the searchengine."; + default: return QVariant(); + } + + } + case Section::Trigger:{ + switch (role) { + case Qt::DisplayRole: return "Trigger"; + case Qt::ToolTipRole: return "The term that triggers this searchengine."; + default: return QVariant(); + } + + } + case Section::URL:{ + switch (role) { + case Qt::DisplayRole: return "URL"; + case Qt::ToolTipRole: return "The URL of this searchengine. %s will be replaced by your searchterm."; + default: return QVariant(); + } + + } + } + } + return QVariant(); +} + + + +/** ***************************************************************************/ +QVariant Websearch::EnginesModel::data(const QModelIndex &index, int role) const { + if ( !index.isValid() || + index.row() >= static_cast(extension_->engines().size()) || + index.column() >= sectionCount ) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: { + switch (static_cast
(index.column())) { + case Section::Name: + return extension_->engines()[static_cast(index.row())].name; + case Section::Trigger: + return extension_->engines()[static_cast(index.row())].trigger; + case Section::URL: + return extension_->engines()[static_cast(index.row())].url; + } + } + case Qt::DecorationRole: { + if (static_cast
(index.column()) == Section::Name) { + // Resizing request thounsands of repaints. Creating an icon for + // ever paint event is to expensive. Therefor maintain an icon cache + const QString &iconPath = extension_->engines()[static_cast(index.row())].iconPath; + std::map::iterator it = iconCache.find(iconPath); + if ( it != iconCache.end() ) + return it->second; + return iconCache.insert(std::make_pair(iconPath, QIcon(iconPath))).second; + } + return QVariant(); + } + case Qt::ToolTipRole: return "Double click to edit"; + default: return QVariant(); + } +} + + + +/** ***************************************************************************/ +bool Websearch::EnginesModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if ( !index.isValid() || + index.row() >= static_cast(extension_->engines().size()) || + index.column() >= sectionCount) + return false; + + switch (role) { + case Qt::DisplayRole: { + if ( !value.canConvert(QMetaType::QString) ) + return false; + QString s = value.toString(); + switch (static_cast
(index.column())) { + case Section::Name: { + std::vector newEngines = extension_->engines(); + newEngines[static_cast(index.row())].name = s; + extension_->setEngines(newEngines); + dataChanged(index, index, QVector({Qt::DisplayRole})); + return true; + } + case Section::Trigger: { + std::vector newEngines = extension_->engines(); + newEngines[static_cast(index.row())].trigger = s; + extension_->setEngines(newEngines); + dataChanged(index, index, QVector({Qt::DisplayRole})); + return true; + } + case Section::URL: { + std::vector newEngines = extension_->engines(); + newEngines[static_cast(index.row())].url = s; + extension_->setEngines(newEngines); + dataChanged(index, index, QVector({Qt::DisplayRole})); + return true; + } + } + return false; + } + case Qt::DecorationRole: { + QFileInfo fileInfo(value.toString()); + + if ( !fileInfo.exists() ) + return false; + + // Remove icon from cache + iconCache.erase(extension_->engines()[static_cast(index.row())].iconPath); + + // Create extension dir if necessary + QDir configDir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)); + if ( !configDir.exists(extension_->Core::Plugin::id()) ) { + if ( !configDir.mkdir(extension_->Core::Plugin::id()) ) { + qWarning() << "Could not create extension data dir."; + return false; + } + } + + configDir.cd(extension_->Core::Plugin::id()); + + // Build the new random path + QString newFilePath = configDir.filePath(QString("%1.%2") + .arg(QUuid::createUuid().toString()) + .arg(fileInfo.suffix())); + + // Copy the file into data dir + if ( !QFile::copy(fileInfo.filePath(), newFilePath) ) { + qWarning() << "Could not copy icon to cache."; + return false; + } + + // Remove old icon and set the copied file as icon + std::vector newEngines = extension_->engines(); + QFile::remove(newEngines[static_cast(index.row())].iconPath); + newEngines[static_cast(index.row())].iconPath = newFilePath; + extension_->setEngines(newEngines); + + // Update the icon in the first section of the row + QModelIndex firstSectionIndex = index.model()->index(index.row(), 0); + dataChanged(firstSectionIndex, firstSectionIndex, QVector({Qt::DecorationRole})); + + return true; + } + default: + return false; + } +} + + + +/** ***************************************************************************/ +Qt::ItemFlags Websearch::EnginesModel::flags(const QModelIndex &index) const { + if (index.isValid()) + return QAbstractTableModel::flags(index) | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; + else + return QAbstractTableModel::flags(index) | Qt::ItemIsDropEnabled; +} + + + +/** ***************************************************************************/ +bool Websearch::EnginesModel::insertRows(int position, int rows, const QModelIndex &) { + if ( position < 0 || rows < 1 || + static_cast(extension_->engines().size()) < position) + return false; + + beginInsertRows(QModelIndex(), position, position + rows - 1); + std::vector newEngines = extension_->engines(); + for ( int row = position; row < position + rows; ++row ) + newEngines.insert(newEngines.begin() + row, + SearchEngine({"", "", ":default", + ""})); + extension_->setEngines(newEngines); + endInsertRows(); + return true; +} + + + +/** ***************************************************************************/ +bool Websearch::EnginesModel::removeRows(int position, int rows, const QModelIndex &) { + if ( position < 0 || rows < 1 || + static_cast(extension_->engines().size()) < position + rows) + return false; + + beginRemoveRows(QModelIndex(), position, position + rows - 1); + std::vector newEngines = extension_->engines(); + newEngines.erase(newEngines.begin() + position, + newEngines.begin() + position + rows); + extension_->setEngines(newEngines); + endRemoveRows(); + return true; +} + + + +/** ***************************************************************************/ +bool Websearch::EnginesModel::moveRows(const QModelIndex &srcParent, int srcRow, int cnt, + const QModelIndex &dstParent, int dstRow) { + if ( srcRow < 0 || cnt < 1 || dstRow < 0 || + static_cast(extension_->engines().size()) < srcRow + cnt - 1 || + static_cast(extension_->engines().size()) < dstRow || + ( srcRow <= dstRow && dstRow < srcRow + cnt) ) // If its inside the source do nothing + return false; + + std::vector newEngines = extension_->engines(); + beginMoveRows(srcParent, srcRow, srcRow + cnt - 1, dstParent, dstRow); + newEngines.insert(newEngines.begin() + dstRow, + extension_->engines().begin() + srcRow, + extension_->engines().begin() + srcRow + cnt); + if ( srcRow < dstRow ) + newEngines.erase(newEngines.begin() + srcRow, + newEngines.begin() + srcRow + cnt); + else + newEngines.erase(newEngines.begin() + srcRow + cnt, + newEngines.begin() + srcRow + cnt * 2); + extension_->setEngines(newEngines); + endMoveRows(); + return true; +} + + + +/** ***************************************************************************/ +void Websearch::EnginesModel::restoreDefaults() { + beginResetModel(); + extension_->restoreDefaultEngines(); + endResetModel(); +} + + + +/** ***************************************************************************/ +Qt::DropActions Websearch::EnginesModel::supportedDropActions() const { + return Qt::MoveAction; +} + + + +/** ***************************************************************************/ +bool Websearch::EnginesModel::dropMimeData(const QMimeData *data, + Qt::DropAction /*action*/, + int dstRow, + int /*column*/, + const QModelIndex &/*parent*/) { + QByteArray encoded = data->data("application/x-qabstractitemmodeldatalist"); + QDataStream stream(&encoded, QIODevice::ReadOnly); + int srcRow = 0; + if (!stream.atEnd()) + stream >> srcRow; + moveRows(QModelIndex(), srcRow, 1, QModelIndex(), dstRow); + return false; +} diff -Nru albert-0.12.0/plugins/websearch/src/enginesmodel.h albert-0.13.1+plugins1/plugins/websearch/src/enginesmodel.h --- albert-0.12.0/plugins/websearch/src/enginesmodel.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/enginesmodel.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace Websearch { + +class Extension; + +class EnginesModel final : public QAbstractTableModel +{ + Q_OBJECT + +public: + + EnginesModel(Extension *extension, QObject *parent = Q_NULLPTR); + + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex & parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex & index) const override; + bool insertRows (int position, int rows, const QModelIndex & parent = QModelIndex()) override; + bool removeRows (int position, int rows, const QModelIndex & parent = QModelIndex()) override; + bool moveRows(const QModelIndex &sourceRow, int srcRow, int cnt, const QModelIndex & dst, int destinationChild) override; + Qt::DropActions supportedDropActions() const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + + void restoreDefaults(); + +private: + + Extension *extension_; + +}; + +} diff -Nru albert-0.12.0/plugins/websearch/src/extension.cpp albert-0.13.1+plugins1/plugins/websearch/src/extension.cpp --- albert-0.12.0/plugins/websearch/src/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/extension.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,247 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "enginesmodel.h" +#include "extension.h" +#include "core/query.h" +#include "util/standardaction.h" +#include "util/standarditem.h" +#include "xdg/iconlookup.h" +using std::shared_ptr; +using std::vector; +using namespace Core; + + +namespace { + +std::vector defaultSearchEngines = { + {"Google", "gg ", ":google", "https://www.google.com/search?q=%s"}, + {"Youtube", "yt ", ":youtube", "https://www.youtube.com/results?search_query=%s"}, + {"Amazon", "ama ", ":amazon", "http://www.amazon.com/s/?field-keywords=%s"}, + {"Ebay", "eb ", ":ebay", "http://www.ebay.com/sch/i.html?_nkw=%s"}, + {"GitHub", "gh ", ":github", "https://github.com/search?utf8=✓&q=%s"}, + {"Wikipedia", "wiki ",":wikipedia", "https://en.wikipedia.org/w/index.php?search=%s"}, + {"Wolfram Alpha", "=", ":wolfram", "https://www.wolframalpha.com/input/?i=%s"}, + {"DuckDuckGo", "dd ", ":duckduckgo","https://duckduckgo.com/?q=%s"}, +}; + +shared_ptr buildWebsearchItem(const Websearch::SearchEngine &se, const QString &searchterm) { + + QString urlString = QString(se.url).replace("%s", QUrl::toPercentEncoding(searchterm)); + QUrl url = QUrl(urlString); + QString desc = QString("Start %1 search in your browser").arg(se.name); + + std::shared_ptr action = std::make_shared(); + action->setText(desc); + action->setAction([=](){ QDesktopServices::openUrl(url); }); + + std::shared_ptr item = std::make_shared(se.name); + item->setText(se.name); + item->setSubtext(desc); + item->setIconPath(se.iconPath); + item->setCompletionString(QString("%1%2").arg(se.trigger, searchterm)); + + item->setActions({action}); + + return item; +} + +static constexpr const char * ENGINES_FILE_NAME = "engines.json"; + +} + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +class Websearch::Private +{ +public: + QPointer widget; + std::vector searchEngines; +}; + + + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +Websearch::Extension::Extension() + : Core::Extension("org.albert.extension.websearch"), + Core::QueryHandler(Core::Plugin::id()), + d(new Private) { + + registerQueryHandler(this); + registerFallbackProvider(this); + + // Move config file from old location to new. (data -> config) TODO: REMOVE in 0.14 + QString oldpath = QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)) + .filePath(QString("%1.json").arg(Core::Plugin::id())); + QString enginesJson = configLocation().filePath(ENGINES_FILE_NAME); + if ( QFile::exists(oldpath) ) { + if ( QFile::exists(enginesJson) ) + QFile::remove(oldpath); + else + QFile::rename(oldpath, enginesJson); + } + + // Deserialize engines + QFile file(enginesJson); + if (file.open(QIODevice::ReadOnly)) { + QJsonArray array = QJsonDocument::fromJson(file.readAll()).array(); + SearchEngine searchEngine; + for ( const QJsonValue& value : array) { + QJsonObject object = value.toObject(); + searchEngine.name = object["name"].toString(); + searchEngine.trigger = object["trigger"].toString(); + searchEngine.iconPath = object["iconPath"].toString(); + searchEngine.url = object["url"].toString(); + d->searchEngines.push_back(searchEngine); + } + } else { + qWarning() << qPrintable(QString("Could not load from file: '%1'.").arg(enginesJson)); + setEngines(defaultSearchEngines); + } +} + + + +/** ***************************************************************************/ +Websearch::Extension::~Extension() { + +} + + + +/** ***************************************************************************/ +QWidget *Websearch::Extension::widget(QWidget *parent) { + if (d->widget.isNull()) + d->widget = new ConfigWidget(this, parent); + return d->widget; +} + + + +/** ***************************************************************************/ +QStringList Websearch::Extension::triggers() const { + QStringList triggers; + for ( const SearchEngine& se : d->searchEngines ) + triggers.push_back(se.trigger); + return triggers; +} + + + +/** ***************************************************************************/ +void Websearch::Extension::handleQuery(Core::Query * query) const { + + if ( query->isTriggered() ) { + for ( const SearchEngine &se : d->searchEngines ) + if ( query->trigger() == se.trigger ) + query->addMatch(buildWebsearchItem(se, query->string())); + } + else + { + QUrl url = QUrl::fromUserInput(query->string().trimmed()); + + // Check syntax and TLD validity + if ( url.isValid() && ( query->string().startsWith("http://") || // explict scheme + query->string().startsWith("https://") || // explict scheme + ( QRegularExpression(R"R(\S+\.\S+$)R").match(url.host()).hasMatch() && + !url.topLevelDomain().isNull()) ) ) { // valid TLD + shared_ptr action = std::make_shared(); + action->setText("Open URL"); + action->setAction([url](){ QDesktopServices::openUrl(url); }); + + std::shared_ptr item = std::make_shared("valid_url"); + item->setText(QString("Open url in browser")); + item->setSubtext(QString("Visit %1").arg(url.authority())); + item->setCompletionString(query->string()); + QString icon = XDG::IconLookup::iconPath({"www", "web-browser", "emblem-web"}); + item->setIconPath(icon.isEmpty() ? ":favicon" : icon); + item->setActions({action}); + + query->addMatch(std::move(item), UINT_MAX); + } + } +} + + + +/** ***************************************************************************/ +vector> Websearch::Extension::fallbacks(const QString & searchterm) { + vector> res; + for (const SearchEngine &se : d->searchEngines) + res.push_back(buildWebsearchItem(se, searchterm)); + return res; +} + + + +/** ***************************************************************************/ +const std::vector &Websearch::Extension::engines() const { + return d->searchEngines; +} + + + +/** ***************************************************************************/ +void Websearch::Extension::setEngines(const std::vector &engines) { + d->searchEngines = engines; + emit enginesChanged(d->searchEngines); + + // Serialize the engines + QFile file(configLocation().filePath(ENGINES_FILE_NAME)); + if (file.open(QIODevice::WriteOnly)) { + QJsonArray array; + for ( const SearchEngine& searchEngine : d->searchEngines ) { + QJsonObject object; + object["name"] = searchEngine.name; + object["url"] = searchEngine.url; + object["trigger"] = searchEngine.trigger; + object["iconPath"] = searchEngine.iconPath; + array.append(object); + } + file.write(QJsonDocument(array).toJson()); + } else + qCritical() << qPrintable(QString("Could not write to file: '%1'.").arg(file.fileName())); +} + + + +/** ***************************************************************************/ +void Websearch::Extension::restoreDefaultEngines() { + setEngines(defaultSearchEngines); +} diff -Nru albert-0.12.0/plugins/websearch/src/extension.h albert-0.13.1+plugins1/plugins/websearch/src/extension.h --- albert-0.12.0/plugins/websearch/src/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/extension.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,62 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "core/extension.h" +#include "core/queryhandler.h" +#include "core/fallbackprovider.h" +#include "searchengine.h" + +namespace Websearch { + +class Private; + +class Extension final : + public Core::Extension, + public Core::QueryHandler, + public Core::FallbackProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") + +public: + + Extension(); + ~Extension(); + + QString name() const override { return "Websearch"; } + QWidget *widget(QWidget *parent = nullptr) override; + QStringList triggers() const override; + void handleQuery(Core::Query * query) const override; + std::vector> fallbacks(const QString &) override; + + const std::vector& engines() const; + void setEngines(const std::vector &engines); + + void restoreDefaultEngines(); + +private: + + std::unique_ptr d; + +signals: + + void enginesChanged(const std::vector &engines); + +}; + +} diff -Nru albert-0.12.0/plugins/websearch/src/searchengineeditor.cpp albert-0.13.1+plugins1/plugins/websearch/src/searchengineeditor.cpp --- albert-0.12.0/plugins/websearch/src/searchengineeditor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/searchengineeditor.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,61 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "searchengineeditor.h" + + + +/** ***************************************************************************/ +Websearch::SearchEngineEditor::SearchEngineEditor(const SearchEngine &searchEngine, QWidget *parent) + : QDialog(parent), searchEngine_(searchEngine) { + + ui.setupUi(this); + setWindowModality(Qt::WindowModal); + + ui.lineEdit_name->setText(searchEngine.name); + ui.lineEdit_trigger->setText(searchEngine.trigger); + ui.lineEdit_url->setText(searchEngine.url); + ui.toolButton_icon->setIcon(QIcon(searchEngine.iconPath)); + + connect(ui.lineEdit_name, &QLineEdit::textChanged, + [this](const QString & text){ searchEngine_.name = text; }); + + connect(ui.lineEdit_trigger, &QLineEdit::textChanged, + [this](const QString & text){ searchEngine_.trigger = text; }); + + connect(ui.lineEdit_url, &QLineEdit::textChanged, + [this](const QString & text){ searchEngine_.url = text; }); + + connect(ui.toolButton_icon, &QToolButton::clicked, + [this](){ + + QString fileName = + QFileDialog::getOpenFileName( + this, + tr("Choose icon"), + QStandardPaths::writableLocation(QStandardPaths::HomeLocation), + tr("Images (*.png *.svg)")); + + if(fileName.isEmpty()) + return; + + searchEngine_.iconPath = fileName; + ui.toolButton_icon->setIcon(QIcon(fileName)); + }); + +} diff -Nru albert-0.12.0/plugins/websearch/src/searchengineeditor.h albert-0.13.1+plugins1/plugins/websearch/src/searchengineeditor.h --- albert-0.12.0/plugins/websearch/src/searchengineeditor.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/searchengineeditor.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,40 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "ui_searchengineeditor.h" +#include "searchengine.h" + +namespace Websearch { + +class SearchEngineEditor : public QDialog +{ + Q_OBJECT + +public: + + explicit SearchEngineEditor(const SearchEngine &searchEngine, QWidget *parent = 0); + const SearchEngine &searchEngine() { return searchEngine_; } + +private: + + SearchEngine searchEngine_; + Ui::SearchEngineEditor ui; + +}; + +} diff -Nru albert-0.12.0/plugins/websearch/src/searchengineeditor.ui albert-0.13.1+plugins1/plugins/websearch/src/searchengineeditor.ui --- albert-0.12.0/plugins/websearch/src/searchengineeditor.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/searchengineeditor.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,194 @@ + + + Websearch::SearchEngineEditor + + + + 0 + 0 + 420 + 320 + + + + Edit search engine + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Click to set an icon for the search engine. + + + + 96 + 96 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Name: + + + + + + + Name of the search engine. + + + Name of the search engine + + + + + + + Trigger: + + + + + + + The query prefix that triggers this engine. Note that it may make sense to append a space to the trigger prefix. + + + The query prefix that triggers this engine + + + + + + + URL: + + + + + + + The URL containing a %s that will be replaced by the query. + + + The URL containing a %s that will be replaced by the query + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + lineEdit_name + lineEdit_trigger + lineEdit_url + toolButton_icon + + + + + buttonBox + accepted() + Websearch::SearchEngineEditor + accept() + + + 275 + 310 + + + 157 + 274 + + + + + buttonBox + rejected() + Websearch::SearchEngineEditor + reject() + + + 343 + 310 + + + 286 + 274 + + + + + diff -Nru albert-0.12.0/plugins/websearch/src/searchengine.h albert-0.13.1+plugins1/plugins/websearch/src/searchengine.h --- albert-0.12.0/plugins/websearch/src/searchengine.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/src/searchengine.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,30 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace Websearch { + +class SearchEngine { +public: + QString name; + QString trigger; + QString iconPath; + QString url; +}; + +} diff -Nru albert-0.12.0/plugins/websearch/websearch.qrc albert-0.13.1+plugins1/plugins/websearch/websearch.qrc --- albert-0.12.0/plugins/websearch/websearch.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/websearch/websearch.qrc 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,13 @@ + + + resources/amazon.svg + resources/default.svg + resources/ebay.svg + resources/google.svg + resources/youtube.svg + resources/octocat.svg + resources/wikipedia.svg + resources/wolfram.png + resources/duckduckgo.svg + + diff -Nru albert-0.12.0/plugins/widgetboxmodel/CMakeLists.txt albert-0.13.1+plugins1/plugins/widgetboxmodel/CMakeLists.txt --- albert-0.12.0/plugins/widgetboxmodel/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/CMakeLists.txt 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(widgetboxmodel) + +file(GLOB_RECURSE SRC src/* metadata.json) + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Widgets Svg) + +add_library(${PROJECT_NAME} SHARED ${SRC}) + +target_include_directories(${PROJECT_NAME} PRIVATE src/) + +target_link_libraries(${PROJECT_NAME} + ${Qt5Widgets_LIBRARIES} + ${Qt5Svg_LIBRARIES} + albertcore +) + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) +install(DIRECTORY "share/" DESTINATION "share/albert/org.albert.frontend.boxmodel.widgets") diff -Nru albert-0.12.0/plugins/widgetboxmodel/metadata.json albert-0.13.1+plugins1/plugins/widgetboxmodel/metadata.json --- albert-0.12.0/plugins/widgetboxmodel/metadata.json 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/metadata.json 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,6 @@ +{ + "id" : "org.albert.frontend.boxmodel.widgets", + "name" : "Widget Box Model", + "version" : "1.0", + "author" : "Manuel Schneider" +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/ArcTemplate.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/ArcTemplate.qss --- albert-0.12.0/plugins/widgetboxmodel/share/ArcTemplate.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/ArcTemplate.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: ubervison + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #%foreground_color%; + background-color: #%background_color%; +} + +#frame { + padding: 4px; + border-radius: 3px; + background-color: #%background_color%; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + border: 1px solid #%border_color%; + font-size: 36px; + selection-color: #%background_color%; + selection-background-color: #%foreground_color%; + background-color: #%inputline_color%; +} + +#settingsButton { + color : #%button_color%; + background-color: #%background_color%; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + selection-color: #%foreground_color%; +} + +QListView::item:selected { + background: #%selection_background_color%; + border: 1px solid #%selection_border_color%; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #%scroll_color%; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/ArcTemplate.sh albert-0.13.1+plugins1/plugins/widgetboxmodel/share/ArcTemplate.sh --- albert-0.12.0/plugins/widgetboxmodel/share/ArcTemplate.sh 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/ArcTemplate.sh 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,21 @@ +#!/bin/bash + +TEMPLATE="ArcTemplate.qss" + +function makeStyle(){ + cat "$1" | sed \ + -e "s/%background_color%/$2/g" \ + -e "s/%foreground_color%/$3/g" \ + -e "s/%inputline_color%/$4/g" \ + -e "s/%border_color%/$5/g" \ + -e "s/%button_color%/$6/g" \ + -e "s/%scroll_color%/$7/g" \ + -e "s/%selection_background_color%/$8/g" \ + -e "s/%selection_border_color%/$9/g" > "${10}" +} + +#makeStyle bg fg input border button scrollbar sel_bg sel_border output +makeStyle "$TEMPLATE" "e7e8eb" "727A8F" "fdfdfd" "CFD6E6" "ffffff" "b8babf" "95c4fb" "cfd6e6" "themes/Arc Blue.qss" +makeStyle "$TEMPLATE" "e7e8eb" "727A8F" "fdfdfd" "CFD6E6" "ffffff" "b8babf" "F5F6F7" "4084D6" "themes/Arc Grey.qss" +makeStyle "$TEMPLATE" "383C4A" "AFB8C5" "404552" "21252B" "ffffff" "b8babf" "4084D6" "4084D6" "themes/Arc Dark Blue.qss" +makeStyle "$TEMPLATE" "383C4A" "AFB8C5" "404552" "21252B" "ffffff" "b8babf" "404552" "2B2E39" "themes/Arc Dark Grey.qss" \ No newline at end of file diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/SpotlightTemplate.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/SpotlightTemplate.qss --- albert-0.12.0/plugins/widgetboxmodel/share/SpotlightTemplate.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/SpotlightTemplate.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #%foreground_color%; + background-color: #%background_color%; +} + +#frame { + padding: 6px 0px; + border-radius: 8px; + background-color: #%background_color%; + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 0px 8px; + font-size: 36px; + selection-color: #%background_color%; + selection-background-color: #%foreground_color%; + background-color: transparent; +} + +#settingsButton { + margin: 6px 6px 0px 0px; + color: #%button_color%; + background-color: transparent; + padding: 2px; + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +/********** ListViews ************/ + +QListView { + background: transparent; + selection-color: #%selection_foreground_color%; +} + +QListView::item:selected { + background: #%selection_background_color%; +} + +QListView QScrollBar:vertical { + width: 3px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #%scroll_color%; + border-radius: 1px; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 40px; + font-size: 24px; +} + +QListView#resultsList::item{ + padding: 8px 0px 0px 0px; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/SpotlightTemplate.sh albert-0.13.1+plugins1/plugins/widgetboxmodel/share/SpotlightTemplate.sh --- albert-0.12.0/plugins/widgetboxmodel/share/SpotlightTemplate.sh 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/SpotlightTemplate.sh 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,17 @@ +#!/bin/bash + +TEMPLATE="SpotlightTemplate.qss" + +function makeStyle(){ + cat "$1" | sed \ + -e "s/%background_color%/$2/g" \ + -e "s/%foreground_color%/$3/g" \ + -e "s/%button_color%/$4/g" \ + -e "s/%scroll_color%/$5/g" \ + -e "s/%selection_foreground_color%/$6/g"\ + -e "s/%selection_background_color%/$7/g" > "${8}" +} + +#makeStyle bg fg button scroll sel_fg sel_bg output +makeStyle "$TEMPLATE" "fcfcfc" "808080" "e0e0e0" "c0c0c0" "606060" "e0e0e0" "${1}Spotlight.qss" +makeStyle "$TEMPLATE" "030303" "808080" "202020" "404040" "a0a0a0" "202020" "${1}Spotlight Dark.qss" diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/StandardThemeTemplate.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/StandardThemeTemplate.qss --- albert-0.12.0/plugins/widgetboxmodel/share/StandardThemeTemplate.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/StandardThemeTemplate.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #%foreground_color%; + background-color: #%background_color%; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #%background_color%; + border: 6px solid #%border_color%; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #%background_color%; + selection-background-color: #%foreground_color%; + background-color: #%inputline_color%; +} + +#settingsButton { + color : #%button_color%; + background-color: #%background_color%; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #%selection_foreground_color%; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20%selection_background_color%, stop:0.5 #10%selection_background_color%, stop:1.0 #20%selection_background_color% ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #%scroll_color%; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/StandardThemeTemplate.sh albert-0.13.1+plugins1/plugins/widgetboxmodel/share/StandardThemeTemplate.sh --- albert-0.12.0/plugins/widgetboxmodel/share/StandardThemeTemplate.sh 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/StandardThemeTemplate.sh 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ +#!/bin/bash + +TEMPLATE="StandardThemeTemplate.qss" + +function makeStyle(){ + cat "${1}" | sed \ + -e "s/%background_color%/${2}/g" \ + -e "s/%foreground_color%/${3}/g" \ + -e "s/%inputline_color%/${4}/g" \ + -e "s/%border_color%/${5}/g" \ + -e "s/%button_color%/${6}/g" \ + -e "s/%scroll_color%/${7}/g" \ + -e "s/%selection_foreground_color%/${8}/g"\ + -e "s/%selection_background_color%/${9}/g" \ + -e "s/%selection_border_color%/${10}/g" > "${11}" +} + +#makeStyle bg fg input border button scroll sel_fg sel_bg sel_bor output +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "808080" "808080" "808080" "808080" "808080" "808080" "${1}Bright.qss" +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "FF8000" "FF8000" "FF8000" "808080" "FF8000" "FF8000" "${1}BrightOrange.qss" +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "FF0080" "FF0080" "FF0080" "808080" "FF0080" "FF0080" "${1}BrightMagenta.qss" +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "00FF80" "00FF80" "00FF80" "808080" "00FF80" "00FF80" "${1}BrightMint.qss" +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "80FF00" "80FF00" "80FF00" "808080" "80FF00" "80FF00" "${1}BrightGreen.qss" +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "0080FF" "0080FF" "0080FF" "808080" "0080FF" "0080FF" "${1}BrightBlue.qss" +makeStyle "$TEMPLATE" "FFFFFF" "808080" "D0D0D0" "8000FF" "8000FF" "8000FF" "808080" "8000FF" "8000FF" "${1}BrightViolet.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "808080" "808080" "808080" "808080" "808080" "808080" "${1}Dark.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "FF8000" "FF8000" "FF8000" "808080" "FF8000" "FF8000" "${1}DarkOrange.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "FF0080" "FF0080" "FF0080" "808080" "FF0080" "FF0080" "${1}DarkMagenta.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "00FF80" "00FF80" "00FF80" "808080" "00FF80" "00FF80" "${1}DarkMint.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "80FF00" "80FF00" "80FF00" "808080" "80FF00" "80FF00" "${1}DarkGreen.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "0080FF" "0080FF" "0080FF" "808080" "0080FF" "0080FF" "${1}DarkBlue.qss" +makeStyle "$TEMPLATE" "404040" "808080" "202020" "8000FF" "8000FF" "8000FF" "808080" "8000FF" "8000FF" "${1}DarkViolet.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "b58900" "b58900" "b58900" "93a1a1" "b58900" "b58900" "${1}SolarizedDarkYellow.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "cb4b16" "cb4b16" "cb4b16" "93a1a1" "cb4b16" "cb4b16" "${1}SolarizedDarkOrange.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "dc322f" "dc322f" "dc322f" "93a1a1" "dc322f" "dc322f" "${1}SolarizedDarkRed.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "d33682" "d33682" "d33682" "93a1a1" "d33682" "d33682" "${1}SolarizedDarkMagenta.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "6c71c4" "6c71c4" "6c71c4" "93a1a1" "6c71c4" "6c71c4" "${1}SolarizedDarkViolet.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "268bd2" "268bd2" "268bd2" "93a1a1" "268bd2" "268bd2" "${1}SolarizedDarkBlue.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "2aa198" "2aa198" "2aa198" "93a1a1" "2aa198" "2aa198" "${1}SolarizedDarkCyan.qss" +makeStyle "$TEMPLATE" "002b36" "93a1a1" "073642" "859900" "859900" "859900" "93a1a1" "859900" "859900" "${1}SolarizedDarkGreen.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "b58900" "b58900" "b58900" "586e75" "b58900" "b58900" "${1}SolarizedBrightYellow.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "cb4b16" "cb4b16" "cb4b16" "586e75" "cb4b16" "cb4b16" "${1}SolarizedBrightOrange.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "dc322f" "dc322f" "dc322f" "586e75" "dc322f" "dc322f" "${1}SolarizedBrightRed.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "d33682" "d33682" "d33682" "586e75" "d33682" "d33682" "${1}SolarizedBrightMagenta.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "6c71c4" "6c71c4" "6c71c4" "586e75" "6c71c4" "6c71c4" "${1}SolarizedBrightViolet.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "268bd2" "268bd2" "268bd2" "586e75" "268bd2" "268bd2" "${1}SolarizedBrightBlue.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "2aa198" "2aa198" "2aa198" "586e75" "2aa198" "2aa198" "${1}SolarizedBrightCyan.qss" +makeStyle "$TEMPLATE" "fdf6e3" "586e75" "eee8d5" "859900" "859900" "859900" "586e75" "859900" "859900" "${1}SolarizedBrightGreen.qss" diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Adapta.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Adapta.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Adapta.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Adapta.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,98 @@ +/* + * author: will8211 + * Modified from a theme by ubervison + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #E6E9EB; + background-color: #2A373E; +} + +#frame { + padding: 4px; + border-radius: 3px; + background-color: #2A373E; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + border: 1px solid #21252B; + font-size: 36px; + selection-color: #2A373E; + selection-background-color: #E6E9EB; + background-color: #3E515A; +} + +#settingsButton { + color : #ffffff; + background-color: #2A373E; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView::item:selected { + background: #00BCD4; + border: 1px solid #00BCD4; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b8babf; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Blue.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Blue.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Blue.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Blue.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: ubervison + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #727A8F; + background-color: #e7e8eb; +} + +#frame { + padding: 4px; + border-radius: 3px; + background-color: #e7e8eb; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + border: 1px solid #CFD6E6; + font-size: 36px; + selection-color: #e7e8eb; + selection-background-color: #727A8F; + background-color: #fdfdfd; +} + +#settingsButton { + color : #ffffff; + background-color: #e7e8eb; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + selection-color: #727A8F; +} + +QListView::item:selected { + background: #95c4fb; + border: 1px solid #cfd6e6; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b8babf; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Dark Blue.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Dark Blue.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Dark Blue.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Dark Blue.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: ubervison + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #AFB8C5; + background-color: #383C4A; +} + +#frame { + padding: 4px; + border-radius: 3px; + background-color: #383C4A; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + border: 1px solid #21252B; + font-size: 36px; + selection-color: #383C4A; + selection-background-color: #AFB8C5; + background-color: #404552; +} + +#settingsButton { + color : #ffffff; + background-color: #383C4A; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + selection-color: #AFB8C5; +} + +QListView::item:selected { + background: #4084D6; + border: 1px solid #4084D6; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b8babf; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Dark Grey.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Dark Grey.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Dark Grey.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Dark Grey.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: ubervison + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #AFB8C5; + background-color: #383C4A; +} + +#frame { + padding: 4px; + border-radius: 3px; + background-color: #383C4A; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + border: 1px solid #21252B; + font-size: 36px; + selection-color: #383C4A; + selection-background-color: #AFB8C5; + background-color: #404552; +} + +#settingsButton { + color : #ffffff; + background-color: #383C4A; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + selection-color: #AFB8C5; +} + +QListView::item:selected { + background: #404552; + border: 1px solid #2B2E39; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b8babf; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Grey.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Grey.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Arc Grey.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Arc Grey.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: ubervison + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #727A8F; + background-color: #e7e8eb; +} + +#frame { + padding: 4px; + border-radius: 3px; + background-color: #e7e8eb; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + border: 1px solid #CFD6E6; + font-size: 36px; + selection-color: #e7e8eb; + selection-background-color: #727A8F; + background-color: #fdfdfd; +} + +#settingsButton { + color : #ffffff; + background-color: #e7e8eb; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + selection-color: #727A8F; +} + +QListView::item:selected { + background: #F5F6F7; + border: 1px solid #4084D6; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b8babf; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightBlue.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightBlue.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightBlue.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightBlue.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #0080FF; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #0080FF; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #200080FF, stop:0.5 #100080FF, stop:1.0 #200080FF ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #0080FF; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightGreen.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightGreen.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightGreen.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightGreen.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #80FF00; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #80FF00; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #2080FF00, stop:0.5 #1080FF00, stop:1.0 #2080FF00 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #80FF00; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightMagenta.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightMagenta.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightMagenta.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightMagenta.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #FF0080; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #FF0080; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF0080, stop:0.5 #10FF0080, stop:1.0 #20FF0080 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #FF0080; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightMint.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightMint.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightMint.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightMint.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #00FF80; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #00FF80; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #2000FF80, stop:0.5 #1000FF80, stop:1.0 #2000FF80 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #00FF80; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightOrange.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightOrange.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightOrange.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightOrange.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #FF8000; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #FF8000; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF8000, stop:0.5 #10FF8000, stop:1.0 #20FF8000 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #FF8000; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Bright.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Bright.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Bright.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Bright.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #808080; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #808080; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20808080, stop:0.5 #10808080, stop:1.0 #20808080 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #808080; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightViolet.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightViolet.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/BrightViolet.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/BrightViolet.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #FFFFFF; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #FFFFFF; + border: 6px solid #8000FF; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #FFFFFF; + selection-background-color: #808080; + background-color: #D0D0D0; +} + +#settingsButton { + color : #8000FF; + background-color: #FFFFFF; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #208000FF, stop:0.5 #108000FF, stop:1.0 #208000FF ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #8000FF; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkBlue.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkBlue.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkBlue.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkBlue.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #0080FF; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #0080FF; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #200080FF, stop:0.5 #100080FF, stop:1.0 #200080FF ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #0080FF; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkGreen.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkGreen.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkGreen.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkGreen.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #80FF00; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #80FF00; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #2080FF00, stop:0.5 #1080FF00, stop:1.0 #2080FF00 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #80FF00; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkMagenta.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkMagenta.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkMagenta.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkMagenta.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #FF0080; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #FF0080; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF0080, stop:0.5 #10FF0080, stop:1.0 #20FF0080 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #FF0080; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkMint.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkMint.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkMint.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkMint.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #00FF80; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #00FF80; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #2000FF80, stop:0.5 #1000FF80, stop:1.0 #2000FF80 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #00FF80; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkOrange.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkOrange.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkOrange.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkOrange.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #FF8000; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #FF8000; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20FF8000, stop:0.5 #10FF8000, stop:1.0 #20FF8000 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #FF8000; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Dark.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Dark.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Dark.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Dark.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #808080; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #808080; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20808080, stop:0.5 #10808080, stop:1.0 #20808080 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #808080; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkViolet.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkViolet.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/DarkViolet.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/DarkViolet.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #404040; + border: 6px solid #8000FF; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #404040; + selection-background-color: #808080; + background-color: #202020; +} + +#settingsButton { + color : #8000FF; + background-color: #404040; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #808080; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #208000FF, stop:0.5 #108000FF, stop:1.0 #208000FF ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #8000FF; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Elementary.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Elementary.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Elementary.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Elementary.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,117 @@ +/* + * author: Bart Zaalberg + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #404040; + +} + +#frame { + padding: 10px; + border-radius: 4px; + background-color: #F5F5F5; + border: 1px solid #808080; + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 0px; + border-radius: 2px; + border: 1px solid lightblue; + font-size:15px; + selection-color: #404040; + selection-background-color: #FFFFFF; + background-color: #FFFFFF; + padding-left:10px; + margin-right:20px; + color:black; +} + +#settingsButton { + color : #808080; + background-color: #F5F5F5; + padding: 4px; + + /* Respect the frame border */ + margin: 12px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + selection-color: #331; + background-color: #F5F5F5; +} + +QListView::item { + background-color: #F5F5F5; + padding:6px; +} + +QListView::item:selected { + border-radius: 4px; + background-color: #D8D8D8; +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #808080; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: #F5F5F5; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 15px; + color: black; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 35px; + font-size: 13px; + color: #331; + fill: #333; + font-family: "Open Sans"; + src: url("//fonts.googleapis.com/css?family=Open+Sans"); + font-weight: 400; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Numix.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Numix.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Numix.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Numix.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * author: + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + + +* { + color : #ccc; + background-color: #2d2d2d; +} + +#frame { + width:640px; + padding: 5px; + background-color: #2d2d2d; + /*border: 1px solid #555;*/ + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + font: 36px "Source Sans Pro Bold"; + selection-color: #fdf6e3; + selection-background-color: #586e75; + border: none; + background-color: #2d2d2d; +} + +#settingsButton { + border: none; + border-radius: 7px; + color : #555; + background-color: transparent; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +#settingsButton:hover { + background-color: #2d2d2d; +} + + +/********** ListViews **********/ + +QListView { + selection-color: #ccc; +} + +QListView::item:selected { + border: none; + background: qlineargradient(x1:0, x2:1, stop:0.0 #3a3a3a, stop:0.5 #3a3a3a, stop:1.0 #3a3a3a ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #AAAAAA; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 36px; + font-size: 26px; + font: 20px "Source Sans Pro Bold"; + background-color: transparent; + border: none; +} + +QListView#resultsList::item{ + height:48px; + padding: 4px; + border-bottom: 1px dotted #555; +} + +QListView#resultsList::item:selected{ + border: none; + background: #3a3a3a; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Numix Rounded.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Numix Rounded.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Numix Rounded.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Numix Rounded.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * author: Leandro Heck + * based on Manuel Schneider's themes Numix and Yosemite Dark + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + color : #ccc; + background-color: #2d2d2d; +} + +#frame { + width:640px; + padding: 12px; + border-radius: 5px; + background-color: #2d2d2d; + /*border: 1px solid #555;*/ + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + font: 36px "Source Sans Pro Bold"; + selection-color: #fdf6e3; + selection-background-color: #586e75; + border: none; + background-color: #2d2d2d; +} + +#settingsButton { + border: none; + border-radius: 7px; + color : #555; + background-color: transparent; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +#settingsButton:hover { + background-color: #2d2d2d; +} + + +/********** ListViews ************/ + +QListView { + selection-color: #ccc; +} + +QListView::item:selected { + border: none; + background: qlineargradient(x1:0, x2:1, stop:0.0 #3a3a3a, stop:0.5 #3a3a3a, stop:1.0 #3a3a3a ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #AAAAAA; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 36px; + font-size: 26px; + font: 20px "Source Sans Pro Bold"; + background-color: transparent; + border: none; +} + +QListView#resultsList::item{ + height:48px; + padding: 4px; + border-bottom: 1px dotted #555; +} + +QListView#resultsList::item:selected{ + border: none; + background: #3a3a3a; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightBlue.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightBlue.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightBlue.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightBlue.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #268bd2; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #268bd2; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20268bd2, stop:0.5 #10268bd2, stop:1.0 #20268bd2 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #268bd2; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightCyan.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightCyan.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightCyan.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightCyan.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #2aa198; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #2aa198; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #202aa198, stop:0.5 #102aa198, stop:1.0 #202aa198 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #2aa198; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightGreen.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightGreen.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightGreen.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightGreen.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #859900; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #859900; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20859900, stop:0.5 #10859900, stop:1.0 #20859900 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #859900; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightMagenta.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightMagenta.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightMagenta.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightMagenta.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #d33682; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #d33682; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20d33682, stop:0.5 #10d33682, stop:1.0 #20d33682 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #d33682; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightOrange.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightOrange.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightOrange.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightOrange.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #cb4b16; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #cb4b16; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20cb4b16, stop:0.5 #10cb4b16, stop:1.0 #20cb4b16 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #cb4b16; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightRed.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightRed.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightRed.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightRed.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #dc322f; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #dc322f; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20dc322f, stop:0.5 #10dc322f, stop:1.0 #20dc322f ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #dc322f; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightViolet.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightViolet.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightViolet.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightViolet.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #6c71c4; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #6c71c4; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #206c71c4, stop:0.5 #106c71c4, stop:1.0 #206c71c4 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #6c71c4; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightYellow.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightYellow.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedBrightYellow.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedBrightYellow.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #586e75; + background-color: #fdf6e3; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #fdf6e3; + border: 6px solid #b58900; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #fdf6e3; + selection-background-color: #586e75; + background-color: #eee8d5; +} + +#settingsButton { + color : #b58900; + background-color: #fdf6e3; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #586e75; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20b58900, stop:0.5 #10b58900, stop:1.0 #20b58900 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b58900; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkBlue.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkBlue.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkBlue.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkBlue.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #268bd2; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #268bd2; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20268bd2, stop:0.5 #10268bd2, stop:1.0 #20268bd2 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #268bd2; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkCyan.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkCyan.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkCyan.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkCyan.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #2aa198; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #2aa198; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #202aa198, stop:0.5 #102aa198, stop:1.0 #202aa198 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #2aa198; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkGreen.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkGreen.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkGreen.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkGreen.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #859900; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #859900; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20859900, stop:0.5 #10859900, stop:1.0 #20859900 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #859900; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkMagenta.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkMagenta.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkMagenta.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkMagenta.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #d33682; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #d33682; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20d33682, stop:0.5 #10d33682, stop:1.0 #20d33682 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #d33682; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkOrange.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkOrange.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkOrange.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkOrange.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #cb4b16; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #cb4b16; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20cb4b16, stop:0.5 #10cb4b16, stop:1.0 #20cb4b16 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #cb4b16; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkRed.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkRed.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkRed.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkRed.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #dc322f; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #dc322f; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20dc322f, stop:0.5 #10dc322f, stop:1.0 #20dc322f ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #dc322f; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkViolet.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkViolet.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkViolet.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkViolet.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #6c71c4; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #6c71c4; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #206c71c4, stop:0.5 #106c71c4, stop:1.0 #206c71c4 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #6c71c4; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkYellow.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkYellow.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/SolarizedDarkYellow.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/SolarizedDarkYellow.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #93a1a1; + background-color: #002b36; +} + +#frame { + padding: 6px; + border-radius: 12px; + background-color: #002b36; + border: 6px solid #b58900; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 2px; + border-radius: 2px; + font-size: 36px; + selection-color: #002b36; + selection-background-color: #93a1a1; + background-color: #073642; +} + +#settingsButton { + color : #b58900; + background-color: #002b36; + padding: 4px; + + /* Respect the frame border */ + margin: 6px 6px 0px 0px; + border-top-right-radius: 6px; + border-bottom-left-radius: 10px; + + /* Workaround for Qt to get fixed size button*/ + min-width:13px; + min-height:13px; + max-width:13px; + max-height:13px; +} + +/********** ListViews **********/ + +QListView { + background: transparent; + selection-color: #93a1a1; +} + +QListView::item:selected { + background: qlineargradient(x1:0, x2:1, stop:0.0 #20b58900, stop:0.5 #10b58900, stop:1.0 #20b58900 ); +} + +QListView QScrollBar:vertical { + width: 5px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #b58900; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 44px; + font-size: 26px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Spotlight Dark.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Spotlight Dark.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Spotlight Dark.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Spotlight Dark.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #030303; +} + +#frame { + padding: 6px 0px; + border-radius: 8px; + background-color: #030303; + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 0px 8px; + font-size: 36px; + selection-color: #030303; + selection-background-color: #808080; + background-color: transparent; +} + +#settingsButton { + margin: 6px 6px 0px 0px; + color: #202020; + background-color: transparent; + padding: 2px; + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +/********** ListViews ************/ + +QListView { + background: transparent; + selection-color: #a0a0a0; +} + +QListView::item:selected { + background: #202020; +} + +QListView QScrollBar:vertical { + width: 3px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #404040; + border-radius: 1px; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 40px; + font-size: 24px; +} + +QListView#resultsList::item{ + padding: 8px 0px 0px 0px; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Spotlight.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Spotlight.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Spotlight.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Spotlight.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,88 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + color : #808080; + background-color: #fcfcfc; +} + +#frame { + padding: 6px 0px; + border-radius: 8px; + background-color: #fcfcfc; + min-width:640px; + max-width:640px; +} + +#inputLine { + padding: 0px 8px; + font-size: 36px; + selection-color: #fcfcfc; + selection-background-color: #808080; + background-color: transparent; +} + +#settingsButton { + margin: 6px 6px 0px 0px; + color: #e0e0e0; + background-color: transparent; + padding: 2px; + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +/********** ListViews ************/ + +QListView { + background: transparent; + selection-color: #606060; +} + +QListView::item:selected { + background: #e0e0e0; +} + +QListView QScrollBar:vertical { + width: 3px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #c0c0c0; + border-radius: 1px; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 40px; + font-size: 24px; +} + +QListView#resultsList::item{ + padding: 8px 0px 0px 0px; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} diff -Nru "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Yosemite Dark.qss" "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Yosemite Dark.qss" --- "/tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/plugins/widgetboxmodel/share/themes/Yosemite Dark.qss" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Yosemite Dark.qss" 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + font-family:"DejaVu Sans"; + font-weight: 200; + color : #ffffff; + background-color: #f4000000; +} + +#frame { + padding: 12px; + border-radius: 5px; + background-color: #f4000000; + border: 1px solid #20808080; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + font-size: 36px; + selection-color: #f4000000; + selection-background-color: #ffffff; + background-color: transparent; +} + +#settingsButton { + color: #484848; + background-color: transparent; + padding: 8px; + + /* Workaround for Qt to get fixed size button*/ + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +/********** ListViews ************/ + +QListView { + selection-color: #ffffff; +} + +QListView::item:selected { + background: #262626; +} + +QListView QScrollBar:vertical { + width: 2px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #484848; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 40px; + font-size: 22px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/share/themes/Yosemite.qss albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Yosemite.qss --- albert-0.12.0/plugins/widgetboxmodel/share/themes/Yosemite.qss 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/share/themes/Yosemite.qss 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * author: Manuel Schneider + * + * Check http://doc.qt.io/qt-5/stylesheet-syntax.html especially the subtopics: + * The Style Sheet Syntax (http://doc.qt.io/qt-5/stylesheet-syntax.html) + * Qt Style Sheets Reference (http://doc.qt.io/qt-5/stylesheet-reference.html) + */ + +* { + border: none; + font-family:"DejaVu Sans"; + font-weight: 200; + color : #000000; + background-color: #fcfcfc; +} + +#frame { + padding: 12px; + border-radius: 5px; + background-color: #fcfcfc; + border: 1px solid #20808080; + + /* Workaround for Qt to get fixed size button*/ + min-width:640px; + max-width:640px; +} + +#inputLine { + font-size: 36px; + selection-color: #fcfcfc; + selection-background-color: #000000; + background-color: transparent; +} + +#settingsButton { + color: #bdbdbd; + background-color: transparent; + padding: 8px; + + /* Workaround for Qt to get fixed size button*/ + min-width:14px; + min-height:14px; + max-width:14px; + max-height:14px; +} + +/********** ListViews ************/ + +QListView { + selection-color: #000000; +} + +QListView::item:selected { + background: #eeeeee; +} + +QListView QScrollBar:vertical { + width: 2px; + background: transparent; +} + +QListView QScrollBar::handle:vertical { + background: #e2e2e2; + min-height: 24px; +} + +QListView QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical, +QListView QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, +QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + border: 0px; + width: 0px; + height: 0px; + background: transparent; +} + +/********** actionList **********/ + +QListView#actionList { + font-size: 20px; +} + +QListView#actionList::item{ + height:28px; +} + +/********** resultsList **********/ + +QListView#resultsList { + icon-size: 40px; + font-size: 22px; +} + +QListView#resultsList::item{ + height:48px; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/actionlist.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/actionlist.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/actionlist.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/actionlist.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,76 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "actionlist.h" + +/** ***************************************************************************/ +WidgetBoxModel::ActionList::ActionList(QWidget *parent) : ResizingList(parent) { + setItemDelegate(new ActionDelegate); +} + + + +/** ***************************************************************************/ +bool WidgetBoxModel::ActionList::eventFilter(QObject*, QEvent *event) { + + if (event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); + switch (keyEvent->key()) { + + // Navigation + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Home: + case Qt::Key_End: + // Activation + case Qt::Key_Enter: + case Qt::Key_Return: + keyPressEvent(keyEvent); + return false; + } + } + return false; +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ActionList::ActionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { + + painter->save(); + + QStyleOptionViewItem option = options; + initStyleOption(&option, index); + + // Draw selection + option.widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, option.widget); + + // Draw text + painter->setFont(option.font); + QString text = QFontMetrics(option.font).elidedText(index.data(Qt::DisplayRole).toString(), option.textElideMode, option.rect.width()); + option.widget->style()->drawItemText(painter, + option.rect, + Qt::AlignCenter|Qt::AlignHCenter, + option.palette, + option.state & QStyle::State_Enabled, + text, + (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::WindowText); + painter->restore(); +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/actionlist.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/actionlist.h --- albert-0.12.0/plugins/widgetboxmodel/src/actionlist.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/actionlist.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,53 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "resizinglist.h" +#include + +namespace WidgetBoxModel { + + +/** ***************************************************************************/ +class ActionList final : public ResizingList +{ + Q_OBJECT + class ActionDelegate; + +public: + + ActionList(QWidget *parent = 0); + +private: + + bool eventFilter(QObject*, QEvent *event) override; + +}; + + + +/** ***************************************************************************/ +class ActionList::ActionDelegate final : public QStyledItemDelegate +{ +public: + + ActionDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} + + void paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override; +}; + +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/configwidget.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/configwidget.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/configwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,125 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include "configwidget.h" +#include "frontendwidget.h" +#include "ui_configwidget.h" +using namespace Core; + +class WidgetBoxModel::ConfigWidget::Private { +public: + WidgetBoxModel::Ui::ConfigWidget ui; + FrontendWidget *frontend = nullptr; +}; + + +/** ***********************************************************************************************/ +WidgetBoxModel::ConfigWidget::ConfigWidget(FrontendWidget *frontend, QWidget *parent) + : QWidget(parent), d(new Private) { + + d->ui.setupUi(this); + + d->frontend = frontend; + + // ALWAYS CENTER + d->ui.checkBox_center->setChecked(d->frontend->showCentered()); + connect(d->ui.checkBox_center, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setShowCentered); + + // ALWAYS ON TOP + d->ui.checkBox_onTop->setChecked(d->frontend->alwaysOnTop()); + connect(d->ui.checkBox_onTop, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setAlwaysOnTop); + + // HIDE ON FOCUS OUT + d->ui.checkBox_hideOnFocusOut->setChecked(d->frontend->hideOnFocusLoss()); + connect(d->ui.checkBox_hideOnFocusOut, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setHideOnFocusLoss); + + // HIDE ON CLOSE + d->ui.checkBox_hideOnClose->setChecked(d->frontend->hideOnClose()); + connect(d->ui.checkBox_hideOnClose, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setHideOnClose); + + // CLEAR ON HIDE + d->ui.checkBox_clearOnHide->setChecked(d->frontend->clearOnHide()); + connect(d->ui.checkBox_clearOnHide, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setClearOnHide); + + // MAX RESULTS + d->ui.spinBox_results->setValue(d->frontend->maxResults()); + connect(d->ui.spinBox_results, static_cast(&QSpinBox::valueChanged), + d->frontend, &FrontendWidget::setMaxResults); + + // DISPLAY SCROLLBAR + d->ui.checkBox_scrollbar->setChecked(d->frontend->displayScrollbar()); + connect(d->ui.checkBox_scrollbar, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setDisplayScrollbar); + + // DISPLAY ICONS + d->ui.checkBox_icons->setChecked(d->frontend->displayIcons()); + connect(d->ui.checkBox_icons, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setDisplayIcons); + + // DISPLAY SHADOW + d->ui.checkBox_shadow->setChecked(d->frontend->displayShadow()); + connect(d->ui.checkBox_shadow, &QCheckBox::toggled, + d->frontend, &FrontendWidget::setDisplayShadow); + + // THEMES + QStringList pluginDataPaths = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, + "org.albert.frontend.boxmodel.widgets", + QStandardPaths::LocateDirectory); + + QFileInfoList themes; + for (const QString &pluginDataPath : pluginDataPaths) + themes << QDir(QString("%1/themes").arg(pluginDataPath)) + .entryInfoList(QStringList("*.qss"), QDir::Files | QDir::NoSymLinks); + + for (const QFileInfo &fi : themes) { + d->ui.comboBox_themes->addItem(fi.baseName(), fi.canonicalFilePath()); + if ( fi.baseName() == d->frontend->theme()) + d->ui.comboBox_themes->setCurrentIndex(d->ui.comboBox_themes->count()-1); + } + + connect(d->ui.comboBox_themes, static_cast(&QComboBox::currentIndexChanged), + [this](int i){ + // Apply and save the theme + QString currentTheme = d->frontend->theme(); + if (!d->frontend->setTheme(d->ui.comboBox_themes->itemText(i))) { + QMessageBox(QMessageBox::Critical, "Error", + "Could not apply theme.", + QMessageBox::NoButton, + this).exec(); + if (!d->frontend->setTheme(currentTheme)) { + qFatal("Rolling back theme failed."); + } + } + }); +} + + +/** ***********************************************************************************************/ +WidgetBoxModel::ConfigWidget::~ConfigWidget() { + // Needed since default dtor of unique ptr in the header has to know the type +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/configwidget.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/configwidget.h --- albert-0.12.0/plugins/widgetboxmodel/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/configwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,42 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include + +namespace WidgetBoxModel { + +class FrontendWidget; + +class ConfigWidget final : public QWidget +{ + Q_OBJECT + + class Private; + +public: + + ConfigWidget(FrontendWidget *frontend, QWidget *parent); + ~ConfigWidget(); + +private: + + std::unique_ptr d; + +}; + +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/configwidget.ui albert-0.13.1+plugins1/plugins/widgetboxmodel/src/configwidget.ui --- albert-0.12.0/plugins/widgetboxmodel/src/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/configwidget.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,311 @@ + + + WidgetBoxModel::ConfigWidget + + + Frontend settings + + + + + + + + User Interface + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 0 + 0 + + + + Theme: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Amount of results: + + + + + + + + 0 + 0 + + + + + + + 1 + + + 10 + + + + + + + + 0 + 0 + + + + Display scrollbar: + + + + + + + + 0 + 0 + + + + If this option is enabled, albert displays +a scrollbar in the results list. + + + + + + + + 0 + 0 + + + + Display icons: + + + + + + + + 0 + 0 + + + + If this option is enabled, albert displays +icons provided by the items. + + + + + + + Display shadow: + + + + + + + + 0 + 0 + + + + If this option is enabled, albert displays a +shadow below the widget. Note that the +shadow area appears to be transparent, +but it is not for mouse clicks due to Qt +limitations. However its just a handful of +pixels and you can use it to drag the window. + + + + + + + + 0 + 0 + + + + Hide on close: + + + + + + + + 0 + 0 + + + + If the user closes the main window, the main window +gets hidden instead of the application getting quit. + + + + + + + + 0 + 0 + + + + Always center Albert: + + + + + + + + 0 + 0 + + + + If this option is enabled, albert +centers the main window in the +screen where the pointer resides. + + + + + + + + 0 + 0 + + + + Always on top: + + + + + + + + 0 + 0 + + + + If this option is enabled, albert will +stay on top of all top level windows. + + + + + + + + 0 + 0 + + + + Hide on focus out: + + + + + + + + 0 + 0 + + + + Hide the main window, if it lost keyboard focus, +e.g. by clicking on another app or changing the +window with Alt+Tab. Note that this feature is +automatically disabled as long as the settings +widget is open. + + + + + + + Clear on hide: + + + + + + + + 0 + 0 + + + + Clear the input line when the window is hidden. + + + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/frontendplugin.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendplugin.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/frontendplugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendplugin.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,79 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "frontendwidget.h" +#include "frontendplugin.h" + + +/** ***************************************************************************/ +WidgetBoxModel::FrontendPlugin::FrontendPlugin() + : Frontend("org.albert.frontend.boxmodel.widgets"), + frontendWidget_(new FrontendWidget(&settings())){ + + connect(frontendWidget_.get(), &FrontendWidget::inputChanged, + this, &Frontend::inputChanged); + + connect(frontendWidget_.get(), &FrontendWidget::settingsWidgetRequested, + this, &Frontend::settingsWidgetRequested); + + connect(frontendWidget_.get(), &FrontendWidget::widgetShown, + this, &Frontend::widgetShown); + + connect(frontendWidget_.get(), &FrontendWidget::widgetHidden, + this, &Frontend::widgetHidden); +} + + +/** ***************************************************************************/ +WidgetBoxModel::FrontendPlugin::~FrontendPlugin() { +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendPlugin::isVisible() { + return frontendWidget_->isVisible(); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendPlugin::setVisible(bool visible) { + frontendWidget_->setVisible(visible); +} + + +/** ***************************************************************************/ +QString WidgetBoxModel::FrontendPlugin::input() { + return frontendWidget_->input(); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendPlugin::setInput(const QString &input) { + frontendWidget_->setInput(input); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendPlugin::setModel(QAbstractItemModel *m) { + frontendWidget_->setModel(m); +} + + +/** ***************************************************************************/ +QWidget *WidgetBoxModel::FrontendPlugin::widget(QWidget *parent) { + return frontendWidget_->widget(parent); +} + diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/frontendplugin.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendplugin.h --- albert-0.12.0/plugins/widgetboxmodel/src/frontendplugin.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendplugin.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core_globals.h" +#include "core/frontend.h" + +namespace WidgetBoxModel { + +class FrontendWidget; + +class FrontendPlugin final : public Core::Frontend +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID ALBERT_FRONTEND_IID FILE "metadata.json") + +public: + + FrontendPlugin(); + ~FrontendPlugin(); + + bool isVisible() override; + void setVisible(bool visible) override; + + QString input() override; + void setInput(const QString&) override; + + void setModel(QAbstractItemModel *) override; + + QWidget* widget(QWidget *parent = nullptr) override; + +private: + + std::unique_ptr frontendWidget_; +}; + +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/frontend.ui albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontend.ui --- albert-0.12.0/plugins/widgetboxmodel/src/frontend.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontend.ui 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,92 @@ + + + WidgetBoxModel::MainWindow + + + + QLayout::SetFixedSize + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + true + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QAbstractItemView::NoEditTriggers + + + true + + + + + + + + + + + ResultsList + QListView +
resultslist.h
+
+ + ActionList + QListView +
actionlist.h
+
+
+ +
diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/frontendwidget.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendwidget.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/frontendwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendwidget.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,738 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core/history.h" +#include "core/itemroles.h" +#include "configwidget.h" +#include "frontendwidget.h" +#include "resultslist.h" +#include "settingsbutton.h" +#include "ui_frontend.h" +#ifdef __unix__ +#include "xcb/xcb.h" +#include +#undef KeyPress +#undef KeyRelease +#include +#endif + + +namespace { + +const char* CFG_WND_POS = "windowPosition"; +const char* CFG_CENTERED = "showCentered"; +const bool DEF_CENTERED = true; +const char* CFG_THEME = "theme"; +const char* DEF_THEME = "Bright"; +const char* CFG_HIDE_ON_FOCUS_LOSS = "hideOnFocusLoss"; +const bool DEF_HIDE_ON_FOCUS_LOSS = true; +const char* CFG_HIDE_ON_CLOSE = "hideOnClose"; +const bool DEF_HIDE_ON_CLOSE = false; +const char* CFG_CLEAR_ON_HIDE = "clearOnHide"; +const bool DEF_CLEAR_ON_HIDE = false; +const char* CFG_ALWAYS_ON_TOP = "alwaysOnTop"; +const bool DEF_ALWAYS_ON_TOP = true; +const char* CFG_MAX_RESULTS = "itemCount"; +const uint8_t DEF_MAX_RESULTS = 5; +const char* CFG_DISPLAY_SCROLLBAR = "displayScrollbar"; +const bool DEF_DISPLAY_SCROLLBAR = false; +const char* CFG_DISPLAY_ICONS = "displayIcons"; +const bool DEF_DISPLAY_ICONS = true; +const char* CFG_DISPLAY_SHADOW = "displayShadow"; +const bool DEF_DISPLAY_SHADOW = true; + +} + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ + +class WidgetBoxModel::FrontendWidget::Private +{ +public: + + /** The name of the current theme */ + QString theme_; + + /** The offset from cursor to topleft. Used when the window is dagged */ + QPoint clickOffset_; + + /** The model of the action list view */ + QStringListModel *actionsListModel_; + + /** The button to open the settings dialog */ + SettingsButton *settingsButton_; + + /** The input history */ + Core::History *history_; + + /** The modifier used to navigate directly in the history */ + Qt::KeyboardModifier historyMoveMod_; + + /** The form of the main app */ + Ui::MainWindow ui; + + QSettings *settings; + + /** Indicates that the app should be shown centered */ + bool showCentered_; + + /** Indicates that the app should be hidden on focus loss */ + bool hideOnFocusLoss_; + + /** Indicates that the app should be hidden on close event */ + bool hideOnClose_; + + /** Indcates the state that the app is in */ + bool actionsShown_; + + /** Indcates that a shadow should be drawn */ + bool displayShadow_; + + /** Indcates that the inputline should be cleared on hide */ + bool clearOnHide_; + +}; + +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +/** ***************************************************************************/ +WidgetBoxModel::FrontendWidget::FrontendWidget(QSettings *settings) : d(new Private) { + + d->actionsShown_ = false; + d->historyMoveMod_ = Qt::ControlModifier; + d->settings = settings; + + // INITIALIZE UI + d->ui.setupUi(this); +// setWindowIcon(qApp->windowIcon()); + setWindowTitle(qAppName()); + setWindowFlags(Qt::Tool + | Qt::WindowCloseButtonHint // No close event w/o this + | Qt::FramelessWindowHint); + setAttribute(Qt::WA_TranslucentBackground); + + QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect(this); + effect->setBlurRadius(20); + effect->setColor(QColor(0, 0, 0 , 192 )) ; + effect->setXOffset(0.0); + effect->setYOffset(3.0); + setGraphicsEffect(effect); + + // Disable tabbing completely + d->ui.actionList->setFocusPolicy(Qt::NoFocus); + d->ui.resultsList->setFocusPolicy(Qt::NoFocus); + + // Set initial event filter pipeline: window -> resultslist -> lineedit + d->ui.inputLine->installEventFilter(d->ui.resultsList); + d->ui.inputLine->installEventFilter(this); + + // Set stringlistmodel for actions view + d->actionsListModel_ = new QStringListModel(this); + d->ui.actionList->setModel(d->actionsListModel_); + + // Hide lists + d->ui.actionList->hide(); + d->ui.resultsList->hide(); + + // Settings button + d->settingsButton_ = new SettingsButton(this); + d->settingsButton_->setObjectName("settingsButton"); + d->settingsButton_->setFocusPolicy(Qt::NoFocus); + d->settingsButton_->setContextMenuPolicy(Qt::ActionsContextMenu); + + // Context menu of settingsbutton + QAction *action = new QAction("Settings", d->settingsButton_); + action->setShortcuts({QKeySequence("Ctrl+,"), QKeySequence("Alt+,")}); + connect(action, &QAction::triggered, this, &FrontendWidget::hide); + connect(action, &QAction::triggered, this, &FrontendWidget::settingsWidgetRequested); + connect(d->settingsButton_, &QPushButton::clicked, action, &QAction::trigger); + d->settingsButton_->addAction(action); + + action = new QAction("Hide", d->settingsButton_); + action->setShortcut(QKeySequence("Esc")); + connect(action, &QAction::triggered, this, &FrontendWidget::hide); + d->settingsButton_->addAction(action); + + action = new QAction("Separator", d->settingsButton_); + action->setSeparator(true); + d->settingsButton_->addAction(action); + + action = new QAction("Quit", d->settingsButton_); + action->setShortcut(QKeySequence("Alt+F4")); + connect(action, &QAction::triggered, qApp, &QApplication::quit); + d->settingsButton_->addAction(action); + + // History + d->history_ = new Core::History(this); + + /* + * Settings + */ + + setShowCentered(d->settings->value(CFG_CENTERED, DEF_CENTERED).toBool()); + if (!showCentered() && d->settings->contains(CFG_WND_POS) + && d->settings->value(CFG_WND_POS).canConvert(QMetaType::QPoint)) + move(d->settings->value(CFG_WND_POS).toPoint()); + setHideOnFocusLoss(d->settings->value(CFG_HIDE_ON_FOCUS_LOSS, DEF_HIDE_ON_FOCUS_LOSS).toBool()); + setHideOnClose(d->settings->value(CFG_HIDE_ON_CLOSE, DEF_HIDE_ON_CLOSE).toBool()); + setClearOnHide(d->settings->value(CFG_CLEAR_ON_HIDE, DEF_CLEAR_ON_HIDE).toBool()); + setAlwaysOnTop(d->settings->value(CFG_ALWAYS_ON_TOP, DEF_ALWAYS_ON_TOP).toBool()); + setMaxResults(d->settings->value(CFG_MAX_RESULTS, DEF_MAX_RESULTS).toUInt()); + setDisplayScrollbar(d->settings->value(CFG_DISPLAY_SCROLLBAR, DEF_DISPLAY_SCROLLBAR).toBool()); + setDisplayIcons(d->settings->value(CFG_DISPLAY_ICONS, DEF_DISPLAY_ICONS).toBool()); + setDisplayShadow(d->settings->value(CFG_DISPLAY_SHADOW, DEF_DISPLAY_SHADOW).toBool()); + d->theme_ = d->settings->value(CFG_THEME, DEF_THEME).toString(); + if (!setTheme(d->theme_)) + qFatal("FATAL: Stylefile not found: %s", d->theme_.toStdString().c_str()); + + + /* + * Signals + */ + + // Trigger query, if text changed + connect(d->ui.inputLine, &QLineEdit::textChanged, this, &FrontendWidget::inputChanged); + + // Hide the actionview, if text was changed + connect(d->ui.inputLine, &QLineEdit::textChanged, this, [this](){ setShowActions(false); }); + + // Reset history, if text was manually changed + connect(d->ui.inputLine, &QLineEdit::textEdited, d->history_, &Core::History::resetIterator); + + // Hide the actionview, if another item gets clicked + connect(d->ui.resultsList, &ResultsList::pressed, this, [this](){ setShowActions(false); }); + + // Trigger default action, if item in resultslist was activated + QObject::connect(d->ui.resultsList, &ResultsList::activated, [this](const QModelIndex &index){ + + switch (qApp->queryKeyboardModifiers()) { + case Qt::MetaModifier: // Default fallback action (Meta) + d->ui.resultsList->model()->setData(index, -1, Core::ItemRoles::FallbackRole); + break; + default: // DefaultAction + d->ui.resultsList->model()->setData(index, -1, Core::ItemRoles::ActionRole); + break; + } + + // Do not move this up! (Invalidates index) + d->history_->add(d->ui.inputLine->text()); + this->setVisible(false); + d->ui.inputLine->clear(); + }); + + // Trigger alternative action, if item in actionList was activated + QObject::connect(d->ui.actionList, &ActionList::activated, [this](const QModelIndex &index){ + d->history_->add(d->ui.inputLine->text()); + d->ui.resultsList->model()->setData(d->ui.resultsList->currentIndex(), index.row(), Core::ItemRoles::AltActionRole); + this->setVisible(false); + d->ui.inputLine->clear(); + }); +} + + +/** ***************************************************************************/ +WidgetBoxModel::FrontendWidget::~FrontendWidget() { + // Needed since default dtor of unique ptr in the header has to know the type +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::isVisible() { + return QWidget::isVisible(); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setVisible(bool visible) { + + // Skip if nothing to do + if ( (isVisible() && visible) || !(isVisible() || visible) ) + return; + + QWidget::setVisible(visible); + + if (visible) { + // Move widget after showing it since QWidget::move works only on widgets + // that have been shown once. Well as long as this does not introduce ugly + // flicker this may be okay. + if (d->showCentered_){ + QDesktopWidget *dw = QApplication::desktop(); + this->move(dw->screenGeometry(dw->screenNumber(QCursor::pos())).center() + -QPoint(rect().right()/2,256 )); + } + this->raise(); + this->activateWindow(); + d->ui.inputLine->setFocus(); + emit widgetShown(); + } else { + setShowActions(false); + d->history_->resetIterator(); + ( d->clearOnHide_ ) ? d->ui.inputLine->clear() : d->ui.inputLine->selectAll(); + emit widgetHidden(); + } +} + + +/** ***************************************************************************/ +QString WidgetBoxModel::FrontendWidget::input() { + return d->ui.inputLine->text(); +} + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setInput(const QString &input) { + d->ui.inputLine->setText(input); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setModel(QAbstractItemModel *m) { + d->ui.resultsList->setModel(m); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setShowCentered(bool b) { + d->settings->setValue(CFG_CENTERED, b); + d->showCentered_ = b; +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::showCentered() const { + return d->showCentered_; +} + + +/** ***************************************************************************/ +const QString &WidgetBoxModel::FrontendWidget::theme() const { + return d->theme_; +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::setTheme(const QString &theme) { + d->theme_ = theme; + QFileInfoList themes; + + + QStringList pluginDataPaths = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, + "org.albert.frontend.boxmodel.widgets", + QStandardPaths::LocateDirectory); + + for (const QString &pluginDataPath : pluginDataPaths) + themes << QDir(QString("%1/themes").arg(pluginDataPath)) + .entryInfoList(QStringList("*.qss"), QDir::Files | QDir::NoSymLinks); + + // Find and apply the theme + bool success = false; + for (const QFileInfo &fi : themes) { + if (fi.baseName() == d->theme_) { + QFile f(fi.canonicalFilePath()); + if (f.open(QFile::ReadOnly)) { + d->settings->setValue(CFG_THEME, d->theme_); + setStyleSheet(f.readAll()); + f.close(); + success = true; + break; + } + } + } + return success; +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::hideOnFocusLoss() const { + return d->hideOnFocusLoss_; +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setHideOnFocusLoss(bool b) { + d->settings->setValue(CFG_HIDE_ON_FOCUS_LOSS, b); + d->hideOnFocusLoss_ = b; +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::hideOnClose() const { + return d->hideOnClose_; +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setHideOnClose(bool b) { + d->settings->setValue(CFG_HIDE_ON_CLOSE, b); + d->hideOnClose_ = b; +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::clearOnHide() const { + return d->clearOnHide_; +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setClearOnHide(bool b) { + d->settings->setValue(CFG_CLEAR_ON_HIDE, b); + d->clearOnHide_ = b; +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::alwaysOnTop() const { + return windowFlags().testFlag(Qt::WindowStaysOnTopHint); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setAlwaysOnTop(bool alwaysOnTop) { + d->settings->setValue(CFG_ALWAYS_ON_TOP, alwaysOnTop); + // TODO: QT_MINREL 5.7 setFlag + alwaysOnTop ? setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint) + : setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setMaxResults(uint maxItems) { + d->settings->setValue(CFG_MAX_RESULTS, maxItems); + d->ui.resultsList->setMaxItems(maxItems); +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::displayIcons() const { + return d->ui.resultsList->displayIcons(); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setDisplayIcons(bool value) { + d->settings->setValue(CFG_DISPLAY_ICONS, value); + d->ui.resultsList->setDisplayIcons(value); +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::displayScrollbar() const { + return d->ui.resultsList->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff; +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setDisplayScrollbar(bool value) { + d->settings->setValue(CFG_DISPLAY_SCROLLBAR, value); + d->ui.resultsList->setVerticalScrollBarPolicy( + value ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::displayShadow() const { + return d->displayShadow_; +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setDisplayShadow(bool value) { + d->settings->setValue(CFG_DISPLAY_SHADOW, value); + d->displayShadow_ = value; + graphicsEffect()->setEnabled(value); + value ? setContentsMargins(20,20,20,20) : setContentsMargins(0,0,0,0); +} + + +/** ***************************************************************************/ +uint WidgetBoxModel::FrontendWidget::maxResults() const { + return d->ui.resultsList->maxItems(); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::setShowActions(bool showActions) { + + // Show actions + if ( showActions && !d->actionsShown_ ) { + + // Skip if nothing selected + if ( !d->ui.resultsList->currentIndex().isValid()) + return; + + // Get actions + d->actionsListModel_->setStringList(d->ui.resultsList->model()->data( + d->ui.resultsList->currentIndex(), + Core::ItemRoles::AltActionRole).toStringList()); + + // Skip if actions are empty + if (d->actionsListModel_->rowCount() < 1) + return; + + d->ui.actionList->setCurrentIndex(d->actionsListModel_->index(0, 0, d->ui.actionList->rootIndex())); + d->ui.actionList->show(); + + // Change event filter pipeline: window -> _action_list -> lineedit + d->ui.inputLine->removeEventFilter(this); + d->ui.inputLine->removeEventFilter(d->ui.resultsList); + d->ui.inputLine->installEventFilter(d->ui.actionList); + d->ui.inputLine->installEventFilter(this); + + // Finally set the state + d->actionsShown_ = true; + } + + // Hide actions + if ( !showActions && d->actionsShown_ ) { + + d->ui.actionList->hide(); + + // Change event filter pipeline: window -> resultslist -> lineedit + d->ui.inputLine->removeEventFilter(this); + d->ui.inputLine->removeEventFilter(d->ui.actionList); + d->ui.inputLine->installEventFilter(d->ui.resultsList); + d->ui.inputLine->installEventFilter(this); + + // Finally set the state + d->actionsShown_ = false; + } +} + + +/** ***************************************************************************/ +QWidget *WidgetBoxModel::FrontendWidget::widget(QWidget *parent) { + return new ConfigWidget(this, parent); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::closeEvent(QCloseEvent *event) { + event->accept(); + if (!d->hideOnClose_) + qApp->quit(); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::resizeEvent(QResizeEvent *event) { + + // Let settingsbutton be in top right corner of frame + d->settingsButton_->move(d->ui.frame->geometry().topRight() - QPoint(d->settingsButton_->width()-1,0)); + +#ifdef __unix__ + // Keep the input shape consistent + int shape_event_base, shape_error_base; + if (XShapeQueryExtension(QX11Info::display(), &shape_event_base, &shape_error_base)) { + + Region region = XCreateRegion(); + XRectangle rectangle; + rectangle.x = static_cast(d->ui.frame->geometry().x()); + rectangle.y = static_cast(d->ui.frame->geometry().y()); + rectangle.width = static_cast(d->ui.frame->geometry().width()); + rectangle.height = static_cast(d->ui.frame->geometry().height()); + XUnionRectWithRegion(&rectangle, region, region); + XShapeCombineRegion(QX11Info::display(), winId(), ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); + } +#endif + + QWidget::resizeEvent(event); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::mouseMoveEvent(QMouseEvent *event) { + // Move the widget with the mouse + move(event->globalPos() - d->clickOffset_); + QWidget::mouseMoveEvent(event); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::mousePressEvent(QMouseEvent *event) { + // Save the offset on press for movement calculations + d->clickOffset_ = event->pos(); + QWidget::mousePressEvent(event); +} + + +/** ***************************************************************************/ +void WidgetBoxModel::FrontendWidget::mouseReleaseEvent(QMouseEvent *event) { + // Save the window position () + d->settings->setValue(CFG_WND_POS, pos()); + QWidget::mousePressEvent(event); +} + + +/** ***************************************************************************/ +bool WidgetBoxModel::FrontendWidget::eventFilter(QObject *, QEvent *event) { + + if ( event->type() == QEvent::KeyPress ) { + QKeyEvent* keyEvent = static_cast(event); + switch (keyEvent->key()) { + + // Toggle insert completion string + case Qt::Key_Tab: + if ( d->ui.resultsList->currentIndex().isValid() ) + d->ui.inputLine->setText( + d->ui.resultsList->model()->data( + d->ui.resultsList->currentIndex(), Core::ItemRoles::CompletionRole + ).toString() + ); + return true; + + case Qt::Key_Alt: + setShowActions(true); + return true; + + case Qt::Key_Up:{ + // Move up in the history + if ( !d->ui.resultsList->currentIndex().isValid() // Empty list + || keyEvent->modifiers() == d->historyMoveMod_ // MoveMod (Ctrl) hold + || ( !d->actionsShown_ // Not in actions state... + && d->ui.resultsList->currentIndex().row()==0 && !keyEvent->isAutoRepeat() ) ){ // ... and first row (non repeat) + QString next = d->history_->next(); + if (!next.isEmpty()) + d->ui.inputLine->setText(next); + return true; + } + return false; + } + + // Move down in the history + case Qt::Key_Down:{ + if ( !d->actionsShown_ && keyEvent->modifiers() == Qt::ControlModifier ) { + QString prev = d->history_->prev(); + if (!prev.isEmpty()) + d->ui.inputLine->setText(prev); + return true; + } + } + } + } + + if ( event->type() == QEvent::KeyRelease ) { + QKeyEvent* keyEvent = static_cast(event); + switch (keyEvent->key()) { + case Qt::Key_Alt: + setShowActions(false); + return true; + } + } + + if (event->type() == QEvent::Wheel) { + QWheelEvent* wheelEvent = static_cast(event); + if ( wheelEvent->angleDelta().y() > 0 ) { + QString next = d->history_->next(); + if (!next.isEmpty()) + d->ui.inputLine->setText(next); + } else { + QString prev = d->history_->prev(); + if (!prev.isEmpty()) + d->ui.inputLine->setText(prev); + } + } + + return false; +} + + +#ifdef Q_OS_LINUX +/** **************************************************************************** + * @brief MainWidget::nativeEvent + * + * The purpose of this function is to hide in special casesonly. + */ +bool WidgetBoxModel::FrontendWidget::nativeEvent(const QByteArray &eventType, void *message, long *) +{ + if (eventType == "xcb_generic_event_t") + { + xcb_generic_event_t* event = static_cast(message); + switch (event->response_type & 127) + { + case XCB_FOCUS_OUT: { + /* This is a horribly hackish but working solution. + + A triggered key grab on X11 steals the focus of the window for short + period of time. This may result in the following annoying behaviour: + When the hotkey is pressed and X11 steals the focus there arises a + race condition between the hotkey event and the focus out event. + When the app is visible and the focus out event is delivered the app + gets hidden. Finally when the hotkey is received the app gets shown + again although the user intended to hide the app with the hotkey. + + Solutions: + Although X11 differs between the two focus out events, qt does not. + One might install a native event filter and use the XCB structs to + decide which type of event is delivered, but this approach is not + platform independent (unless designed so explicitely, but its a + hassle). The behaviour was expected when the app hides on: + + (mode==XCB_NOTIFY_MODE_GRAB && detail==XCB_NOTIFY_DETAIL_NONLINEAR)|| + (mode==XCB_NOTIFY_MODE_NORMAL && detail==XCB_NOTIFY_DETAIL_NONLINEAR) + (Check Xlib Programming Manual) + + Another much simpler but less elegant solution is to delay the + hiding a few milliseconds, so that the hotkey event will always be + handled first. */ + + xcb_focus_out_event_t *fe = reinterpret_cast(event); +// qDebug() << "MainWidget::nativeEvent::XCB_FOCUS_OUT\t"; +// switch (fe->mode) { +// case XCB_NOTIFY_MODE_NORMAL: qDebug() << "XCB_NOTIFY_MODE_NORMAL";break; +// case XCB_NOTIFY_MODE_GRAB: qDebug() << "XCB_NOTIFY_MODE_GRAB";break; +// case XCB_NOTIFY_MODE_UNGRAB: qDebug() << "XCB_NOTIFY_MODE_UNGRAB";break; +// case XCB_NOTIFY_MODE_WHILE_GRABBED: qDebug() << "XCB_NOTIFY_MODE_WHILE_GRABBED";break; +// } +// switch (fe->detail) { +// case XCB_NOTIFY_DETAIL_ANCESTOR: qDebug() << "ANCESTOR";break; +// case XCB_NOTIFY_DETAIL_INFERIOR: qDebug() << "INFERIOR";break; +// case XCB_NOTIFY_DETAIL_NONE: qDebug() << "NONE";break; +// case XCB_NOTIFY_DETAIL_NONLINEAR: qDebug() << "NONLINEAR";break; +// case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL: qDebug() << "NONLINEAR_VIRTUAL";break; +// case XCB_NOTIFY_DETAIL_POINTER: qDebug() << "POINTER";break;break; +// case XCB_NOTIFY_DETAIL_POINTER_ROOT: qDebug() << "POINTER_ROOT"; +// case XCB_NOTIFY_DETAIL_VIRTUAL: qDebug() << "VIRTUAL";break; +// } + if ((/*(fe->mode==XCB_NOTIFY_MODE_GRAB && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR) ||*/ + (fe->mode==XCB_NOTIFY_MODE_NORMAL && fe->detail==XCB_NOTIFY_DETAIL_NONLINEAR )) && + d->hideOnFocusLoss_) + hide(); + return true; + } + } + } + return false; +} +#endif diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/frontendwidget.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendwidget.h --- albert-0.12.0/plugins/widgetboxmodel/src/frontendwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/frontendwidget.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,102 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "core_globals.h" +#include "core/frontend.h" + +namespace WidgetBoxModel { + +class FrontendWidget final : public QWidget +{ + Q_OBJECT + + class Private; + +public: + + FrontendWidget(QSettings*); + ~FrontendWidget(); + + bool isVisible(); + void setVisible(bool visible) override; + + QString input(); + void setInput(const QString&); + + void setModel(QAbstractItemModel *); + + QWidget* widget(QWidget *parent = nullptr); + + const QString &theme() const; + bool setTheme(const QString& theme); + + uint maxResults() const; + void setMaxResults(uint max); + + bool showCentered() const; + void setShowCentered(bool b = true); + + bool hideOnFocusLoss() const; + void setHideOnFocusLoss(bool b = true); + + bool hideOnClose() const; + void setHideOnClose(bool b = true); + + bool clearOnHide() const; + void setClearOnHide(bool b = true); + + bool alwaysOnTop() const; + void setAlwaysOnTop(bool alwaysOnTop); + + bool displayIcons() const; + void setDisplayIcons(bool value); + + bool displayScrollbar() const; + void setDisplayScrollbar(bool value); + + bool displayShadow() const; + void setDisplayShadow(bool value); + + +protected: + + void closeEvent(QCloseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent * event) override; + void mouseReleaseEvent(QMouseEvent * event) override; + void resizeEvent(QResizeEvent* event) override; + bool nativeEvent(const QByteArray &eventType, void *message, long *) override; + bool eventFilter(QObject*, QEvent *event) override; + + void setShowActions(bool showActions); + +private: + + std::unique_ptr d; + +signals: + + void widgetShown(); + void widgetHidden(); + void inputChanged(QString qry); + void settingsWidgetRequested(); +}; + +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/resizinglist.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resizinglist.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/resizinglist.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resizinglist.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,86 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "resizinglist.h" +#include + +/** ***************************************************************************/ +uint WidgetBoxModel::ResizingList::maxItems() const { + return maxItems_; +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ResizingList::setMaxItems(uint maxItems) { + maxItems_ = maxItems; + updateGeometry(); +} + + + +/** ***************************************************************************/ +QSize WidgetBoxModel::ResizingList::sizeHint() const { + if (model() == nullptr) + return QSize(); + return QSize(width(), sizeHintForRow(0) * std::min(static_cast(maxItems_), model()->rowCount(rootIndex()))); +} + + + +/** ***************************************************************************/ +QSize WidgetBoxModel::ResizingList::minimumSizeHint() const { + return QSize(0,0); // Fix for small lists +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ResizingList::setModel(QAbstractItemModel * m) { + if (model() == m) + return; + + if (model()!=nullptr) { + disconnect(this->model(), &QAbstractItemModel::rowsInserted, this, &ResizingList::updateAppearance); + disconnect(this->model(), &QAbstractItemModel::modelReset, this, &ResizingList::updateAppearance); + } + + QItemSelectionModel *sm = selectionModel(); + QAbstractItemView::setModel(m); + delete sm; + updateAppearance(); + + // If not empty show and select first, update geom. If not null connect. + if (model()!=nullptr) { + connect(this->model(), &QAbstractItemModel::rowsInserted, this, &ResizingList::updateAppearance); + connect(this->model(), &QAbstractItemModel::modelReset, this, &ResizingList::updateAppearance); + } +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ResizingList::updateAppearance() { + if ( model() == nullptr || model()->rowCount() == 0 ) + hide(); + else { + show(); + if ( !currentIndex().isValid() ) + setCurrentIndex(model()->index(0, 0)); + updateGeometry(); + } +} + diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/resizinglist.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resizinglist.h --- albert-0.12.0/plugins/widgetboxmodel/src/resizinglist.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resizinglist.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,51 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace WidgetBoxModel { + +class ResizingList : public QListView +{ + Q_OBJECT + Q_PROPERTY(int maxItems READ maxItems WRITE setMaxItems MEMBER maxItems_ NOTIFY maxItemsChanged) + +public: + + ResizingList(QWidget *parent = 0) : QListView(parent), maxItems_(5) {} + virtual ~ResizingList() {} + + uint maxItems() const; + void setMaxItems(uint maxItems); + + QSize minimumSizeHint() const override; + QSize sizeHint() const override; + void setModel(QAbstractItemModel * model) override; + +private: + + void updateAppearance(); + + uint maxItems_; + +signals: + + void maxItemsChanged(); + +}; + +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/resultslist.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resultslist.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/resultslist.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resultslist.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,245 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include "resultslist.h" +#include "core/itemroles.h" + +/** ***************************************************************************/ +class WidgetBoxModel::ResultsList::ItemDelegate final : public QStyledItemDelegate +{ +public: + ItemDelegate(QObject *parent = nullptr) + : QStyledItemDelegate(parent), drawIcon(true), subTextRole(Core::ItemRoles::ToolTipRole) {} + + void paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override; + + bool drawIcon; + int subTextRole; +}; + + + +/** ***************************************************************************/ +WidgetBoxModel::ResultsList::ResultsList(QWidget *parent) : ResizingList(parent) { + setItemDelegate(delegate_ = new ItemDelegate(this)); + + // Single click activation (segfaults without queued connection) + connect(this, &ResultsList::clicked, this, &ResultsList::activated, Qt::QueuedConnection); +} + + + +/** ***************************************************************************/ +bool WidgetBoxModel::ResultsList::displayIcons() const { + return delegate_->drawIcon; +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ResultsList::setDisplayIcons(bool value) { + delegate_->drawIcon = value; + update(); +} + + + +/** ***************************************************************************/ +bool WidgetBoxModel::ResultsList::eventFilter(QObject*, QEvent *event) { + + if (event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); + switch (keyEvent->key()) { + + // Display different subtexts according to the KeyboardModifiers + case Qt::Key_Control: + case Qt::Key_Shift: + case Qt::Key_Alt: + case Qt::Key_Meta: + switch (keyEvent->modifiers()) { + case Qt::MetaModifier: // Default fallback action (Meta) + delegate_->subTextRole = Core::ItemRoles::FallbackRole; + break; + default: // DefaultAction + delegate_->subTextRole = Core::ItemRoles::ToolTipRole; + break; + } + update(); + return false; + + + // Expose the navigation hidden by the lineedit with the control modifier + case Qt::Key_Home: + case Qt::Key_End: + if ( keyEvent->modifiers() == Qt::ControlModifier ) { + keyPressEvent(keyEvent); + return true; + } + return false; + + // Navigation + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + // Activation + case Qt::Key_Enter: + case Qt::Key_Return: + keyPressEvent(keyEvent); + return true; + } + } + + if (event->type() == QEvent::KeyRelease) { + QKeyEvent* keyEvent = static_cast(event); + switch (keyEvent->key()) { + + // Display different subtexts according to the KeyboardModifiers + case Qt::Key_Control: + case Qt::Key_Shift: + case Qt::Key_Alt: + case Qt::Key_Meta: + switch (keyEvent->modifiers()) { + case Qt::MetaModifier: // Default fallback action (Meta) + delegate_->subTextRole = Core::ItemRoles::FallbackRole; + break; + default: // DefaultAction + delegate_->subTextRole = Core::ItemRoles::ToolTipRole; + break; + } + update(); + return false; + } + } + return false; +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ResultsList::showEvent(QShowEvent *event) { + QWidget::showEvent(event); + if (qApp->keyboardModifiers() == Qt::MetaModifier) + delegate_->subTextRole = Core::ItemRoles::FallbackRole; + else + delegate_->subTextRole = Core::ItemRoles::ToolTipRole; +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::ResultsList::ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { + + painter->save(); + + QStyleOptionViewItem option = options; + initStyleOption(&option, index); + + /* + * fm(x) := fontmetrics of x + * DR := DisplayRole + * TR := ToolTipRole + * +---------------------+----------------------------------------+ + * | | | + * | +-------------+ | | + * | | | | | + * | | | |a*fm(DR)/(fm(DR)+fm(TR)) DisplayRole | + * a| | icon | | | + * | | | | | + * | | | +----------------------------------------+ + * | | | | | + * | +-------------+ |a*fm(TR)/(fm(DR)+fm(TR)) ToolTipRole+x | + * | | | + * +---------------------------------------------------------------+ + */ + + + // Avoid ugly dark blue mouseover background + // TODO: QT_MINREL 5.7 setFlag + option.state &= ~QStyle::State_MouseOver; + + // Draw selection + option.widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, option.widget); + + // Draw icon + if ( drawIcon ){ + QRect iconRect = QRect( + QPoint((option.rect.height() - option.decorationSize.width())/2 + option.rect.x(), + (option.rect.height() - option.decorationSize.height())/2 + option.rect.y()), + option.decorationSize); + QPixmap pixmap; + QString iconPath = index.data(Core::ItemRoles::DecorationRole).value(); + QString cacheKey = QString("%1%2%3").arg(option.decorationSize.width(), option.decorationSize.height()).arg(iconPath); + if ( !QPixmapCache::find(cacheKey, &pixmap) ) { + pixmap = QPixmap(iconPath).scaled(option.decorationSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmapCache::insert(cacheKey, pixmap); + } + painter->drawPixmap(iconRect, pixmap); + } + + // Calculate text rects + QFont font1 = option.font; + QFont font2 = option.font; + font2.setPixelSize(12); + QFontMetrics fontMetrics1 = QFontMetrics(font1); + QFontMetrics fontMetrics2 = QFontMetrics(font2); + QRect contentRect = option.rect; + contentRect.setLeft(drawIcon ? option.rect.height() : 0); + contentRect.setTop(option.rect.y()+option.rect.height()/2-(fontMetrics1.height()+fontMetrics2.height())/2); + contentRect.setBottom(option.rect.y()+option.rect.height()/2+(fontMetrics1.height()+fontMetrics2.height())/2); + QRect textRect = contentRect.adjusted(0,-2,0,-fontMetrics2.height()-2); + QRect subTextRect = contentRect.adjusted(0,fontMetrics1.height()-2,0,-2); + + // // Test + // painter->fillRect(iconRect, Qt::magenta); + // painter->fillRect(contentRect, Qt::red); + // painter->fillRect(textRect, Qt::blue); + // painter->fillRect(subTextRect, Qt::yellow); + + + // Draw display role + painter->setFont(font1); + QString text = fontMetrics1.elidedText(index.data(Core::ItemRoles::TextRole).toString(), + option.textElideMode, + textRect.width()); + option.widget->style()->drawItemText(painter, + textRect, + option.displayAlignment, + option.palette, + option.state & QStyle::State_Enabled, + text, + (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::WindowText); + + // Draw tooltip role + painter->setFont(font2); + text = fontMetrics2.elidedText(index.data(option.state.testFlag(QStyle::State_Selected) + ? subTextRole + : Core::ItemRoles::ToolTipRole).toString(), + option.textElideMode, + subTextRect.width()); + option.widget->style()->drawItemText(painter, + subTextRect, + Qt::AlignBottom|Qt::AlignLeft, + option.palette, + option.state & QStyle::State_Enabled, + text, + (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::WindowText); + painter->restore(); +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/resultslist.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resultslist.h --- albert-0.12.0/plugins/widgetboxmodel/src/resultslist.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/resultslist.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,43 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "resizinglist.h" +#include + +namespace WidgetBoxModel { + +class ResultsList final : public ResizingList +{ + Q_OBJECT + class ItemDelegate; + +public: + + ResultsList(QWidget *parent = 0); + + bool displayIcons() const; + void setDisplayIcons(bool value); + +private: + + bool eventFilter(QObject*, QEvent *event) override; + void showEvent(QShowEvent *event) override; + + ItemDelegate *delegate_; +}; +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/settingsbutton.cpp albert-0.13.1+plugins1/plugins/widgetboxmodel/src/settingsbutton.cpp --- albert-0.12.0/plugins/widgetboxmodel/src/settingsbutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/settingsbutton.cpp 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,91 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "settingsbutton.h" +#include +#include +#include +#include +#include +#include +#include + +/** ***************************************************************************/ +WidgetBoxModel::SettingsButton::SettingsButton(QWidget *parent) : QPushButton(parent) { + animation_ = new QPropertyAnimation(this, "angle"); + animation_->setDuration(10000); + animation_->setStartValue(0); + animation_->setEndValue(360); + animation_->setLoopCount(-1); + animation_->start(); + connect(animation_, &QPropertyAnimation::valueChanged, this, static_cast(&QWidget::update)); + + svgRenderer_ = new QSvgRenderer(QString(":gear")); + + setCursor(Qt::PointingHandCursor); +} + + + +/** ***************************************************************************/ +WidgetBoxModel::SettingsButton::~SettingsButton() { + delete animation_; + delete svgRenderer_; +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::SettingsButton::hideEvent(QHideEvent *event) { + animation_->stop(); + QPushButton::hideEvent(event); +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::SettingsButton::showEvent(QShowEvent *event) { + animation_->start(); + QPushButton::showEvent(event); +} + + + +/** ***************************************************************************/ +void WidgetBoxModel::SettingsButton::paintEvent(QPaintEvent *event) { + QPushButton::paintEvent(event); + + QStyleOptionButton option; + option.initFrom(this); + QRect contentRect = style()->subElementRect(QStyle::SE_PushButtonContents, &option, this); + + // Prepare image in pixmap using mask + QPixmap gearPixmap(contentRect.size()); + QRectF pixmapRect(QPoint(), contentRect.size()); + gearPixmap.fill(Qt::transparent); + QPainter pixmapPainter(&gearPixmap); + pixmapPainter.translate(pixmapRect.center()); + pixmapPainter.rotate(angle_); + svgRenderer_->render(&pixmapPainter, pixmapRect.translated(-pixmapRect.center())); + pixmapPainter.resetTransform(); + pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); + pixmapPainter.fillRect(pixmapRect, option.palette.windowText().color()); + + // Draw pixmap on button + QPainter painter(this); + painter.drawPixmap(contentRect, gearPixmap); + +} diff -Nru albert-0.12.0/plugins/widgetboxmodel/src/settingsbutton.h albert-0.13.1+plugins1/plugins/widgetboxmodel/src/settingsbutton.h --- albert-0.12.0/plugins/widgetboxmodel/src/settingsbutton.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/plugins/widgetboxmodel/src/settingsbutton.h 2017-10-17 10:13:29.000000000 +0000 @@ -0,0 +1,48 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +class QPropertyAnimation; +class QSvgRenderer; + +namespace WidgetBoxModel { + +class SettingsButton final : public QPushButton +{ + Q_OBJECT + Q_PROPERTY(int angle MEMBER angle_) + +public: + + SettingsButton(QWidget *parent = 0); + ~SettingsButton(); + +protected: + + void hideEvent(QHideEvent * event) override; + void showEvent(QShowEvent * event) override; + +private: + + void paintEvent(QPaintEvent *event) override; + + int angle_; + QPropertyAnimation *animation_; + QSvgRenderer *svgRenderer_; + +}; +} diff -Nru albert-0.12.0/src/application/CMakeLists.txt albert-0.13.1+plugins1/src/application/CMakeLists.txt --- albert-0.12.0/src/application/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/application/CMakeLists.txt 2017-09-30 09:43:39.000000000 +0000 @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.3) project(albert) diff -Nru albert-0.12.0/src/application/main.cpp albert-0.13.1+plugins1/src/application/main.cpp --- albert-0.12.0/src/application/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/application/main.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "albert.h" +#include "core/albert.h" int main(int argc, char **argv) { - return Albert::run(argc, argv); + Core::AlbertApp::run(argc, argv); } diff -Nru albert-0.12.0/src/lib/albert/CMakeLists.txt albert-0.13.1+plugins1/src/lib/albert/CMakeLists.txt --- albert-0.12.0/src/lib/albert/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -project(albertcore) - -add_definitions(-DCORE) #export branch - -# Get Qt libraries -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Concurrent - Network - Sql - Svg - Widgets -) - -# List files in the source directory -FILE(GLOB_RECURSE SRC include/* src/*) - -qt5_wrap_ui(UI - src/albert/mainwindow/mainwindow.ui - src/albert/settingswidget/settingswidget.ui -) - -qt5_add_resources(QRC - resources.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} - PUBLIC - include/ - PRIVATE - src/ - src/albert/ - src/albert/settingswidget/ - src/albert/mainwindow/ -) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - PRIVATE - ${Qt5Concurrent_LIBRARIES} - ${Qt5Network_LIBRARIES} - ${Qt5Sql_LIBRARIES} - ${Qt5Svg_LIBRARIES} - ${Qt5Widgets_LIBRARIES} - globalshortcut - xdg -) - -# Set the RPATH for the library lookup -set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/albert") - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert) diff -Nru albert-0.12.0/src/lib/albert/include/action.h albert-0.13.1+plugins1/src/lib/albert/include/action.h --- albert-0.12.0/src/lib/albert/include/action.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/action.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "core_globals.h" - -namespace Core { - -/** - * @brief The action interface - * A base class for actions (and items) - */ -class EXPORT_CORE Action -{ -public: - - virtual ~Action() {} - - /** A description */ - virtual QString text() const = 0; - - /** Activates the item */ - virtual void activate() = 0; -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/albert.h albert-0.13.1+plugins1/src/lib/albert/include/albert.h --- albert-0.12.0/src/lib/albert/include/albert.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/albert.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include "core_globals.h" - -namespace Albert { - int EXPORT_CORE run(int argc, char **argv); -} - - diff -Nru albert-0.12.0/src/lib/albert/include/core_globals.h albert-0.13.1+plugins1/src/lib/albert/include/core_globals.h --- albert-0.12.0/src/lib/albert/include/core_globals.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/core_globals.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#if defined(_MSC_VER) - #define EXPORT __declspec(dllexport) - #define IMPORT __declspec(dllimport) -#elif defined(__GNUC__) - #define EXPORT __attribute__((visibility("default"))) - #define IMPORT -#else - #define EXPORT - #define IMPORT - #pragma warning Unknown dynamic link import/export semantics. -#endif - -#ifdef CORE - #define EXPORT_CORE EXPORT -#else - #define EXPORT_CORE IMPORT -#endif - -#define ALBERT_EXTENSION_IID "ExtensionInterface/v1.0-alpha" - diff -Nru albert-0.12.0/src/lib/albert/include/extension.h albert-0.13.1+plugins1/src/lib/albert/include/extension.h --- albert-0.12.0/src/lib/albert/include/extension.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/extension.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "core_globals.h" - -namespace Core { - -/** - * @brief The extension interface - */ -class EXPORT_CORE Extension -{ -public: - - Extension(const QString &id) : id(id) {} - virtual ~Extension() {} - - /** - * @brief An immutable application-wide unique identifier - */ - const QString id; - - /** - * @brief A human readable name of the plugin - * @return The human readable name - */ - virtual QString name() const = 0; - - /** - * @brief The settings widget factory - * This has to return the widget that is accessible to the user from the - * albert settings plugin tab. If the return value is a nullptr there will - * be no settings widget available in the settings. - * @return The settings widget - */ - virtual QWidget* widget(QWidget *parent = nullptr) = 0; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/extensionmanager.h albert-0.13.1+plugins1/src/lib/albert/include/extensionmanager.h --- albert-0.12.0/src/lib/albert/include/extensionmanager.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/extensionmanager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include -#include -#include "extension.h" -#include "core_globals.h" - -namespace Core { - -class Extension; -class ExtensionSpec; -class ExtensionManagerPrivate; - -class EXPORT_CORE ExtensionManager final : public QObject -{ - Q_OBJECT - -public: - - ExtensionManager(); - ~ExtensionManager(); - - void setPluginDirs(const QStringList&); - void reloadExtensions(); - const std::vector> & extensionSpecs() const; - void enableExtension(const std::unique_ptr &); - void disableExtension(const std::unique_ptr &); - bool extensionIsEnabled(const std::unique_ptr &); - - void registerObject(QObject *); - void unregisterObject(QObject*); - const std::set objects() const; - template - std::set objectsByType() { - std::set results; - for (QObject * object : objects()) { - T *result = dynamic_cast(object); - if (result) - results.insert(result); - } - return results; - } - - static ExtensionManager *instance; - -private: - - void loadExtension(const std::unique_ptr &); - void unloadExtension(const std::unique_ptr &); - - std::unique_ptr d; - -signals: - - void extensionLoaded(Extension*); - void extensionAboutToUnload(Extension*); - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/fallbackprovider.h albert-0.13.1+plugins1/src/lib/albert/include/fallbackprovider.h --- albert-0.12.0/src/lib/albert/include/fallbackprovider.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/fallbackprovider.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "core_globals.h" - -namespace Core { - -class Item; - -class EXPORT_CORE FallbackProvider -{ -public: - - virtual ~FallbackProvider() {} - - /** - * @brief Fallbacks - * This items show up if a query yields no results - */ - virtual std::vector> fallbacks(const QString &) = 0; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/indexable.h albert-0.13.1+plugins1/src/lib/albert/include/indexable.h --- albert-0.12.0/src/lib/albert/include/indexable.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/indexable.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "core_globals.h" - -namespace Core { - -/** - * @brief The Indexable class - * The interface items need to be indexable by the offline index - */ -class EXPORT_CORE Indexable -{ - -public: - - struct WeightedKeyword { - WeightedKeyword(const QString& kw, uint32_t r) : keyword(kw), relevance(r){} - QString keyword; - uint32_t relevance; - }; - - virtual ~Indexable() {} - - virtual std::vector indexKeywords() const = 0; - -}; - -} - diff -Nru albert-0.12.0/src/lib/albert/include/item.h albert-0.13.1+plugins1/src/lib/albert/include/item.h --- albert-0.12.0/src/lib/albert/include/item.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "core_globals.h" - -namespace Core { - -class Action; - -/** **************************************************************************** - * @brief The item interface - * Subclass this class to make your object displayable in the results list. - */ -class EXPORT_CORE Item -{ - -public: - - /** - * An enumeration of urgency levels - * Notifications are placed on top. Alert too but additionally get an visual - * emphasis. Normal items are not handled in a special way. - */ - enum class Urgency : unsigned char { Normal, Notification, Alert }; - - virtual ~Item() {} - - /** An persistant, extensionwide unique identifier, "" if item is dynamic */ - virtual QString id() const = 0; - - /** The icon for the item */ - virtual QString iconPath() const = 0; - - /** The title for the item */ - virtual QString text() const = 0; - - /** The declarative subtext for the item */ - virtual QString subtext() const = 0; - - /** The string to use for completion */ - virtual QString completionString() const { return text(); } - - /** Urgency level of the item, defautls to "Normal" */ - virtual Urgency urgency() const { return Urgency::Normal; } - - /** The alternative actions of the item*/ - virtual std::vector> actions() = 0; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/offlineindex.h albert-0.13.1+plugins1/src/lib/albert/include/offlineindex.h --- albert-0.12.0/src/lib/albert/include/offlineindex.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/offlineindex.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "core_globals.h" - -namespace Core { - -class IndexImpl; -class Indexable; - -class EXPORT_CORE OfflineIndex final { - -public: - /** - * @brief Contstructs a search - * @param fuzzy Sets the type of the search. Defaults to false. - */ - OfflineIndex(bool fuzzy = false); - - /** - * @brief Destructs the search - * @param - */ - ~OfflineIndex(); - - /** - * @brief Sets the type of the search to fuzzy - * @param fuzzy The type to set. Defaults to true. - */ - void setFuzzy(bool fuzzy = true); - - /** - * @brief Type of the search - * @return True if the search is fuzzy else false. - */ - bool fuzzy(); - - /** - * @brief Set the error tolerance of the fuzzy search - * - * If the value d is >1, the search tolerates d errors. If the value d is <1, - * the search tolerates wordlength * d errors. The "amount of tolerance" is - * measures in maximal prefix edit distance. If the search is not set to fuzzy - * setDelta has no effect. - * - * @param t The amount of error tolerance - */ - void setDelta(double d); - - /** - * @brief The error tolerance of the fuzzy search - * @return The amount of error tolerance if search is fuzzy 0 else. - */ - double delta(); - - /** - * @brief Build the search index - * @param The items to index - */ - void add(std::shared_ptr idxble); - - /** - * @brief Clear the search index - */ - void clear(); - - /** - * @brief Perform a search on the index - * @param req The query string - */ - std::vector> search(const QString &req) const; - -private: - IndexImpl *impl_; -}; - -} - - - diff -Nru albert-0.12.0/src/lib/albert/include/query.h albert-0.13.1+plugins1/src/lib/albert/include/query.h --- albert-0.12.0/src/lib/albert/include/query.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/query.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include -#include -#include "core_globals.h" -#include "queryhandler.h" - -class QueryManager; - -namespace Core { - -class Extension; -class Item; - -/** - * @brief The Query class - * Represents the execution of a query - */ -class EXPORT_CORE Query : public QObject -{ - Q_OBJECT - - friend class ::QueryManager; - class QueryPrivate; - -public: - - enum class State { - Idle = 0, - Running, - Finished, - Canceled - }; - - const State &state() const; - - const QString &searchTerm() const; - - bool isValid() const; - - bool isTriggered() const; - const QString &trigger() const; - - void addMatch(std::shared_ptr item, short score = 0); - void addMatches(std::vector,short>>::iterator begin, - std::vector,short>>::iterator end); - - std::map runtimes(); - -private: - - Query(); - ~Query(); - - void setSearchTerm(const QString &); - - void invalidate(); - - void setTrigger(const QString &trigger); - - void setQueryHandlers(const std::set &); - - void setFallbacks(const std::vector> &); - - void run(); - - std::unique_ptr d; - -signals: - - void resultsReady(QAbstractItemModel *); - void finished(); - -}; - -} - - diff -Nru albert-0.12.0/src/lib/albert/include/queryhandler.h albert-0.13.1+plugins1/src/lib/albert/include/queryhandler.h --- albert-0.12.0/src/lib/albert/include/queryhandler.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/queryhandler.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "core_globals.h" - -namespace Core { - -class Query; - -class EXPORT_CORE QueryHandler -{ -public: - - QueryHandler(QString id) : id(id) {} - virtual ~QueryHandler() {} - - const QString id; - - /** - * @brief The triggers that makes the plugin beeing run exclusice - */ - virtual QStringList triggers() const { return QStringList(); } - - /** - * @brief Session setup - * Called when the users started a session, i.e. before the the main window - * is shown. Setup session stage has to be finished before the actual query - * handling will begin so do not do any long running jobs in here. If you - * really have to, do it asynchonous or threaded (only recommended if you - * know what you do). - */ - virtual void setupSession() {} - - /** - * @brief Session teardown - * Called when the user finshed a session, i.e. after the the main window - * has been hidden. Although the app is hidden now this method should not - * block since the user may want start another session immediately. - * @see setupSession - */ - virtual void teardownSession() {} - - virtual bool isLongRunning() const { return false; } - - /** - * @brief Query handling - * This method is called for every user input. Add the results to the query - * passed as parameter. The results are sorted by usage. After 100 ms - * they are just appended to not disturb the users interaction. Queries can - * get invalidated so make sure to regularly check isValid() to cancel - * long running operations. This method is called in a thread without event - * loop, be aware of the consequences (especially regarding signal/slot - * mechanism). - * @param query Holds the query context - */ - virtual void handleQuery(Query *query) = 0; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/shlex.h albert-0.13.1+plugins1/src/lib/albert/include/shlex.h --- albert-0.12.0/src/lib/albert/include/shlex.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/shlex.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "core_globals.h" - -namespace Util { - -class EXPORT_CORE ShellLexer -{ -public: - static QString quote(QString input); - static QStringList split(const QString &input); - -}; - -} - diff -Nru albert-0.12.0/src/lib/albert/include/standardaction.h albert-0.13.1+plugins1/src/lib/albert/include/standardaction.h --- albert-0.12.0/src/lib/albert/include/standardaction.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/standardaction.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "action.h" -#include "core_globals.h" - -namespace Core { - - -/** **************************************************************************** -* @brief A standard action -* If you dont need the flexibility subclassing the abstract classes provided, -* you can simply use this container, fill it with data. -*/ -struct EXPORT_CORE StandardAction final : public Action -{ -public: - - StandardAction(); - StandardAction(const QString &text, std::function f); - - QString text() const override; - void setText(const QString &text); - - const std::function &action(); - void setAction(std::function &&action); - - void activate() override; - -private: - - QString text_; - std::function action_; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/standardindexitem.h albert-0.13.1+plugins1/src/lib/albert/include/standardindexitem.h --- albert-0.12.0/src/lib/albert/include/standardindexitem.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/standardindexitem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "standarditem.h" -#include "core_globals.h" -#include "indexable.h" - -namespace Core { - -/** **************************************************************************** -* @brief A standard index item -* If you dont need the flexibility subclassing the abstract classes provided, -* you can simply use this container, fill it with data. -*/ -class EXPORT_CORE StandardIndexItem final : public StandardItem, public Indexable -{ -public: - - StandardIndexItem(const QString &id); - - virtual std::vector indexKeywords() const override; - virtual void setIndexKeywords(std::vector &&indexKeywords); - -private: - - std::vector indexKeywords_; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/include/standarditem.h albert-0.13.1+plugins1/src/lib/albert/include/standarditem.h --- albert-0.12.0/src/lib/albert/include/standarditem.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/include/standarditem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "core_globals.h" -#include "item.h" - -namespace Core { - -class Action; - -/** -* @brief A standard item -* If you dont need the flexibility subclassing the abstract classes provided, -* you can simply use this container, fill it with data. -*/ -class EXPORT_CORE StandardItem : public Item -{ -public: - - StandardItem(const QString &id = QString()); - - QString id() const override final; - - QString text() const override; - void setText(const QString &text); - - QString subtext() const override; - void setSubtext(const QString &subtext); - - QString completionString() const override; - void setCompletionString(const QString &completion); - - QString iconPath() const override; - void setIconPath( const QString &iconPath); - - std::vector> actions() override; - void setActions(std::vector> &&actions); - -protected: - - QString id_; - QString text_; - QString subtext_; - QString completion_; - QString iconPath_; - std::vector> actions_; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/resources/icons/albert.svg albert-0.13.1+plugins1/src/lib/albert/resources/icons/albert.svg --- albert-0.12.0/src/lib/albert/resources/icons/albert.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/resources/icons/albert.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/lib/albert/resources/icons/gear.svg albert-0.13.1+plugins1/src/lib/albert/resources/icons/gear.svg --- albert-0.12.0/src/lib/albert/resources/icons/gear.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/resources/icons/gear.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/lib/albert/resources/icons/plugin_error.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/lib/albert/resources/icons/plugin_error.png differ Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/lib/albert/resources/icons/plugin_notloaded.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/lib/albert/resources/icons/plugin_notloaded.png differ Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/lib/albert/resources/icons/plugin_ok.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/lib/albert/resources/icons/plugin_ok.png differ diff -Nru albert-0.12.0/src/lib/albert/resources/icons/unknown.svg albert-0.13.1+plugins1/src/lib/albert/resources/icons/unknown.svg --- albert-0.12.0/src/lib/albert/resources/icons/unknown.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/resources/icons/unknown.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/lib/albert/resources.qrc albert-0.13.1+plugins1/src/lib/albert/resources.qrc --- albert-0.12.0/src/lib/albert/resources.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/resources.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - - - resources/icons/plugin_error.png - resources/icons/plugin_notloaded.png - resources/icons/plugin_ok.png - resources/icons/albert.svg - resources/icons/gear.svg - resources/icons/unknown.svg - - diff -Nru albert-0.12.0/src/lib/albert/src/albert/albert.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/albert.cpp --- albert-0.12.0/src/lib/albert/src/albert/albert.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/albert.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,496 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "albert.h" -#include "extensionmanager.h" -#include "hotkeymanager.h" -#include "mainwindow.h" -#include "querymanager.h" -#include "settingswidget.h" -#include "trayicon.h" -#include "xdgiconlookup.h" -using Core::ExtensionManager; - -static void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &message); -static void shutdownHandler(int); -static void dispatchMessage(); - - -static QApplication *app; -static QueryManager *queryManager; -static MainWindow *mainWindow; -static HotkeyManager *hotkeyManager; -static SettingsWidget *settingsWidget; -static TrayIcon *trayIcon; -static QMenu *trayIconMenu; -static QLocalServer *localServer; - - -int Albert::run(int argc, char **argv) { - - { - bool showSettingsWhenInitialized = false; - - /* - * INITIALIZE APPLICATION - */ - - qInstallMessageHandler(myMessageOutput); - - app = new QApplication(argc, argv); - app->setApplicationName("albert"); - app->setApplicationDisplayName("Albert"); - app->setApplicationVersion("v0.12.0"); - app->setQuitOnLastWindowClosed(false); - QString icon = XdgIconLookup::iconPath("albert"); - if ( icon.isEmpty() ) icon = ":app_icon"; - app->setWindowIcon(QIcon(icon)); - - QString socketPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/socket"; - - // Set link color applicationwide to cyan - QPalette palette(qApp->palette()); - palette.setColor(QPalette::Link, QColor("#00CCCC")); - qApp->setPalette(palette); - - /* - * PARSE COMMANDLINE - */ - - QCommandLineParser parser; - parser.setApplicationDescription("Albert is still in alpha. These options may change in future versions."); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addOption(QCommandLineOption({"k", "hotkey"}, "Overwrite the hotkey to use.", "hotkey")); - parser.addOption(QCommandLineOption({"p", "plugin-dirs"}, "Set the plugin dirs to use. Comma separated.", "directory")); - parser.addPositionalArgument("command", "Command to send to a running instance, if any. (show, hide, toggle)", "[command]"); - parser.process(*app); - - - /* - * START IPC CLIENT - */ - - const QStringList args = parser.positionalArguments(); - QLocalSocket socket; - socket.connectToServer(socketPath); - if ( socket.waitForConnected(500) ) { - // If there is a command send it - if ( args.count() == 1 ){ - socket.write(args.at(0).toLocal8Bit()); - socket.flush(); - socket.waitForReadyRead(500); - if (socket.bytesAvailable()) - qDebug() << socket.readAll(); - } - else - qDebug("There is another instance of albert running."); - socket.close(); - ::exit(EXIT_SUCCESS); - } else if ( args.count() == 1 ) { - qDebug("There is no other instance of albert running."); - ::exit(EXIT_FAILURE); - } - - - /* - * INITIALIZE PATHS - */ - - // Make sure data, cache and config dir exists - QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); - QString configLocation = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); - for ( const QString &location : {dataLocation, cacheLocation, configLocation} ) - if (!QDir(location).mkpath(".")) - qFatal("Could not create dir: %s", qPrintable(location)); - - // Move old config for user convenience TODO drop somewhen - QFileInfo oldcfg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/albert/albert.conf"); - QFileInfo newcfg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/albert.conf"); - if (oldcfg.exists()){ - if (newcfg.exists()) - QFile::remove(newcfg.path()); - QFile::rename(oldcfg.filePath(), newcfg.filePath()); - oldcfg.dir().removeRecursively(); - } - - - /* - * DETECT FIRST RUN AND VERSION CHANGE - */ - - // If there is a file in .cache, move it - if ( QFile::exists(QString("%1/firstrun").arg(cacheLocation)) ) - QFile::rename(QString("%1/firstrun").arg(cacheLocation), - QString("%1/firstrun").arg(dataLocation)); - - // If there is a firstRun file, rename it to lastVersion (since v0.11) - if ( QFile::exists(QString("%1/firstrun").arg(dataLocation)) ) - QFile::rename(QString("%1/firstrun").arg(dataLocation), - QString("%1/last_used_version").arg(dataLocation)); - - QFile file(QString("%1/last_used_version").arg(dataLocation)); - if ( file.exists() ) { - // Read last used version - if ( file.open(QIODevice::ReadOnly|QIODevice::Text) ) { - QString lastUsedVersion; - QTextStream(&file) >> lastUsedVersion; - file.close(); - - // Show newsbox in case of major version change - if ( app->applicationVersion().section('.', 1, 1) != lastUsedVersion.section('.', 1, 1) ){ - // Do whatever is neccessary on first run - QMessageBox(QMessageBox::Information, "Major version changed", - QString("You are now using Albert %1. Albert is still in the alpha " - "stage. This means things may change unexpectedly. Check " - "the " - "news to read about the things that changed.") - .arg(app->applicationVersion()) - ).exec(); - } - } - else - qCritical() << qPrintable(QString("Could not open file %1: %2,. Config migration may fail.") - .arg(file.fileName(), file.errorString())); - } else { - // Do whatever is neccessary on first run - if ( QMessageBox(QMessageBox::Information, "First run", - "Seems like this is the first time you run Albert. " - "Most probably you want to set a hotkey to show " - "Albert. Do you want to open the settings dialog?", - QMessageBox::No|QMessageBox::Yes).exec() == QMessageBox::Yes ) - showSettingsWhenInitialized = true; - } - - // Write the current version into the file - if ( file.open(QIODevice::WriteOnly|QIODevice::Text) ) { - QTextStream out(&file); - out << app->applicationVersion(); - file.close(); - } else - qCritical() << qPrintable(QString("Could not open file %1: %2").arg(file.fileName(), file.errorString())); - - - /* - * INITIALIZE DATABASE - */ - - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); - if ( !db.isValid() ) - qFatal("No sqlite available"); - - if (!db.driver()->hasFeature(QSqlDriver::Transactions)) - qFatal("QSqlDriver::Transactions not available."); - - db.setDatabaseName(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)).filePath("core.db")); - if (!db.open()) - qFatal("Unable to establish a database connection."); - - db.transaction(); - - // Create tables - QSqlQuery q; - if (!q.exec("CREATE TABLE IF NOT EXISTS usages ( " - " input TEXT NOT NULL, " - " itemId TEXT, " - " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP " - ");")) - qFatal("Unable to create table 'usages': %s", q.lastError().text().toUtf8().constData()); - - if (!q.exec("CREATE TABLE IF NOT EXISTS runtimes ( " - " extensionId TEXT NOT NULL, " - " runtime INTEGER NOT NULL, " - " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP " - ");")) - qFatal("Unable to create table 'runtimes': %s", q.lastError().text().toUtf8().constData()); - - // Do regular cleanup - if (!q.exec("DELETE FROM usages WHERE julianday('now')-julianday(timestamp)>90;")) - qWarning("Unable to cleanup usages table."); - - if (!q.exec("DELETE FROM runtimes WHERE julianday('now')-julianday(timestamp)>7;")) - qWarning("Unable to cleanup runtimes table."); - - db.commit(); - - - /* - * INITIALIZE APPLICATION COMPONENTS - */ - - ExtensionManager::instance = new Core::ExtensionManager; - trayIcon = new TrayIcon; - trayIconMenu = new QMenu; - hotkeyManager = new HotkeyManager; - mainWindow = new MainWindow; - queryManager = new QueryManager(ExtensionManager::instance); - localServer = new QLocalServer; - - - /* - * START IPC SERVER - */ - - // Remove pipes potentially leftover after crash - QLocalServer::removeServer(socketPath); - - // Create server and handle messages - if ( !localServer->listen(socketPath) ) - qWarning() << "Local server could not be created. IPC will not work! Reason:" << localServer->errorString(); - - // Handle incomin messages - QObject::connect(localServer, &QLocalServer::newConnection, dispatchMessage); - - - /* - * Build Tray Icon - */ - - QAction* showAction = new QAction("Show", trayIconMenu); - QAction* settingsAction = new QAction("Settings", trayIconMenu); - QAction* quitAction = new QAction("Quit", trayIconMenu); - - showAction->setIcon(app->style()->standardIcon(QStyle::SP_TitleBarMaxButton)); - settingsAction->setIcon(app->style()->standardIcon(QStyle::SP_FileDialogDetailedView)); - quitAction->setIcon(app->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); - - trayIconMenu->addAction(showAction); - trayIconMenu->addAction(settingsAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(quitAction); - - trayIcon->setContextMenu(trayIconMenu); - - - /* - * Alfred demarcation - */ - - QSettings settings(qApp->applicationName()); - bool alfred_note_shown = settings.value("alfred_note_shown", false).toBool(); - if ( !alfred_note_shown ) { - QMessageBox(QMessageBox::Information, "Note", - "This is standalone free and open source software. This project is not " - "related or affiliated to any other projects or corporations.").exec(); - settings.setValue("alfred_note_shown", true); - } - - - /* - * Hotkey - */ - - // Check for a command line override - QString hotkey; - if ( parser.isSet("hotkey") ) { - hotkey = parser.value("hotkey"); - if ( !hotkeyManager->registerHotkey(hotkey) ) - qFatal("Failed to set hotkey to %s.", hotkey.toLocal8Bit().constData()); - - // Check if the settings contains a hotkey entry - } else if ( settings.contains("hotkey") ) { - hotkey = settings.value("hotkey").toString(); - if ( !hotkeyManager->registerHotkey(hotkey) ){ - if ( QMessageBox(QMessageBox::Critical, "Error", - QString("Failed to set hotkey: '%1'. Do you want to open the settings?").arg(hotkey), - QMessageBox::No|QMessageBox::Yes).exec() == QMessageBox::Yes ) - showSettingsWhenInitialized = true; - } - } - - - /* - * MISC - */ - - // Quit gracefully on unix signals - for ( int sig : { SIGINT, SIGTERM, SIGHUP, SIGPIPE } ) - signal(sig, shutdownHandler); - - // Print a message if the app was not terminated graciously - QString filePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/running"; - if (QFile::exists(filePath)){ - qWarning() << "Application has not been terminated graciously."; - } else { - // Create the running indicator file - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly)) - qWarning() << "Could not create file:" << filePath; - file.close(); - } - - // Check for a plugin override - if ( parser.isSet("plugin-dirs") ) - Core::ExtensionManager::instance->setPluginDirs(parser.value("plugin-dirs").split(',')); - - // Load extensions - Core::ExtensionManager::instance->reloadExtensions(); - - // Application is initialized create the settings widget - settingsWidget = new SettingsWidget(mainWindow, hotkeyManager, ExtensionManager::instance, trayIcon); - - // If somebody requested the settings dialog open it - if ( showSettingsWhenInitialized ) - settingsWidget->show(); - - - /* - * SIGNALING - */ - - QObject::connect(hotkeyManager, &HotkeyManager::hotKeyPressed, - mainWindow, &MainWindow::toggleVisibility); - - QObject::connect(queryManager, &QueryManager::resultsReady, - mainWindow, &MainWindow::setModel); - - QObject::connect(showAction, &QAction::triggered, - mainWindow, &MainWindow::show); - - QObject::connect(settingsAction, &QAction::triggered, - settingsWidget, &SettingsWidget::show); - - QObject::connect(settingsAction, &QAction::triggered, - settingsWidget, &SettingsWidget::raise); - - QObject::connect(quitAction, &QAction::triggered, - app, &QApplication::quit); - - QObject::connect(trayIcon, &TrayIcon::activated, [](QSystemTrayIcon::ActivationReason reason){ - if( reason == QSystemTrayIcon::ActivationReason::Trigger) - mainWindow->toggleVisibility(); - }); - - - QObject::connect(mainWindow, &MainWindow::settingsWidgetRequested, - std::bind(&SettingsWidget::setVisible, settingsWidget, true)); - - QObject::connect(mainWindow, &MainWindow::settingsWidgetRequested, - settingsWidget, &SettingsWidget::raise); - - QObject::connect(mainWindow, &MainWindow::widgetShown, - queryManager, &QueryManager::setupSession); - - QObject::connect(mainWindow, &MainWindow::widgetHidden, - queryManager, &QueryManager::teardownSession); - - QObject::connect(mainWindow, &MainWindow::inputChanged, - queryManager, &QueryManager::startQuery); - - } - - - /* - * ENTER EVENTLOOP - */ - - int retval = app->exec(); - - - /* - * FINALIZE APPLICATION - */ - - delete settingsWidget; - delete trayIconMenu; - delete trayIcon; - delete queryManager; - delete hotkeyManager; - delete mainWindow; - delete ExtensionManager::instance; - - localServer->close(); - - // Delete the running indicator file - QFile::remove(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/running"); - - return retval; -} - - -/** ***************************************************************************/ -void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &message) { - QString suffix; - if (context.function) - suffix = QString(" -- [%1]").arg(context.function); - switch (type) { -#if QT_VERSION >= 0x050500 - case QtInfoMsg: -#endif - case QtDebugMsg: - fprintf(stderr, "%s\n", message.toLocal8Bit().constData()); - break; - case QtWarningMsg: - fprintf(stderr, "\x1b[33;1mWarning:\x1b[0;1m %s%s\x1b[0m\n", message.toLocal8Bit().constData(), suffix.toLocal8Bit().constData()); - break; - case QtCriticalMsg: - fprintf(stderr, "\x1b[31;1mCritical:\x1b[0;1m %s%s\x1b[0m\n", message.toLocal8Bit().constData(), suffix.toLocal8Bit().constData()); - break; - case QtFatalMsg: - fprintf(stderr, "\x1b[41;30;4mFATAL:\x1b[0;1m %s%s\x1b[0m\n", message.toLocal8Bit().constData(), suffix.toLocal8Bit().constData()); - exit(1); - } -} - - - -/** ***************************************************************************/ -void shutdownHandler(int) { - QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection); -} - - - -/** ***************************************************************************/ -void dispatchMessage() { - QLocalSocket* socket = localServer->nextPendingConnection(); // Should be safe - socket->waitForReadyRead(500); - if (socket->bytesAvailable()) { - QString msg = QString::fromLocal8Bit(socket->readAll()); - if ( msg == "show") { - mainWindow->setVisible(true); - socket->write("Application set visible."); - } else if ( msg == "hide") { - mainWindow->setVisible(false); - socket->write("Application set invisible."); - } else if ( msg == "toggle") { - mainWindow->toggleVisibility(); - socket->write("Visibility toggled."); - } else - socket->write("Command not supported."); - } - socket->flush(); - socket->close(); - socket->deleteLater(); -} - diff -Nru albert-0.12.0/src/lib/albert/src/albert/extensionmanager.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/extensionmanager.cpp --- albert-0.12.0/src/lib/albert/src/albert/extensionmanager.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/extensionmanager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,222 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "extensionmanager.h" -#include "extensionspec.h" -using std::set; -using std::unique_ptr; -using std::vector; -using std::chrono::system_clock; - -Core::ExtensionManager *Core::ExtensionManager::instance = nullptr; - -/** ***************************************************************************/ -class Core::ExtensionManagerPrivate { -public: - vector> extensionSpecs_; // TASK: Rename _ - set extensions_; - set pluginDirs; -}; - - -/** ***************************************************************************/ -Core::ExtensionManager::ExtensionManager() : d(new ExtensionManagerPrivate) { - // DO NOT LOAD EXTENSIONS HERE! - - // Get plugindirs -#if defined __linux__ - - QStringList dirs = { - "/usr/lib/", "/usr/local/lib/", "/usr/lib64/", "/usr/local/lib64/", - QDir::home().filePath(".local/lib/"), - QDir::home().filePath(".local/lib64/") - }; - - for ( const QString& dir : dirs ) { - QFileInfo fileInfo = QFileInfo(QDir(dir).filePath("albert/plugins")); - if ( fileInfo.isDir() ) - d->pluginDirs.insert(fileInfo.canonicalFilePath()); - } - -#elif defined __APPLE__ - throw "Not implemented"; -#elif defined _WIN32 - throw "Not implemented"; -#endif - -} - - -/** ***************************************************************************/ -Core::ExtensionManager::~ExtensionManager() { - for (unique_ptr & extensionSpec : d->extensionSpecs_) - unloadExtension(extensionSpec); -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::setPluginDirs(const QStringList &dirs) { - d->pluginDirs.insert(dirs.begin(), dirs.end()); -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::reloadExtensions() { - - // Unload everything - for (unique_ptr & extensionSpec : d->extensionSpecs_) - unloadExtension(extensionSpec); - - d->extensionSpecs_.clear(); - - // Iterate over all files in the plugindirs - for (const QString &pluginDir : d->pluginDirs) { - QDirIterator dirIterator(pluginDir, QDir::Files); - while (dirIterator.hasNext()) { - dirIterator.next(); - - QString path = dirIterator.fileInfo().canonicalFilePath(); - - // Check if this path is a lib - if ( !QLibrary::isLibrary(path) ) { - qWarning() << "File is not a library:" << path; - continue; - } - - QPluginLoader loader(path); - - if ( loader.metaData().empty() ) { - qWarning() << qPrintable(QString("Metadata empty. Is this a QPlugin? (%1)").arg(path)); - continue; - } - - // Check for a sane interface ID (IID) - QString iid = loader.metaData()["IID"].toString(); - if (iid != ALBERT_EXTENSION_IID) { - qWarning() << qPrintable(QString("Extension IDs do not match. App:'%1'. Ext: '%2' (%3)") - .arg(ALBERT_EXTENSION_IID, iid, path)); - continue; - } - - // Check for duplicates - QString id = loader.metaData()["MetaData"].toObject()["id"].toString(); - if (std::any_of(d->extensionSpecs_.begin(), d->extensionSpecs_.end(), - [&id](const unique_ptr & spec){ return id == spec->id(); })) { - qWarning() << qPrintable(QString("Extension IDs already exists. Skipping. (%1)").arg(path)); - continue; - } - - // Put it to the results - d->extensionSpecs_.emplace_back(new ExtensionSpec(path)); - } - } - - // Sort alphabetically - std::sort(d->extensionSpecs_.begin(), - d->extensionSpecs_.end(), - [](const unique_ptr& lhs, const unique_ptr& rhs){ return lhs->name() < rhs->name(); }); - - // Load if enabled - QSettings settings(qApp->applicationName()); - for (unique_ptr & extensionSpec : d->extensionSpecs_){ - QString configName = QString("%1/enabled").arg(extensionSpec->id()); - if ( (settings.contains(configName) && settings.value(configName).toBool()) - || (!settings.contains(configName) && extensionSpec->enabledByDefault()) ) - loadExtension(extensionSpec); - } -} - - -/** ***************************************************************************/ -const vector>& Core::ExtensionManager::extensionSpecs() const { - return d->extensionSpecs_; -} - - -/** ***************************************************************************/ -const set Core::ExtensionManager::objects() const { - return d->extensions_; -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::loadExtension(const unique_ptr &spec) { - if (spec->state() != ExtensionSpec::State::Loaded){ -// system_clock::time_point start = system_clock::now(); - if ( spec->load() ) { -// TODO wrtie to database -// auto msecs = std::chrono::duration_cast(system_clock::now()-start); -// qDebug() << QString("Loading %1 done in %2 milliseconds").arg(spec->id()).arg(msecs.count()).toLocal8Bit().data(); - d->extensions_.insert(spec->instance()); - } else - qDebug() << QString("Loading %1 failed. (%2)").arg(spec->id(), spec->lastError()).toLocal8Bit().data(); - } -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::unloadExtension(const unique_ptr &spec) { - if (spec->state() != ExtensionSpec::State::NotLoaded) { - d->extensions_.erase(spec->instance()); - spec->unload(); - } -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::enableExtension(const unique_ptr &extensionSpec) { - QSettings(qApp->applicationName()).setValue(QString("%1/enabled").arg(extensionSpec->id()), true); - loadExtension(extensionSpec); -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::disableExtension(const unique_ptr &extensionSpec) { - QSettings(qApp->applicationName()).setValue(QString("%1/enabled").arg(extensionSpec->id()), false); - unloadExtension(extensionSpec); -} - - -/** ***************************************************************************/ -bool Core::ExtensionManager::extensionIsEnabled(const unique_ptr &extensionSpec) { - QSettings settings(qApp->applicationName()); - QString configName = QString("%1/enabled").arg(extensionSpec->id()); - return ( (settings.contains(configName) && settings.value(configName).toBool()) - || (!settings.contains(configName) && extensionSpec->enabledByDefault()) ); -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::registerObject(QObject *object) { - d->extensions_.insert(object); -} - - -/** ***************************************************************************/ -void Core::ExtensionManager::unregisterObject(QObject *object) { - d->extensions_.erase(object); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/extensionspec.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/extensionspec.cpp --- albert-0.12.0/src/lib/albert/src/albert/extensionspec.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/extensionspec.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include "extensionspec.h" -#include "extension.h" - - - -/** ***************************************************************************/ -Core::ExtensionSpec::ExtensionSpec(const QString &path) - : loader_(path), state_(State::NotLoaded) { - - id_ = loader_.metaData()["MetaData"].toObject()["id"].toString(); - enabledByDefault_ = loader_.metaData()["MetaData"].toObject()["enabledbydefault"].toBool(); - name_ = loader_.metaData()["MetaData"].toObject()["name"].toString(); - version_ = loader_.metaData()["MetaData"].toObject()["version"].toString(); - author_ = loader_.metaData()["MetaData"].toObject()["author"].toString(); - for (QVariant &var : loader_.metaData()["MetaData"].toObject()["dependencies"].toArray().toVariantList()) - dependencies_.push_back(var.toString()); -} - - - -/** ***************************************************************************/ -Core::ExtensionSpec::~ExtensionSpec() { - -} - - - -/** ***************************************************************************/ -bool Core::ExtensionSpec::load(){ - - if ( state_ == State::Loaded ) - return true; - - if ( loader_.load() ) { - state_ = State::Loaded; - } else { - state_ = State::Error; - lastError_ = loader_.errorString(); - } - return state_==State::Loaded; -} - - - -/** ***************************************************************************/ -bool Core::ExtensionSpec::unload(){ -// if ( loader_.unload() ) { -// state_ = State::NotLoaded; -// } else { -// state_ = State::Error; -// lastError_ = loader_.errorString(); -// qWarning() << "Failed to unload extension:" << lastError_.toLocal8Bit().data(); -// } -// return state_==State::NotLoaded; - - /* - * Never really unload a plugin, since otherwise all objects instanciated by - * this extension (items, widgets, etc) and spread all over the app would - * have to be deleted. This is a lot of work an nobody cares about that - * little amount of extra KBs in RAM until next restart. - */ - if ( state_ == State::NotLoaded ) - return true; - - delete instance(); - state_ = State::NotLoaded; - return true; - -} - - - -/** ***************************************************************************/ -QString Core::ExtensionSpec::lastError() const { - return (state_==State::Error) ? lastError_ : QString(); -} - - - -/** ***************************************************************************/ -QObject *Core::ExtensionSpec::instance() { - - auto errorHandler = [this]() { - state_ = State::Error; - qWarning() << id() << "Failed to instanciate extension:" << lastError_.toLocal8Bit().data(); - return nullptr; - }; - - try { - return (state_==State::Loaded) ? loader_.instance() : nullptr; - } catch (const std::exception& ex) { - lastError_ = ex.what(); - return errorHandler(); - } catch (const std::string& s) { - lastError_ = QString::fromStdString(s); - return errorHandler(); - } catch (const QString& s) { - lastError_ = s; - return errorHandler(); - } catch (const char *s) { - lastError_ = s; - return errorHandler(); - } catch (...) { - lastError_ = "Unkown exception in extension constructor."; - return errorHandler(); - } -} - - - -/** ***************************************************************************/ -QString Core::ExtensionSpec::path() const { - return loader_.fileName(); -} - - - -/** ***************************************************************************/ -QString Core::ExtensionSpec::id() const { - return id_; -} - - - -/** ***************************************************************************/ -QString Core::ExtensionSpec::name() const { - return name_; -} - - - -/** ***************************************************************************/ -QString Core::ExtensionSpec::version() const { - return version_; -} - - - -/** ***************************************************************************/ -QString Core::ExtensionSpec::author() const { - return author_; -} - - - -/** ***************************************************************************/ -QStringList Core::ExtensionSpec::dependencies() const { - return dependencies_; -} - -/** ***************************************************************************/ -bool Core::ExtensionSpec::enabledByDefault() const { - return enabledByDefault_; -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/extensionspec.h albert-0.13.1+plugins1/src/lib/albert/src/albert/extensionspec.h --- albert-0.12.0/src/lib/albert/src/albert/extensionspec.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/extensionspec.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include - -namespace Core { - -class Extension; - -class ExtensionSpec final -{ -public: - - enum class State { - Loaded, - NotLoaded, - Error - }; - - ExtensionSpec(const QString &path); - ~ExtensionSpec(); - - State state() { return state_; } - bool load(); - bool unload(); - QString lastError() const; - QObject *instance(); - QString path() const; - - // Metadata - QString id() const; - QString name() const; - QString version() const; - QString author() const; - QStringList dependencies() const; - bool enabledByDefault() const; - -private: - - QPluginLoader loader_; - State state_; - QString lastError_; - - // Metadata - QString id_; - QString name_; - QString version_; - QString author_; - QStringList dependencies_; - bool enabledByDefault_; - -}; - -} - - - - diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/actionlist.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/actionlist.cpp --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/actionlist.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/actionlist.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include "actionlist.h" - -/** ***************************************************************************/ -ActionList::ActionList(QWidget *parent) : ResizingList(parent) { - setItemDelegate(new ActionDelegate); -} - - - -/** ***************************************************************************/ -bool ActionList::eventFilter(QObject*, QEvent *event) { - - if (event->type() == QEvent::KeyPress) { - QKeyEvent* keyEvent = static_cast(event); - switch (keyEvent->key()) { - - // Navigation - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_PageUp: - case Qt::Key_PageDown: - case Qt::Key_Home: - case Qt::Key_End: - // Activation - case Qt::Key_Enter: - case Qt::Key_Return: - keyPressEvent(keyEvent); - return false; - } - } - return false; -} - - - -/** ***************************************************************************/ -void ActionList::ActionDelegate::paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { - - painter->save(); - - QStyleOptionViewItem option = options; - initStyleOption(&option, index); - - // Draw selection - option.widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, option.widget); - - // Draw text - painter->setFont(option.font); - QString text = QFontMetrics(option.font).elidedText(index.data(Qt::DisplayRole).toString(), option.textElideMode, option.rect.width()); - option.widget->style()->drawItemText(painter, - option.rect, - Qt::AlignCenter|Qt::AlignHCenter, - option.palette, - option.state & QStyle::State_Enabled, - text, - (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::WindowText); - painter->restore(); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/actionlist.h albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/actionlist.h --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/actionlist.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/actionlist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "resizinglist.h" -#include - -/** ***************************************************************************/ -class ActionList final : public ResizingList -{ - Q_OBJECT - class ActionDelegate; - -public: - - ActionList(QWidget *parent = 0); - -private: - - bool eventFilter(QObject*, QEvent *event) override; - -}; - - - -/** ***************************************************************************/ -class ActionList::ActionDelegate final : public QStyledItemDelegate -{ -public: - - ActionDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} - - void paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override; -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/history.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/history.cpp --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/history.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/history.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include "history.h" - - -History::History(QObject *parent) : QObject(parent) { - currentLine_ = -1; // This means historymode is not active -} - - -/** ***************************************************************************/ -void History::add(QString str) { - if (!str.isEmpty()){ - if (lines_.contains(str)) - lines_.removeAll(str); // Remove dups - lines_.prepend(str); - } -} - - -/** ***************************************************************************/ -QString History::next() { - // Update the history at the beginnig - if (currentLine_ == -1) - updateHistory(); - - if (currentLine_+1 < static_cast(lines_.size()) - && static_cast(lines_.size())!=0 ) { - ++currentLine_; - return lines_[currentLine_]; - } else return QString(); -} - - -/** ***************************************************************************/ -QString History::prev() { - if (0 < currentLine_) { - --currentLine_; - return lines_[currentLine_]; - } else return QString(); -} - - -/** ***************************************************************************/ -void History::resetIterator() { - currentLine_ = -1; -} - - -/** ***************************************************************************/ -void History::updateHistory() { - lines_.clear(); - QSqlQuery query; - query.exec("SELECT input FROM usages GROUP BY input ORDER BY max(timestamp) DESC"); - while (query.next()) - lines_.append(query.value(0).toString()); -} - diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/history.h albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/history.h --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/history.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/history.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include - -class History final : public QObject -{ - Q_OBJECT - -public: - - History(QObject *parent = 0); - - Q_INVOKABLE void add(QString str); - Q_INVOKABLE QString next(); - Q_INVOKABLE QString prev(); - Q_INVOKABLE void resetIterator(); - -private: - - void updateHistory(); - - QStringList lines_; - int currentLine_; - -}; - diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/mainwindow.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/mainwindow.cpp --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/mainwindow.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/mainwindow.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,631 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "mainwindow.h" - -namespace { - -const char* CFG_WND_POS = "windowPosition"; -const char* CFG_CENTERED = "showCentered"; -const bool DEF_CENTERED = true; -const char* CFG_THEME = "theme"; -const char* DEF_THEME = "Bright"; -const char* CFG_HIDE_ON_FOCUS_LOSS = "hideOnFocusLoss"; -const bool DEF_HIDE_ON_FOCUS_LOSS = true; -const char* CFG_HIDE_ON_CLOSE = "hideOnClose"; -const bool DEF_HIDE_ON_CLOSE = false; -const char* CFG_CLEAR_ON_HIDE = "clearOnHide"; -const bool DEF_CLEAR_ON_HIDE = false; -const char* CFG_ALWAYS_ON_TOP = "alwaysOnTop"; -const bool DEF_ALWAYS_ON_TOP = true; -const char* CFG_MAX_PROPOSALS = "itemCount"; -const uint8_t DEF_MAX_PROPOSALS = 5; -const char* CFG_DISPLAY_SCROLLBAR = "displayScrollbar"; -const bool DEF_DISPLAY_SCROLLBAR = false; -const char* CFG_DISPLAY_ICONS = "displayIcons"; -const bool DEF_DISPLAY_ICONS = true; -const char* CFG_DISPLAY_SHADOW = "displayShadow"; -const bool DEF_DISPLAY_SHADOW = true; - -} - - -/** ***************************************************************************/ -MainWindow::MainWindow(QWidget *parent) - : QWidget(parent), - actionsShown_(false), - historyMoveMod_(Qt::ControlModifier) { - - // INITIALIZE UI - ui.setupUi(this); - setWindowTitle(qAppName()); - setWindowFlags(Qt::Tool - | Qt::WindowCloseButtonHint // No close event w/o this - | Qt::FramelessWindowHint); - setAttribute(Qt::WA_TranslucentBackground); - - QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect(); - effect->setBlurRadius(20); - effect->setColor(QColor(0, 0, 0 , 192 )) ; - effect->setXOffset(0.0); - effect->setYOffset(3.0); - setGraphicsEffect(effect); - - // Disable tabbing completely - ui.actionList->setFocusPolicy(Qt::NoFocus); - ui.proposalList->setFocusPolicy(Qt::NoFocus); - - // Set initial event filter pipeline: window -> proposallist -> lineedit - ui.inputLine->installEventFilter(ui.proposalList); - ui.inputLine->installEventFilter(this); - - // Set stringlistmodel for actions view - actionsListModel_ = new QStringListModel(this); - ui.actionList->setModel(actionsListModel_); - - // Hide lists - ui.actionList->hide(); - ui.proposalList->hide(); - - // Settings button - settingsButton_ = new SettingsButton(this); - settingsButton_->setObjectName("settingsButton"); - settingsButton_->setFocusPolicy(Qt::NoFocus); - settingsButton_->setContextMenuPolicy(Qt::ActionsContextMenu); - - // Context menu of settingsbutton - QAction *action = new QAction("Settings", settingsButton_); - action->setShortcuts({QKeySequence("Ctrl+,"), QKeySequence("Alt+,")}); - connect(action, &QAction::triggered, this, &MainWindow::hide); - connect(action, &QAction::triggered, this, &MainWindow::settingsWidgetRequested); - connect(settingsButton_, &QPushButton::clicked, action, &QAction::trigger); - settingsButton_->addAction(action); - - action = new QAction("Hide", settingsButton_); - action->setShortcut(QKeySequence("Esc")); - connect(action, &QAction::triggered, this, &MainWindow::hide); - settingsButton_->addAction(action); - - action = new QAction("Separator", settingsButton_); - action->setSeparator(true); - settingsButton_->addAction(action); - - action = new QAction("Quit", settingsButton_); - action->setShortcut(QKeySequence("Alt+F4")); - connect(action, &QAction::triggered, qApp, &QApplication::quit); - settingsButton_->addAction(action); - - // History - history_ = new History(this); - - /* - * Settings - */ - - QSettings s(qApp->applicationName()); - setShowCentered(s.value(CFG_CENTERED, DEF_CENTERED).toBool()); - if (!showCentered() && s.contains(CFG_WND_POS) && s.value(CFG_WND_POS).canConvert(QMetaType::QPoint)) - move(s.value(CFG_WND_POS).toPoint()); - setHideOnFocusLoss(s.value(CFG_HIDE_ON_FOCUS_LOSS, DEF_HIDE_ON_FOCUS_LOSS).toBool()); - setHideOnClose(s.value(CFG_HIDE_ON_CLOSE, DEF_HIDE_ON_CLOSE).toBool()); - setClearOnHide(s.value(CFG_CLEAR_ON_HIDE, DEF_CLEAR_ON_HIDE).toBool()); - setAlwaysOnTop(s.value(CFG_ALWAYS_ON_TOP, DEF_ALWAYS_ON_TOP).toBool()); - setMaxProposals(s.value(CFG_MAX_PROPOSALS, DEF_MAX_PROPOSALS).toInt()); - setDisplayScrollbar(s.value(CFG_DISPLAY_SCROLLBAR, DEF_DISPLAY_SCROLLBAR).toBool()); - setDisplayIcons(s.value(CFG_DISPLAY_ICONS, DEF_DISPLAY_ICONS).toBool()); - setDisplayShadow(s.value(CFG_DISPLAY_SHADOW, DEF_DISPLAY_SHADOW).toBool()); - theme_ = s.value(CFG_THEME, DEF_THEME).toString(); - if (!setTheme(theme_)) { - qFatal("FATAL: Stylefile not found: %s", theme_.toStdString().c_str()); - qApp->quit(); - } - - - /* - * Signals - */ - - // Trigger query, if text changed - connect(ui.inputLine, &QLineEdit::textChanged, this, &MainWindow::inputChanged); - - // Hide the actionview, if text was changed - connect(ui.inputLine, &QLineEdit::textChanged, this, &MainWindow::hideActions); - - // Reset history, if text was manually changed - connect(ui.inputLine, &QLineEdit::textEdited, history_, &History::resetIterator); - - // Hide the actionview, if another item gets clicked - connect(ui.proposalList, &ProposalList::pressed, this, &MainWindow::hideActions); - - // Trigger default action, if item in proposallist was activated - QObject::connect(ui.proposalList, &ProposalList::activated, [this](const QModelIndex &index){ - - switch (qApp->queryKeyboardModifiers()) { - case Qt::MetaModifier: // Default fallback action (Meta) - ui.proposalList->model()->setData(index, -1, Qt::UserRole+101); - break; - default: // DefaultAction - ui.proposalList->model()->setData(index, -1, Qt::UserRole+100); - break; - } - - // Do not move this up! (Invalidates index) - history_->add(ui.inputLine->text()); - this->setVisible(false); - ui.inputLine->clear(); - }); - - // Trigger alternative action, if item in actionList was activated - QObject::connect(ui.actionList, &ActionList::activated, [this](const QModelIndex &index){ - history_->add(ui.inputLine->text()); - ui.proposalList->model()->setData(ui.proposalList->currentIndex(), index.row(), Qt::UserRole); - this->setVisible(false); - ui.inputLine->clear(); - }); -} - - - -/** ***************************************************************************/ -void MainWindow::setVisible(bool visible) { - - // Skip if nothing to do - if ( (isVisible() && visible) || !(isVisible() || visible) ) - return; - - QWidget::setVisible(visible); - - if (visible) { - // Move widget after showing it since QWidget::move works only on widgets - // that have been shown once. Well as long as this does not introduce ugly - // flicker this may be okay. - if (showCentered_){ - QDesktopWidget *dw = QApplication::desktop(); - this->move(dw->screenGeometry(dw->screenNumber(QCursor::pos())).center() - -QPoint(rect().right()/2,192 )); - } - this->raise(); - this->activateWindow(); - ui.inputLine->setFocus(); - emit widgetShown(); - } else { - setShowActions(false); - history_->resetIterator(); - ( clearOnHide_ ) ? ui.inputLine->clear() : ui.inputLine->selectAll(); - emit widgetHidden(); - } -} - - -/** ***************************************************************************/ -void MainWindow::toggleVisibility() { - setVisible(!isVisible()); -} - - -/** ***************************************************************************/ -void MainWindow::setInput(const QString &input) { - ui.inputLine->setText(input); -} - - - -/** ***************************************************************************/ -void MainWindow::setModel(QAbstractItemModel *m) { - ui.proposalList->setModel(m); -} - - - -/** ***************************************************************************/ -void MainWindow::setShowCentered(bool b) { - QSettings(qApp->applicationName()).setValue(CFG_CENTERED, b); - showCentered_ = b; -} - - - -/** ***************************************************************************/ -bool MainWindow::showCentered() const { - return showCentered_; -} - - - -/** ***************************************************************************/ -const QString &MainWindow::theme() const { - return theme_; -} - - - -/** ***************************************************************************/ -bool MainWindow::setTheme(const QString &theme) { - theme_ = theme; - QFileInfoList themes; - QStringList themeDirs = QStandardPaths::locateAll( - QStandardPaths::DataLocation, "themes", QStandardPaths::LocateDirectory); - for (const QDir &d : themeDirs) - themes << d.entryInfoList(QStringList("*.qss"), QDir::Files | QDir::NoSymLinks); - // Find and apply the theme - bool success = false; - for (const QFileInfo &fi : themes) { - if (fi.baseName() == theme_) { - QFile f(fi.canonicalFilePath()); - if (f.open(QFile::ReadOnly)) { - QSettings(qApp->applicationName()).setValue(CFG_THEME, theme_); - setStyleSheet(f.readAll()); - f.close(); - success = true; - break; - } - } - } - return success; -} - - - -/** ***************************************************************************/ -bool MainWindow::hideOnFocusLoss() const { - return hideOnFocusLoss_; -} - - - -/** ***************************************************************************/ -void MainWindow::setHideOnFocusLoss(bool b) { - QSettings(qApp->applicationName()).setValue(CFG_HIDE_ON_FOCUS_LOSS, b); - hideOnFocusLoss_ = b; -} - - - -/** ***************************************************************************/ -bool MainWindow::hideOnClose() const { - return hideOnClose_; -} - - - -/** ***************************************************************************/ -void MainWindow::setHideOnClose(bool b) { - QSettings(qApp->applicationName()).setValue(CFG_HIDE_ON_CLOSE, b); - hideOnClose_ = b; -} - - - -/** ***************************************************************************/ -bool MainWindow::clearOnHide() const { - return clearOnHide_; -} - - - -/** ***************************************************************************/ -void MainWindow::setClearOnHide(bool b) { - QSettings(qApp->applicationName()).setValue(CFG_CLEAR_ON_HIDE, b); - clearOnHide_ = b; -} - - - -/** ***************************************************************************/ -bool MainWindow::alwaysOnTop() const { - return windowFlags().testFlag(Qt::WindowStaysOnTopHint); -} - - - -/** ***************************************************************************/ -void MainWindow::setAlwaysOnTop(bool alwaysOnTop) { - QSettings(qApp->applicationName()).setValue(CFG_ALWAYS_ON_TOP, alwaysOnTop); - // TODO: QT_MINREL 5.7 setFlag - alwaysOnTop ? setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint) - : setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); -} - - - -/** ***************************************************************************/ -void MainWindow::setMaxProposals(uint8_t maxItems) { - QSettings(qApp->applicationName()).setValue(CFG_MAX_PROPOSALS, maxItems); - ui.proposalList->setMaxItems(maxItems); -} - - - -/** ***************************************************************************/ -bool MainWindow::displayIcons() const { - return ui.proposalList->displayIcons(); -} - - - -/** ***************************************************************************/ -void MainWindow::setDisplayIcons(bool value) { - QSettings(qApp->applicationName()).setValue(CFG_DISPLAY_ICONS, value); - ui.proposalList->setDisplayIcons(value); -} - - - -/** ***************************************************************************/ -bool MainWindow::displayScrollbar() const { - return ui.proposalList->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff; -} - - - -/** ***************************************************************************/ -void MainWindow::setDisplayScrollbar(bool value) { - QSettings(qApp->applicationName()).setValue(CFG_DISPLAY_SCROLLBAR, value); - ui.proposalList->setVerticalScrollBarPolicy( - value ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); -} - - - -/** ***************************************************************************/ -bool MainWindow::displayShadow() const { - return displayShadow_; -} - - - -/** ***************************************************************************/ -void MainWindow::setDisplayShadow(bool value) { - QSettings(qApp->applicationName()).setValue(CFG_DISPLAY_SHADOW, value); - displayShadow_ = value; - graphicsEffect()->setEnabled(value); - value ? setContentsMargins(20,20,20,20) : setContentsMargins(0,0,0,0); -} - - - -/** ***************************************************************************/ -uint8_t MainWindow::maxProposals() const { - return ui.proposalList->maxItems(); -} - - - -/** ***************************************************************************/ -bool MainWindow::actionsAreShown() const { - return actionsShown_; -} - - - -/** ***************************************************************************/ -void MainWindow::setShowActions(bool showActions) { - - // Show actions - if ( showActions && !actionsShown_ ) { - - // Skip if nothing selected - if ( !ui.proposalList->currentIndex().isValid()) - return; - - // Get actions - actionsListModel_->setStringList(ui.proposalList->model()->data( - ui.proposalList->currentIndex(), - Qt::UserRole).toStringList()); - - // Skip if actions are empty - if (actionsListModel_->rowCount() < 1) - return; - - ui.actionList->setCurrentIndex(actionsListModel_->index(0, 0, ui.actionList->rootIndex())); - ui.actionList->show(); - - // Change event filter pipeline: window -> _action_list -> lineedit - ui.inputLine->removeEventFilter(this); - ui.inputLine->removeEventFilter(ui.proposalList); - ui.inputLine->installEventFilter(ui.actionList); - ui.inputLine->installEventFilter(this); - - // Finally set the state - actionsShown_ = true; - } - - // Hide actions - if ( !showActions && actionsShown_ ) { - - ui.actionList->hide(); - - // Change event filter pipeline: window -> _proposal_list -> lineedit - ui.inputLine->removeEventFilter(this); - ui.inputLine->removeEventFilter(ui.actionList); - ui.inputLine->installEventFilter(ui.proposalList); - ui.inputLine->installEventFilter(this); - - // Finally set the state - actionsShown_ = false; - } -} - - - -/** ***************************************************************************/ -void MainWindow::closeEvent(QCloseEvent *event) { - event->accept(); - if (!hideOnClose_) - qApp->quit(); -} - - - -/** ***************************************************************************/ -void MainWindow::resizeEvent(QResizeEvent *event) { - // Let settingsbutton be in top right corner of frame - settingsButton_->move(ui.frame->geometry().topRight() - QPoint(settingsButton_->width()-1,0)); - QWidget::resizeEvent(event); -} - - - -/** ***************************************************************************/ -void MainWindow::mouseMoveEvent(QMouseEvent *event) { - // Move the widget with the mouse - move(event->globalPos() - clickOffset_); - QWidget::mouseMoveEvent(event); -} - - - -/** ***************************************************************************/ -void MainWindow::mousePressEvent(QMouseEvent *event) { - // Save the offset on press for movement calculations - clickOffset_ = event->pos(); - QWidget::mousePressEvent(event); -} - - - -/** ***************************************************************************/ -void MainWindow::mouseReleaseEvent(QMouseEvent *event) { - // Save the window position () - QSettings(qApp->applicationName()).setValue(CFG_WND_POS, pos()); - QWidget::mousePressEvent(event); -} - - - -/** ***************************************************************************/ -bool MainWindow::eventFilter(QObject *, QEvent *event) { - - if ( event->type() == QEvent::KeyPress ) { - QKeyEvent* keyEvent = static_cast(event); - switch (keyEvent->key()) { - - // Toggle actionsview - case Qt::Key_Tab: - // see query.cpp for userroles - if ( ui.proposalList->currentIndex().isValid() ) - ui.inputLine->setText( - ui.proposalList->model()->data( - ui.proposalList->currentIndex(), Qt::UserRole+1 - ).toString() - ); - return true; - - case Qt::Key_Alt: - setShowActions(true); - return true; - - case Qt::Key_Up:{ - // Move up in the history - if ( !ui.proposalList->currentIndex().isValid() // Empty list - || keyEvent->modifiers() == historyMoveMod_ // MoveMod (Ctrl) hold - || ( !actionsAreShown() // Not in actions state... - && ui.proposalList->currentIndex().row()==0 && !keyEvent->isAutoRepeat() ) ){ // ... and first row (non repeat) - QString next = history_->next(); - if (!next.isEmpty()) - ui.inputLine->setText(next); - return true; - } - } - - // Move down in the history - case Qt::Key_Down:{ - if ( !actionsAreShown() && keyEvent->modifiers() == Qt::ControlModifier ) { - QString prev = history_->prev(); - if (!prev.isEmpty()) - ui.inputLine->setText(prev); - return true; - } - } - } - } - - if ( event->type() == QEvent::KeyRelease ) { - QKeyEvent* keyEvent = static_cast(event); - switch (keyEvent->key()) { - case Qt::Key_Alt: - setShowActions(false); - return true; - } - } - - if (event->type() == QEvent::Wheel) { - QWheelEvent* wheelEvent = static_cast(event); - if ( wheelEvent->angleDelta().y() > 0 ) { - QString next = history_->next(); - if (!next.isEmpty()) - ui.inputLine->setText(next); - } else { - QString prev = history_->prev(); - if (!prev.isEmpty()) - ui.inputLine->setText(prev); - } - } - - return false; -} - - - -/** ***************************************************************************/ -bool MainWindow::event(QEvent *event) { - if (event->type() == QEvent::WindowDeactivate) { - /* This is a horribly hackish but working solution. - - A triggered key grab on X11 steals the focus of the window for short - period of time. This may result in the following annoying behaviour: - When the hotkey is pressed and X11 steals the focus there arises a - race condition between the hotkey event and the focus out event. - When the app is visible and the focus out event is delivered the app - gets hidden. Finally when the hotkey is received the app gets shown - again although the user intended to hide the app with the hotkey. - - Solutions: - Although X11 differs between the two focus out events, qt does not. - One might install a native event filter and use the XCB structs to - decide which type of event is delivered, but this approach is not - platform independent (unless designed so explicitely, but its a - hassle). The behaviour was expected when the app hides on: - - (mode==XCB_NOTIFY_MODE_GRAB && detail==XCB_NOTIFY_DETAIL_NONLINEAR)|| - (mode==XCB_NOTIFY_MODE_NORMAL && detail==XCB_NOTIFY_DETAIL_NONLINEAR) - (Check Xlib Programming Manual) - - The current, much simpler but less elegant solution is to delay the - hiding a few milliseconds, so that the hotkey event will always be - handled first. */ - if (hideOnFocusLoss_){ - // Note fix if least LTS goes beyond Qt5.4 - // QTimer::singleShot(50, this, &MainWindow::hide); - QTimer::singleShot(50, this, SLOT(hide())); - } - } - return QWidget::event(event); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/mainwindow.h albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/mainwindow.h --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/mainwindow.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/mainwindow.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "proposallist.h" -#include "settingsbutton.h" -#include "history.h" -#include "ui_mainwindow.h" -class QAbstractItemModel; - -class MainWindow final : public QWidget -{ - Q_OBJECT - -public: - - MainWindow(QWidget *parent = 0); - - void setVisible(bool visible) override; - void toggleVisibility(); - - void setInput(const QString&); - - bool showCentered() const; - void setShowCentered(bool b = true); - - const QString &theme() const; - bool setTheme(const QString& theme); - - bool hideOnFocusLoss() const; - void setHideOnFocusLoss(bool b = true); - - bool hideOnClose() const; - void setHideOnClose(bool b = true); - - bool clearOnHide() const; - void setClearOnHide(bool b = true); - - bool alwaysOnTop() const; - void setAlwaysOnTop(bool alwaysOnTop); - - uint8_t maxProposals() const; - void setMaxProposals(uint8_t max); - - bool displayIcons() const; - void setDisplayIcons(bool value); - - bool displayScrollbar() const; - void setDisplayScrollbar(bool value); - - bool displayShadow() const; - void setDisplayShadow(bool value); - - void setModel(QAbstractItemModel *); - - bool actionsAreShown() const; - void setShowActions(bool showActions); - void showActions() { setShowActions(true); } - void hideActions() { setShowActions(false); } - -protected: - - void closeEvent(QCloseEvent* event) override; - void mouseMoveEvent(QMouseEvent* event) override; - void mousePressEvent(QMouseEvent * event) override; - void mouseReleaseEvent(QMouseEvent * event) override; - void resizeEvent(QResizeEvent* event) override; - bool event(QEvent *event) override; - bool eventFilter(QObject*, QEvent *event) override; - -private: - - /** The name of the current theme */ - QString theme_; - - /** Indicates that the app should be shown centered */ - bool showCentered_; - - /** Indicates that the app should be hidden on focus loss */ - bool hideOnFocusLoss_; - - /** Indicates that the app should be hidden on close event */ - bool hideOnClose_; - - /** The offset from cursor to topleft. Used when the window is dagged */ - QPoint clickOffset_; - - /** Indcates the state that the app is in */ - bool actionsShown_; - - /** Indcates that a shadow should be drawn */ - bool displayShadow_; - - /** Indcates that the inputline should be cleared on hide */ - bool clearOnHide_; - - /** The model of the action list view */ - QStringListModel *actionsListModel_; - - /** The button to open the settings dialog */ - SettingsButton *settingsButton_; - - /** The input history */ - History *history_; - - /** The modifier used to navigate directly in the history */ - Qt::KeyboardModifier historyMoveMod_; - - /** The form of the main app */ - Ui::MainWindow ui; - -signals: - void widgetShown(); - void widgetHidden(); - void inputChanged(QString qry); - void settingsWidgetRequested(); -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/mainwindow.ui albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/mainwindow.ui --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/mainwindow.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/mainwindow.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ - - - MainWindow - - - - :/app_icon:/app_icon - - - - QLayout::SetFixedSize - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - QAbstractItemView::NoEditTriggers - - - true - - - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QAbstractItemView::NoEditTriggers - - - true - - - - - - - - - - - ProposalList - QListView -
proposallist.h
-
- - ActionList - QListView -
actionlist.h
-
-
- - - - -
diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/proposallist.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/proposallist.cpp --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/proposallist.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/proposallist.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,242 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include "proposallist.h" - -/** ***************************************************************************/ -class ProposalList::ItemDelegate final : public QStyledItemDelegate -{ -public: - ItemDelegate(QObject *parent = nullptr) - : QStyledItemDelegate(parent), drawIcon(true), subTextRole(Qt::ToolTipRole) {} - - void paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override; - - bool drawIcon; - int subTextRole; -}; - - - -/** ***************************************************************************/ -ProposalList::ProposalList(QWidget *parent) : ResizingList(parent) { - setItemDelegate(delegate_ = new ItemDelegate(this)); - - // Single click activation (segfaults without queued connection) - connect(this, &ProposalList::clicked, this, &ProposalList::activated, Qt::QueuedConnection); -} - - - -/** ***************************************************************************/ -bool ProposalList::displayIcons() const { - return delegate_->drawIcon; -} - - - -/** ***************************************************************************/ -void ProposalList::setDisplayIcons(bool value) { - delegate_->drawIcon = value; - update(); -} - - - -/** ***************************************************************************/ -bool ProposalList::eventFilter(QObject*, QEvent *event) { - - if (event->type() == QEvent::KeyPress) { - QKeyEvent* keyEvent = static_cast(event); - switch (keyEvent->key()) { - - // Display different subtexts according to the KeyboardModifiers - case Qt::Key_Control: - case Qt::Key_Shift: - case Qt::Key_Alt: - case Qt::Key_Meta: - switch (keyEvent->modifiers()) { - case Qt::MetaModifier: // Default fallback action (Meta) - delegate_->subTextRole = Qt::UserRole+101; - break; - default: // DefaultAction - delegate_->subTextRole = Qt::ToolTipRole; - break; - } - update(); - return false; - - - // Expose the navigation hidden by the lineedit with the control modifier - case Qt::Key_Home: - case Qt::Key_End: - if ( keyEvent->modifiers() == Qt::ControlModifier ) { - keyPressEvent(keyEvent); - return true; - } - return false; - - // Navigation - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_PageUp: - case Qt::Key_PageDown: - // Activation - case Qt::Key_Enter: - case Qt::Key_Return: - keyPressEvent(keyEvent); - return true; - } - } - - if (event->type() == QEvent::KeyRelease) { - QKeyEvent* keyEvent = static_cast(event); - switch (keyEvent->key()) { - - // Display different subtexts according to the KeyboardModifiers - case Qt::Key_Control: - case Qt::Key_Shift: - case Qt::Key_Alt: - case Qt::Key_Meta: - switch (keyEvent->modifiers()) { - case Qt::MetaModifier: // Default fallback action (Meta) - delegate_->subTextRole = Qt::UserRole+101; - break; - default: // DefaultAction - delegate_->subTextRole = Qt::ToolTipRole; - break; - } - update(); - return false; - } - } - return false; -} - - - -/** ***************************************************************************/ -void ProposalList::showEvent(QShowEvent *event) { - QWidget::showEvent(event); - if (qApp->keyboardModifiers() == Qt::MetaModifier) - delegate_->subTextRole = Qt::UserRole+101; - else - delegate_->subTextRole = Qt::ToolTipRole; -} - - - -/** ***************************************************************************/ -void ProposalList::ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { - - painter->save(); - - QStyleOptionViewItem option = options; - initStyleOption(&option, index); - - /* - * fm(x) := fontmetrics of x - * DR := DisplayRole - * TR := ToolTipRole - * +---------------------+----------------------------------------+ - * | | | - * | +-------------+ | | - * | | | | | - * | | | |a*fm(DR)/(fm(DR)+fm(TR)) DisplayRole | - * a| | icon | | | - * | | | | | - * | | | +----------------------------------------+ - * | | | | | - * | +-------------+ |a*fm(TR)/(fm(DR)+fm(TR)) ToolTipRole+x | - * | | | - * +---------------------------------------------------------------+ - */ - - - // Avoid ugly dark blue mouseover background - // TODO: QT_MINREL 5.7 setFlag - option.state &= ~QStyle::State_MouseOver; - - // Draw selection - option.widget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, option.widget); - - // Draw icon - if ( drawIcon ){ - QRect iconRect = QRect( - QPoint((option.rect.height() - option.decorationSize.width())/2 + option.rect.x(), - (option.rect.height() - option.decorationSize.height())/2 + option.rect.y()), - option.decorationSize); - QPixmap pixmap; - QString iconPath = index.data(Qt::DecorationRole).value(); - QString cacheKey = QString("%1%2%3").arg(option.decorationSize.width(), option.decorationSize.height()).arg(iconPath); - if ( !QPixmapCache::find(cacheKey, &pixmap) ) { - pixmap = QPixmap(iconPath).scaled(option.decorationSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QPixmapCache::insert(cacheKey, pixmap); - } - painter->drawPixmap(iconRect, pixmap); - } - - // Calculate text rects - QFont font1 = option.font; - QFont font2 = option.font; - font2.setPixelSize(12); - QFontMetrics fontMetrics1 = QFontMetrics(font1); - QFontMetrics fontMetrics2 = QFontMetrics(font2); - QRect contentRect = option.rect; - contentRect.setLeft(drawIcon ? option.rect.height() : 0); - contentRect.setTop(option.rect.y()+option.rect.height()/2-(fontMetrics1.height()+fontMetrics2.height())/2); - contentRect.setBottom(option.rect.y()+option.rect.height()/2+(fontMetrics1.height()+fontMetrics2.height())/2); - QRect textRect = contentRect.adjusted(0,-2,0,-fontMetrics2.height()-2); - QRect subTextRect = contentRect.adjusted(0,fontMetrics1.height()-2,0,-2); - - // // Test - // painter->fillRect(iconRect, Qt::magenta); - // painter->fillRect(contentRect, Qt::red); - // painter->fillRect(textRect, Qt::blue); - // painter->fillRect(subTextRect, Qt::yellow); - - - // Draw display role - painter->setFont(font1); - QString text = fontMetrics1.elidedText(index.data(Qt::DisplayRole).toString(), - option.textElideMode, - textRect.width()); - option.widget->style()->drawItemText(painter, - textRect, - option.displayAlignment, - option.palette, - option.state & QStyle::State_Enabled, - text, - (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::WindowText); - - // Draw tooltip role - painter->setFont(font2); - text = fontMetrics2.elidedText(index.data(option.state.testFlag(QStyle::State_Selected)? subTextRole : Qt::ToolTipRole).toString(), - option.textElideMode, - subTextRect.width()); - option.widget->style()->drawItemText(painter, - subTextRect, - Qt::AlignBottom|Qt::AlignLeft, - option.palette, - option.state & QStyle::State_Enabled, - text, - (option.state & QStyle::State_Selected) ? QPalette::HighlightedText : QPalette::WindowText); - painter->restore(); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/proposallist.h albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/proposallist.h --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/proposallist.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/proposallist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "resizinglist.h" -#include - -class ProposalList final : public ResizingList -{ - Q_OBJECT - class ItemDelegate; - -public: - - ProposalList(QWidget *parent = 0); - - bool displayIcons() const; - void setDisplayIcons(bool value); - -private: - - bool eventFilter(QObject*, QEvent *event) override; - void showEvent(QShowEvent *event) override; - - ItemDelegate *delegate_; -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/resizinglist.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/resizinglist.cpp --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/resizinglist.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/resizinglist.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "resizinglist.h" -#include - -/** ***************************************************************************/ -uint8_t ResizingList::maxItems() const { - return maxItems_; -} - - - -/** ***************************************************************************/ -void ResizingList::setMaxItems(uint8_t maxItems) { - maxItems_ = maxItems; - updateGeometry(); -} - - - -/** ***************************************************************************/ -QSize ResizingList::sizeHint() const { - if (model() == nullptr) - return QSize(); - return QSize(width(), sizeHintForRow(0) * std::min(static_cast(maxItems_), model()->rowCount(rootIndex()))); -} - - - -/** ***************************************************************************/ -QSize ResizingList::minimumSizeHint() const { - return QSize(0,0); // Fix for small lists -} - - - -/** ***************************************************************************/ -void ResizingList::setModel(QAbstractItemModel * m) { - if (model() == m) - return; - - if (model()!=nullptr) { - disconnect(this->model(), &QAbstractItemModel::rowsInserted, this, &ResizingList::updateAppearance); - disconnect(this->model(), &QAbstractItemModel::modelReset, this, &ResizingList::updateAppearance); - } - - QItemSelectionModel *sm = selectionModel(); - QAbstractItemView::setModel(m); - delete sm; - updateAppearance(); - - // If not empty show and select first, update geom. If not null connect. - if (model()!=nullptr) { - connect(this->model(), &QAbstractItemModel::rowsInserted, this, &ResizingList::updateAppearance); - connect(this->model(), &QAbstractItemModel::modelReset, this, &ResizingList::updateAppearance); - } -} - - - -/** ***************************************************************************/ -void ResizingList::updateAppearance() { - if ( model() == nullptr || model()->rowCount() == 0 ) - hide(); - else { - show(); - if ( !currentIndex().isValid() ) - setCurrentIndex(model()->index(0, 0)); - updateGeometry(); - } -} - diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/resizinglist.h albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/resizinglist.h --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/resizinglist.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/resizinglist.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include - -class ResizingList : public QListView -{ - Q_OBJECT - Q_PROPERTY(int maxItems READ maxItems WRITE setMaxItems MEMBER maxItems_ NOTIFY maxItemsChanged) - -public: - - ResizingList(QWidget *parent = 0) : QListView(parent), maxItems_(5) {} - virtual ~ResizingList() {} - - uint8_t maxItems() const; - void setMaxItems(uint8_t maxItems); - - QSize minimumSizeHint() const override; - QSize sizeHint() const override; - void setModel(QAbstractItemModel * model) override; - -private: - - void updateAppearance(); - - uint8_t maxItems_; - -signals: - - void maxItemsChanged(); - -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/settingsbutton.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/settingsbutton.cpp --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/settingsbutton.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/settingsbutton.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "settingsbutton.h" -#include -#include -#include -#include -#include -#include -#include - -/** ***************************************************************************/ -SettingsButton::SettingsButton(QWidget *parent) : QPushButton(parent) { - animation_ = new QPropertyAnimation(this, "angle"); - animation_->setDuration(10000); - animation_->setStartValue(0); - animation_->setEndValue(360); - animation_->setLoopCount(-1); - animation_->start(); - connect(animation_, &QPropertyAnimation::valueChanged, this, static_cast(&QWidget::update)); - - svgRenderer_ = new QSvgRenderer(QString(":gear")); - - setCursor(Qt::PointingHandCursor); -} - - - -/** ***************************************************************************/ -SettingsButton::~SettingsButton() { - delete animation_; - delete svgRenderer_; -} - - - -/** ***************************************************************************/ -void SettingsButton::hideEvent(QHideEvent *event) { - animation_->stop(); - QPushButton::hideEvent(event); -} - - - -/** ***************************************************************************/ -void SettingsButton::showEvent(QShowEvent *event) { - animation_->start(); - QPushButton::showEvent(event); -} - - - -/** ***************************************************************************/ -void SettingsButton::paintEvent(QPaintEvent *event) { - QPushButton::paintEvent(event); - - QStyleOptionButton option; - option.initFrom(this); - QRect contentRect = style()->subElementRect(QStyle::SE_PushButtonContents, &option, this); - - // Prepare image in pixmap using mask - QPixmap gearPixmap(contentRect.size()); - QRectF pixmapRect(QPoint(), contentRect.size()); - gearPixmap.fill(Qt::transparent); - QPainter pixmapPainter(&gearPixmap); - pixmapPainter.translate(pixmapRect.center()); - pixmapPainter.rotate(angle_); - svgRenderer_->render(&pixmapPainter, pixmapRect.translated(-pixmapRect.center())); - pixmapPainter.resetTransform(); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); - pixmapPainter.fillRect(pixmapRect, option.palette.windowText().color()); - - // Draw pixmap on button - QPainter painter(this); - painter.drawPixmap(contentRect, gearPixmap); - -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/mainwindow/settingsbutton.h albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/settingsbutton.h --- albert-0.12.0/src/lib/albert/src/albert/mainwindow/settingsbutton.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/mainwindow/settingsbutton.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -class QPropertyAnimation; -class QSvgRenderer; - -class SettingsButton final : public QPushButton -{ - Q_OBJECT - Q_PROPERTY(int angle MEMBER angle_) - -public: - - SettingsButton(QWidget *parent = 0); - ~SettingsButton(); - -protected: - - void hideEvent(QHideEvent * event) override; - void showEvent(QShowEvent * event) override; - -private: - - void paintEvent(QPaintEvent *event) override; - - int angle_; - QPropertyAnimation *animation_; - QSvgRenderer *svgRenderer_; - -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/matchcompare.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/matchcompare.cpp --- albert-0.12.0/src/lib/albert/src/albert/matchcompare.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/matchcompare.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include "item.h" -#include "matchcompare.h" -using namespace std; - - -/** ***************************************************************************/ -map Core::MatchCompare::order; - -/** ***************************************************************************/ -bool Core::MatchCompare::operator()(const pair, short> &lhs, - const pair, short> &rhs) { - // Compare urgency - if (lhs.first->urgency() != rhs.first->urgency()) - return lhs.first->urgency() > rhs.first->urgency(); - - // Compare usage scores - const map::iterator &lit = order.find(lhs.first->id()); - const map::iterator &rit = order.find(rhs.first->id()); - if (lit==order.cend()) // |- lhs zero - if (rit==order.cend()) // |- rhs zero - return lhs.second > rhs.second; // Compare match score - else // |- rhs > 0 - return false; // lhs==0 && rhs>0 implies lhsrhs) - else - if (rit==order.cend()) - return true; // lhs>0 && rhs=0 implies lhs>rhs - else - return lit->second > rit->second; // Both usage scores available, return lhs>rhs -} - - -/** ***************************************************************************/ -void Core::MatchCompare::update() { - order.clear(); - - // Update the results ranking - QSqlQuery query; - query.exec("SELECT t.itemId AS id, SUM(t.score) AS usageScore " - "FROM ( " - " SELECT itemId, 1/max(julianday('now')-julianday(timestamp),1) AS score " - " FROM usages " - " WHERE itemId<>'' " - ") t " - "GROUP BY t.itemId"); - while (query.next()) - MatchCompare::order.emplace(query.value(0).toString(), - query.value(1).toDouble()); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/matchcompare.h albert-0.13.1+plugins1/src/lib/albert/src/albert/matchcompare.h --- albert-0.12.0/src/lib/albert/src/albert/matchcompare.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/matchcompare.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "item.h" - -namespace Core { - -/** - * @brief The MatchOrder class - * The implements the order of the results - */ -class MatchCompare -{ -public: - - static void update(); - bool operator()(const std::pair, short>& lhs, - const std::pair, short>& rhs); - -private: - - static std::map order; -}; - -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/query.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/query.cpp --- albert-0.12.0/src/lib/albert/src/albert/query.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/query.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,451 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "action.h" -#include "extension.h" -#include "item.h" -#include "matchcompare.h" -#include "query.h" -using std::chrono::system_clock; -using namespace std; - - -/** ***************************************************************************/ -class Core::Query::QueryPrivate : public QAbstractListModel -{ -public: - QueryPrivate(Query *q) : q(q), isValid(true), state(State::Idle) { } - - Query *q; - - QString searchTerm; - QString trigger; - bool isValid; - Query::State state; - - set syncHandlers; - set asyncHandlers; - map runtimes; - - vector> results; - vector> fallbacks; - - QTimer fiftyMsTimer; - mutable QMutex pendingResultsMutex; - vector, short>> pendingResults; - - QFuture> future; - QFutureWatcher> futureWatcher; - - - - /** ***************************************************************************/ - void run() { - - if ( !syncHandlers.empty() ) - return runSyncHandlers(); - - emit q->resultsReady(this); - - if ( !asyncHandlers.empty() ) - return runAsyncHandlers(); - - state = State::Finished; - emit q->finished(); - } - - - /** ***************************************************************************/ - pair mappedFunction (QueryHandler* queryHandler) { - system_clock::time_point then = system_clock::now(); - queryHandler->handleQuery(q); - system_clock::time_point now = system_clock::now(); - return std::make_pair(queryHandler, std::chrono::duration_cast(now-then).count()); - } - - - /** ***************************************************************************/ - void runSyncHandlers() { - - // Call onSyncHandlersFinsished when all handlers finished - connect(&futureWatcher, &QFutureWatcher>::finished, - this, &QueryPrivate::onSyncHandlersFinsished); - - // Run the handlers concurrently and measure the runtimes - future = QtConcurrent::mapped(syncHandlers.begin(), - syncHandlers.end(), - std::bind(&QueryPrivate::mappedFunction, this, std::placeholders::_1)); - futureWatcher.setFuture(future); - } - - - /** ***************************************************************************/ - void runAsyncHandlers() { - - // Call onAsyncHandlersFinsished when all handlers finished - disconnect(&futureWatcher, &QFutureWatcher>::finished, - this, &QueryPrivate::onSyncHandlersFinsished); - - connect(&futureWatcher, &QFutureWatcher>::finished, - this, &QueryPrivate::onAsyncHandlersFinsished); - - // Run the handlers concurrently and measure the runtimes - future = QtConcurrent::mapped(asyncHandlers.begin(), - asyncHandlers.end(), - std::bind(&QueryPrivate::mappedFunction, this, std::placeholders::_1)); - futureWatcher.setFuture(future); - - // Insert pending results every 50 milliseconds - connect(&fiftyMsTimer, &QTimer::timeout, this, &QueryPrivate::insertPendingResults); - fiftyMsTimer.start(50); - } - - - - /** ***************************************************************************/ - void onSyncHandlersFinsished() { - - // Save the runtimes of the current future - for ( auto it = future.begin(); it != future.end(); ++it ) - runtimes.emplace(it->first->id, it->second); - - /* - * Publish the results - */ - - // Lock the pending results - QMutexLocker lock(&pendingResultsMutex); - - // Sort the results - std::stable_sort(pendingResults.begin(), - pendingResults.end(), - MatchCompare()); - - // Preallocate space in "results" to avoid multiple allocations - results.reserve(results.size() + pendingResults.size()); - - // Move the items of the "pending results" into "results" - std::transform(pendingResults.begin(), - pendingResults.end(), - std::back_inserter(results), - [](const pair,short>& p){ return std::move(p.first); }); - - pendingResults.clear(); - - emit q->resultsReady(this); - - if ( asyncHandlers.empty() ) - finishQuery(); - else - runAsyncHandlers(); - } - - - /** ***************************************************************************/ - void onAsyncHandlersFinsished() { - - // Save the runtimes of the current future - for ( auto it = future.begin(); it != future.end(); ++it ) - runtimes.emplace(it->first->id, it->second); - - // Finally done - fiftyMsTimer.stop(); - fiftyMsTimer.disconnect(); - insertPendingResults(); - - finishQuery(); - } - - - /** ***************************************************************************/ - void insertPendingResults() { - - if(pendingResults.size()) { - - QMutexLocker lock(&pendingResultsMutex); - - beginInsertRows(QModelIndex(), results.size(), results.size() + pendingResults.size() - 1); - - // Preallocate space to avoid multiple allocatoins - results.reserve(results.size() + pendingResults.size()); - - // Copy the items of the matches into the results - std::transform(pendingResults.begin(), pendingResults.end(), - std::back_inserter(results), - [](const pair,short>& p){ return std::move(p.first); }); - - endInsertRows(); - - // Clear the empty matches - pendingResults.clear(); - } - } - - - /** ***************************************************************************/ - void finishQuery() { - - /* - * If results are empty show fallbacks - */ - - if( results.empty() ){ - beginInsertRows(QModelIndex(), 0, fallbacks.size() - 1); - results.insert(results.end(), - fallbacks.begin(), - fallbacks.end()); - endInsertRows(); - } - - state = State::Finished; - - emit q->finished(); - } - - - /** ***************************************************************************/ - int rowCount(const QModelIndex &) const override { - return static_cast(results.size()); - } - - - - /** ***************************************************************************/ - QVariant data(const QModelIndex &index, int role) const override { - if (index.isValid()) { - const shared_ptr &item = results[static_cast(index.row())]; - - switch (role) { - case Qt::DisplayRole: - return item->text(); - case Qt::ToolTipRole: - return item->subtext(); - case Qt::DecorationRole: - return item->iconPath(); - - case Qt::UserRole: { // Actions list - QStringList actionTexts; - for (const shared_ptr &action : item->actions()) - actionTexts.append(action->text()); - return actionTexts; - } - case Qt::UserRole+1: // Completion string - return item->completionString(); - - case Qt::UserRole+100: // DefaultAction - return (0 < static_cast(item->actions().size())) ? item->actions()[0]->text() : item->subtext(); - case Qt::UserRole+101: // AltAction - return "Search '"+searchTerm+"' using default fallback"; - case Qt::UserRole+102: // MetaAction - return (1 < static_cast(item->actions().size())) ? item->actions()[1]->text() : item->subtext(); - case Qt::UserRole+103: // ControlAction - return (2 < static_cast(item->actions().size())) ? item->actions()[2]->text() : item->subtext(); - case Qt::UserRole+104: // ShiftAction - return (3 < static_cast(item->actions().size())) ? item->actions()[3]->text() : item->subtext(); - default: - return QVariant(); - } - } - return QVariant(); - } - - - - /** ***************************************************************************/ - bool setData(const QModelIndex &index, const QVariant &value, int role) override { - if (index.isValid()) { - shared_ptr &item = results[static_cast(index.row())]; - QString itemId = item->id(); - - switch (role) { - - // Activation by index - case Qt::UserRole:{ - size_t actionValue = static_cast(value.toInt()); - if (actionValue < item->actions().size()) - item->actions()[actionValue]->activate(); - break; - } - - // Activation by modifier - case Qt::UserRole+100: // DefaultAction - if (0U < item->actions().size()) - item->actions()[0]->activate(); - break; - case Qt::UserRole+101: // Default fallback action (Meta) - if (0U < fallbacks.size() && 0U < item->actions().size()) { - fallbacks[0]->actions()[0]->activate(); - itemId = fallbacks[0]->id(); - } - break; - } - - // Save usage - QSqlQuery query; - query.prepare("INSERT INTO usages (input, itemId) VALUES (:input, :itemId);"); - query.bindValue(":input", searchTerm); - query.bindValue(":itemId", item->id()); - if (!query.exec()) - qWarning() << query.lastError(); - } - return false; - } -}; - - - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -Core::Query::Query() : d(new QueryPrivate(this)) { - -} - - -/** ***************************************************************************/ -Core::Query::~Query() { - -} - - -/** ***************************************************************************/ -const Core::Query::State &Core::Query::state() const { - return d->state; -} - - -/** ***************************************************************************/ -const QString &Core::Query::searchTerm() const { - return d->searchTerm; -} - - -/** ***************************************************************************/ -bool Core::Query::isValid() const { - return d->isValid; -} - - -/** ***************************************************************************/ -bool Core::Query::isTriggered() const { - return !d->trigger.isEmpty(); -} - - -/** ***************************************************************************/ -const QString &Core::Query::trigger() const { - return d->trigger; -} - - -/** ***************************************************************************/ -void Core::Query::setTrigger(const QString &trigger) { - d->trigger = trigger; -} - - -/** ***************************************************************************/ -void Core::Query::addMatch(shared_ptr item, short score) { - if ( d->isValid ) { - d->pendingResultsMutex.lock(); - d->pendingResults.push_back({item, score}); - d->pendingResultsMutex.unlock(); - } -} - - -/** ***************************************************************************/ -void Core::Query::addMatches(vector,short>>::iterator begin, - vector,short>>::iterator end) { - if ( d->isValid ) { - d->pendingResultsMutex.lock(); - d->pendingResults.insert(d->pendingResults.end(), - std::make_move_iterator(begin), - std::make_move_iterator(end)); - d->pendingResultsMutex.unlock(); - } -} - - -/** ***************************************************************************/ -std::map Core::Query::runtimes() { - return d->runtimes; -} - - -/** ***************************************************************************/ -void Core::Query::setSearchTerm(const QString &searchTerm) { - d->searchTerm = searchTerm; -} - - -/** ***************************************************************************/ -void Core::Query::invalidate() { - d->isValid = false; -} - - -/** ***************************************************************************/ -void Core::Query::setQueryHandlers(const set &queryHandlers) { - - if (d->state != State::Idle) - return; - - for ( auto handler : queryHandlers ) - if ( handler->isLongRunning() ) - d->asyncHandlers.insert(handler); - else - d->syncHandlers.insert(handler); -} - - -/** ***************************************************************************/ -void Core::Query::setFallbacks(const vector > &fallbacks) { - - if (d->state != State::Idle) - return; - - d->fallbacks = fallbacks; -} - - -/** ***************************************************************************/ -void Core::Query::run() { - - if (d->state != State::Idle) - return; - - d->state = State::Running; - - - d->run(); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/querymanager.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/querymanager.cpp --- albert-0.12.0/src/lib/albert/src/albert/querymanager.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/querymanager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include "extension.h" -#include "extensionmanager.h" -#include "fallbackprovider.h" -#include "item.h" -#include "matchcompare.h" -#include "query.h" -#include "queryhandler.h" -#include "querymanager.h" -using namespace Core; -using std::set; -using std::vector; -using std::shared_ptr; - -/** ***************************************************************************/ -QueryManager::QueryManager(ExtensionManager* em, QObject *parent) - : QObject(parent), - extensionManager_(em), - currentQuery_(nullptr) { - - // Initialize the order - Core::MatchCompare::update(); -} - - - -/** ***************************************************************************/ -void QueryManager::setupSession() { - // Call all setup routines - for (Core::QueryHandler *handler : extensionManager_->objectsByType()) - handler->setupSession(); -} - - - -/** ***************************************************************************/ -void QueryManager::teardownSession() { - - // Call all teardown routines - for (Core::QueryHandler *handler : extensionManager_->objectsByType()) - handler->teardownSession(); - - // Open database to store the runtimes - QSqlDatabase db = QSqlDatabase::database(); - QSqlQuery sqlQuery; - db.transaction(); - - // Delete finished queries and prepare sql transaction containing runtimes - vector::iterator it = pastQueries_.begin(); - while ( it != pastQueries_.end()){ - if ( (*it)->state() != Query::State::Running ) { - - // Store the runtimes - for ( const std::pair &handlerRuntime : (*it)->runtimes() ) { - sqlQuery.prepare("INSERT INTO runtimes (extensionId, runtime) VALUES (:extensionId, :runtime);"); - sqlQuery.bindValue(":extensionId", handlerRuntime.first); - sqlQuery.bindValue(":runtime", handlerRuntime.second); - if (!sqlQuery.exec()) - qWarning() << sqlQuery.lastError(); - } - - // Delete the query - (*it)->deleteLater(); - it = pastQueries_.erase(it); - } else - ++it; - } - - // Finally send the sql transaction - db.commit(); - - // Compute new match rankings - Core::MatchCompare::update(); -} - - - -/** ***************************************************************************/ -void QueryManager::startQuery(const QString &searchTerm) { - - if ( currentQuery_ != nullptr ) { - // Stop last query - disconnect(currentQuery_, &Query::resultsReady, this, &QueryManager::resultsReady); - currentQuery_->invalidate(); - // Store for later deletion (listview still has the model) - pastQueries_.push_back(currentQuery_); - } - - // Do nothing if nothing is loaded - if ( extensionManager_->objects().empty() ) - return; - - // Do nothing if query is empty - if ( searchTerm.trimmed().isEmpty() ) { - currentQuery_ = nullptr; - emit resultsReady(nullptr); - return; - } - - // Start query - currentQuery_ = new Query; - currentQuery_->setSearchTerm(searchTerm); - connect(currentQuery_, &Query::resultsReady, this, &QueryManager::resultsReady); - - // Run with a single handler if the trigger matches - const set availableHandlers = extensionManager_->objectsByType(); - for ( QueryHandler *handler : availableHandlers ) { - for ( const QString& trigger : handler->triggers() ) { - if ( !trigger.isEmpty() && searchTerm.startsWith(trigger) ) { - currentQuery_->setTrigger(trigger); - currentQuery_->setQueryHandlers({handler}); - currentQuery_->run(); - return; - } - } - } - - // Else run all handlers - set handlers; - for ( QueryHandler *handler : availableHandlers ) - handlers.insert(handler); - currentQuery_->setQueryHandlers(handlers); - - // Get fallbacks - vector> fallbacks; - for ( FallbackProvider *extension : extensionManager_->objectsByType() ) { - vector> && tmpFallbacks = extension->fallbacks(searchTerm); - fallbacks.insert(fallbacks.end(), - std::make_move_iterator(tmpFallbacks.begin()), - std::make_move_iterator(tmpFallbacks.end())); - } - - currentQuery_->setFallbacks(fallbacks); - currentQuery_->run(); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/querymanager.h albert-0.13.1+plugins1/src/lib/albert/src/albert/querymanager.h --- albert-0.12.0/src/lib/albert/src/albert/querymanager.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/querymanager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include - -namespace Core { -class ExtensionManager; -class Query; -} - -class QueryManager : public QObject -{ - Q_OBJECT - -public: - - explicit QueryManager(Core::ExtensionManager* em, QObject *parent = 0); - - void setupSession(); - void teardownSession(); - void startQuery(const QString &searchTerm); - -private: - - Core::ExtensionManager *extensionManager_; - Core::Query *currentQuery_; - std::vector pastQueries_; - -signals: - - void resultsReady(QAbstractItemModel*); -}; - diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/grabkeybutton.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/grabkeybutton.cpp --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/grabkeybutton.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/grabkeybutton.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "grabkeybutton.h" - -/** ***************************************************************************/ - -GrabKeyButton::GrabKeyButton(QWidget * parent) : QPushButton(parent) { - waitingForHotkey_ = false; - connect(this, &QPushButton::clicked, - this, &GrabKeyButton::onClick); -} - - - -/** ***************************************************************************/ -GrabKeyButton::~GrabKeyButton() { -} - - - -/** ***************************************************************************/ -void GrabKeyButton::onClick() { - oldText_ = text(); - setText("?"); - grabAll(); -} - - - -/** ***************************************************************************/ -void GrabKeyButton::grabAll() { - grabKeyboard(); - grabMouse(); - waitingForHotkey_ = true; -} - - - -/** ***************************************************************************/ -void GrabKeyButton::releaseAll() { - releaseKeyboard(); - releaseMouse(); - waitingForHotkey_ = false; -} - - - -/** ***************************************************************************/ -void GrabKeyButton::keyPressEvent(QKeyEvent *event) { - if ( waitingForHotkey_ ) { - // Modifier pressed -> update the label - int key = event->key(); - int mods = event->modifiers(); - if(key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Meta ) { - setText(QKeySequence((mods&~Qt::GroupSwitchModifier)|Qt::Key_Question).toString());//QTBUG-45568 - event->accept(); - return; - } - - if(key == Qt::Key_Escape) { - event->accept(); - setText(oldText_); - releaseAll(); // Can not be before since window closes on esc - return; - } - releaseAll(); - - setText(QKeySequence((mods&~Qt::GroupSwitchModifier)|key).toString()); //QTBUG-45568 - emit keyCombinationPressed(mods|key); - return; - } -// QWidget::keyPressEvent( event ); -} - - - -/** ***************************************************************************/ -void GrabKeyButton::keyReleaseEvent(QKeyEvent *event) { - if ( waitingForHotkey_ ) { - // Modifier released -> update the label - int key = event->key(); - if(key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Meta) { - setText(QKeySequence((event->modifiers()&~Qt::GroupSwitchModifier)|Qt::Key_Question).toString());//QTBUG-45568 - event->accept(); - return; - } - return; - } - QWidget::keyReleaseEvent( event ); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/grabkeybutton.h albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/grabkeybutton.h --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/grabkeybutton.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/grabkeybutton.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include - -class GrabKeyButton final : public QPushButton -{ - Q_OBJECT - -public: - GrabKeyButton(QWidget * parent = 0); - ~GrabKeyButton(); - -private: - bool waitingForHotkey_; - QString oldText_; - - void grabAll(); - void releaseAll(); - void onClick(); - void keyPressEvent (QKeyEvent *) override; - void keyReleaseEvent ( QKeyEvent* ) override; - -signals: - void keyCombinationPressed(int); -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/loadermodel.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/loadermodel.cpp --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/loadermodel.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/loadermodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include "loadermodel.h" -#include "extensionmanager.h" -#include "extensionspec.h" -using std::unique_ptr; -using namespace Core; - - - -/** ***************************************************************************/ -LoaderModel::LoaderModel(ExtensionManager* pm, QObject *parent) - : QAbstractListModel(parent), extensionManager_(pm){ -} - - - -/** ***************************************************************************/ -int LoaderModel::rowCount(const QModelIndex &) const { - return static_cast(extensionManager_->extensionSpecs().size()); -} - - - -/** ***************************************************************************/ -QVariant LoaderModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() < 0 || rowCount() <= index.row()) - return QVariant(); - - const unique_ptr &loader = extensionManager_->extensionSpecs()[index.row()]; - - switch (role) { - case Qt::DisplayRole: - return loader->name(); - case Qt::ToolTipRole:{ - QString toolTip; - toolTip = QString("ID: %1\nVersion: %2\nAuthor: %3\n").arg(loader->id(), loader->version(), loader->author()); - if (!loader->lastError().isEmpty()) - toolTip.append(QString("Error: %1\n").arg(loader->lastError())); - if (!loader->dependencies().empty()) - toolTip.append(QString("Dependencies: %1\n").arg(loader->dependencies().join(", "))); - toolTip.append(QString("Path: %1").arg(loader->path())); - return toolTip; - } - case Qt::DecorationRole: - switch (loader->state()) { - case ExtensionSpec::State::Loaded: - return QIcon(":plugin_loaded"); - case ExtensionSpec::State::NotLoaded: - return QIcon(":plugin_notloaded"); - case ExtensionSpec::State::Error: - return QIcon(":plugin_error"); - } - case Qt::CheckStateRole: - return (extensionManager_->extensionIsEnabled(loader))?Qt::Checked:Qt::Unchecked; - default: - return QVariant(); - } -} - - - -/** ***************************************************************************/ -bool LoaderModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (!index.isValid() || index.row() < 0 || rowCount() <= index.row()) - return false; - - switch (role) { - case Qt::CheckStateRole: - if (value == Qt::Checked) - extensionManager_->enableExtension(extensionManager_->extensionSpecs()[index.row()]); - else - extensionManager_->disableExtension(extensionManager_->extensionSpecs()[index.row()]); - dataChanged(index, index, {Qt::CheckStateRole}); - return true; - default: - return false; - } -} - - - -/** ***************************************************************************/ -Qt::ItemFlags LoaderModel::flags(const QModelIndex &) const { - return Qt::ItemIsSelectable - |Qt::ItemIsUserCheckable - |Qt::ItemIsEnabled - |Qt::ItemNeverHasChildren; -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/loadermodel.h albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/loadermodel.h --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/loadermodel.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/loadermodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -namespace Core { -class ExtensionManager; -} - -class LoaderModel final : public QAbstractListModel -{ -public: - LoaderModel(Core::ExtensionManager* pm, QObject *parent = nullptr); - int rowCount(const QModelIndex & parent = QModelIndex()) const override; - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; - Qt::ItemFlags flags(const QModelIndex & index) const override; -private: - Core::ExtensionManager *extensionManager_; -}; - diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/settingswidget.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/settingswidget.cpp --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/settingswidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/settingswidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,345 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "core_globals.h" -#include "extension.h" -#include "extensionspec.h" -#include "extensionmanager.h" -#include "hotkeymanager.h" -#include "loadermodel.h" -#include "mainwindow.h" -#include "settingswidget.h" -#include "trayicon.h" -using Core::Extension; -using Core::ExtensionSpec; -using Core::ExtensionManager; - -namespace { -const char* CFG_TERM = "terminal"; -const char* DEF_TERM = "xterm -e"; -} - -EXPORT_CORE QString terminalCommand; - - -/** ***************************************************************************/ -SettingsWidget::SettingsWidget(MainWindow *mainWindow, - HotkeyManager *hotkeyManager, - ExtensionManager *extensionManager, - TrayIcon *systemTrayIcon, - QWidget *parent, Qt::WindowFlags f) - : QWidget(parent, f), - mainWindow_(mainWindow), - hotkeyManager_(hotkeyManager), - extensionManager_(extensionManager), - trayIcon_(systemTrayIcon) { - - ui.setupUi(this); - - - /* - * GENERAL - */ - - // HOTKEY - QSet hks = hotkeyManager->hotkeys(); - if (hks.size() < 1) - ui.grabKeyButton_hotkey->setText("Press to set hotkey"); - else - ui.grabKeyButton_hotkey->setText(QKeySequence(*hks.begin()).toString()); // OMG - connect(ui.grabKeyButton_hotkey, &GrabKeyButton::keyCombinationPressed, - this, &SettingsWidget::changeHotkey); - - // TRAY - ui.checkBox_showTray->setChecked(trayIcon_->isVisible()); - connect(ui.checkBox_showTray, &QCheckBox::toggled, - trayIcon_, &TrayIcon::setVisible); - - - /* - * MAINWINDOW - */ - - // ALWAYS CENTER - ui.checkBox_center->setChecked(mainWindow_->showCentered()); - connect(ui.checkBox_center, &QCheckBox::toggled, - mainWindow_, &MainWindow::setShowCentered); - - // ALWAYS ON TOP - ui.checkBox_onTop->setChecked(mainWindow_->alwaysOnTop()); - connect(ui.checkBox_onTop, &QCheckBox::toggled, - mainWindow_, &MainWindow::setAlwaysOnTop); - - // HIDE ON FOCUS OUT - ui.checkBox_hideOnFocusOut->setChecked(mainWindow_->hideOnFocusLoss()); - connect(ui.checkBox_hideOnFocusOut, &QCheckBox::toggled, - mainWindow_, &MainWindow::setHideOnFocusLoss); - - // HIDE ON CLOSE - ui.checkBox_hideOnClose->setChecked(mainWindow_->hideOnClose()); - connect(ui.checkBox_hideOnClose, &QCheckBox::toggled, - mainWindow_, &MainWindow::setHideOnClose); - - // CLEAR ON HIDE - ui.checkBox_clearOnHide->setChecked(mainWindow_->clearOnHide()); - connect(ui.checkBox_clearOnHide, &QCheckBox::toggled, - mainWindow_, &MainWindow::setClearOnHide); - - // MAX PROPOSALS - ui.spinBox_proposals->setValue(mainWindow_->maxProposals()); - connect(ui.spinBox_proposals, (void (QSpinBox::*)(int))&QSpinBox::valueChanged, - mainWindow_, &MainWindow::setMaxProposals); - - // DISPLAY SCROLLBAR - ui.checkBox_scrollbar->setChecked(mainWindow_->displayScrollbar()); - connect(ui.checkBox_scrollbar, &QCheckBox::toggled, - mainWindow_, &MainWindow::setDisplayScrollbar); - - // DISPLAY ICONS - ui.checkBox_icons->setChecked(mainWindow_->displayIcons()); - connect(ui.checkBox_icons, &QCheckBox::toggled, - mainWindow_, &MainWindow::setDisplayIcons); - - // DISPLAY SHADOW - ui.checkBox_shadow->setChecked(mainWindow_->displayShadow()); - connect(ui.checkBox_shadow, &QCheckBox::toggled, - mainWindow_, &MainWindow::setDisplayShadow); - - // TERM CMD (TOOOOOOOOOOODOOOOOOOOOO CENTRALIZE THIS) - // Define the (global extern) terminal command - terminalCommand = QSettings(qApp->applicationName()).value(CFG_TERM, DEF_TERM).toString(); - - // Available terms - std::vector> terms { - {"Cool Retro Term", "cool-retro-term -e"}, - {"Gnome Terminal", "gnome-terminal -x"}, - {"Konsole", "konsole -e"}, - {"LXTerminal", "lxterminal -e"}, - {"Mate-Termial", "mate-terminal -x"}, - {"RoxTerm", "roxterm -x"}, - {"Terminator", "terminator -x"}, - {"urxvt", "urxvt -e"}, - {"UXTerm", "uxterm -e"}, - {"XFCE-Terminal", "xfce4-terminal -x"}, - {"XTerm", "xterm -e"} - }; - - // Fill checkbox - for ( ulong i = 0; i < terms.size(); ++i ) { - if ( !QStandardPaths::findExecutable(terms[i].second.split(' ').first()).isEmpty() ){ - ui.comboBox_term->addItem(terms[i].first, terms[i].second); - if ( terms[i].second == terminalCommand ) - ui.comboBox_term->setCurrentIndex(static_cast(ui.comboBox_term->count()-1)); - } - } - ui.comboBox_term->insertSeparator(ui.comboBox_term->count()); - ui.comboBox_term->addItem(tr("Custom")); - - ui.lineEdit_term->setText(terminalCommand); - ui.lineEdit_term->setEnabled(ui.comboBox_term->currentIndex() == ui.comboBox_term->count()-1); - connect(ui.comboBox_term, static_cast(&QComboBox::currentIndexChanged), - [this](int index){ - if ( index != ui.comboBox_term->count()-1) { - terminalCommand = ui.comboBox_term->currentData(Qt::UserRole).toString(); - QSettings(qApp->applicationName()).setValue(CFG_TERM, terminalCommand); - } - ui.lineEdit_term->setEnabled(index == ui.comboBox_term->count()-1); - ui.lineEdit_term->setText(terminalCommand); - }); - - connect(ui.lineEdit_term, &QLineEdit::textEdited, [](QString str){ - terminalCommand = str; - QSettings(qApp->applicationName()).setValue(CFG_TERM, terminalCommand); - }); - - // THEMES - QFileInfoList themes; - int i = 0 ; - QStringList themeDirs = - QStandardPaths::locateAll(QStandardPaths::DataLocation, "themes", - QStandardPaths::LocateDirectory); - for (const QDir &d : themeDirs) - themes << d.entryInfoList(QStringList("*.qss"), QDir::Files | QDir::NoSymLinks); - for (const QFileInfo &fi : themes) { - ui.comboBox_themes->addItem(fi.baseName(), fi.canonicalFilePath()); - if ( fi.baseName() == mainWindow_->theme()) - ui.comboBox_themes->setCurrentIndex(i); - ++i; - } - connect(ui.comboBox_themes, (void (QComboBox::*)(int))&QComboBox::currentIndexChanged, - this, &SettingsWidget::onThemeChanged); - - // Cache - connect(ui.pushButton_clearCache, &QPushButton::clicked, [](){ - QSqlQuery("DELETE FROM usages;"); - }); - - - /* - * PLUGINS - */ - - // Show the plugins. This* widget takes ownership of the model - ui.listView_plugins->setModel(new LoaderModel(extensionManager_, ui.listView_plugins)); - - // Update infos when item is changed - connect(ui.listView_plugins->selectionModel(), &QItemSelectionModel::currentChanged, - this, &SettingsWidget::updatePluginInformations); - - connect(ui.listView_plugins->model(), &QAbstractListModel::dataChanged, - this, &SettingsWidget::onPluginDataChanged); - - // Initially hide the title label - ui.label_pluginTitle->hide(); - - - /* - * ABOUT - */ - - ui.about_text->setText(QString(ui.about_text->text()).replace("___versionstring___", qApp->applicationVersion())); - - QDesktopWidget *dw = QApplication::desktop(); - move(dw->availableGeometry(dw->screenNumber(QCursor::pos())).center() - -QPoint(width()/2,height()/2)); - raise(); - activateWindow(); -} - - - -/** ***************************************************************************/ -void SettingsWidget::updatePluginInformations(const QModelIndex & current) { - // Hidde the placehodler text - QLayoutItem *i = ui.widget_pluginInfos->layout()->takeAt(1); - delete i->widget(); - delete i; - - if (extensionManager_->extensionSpecs()[current.row()]->state() == ExtensionSpec::State::Loaded){ - Extension *extension = dynamic_cast(extensionManager_->extensionSpecs()[current.row()]->instance()); - if (!extension){ - qWarning() << "Cannot cast an object of extension spec to an extension!"; - return; // Should no happen - } - QWidget *pw = extension->widget(); - if ( pw->layout() != nullptr) - pw->layout()->setMargin(0); - ui.widget_pluginInfos->layout()->addWidget(pw);// Takes ownership - ui.label_pluginTitle->setText(extension->name()); - ui.label_pluginTitle->show(); - } - else{ - QString msg("Plugin not loaded.\n%1"); - QLabel *lbl = new QLabel(msg.arg(extensionManager_->extensionSpecs()[current.row()]->lastError())); - lbl->setEnabled(false); - lbl->setAlignment(Qt::AlignCenter); - ui.widget_pluginInfos->layout()->addWidget(lbl); - ui.label_pluginTitle->hide(); - } -} - - - -/** ***************************************************************************/ -void SettingsWidget::changeHotkey(int newhk) { - int oldhk = *hotkeyManager_->hotkeys().begin(); //TODO Make cool sharesdpointer design - - // Try to set the hotkey - if (hotkeyManager_->registerHotkey(newhk)) { - QString hkText(QKeySequence((newhk&~Qt::GroupSwitchModifier)).toString());//QTBUG-45568 - ui.grabKeyButton_hotkey->setText(hkText); - QSettings(qApp->applicationName()).setValue("hotkey", hkText); - hotkeyManager_->unregisterHotkey(oldhk); - } else { - ui.grabKeyButton_hotkey->setText(QKeySequence(oldhk).toString()); - QMessageBox(QMessageBox::Critical, "Error", - QKeySequence(newhk).toString() + " could not be registered.", - QMessageBox::NoButton, - this).exec(); - } -} - - - -/** ***************************************************************************/ -void SettingsWidget::onThemeChanged(int i) { - // Apply and save the theme - QString currentTheme = mainWindow_->theme(); - if (!mainWindow_->setTheme(ui.comboBox_themes->itemText(i))) { - QMessageBox(QMessageBox::Critical, "Error", - "Could not apply theme.", - QMessageBox::NoButton, - this).exec(); - if (!mainWindow_->setTheme(currentTheme)) { - qFatal("Rolling back theme failed."); - } - } -} - - - -/** ***************************************************************************/ -void SettingsWidget::onPluginDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { - Q_UNUSED(bottomRight) - if (topLeft == ui.listView_plugins->currentIndex()) - for (int role : roles) - if (role == Qt::CheckStateRole) - updatePluginInformations(topLeft); -} - - - -/** ***************************************************************************/ -void SettingsWidget::keyPressEvent(QKeyEvent *event) { - if (event->modifiers() == Qt::NoModifier && event->key() == Qt::Key_Escape ) { - close(); - } -} - - - -/** ***************************************************************************/ -void SettingsWidget::closeEvent(QCloseEvent *event) { - if (hotkeyManager_->hotkeys().empty()) { - QMessageBox msgBox(QMessageBox::Critical, "Error", - "Hotkey is invalid, please set it. Press Ok to go "\ - "back to the settings, or press Cancel to quit albert.", - QMessageBox::Close|QMessageBox::Ok, - this); - msgBox.exec(); - if ( msgBox.result() == QMessageBox::Ok ) { - ui.tabs->setCurrentIndex(0); - show(); - } - else - qApp->quit(); - event->ignore(); - return; - } - event->accept(); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/settingswidget.h albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/settingswidget.h --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/settingswidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/settingswidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include "ui_settingswidget.h" -namespace Core { -class ExtensionManager; -} -class HotkeyManager; -class MainWindow; -class TrayIcon; - -class SettingsWidget final : public QWidget -{ - Q_OBJECT - -public: - - SettingsWidget(MainWindow *mainWindow, - HotkeyManager *hotkeyManager, - Core::ExtensionManager *extensionManager, - TrayIcon *trayIcon, - QWidget * parent = 0, Qt::WindowFlags f = 0); - -private: - - void keyPressEvent(QKeyEvent * event) override; - void closeEvent(QCloseEvent * event) override; - void onThemeChanged(int); - void onPluginDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); - void changeHotkey(int); - void updatePluginInformations(const QModelIndex & curr); - - MainWindow *mainWindow_; - HotkeyManager *hotkeyManager_; - Core::ExtensionManager *extensionManager_; - TrayIcon *trayIcon_; - Ui::SettingsDialog ui; - -}; diff -Nru albert-0.12.0/src/lib/albert/src/albert/settingswidget/settingswidget.ui albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/settingswidget.ui --- albert-0.12.0/src/lib/albert/src/albert/settingswidget/settingswidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/settingswidget/settingswidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,639 +0,0 @@ - - - SettingsDialog - - - - 0 - 0 - 720 - 400 - - - - - 720 - 400 - - - - - 1280 - 720 - - - - Settings - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - General - - - - - - - - General - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 0 - 0 - - - - - 120 - 0 - - - - - - - - - - - Hotkey: - - - - - - - Show tray icon: - - - - - - - If this option is enabled, albert displays \nan icon in the system tray. - - - - - - - - - - - - - Appearance - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 0 - 0 - - - - Amount of proposals: - - - - - - - - 0 - 0 - - - - - - - 1 - - - 10 - - - - - - - - 0 - 0 - - - - Theme: - - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Display scrollbar: - - - - - - - - 0 - 0 - - - - If this option is enabled, albert displays -a scrollbar in the results list. - - - - - - - - 0 - 0 - - - - Display icons: - - - - - - - - 0 - 0 - - - - If this option is enabled, albert displays -icons provided by the items. - - - - - - - Display shadow: - - - - - - - - 0 - 0 - - - - If this option is enabled, albert displays a -shadow below the widget. Note that the -shadow area appears to be transparent, -but it is not for mouse clicks due to Qt -limitations. However its just a handful of -pixels and you can use it to drag the window. - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Behaviour - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 0 - 0 - - - - Always on top: - - - - - - - - 0 - 0 - - - - If this option is enabled, albert will -stay on top of all top level windows. - - - - - - - - 0 - 0 - - - - Always center Albert: - - - - - - - - 0 - 0 - - - - If this option is enabled, albert -centers the main window in the -screen where the pointer resides. - - - - - - - - 0 - 0 - - - - Hide on focus out: - - - - - - - - 0 - 0 - - - - Hide the main window, if it lost keyboard focus, -e.g. by clicking on another app or changing the -window with Alt+Tab. Note that this feature is -automatically disabled as long as the settings -widget is open. - - - - - - - - 0 - 0 - - - - Hide on close: - - - - - - - - 0 - 0 - - - - If the user closes the main window, the main window -gets hidden instead of the application getting quit. - - - - - - - Clear on hide: - - - - - - - - - - - - - - Terminal command: - - - - - - - - 0 - 0 - - - - - - - - This is the command that is used to start -terminal applications, i.e. applications -that use a textual user interface. - - - - - - - - 0 - 0 - - - - Clear history/usage - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - Plugins - - - - - - - - - 0 - 0 - - - - - 200 - 0 - - - - - 200 - 16777215 - - - - Qt::ScrollBarAlwaysOff - - - true - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - font-size: 12pt;padding-bottom: 5px; - - - - - - - false - - - Select a plugin. - - - Qt::AlignCenter - - - - - - - - - - - About - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - :/app_icon - - - false - - - Qt::AlignCenter - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html> -<head> -<meta name="qrichtext" content="1" /> -<style type="text/css"> -p, li { white-space: pre-wrap; } -</style> -</head> -<body> -<h2>Albert launcher ___versionstring___</h2> -<p>If you encounter bugs or think you have suggestions for improvement, tell me at <a href="https://github.com/ManuelSchneid3r/albert/issues">Github</a>.</p> -<p>If you really like this software please consider a donation via <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=W74BQPKPGNSNC">PayPal</a> or become a <a href="https://www.patreon.com/albertlauncher">patron</a>.</p> -<p>I'd like to thank all <a href="https://github.com/albertlauncher/albert/graphs/contributors">contributors</a>, <a href="https://albertlauncher.github.io/docs/contributing/#supporters">supporters</a> and users. You keep this project going on.</p> -</body> -</html> - - - Qt::AlignCenter - - - true - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - GrabKeyButton - QPushButton -
grabkeybutton.h
-
-
- - - - -
diff -Nru albert-0.12.0/src/lib/albert/src/albert/trayicon.cpp albert-0.13.1+plugins1/src/lib/albert/src/albert/trayicon.cpp --- albert-0.12.0/src/lib/albert/src/albert/trayicon.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/trayicon.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include "trayicon.h" - -namespace { - const char* CFG_SHOWTRAY = "showTray"; - const bool DEF_SHOWTRAY = true; -} - -/** ***************************************************************************/ -TrayIcon::TrayIcon() { - setIcon(qApp->windowIcon()); - if (QSettings(qApp->applicationName()).value(CFG_SHOWTRAY, DEF_SHOWTRAY).toBool()) - setVisible(true); -} - - -/** ***************************************************************************/ -void TrayIcon::setVisible(bool enable) { - QSettings(qApp->applicationName()).setValue(CFG_SHOWTRAY, enable); - QSystemTrayIcon::setVisible(enable); - emit stateChanged(enable); -} diff -Nru albert-0.12.0/src/lib/albert/src/albert/trayicon.h albert-0.13.1+plugins1/src/lib/albert/src/albert/trayicon.h --- albert-0.12.0/src/lib/albert/src/albert/trayicon.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/albert/trayicon.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include - -class TrayIcon : public QSystemTrayIcon -{ - Q_OBJECT - -public: - - TrayIcon(); - - void setVisible(bool = true); - -signals: - - void stateChanged(bool); -}; diff -Nru albert-0.12.0/src/lib/albert/src/offlineindex/fuzzysearch.cpp albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/fuzzysearch.cpp --- albert-0.12.0/src/lib/albert/src/offlineindex/fuzzysearch.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/fuzzysearch.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,255 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include "fuzzysearch.h" -#include "indexable.h" -#include "prefixsearch.h" -using std::map; -using std::set; -using std::pair; -using std::shared_ptr; -using std::vector; - -namespace { - -bool checkPrefixEditDistance(const QString &prefix, const QString &str, uint delta) { - uint n = prefix.size() + 1; - uint m = std::min(prefix.size() + delta + 1, static_cast(str.size()) + 1); - - uint* matrix = new uint[n*m]; - - // Initialize left and top row. - for (uint i = 0; i < n; ++i) { matrix[i*m+0] = i; } - for (uint i = 0; i < m; ++i) { matrix[0*m+i] = i; } - - // Now fill the whole matrix. - for (uint i = 1; i < n; ++i) { - for (uint j = 1; j < m; ++j) { - uint dia = matrix[(i-1)*m+j-1] + (prefix[i-1] == str[j-1] ? 0 : 1); - matrix[i*m+j] = std::min(std::min( - dia, - matrix[i*m+j-1] + 1), - matrix[(i-1)*m+j] + 1); - } - } - - // Check the last row if there is an entry <= delta. - bool result = false; - for (uint j = 0; j < m; ++j) { - if (matrix[(n-1)*m+j] <= delta) { - result = true; - break; - } - } - delete[] matrix; - return result; -} - -} - - - -/** ***************************************************************************/ -Core::FuzzySearch::FuzzySearch(uint q, double d) : q_(q), delta_(d) { - -} - - - -/** ***************************************************************************/ -Core::FuzzySearch::FuzzySearch(const Core::PrefixSearch &rhs, uint q, double d) - : PrefixSearch(rhs), q_(q), delta_(d) { - // Iterate over the inverted index and build the qGramindex - for ( const std::pair> &invertedIndexEntry : invertedIndex_ ) { - QString spaced = QString(q_-1,' ').append(invertedIndexEntry.first); - for (uint i = 0 ; i < static_cast(invertedIndexEntry.first.size()); ++i) - ++qGramIndex_[spaced.mid(i,q_)][invertedIndexEntry.first]; - } -} - - - -/** ***************************************************************************/ -Core::FuzzySearch::~FuzzySearch() { - -} - - - -/** ***************************************************************************/ -void Core::FuzzySearch::add(shared_ptr indexable) { - - // Add indexable to the index - index_.push_back(indexable); - uint id = static_cast(index_.size()-1); - - // Add a mappings to the inverted index which maps on t. - vector indexKeywords = indexable->indexKeywords(); - for (const auto &wkw : indexKeywords) { - QStringList words = wkw.keyword.split(QRegularExpression(SEPARATOR_REGEX), QString::SkipEmptyParts); - for (QString &w : words) { - - // Make this search case insensitive - w=w.toLower(); - - // Add word to inverted index (map word to item) - this->invertedIndex_[w].insert(id); - - // Build a qGram index (map substring to word) - QString spaced = QString(q_-1,' ').append(w); - for (uint i = 0 ; i < static_cast(w.size()); ++i) - ++qGramIndex_[spaced.mid(i,q_)][w]; //FIXME Currently occurences are not uses - } - } -} - - - -/** ***************************************************************************/ -void Core::FuzzySearch::clear() { - qGramIndex_.clear(); - invertedIndex_.clear(); - index_.clear(); -} - - - -/** ***************************************************************************/ -vector > Core::FuzzySearch::search(const QString &req) const { - vector words; - for (QString &word : req.split(QRegularExpression(SEPARATOR_REGEX), QString::SkipEmptyParts)) - words.push_back(word.toLower()); - vector> resultsPerWord; // id, count - - // Quit if there are no words in query - if (words.empty()) - return vector>(); - - // Split the query into words - for (QString &word : words) { - - uint delta = static_cast((delta_ < 1)? word.size()*delta_ : delta_); - - // Generate the qGrams of this word - map qGrams; - QString spaced(q_-1,' '); - spaced.append(word.toLower()); - for ( uint i = 0; i < static_cast(word.size()); ++i ) - ++qGrams[spaced.mid(i,q_)]; - - // Get the words referenced by each qGram and count the references - map wordMatches; - for ( const pair &qGram : qGrams) { - - // Find the qGram in the index, skip if nothing found - decltype(qGramIndex_)::const_iterator qGramIndexIt = qGramIndex_.find(qGram.first); - if ( qGramIndexIt == qGramIndex_.end() ) - continue; - - // Iterate over the set of words referenced by this qGram - for (const pair &indexEntry : qGramIndexIt->second) { - // CRUCIAL: The match can contain only the commom amount of qGrams - wordMatches[indexEntry.first] += std::min(qGram.second, indexEntry.second); - } - } - - // Unite the items referenced by the words accumulating their #matches - map results; // id, count - for (const pair &wordMatch : wordMatches) { - - /* - * Do some kind of (cheap) preselection by mathematical bound - * If the matched word has less than |word|-δ*q matching qGrams - * it cannot be a match. - * This is because a single error can reduce the common qGram by - * maximum q. δ errors can therefore reduce the common qGrams by - * maximum δ*q. If the common qGrams are less than |word|-δ*q this - * implies that there are more errors than δ. - */ - if (wordMatch.second < (word.size()-delta*q_) ) - continue; - - // Now check the (expensive) prefix edit distance - if (!checkPrefixEditDistance(word, wordMatch.first, delta)) - continue; - - // Checks should not be neccessary since this builds on the index - for(uint id : invertedIndex_.at(wordMatch.first)) { - results[id] += wordMatch.second; - } - } - - resultsPerWord.push_back(std::move(results)); - } - - // Intersect the set of items references by the (referenced) words - // This assusmes that there is at least one word (the query would not have - // been started elsewise) - vector> finalResult; - if (resultsPerWord.size() > 1) { - // Get the smallest list for intersection (performance) - uint smallest=0; - for (uint i = 1; i < static_cast(resultsPerWord.size()); ++i) - if (resultsPerWord[i].size() < resultsPerWord[smallest].size()) - smallest = i; - - bool allResultsContainEntry; - for (map::const_iterator r = resultsPerWord[smallest].begin(); - r != resultsPerWord[smallest].cend(); ++r) { - // Check if all results contain this entry - allResultsContainEntry=true; - uint accMatches = resultsPerWord[smallest][r->first]; - for (uint i = 0; i < static_cast(resultsPerWord.size()); ++i) { - // Ignore itself - if (i==smallest) - continue; - - // If it is in: check next relutlist - if (resultsPerWord[i].find(r->first) != resultsPerWord[i].end() ) { - // Accumulate matches - accMatches += resultsPerWord[i][r->first]; - continue; - } - - allResultsContainEntry = false; - break; - } - - // If this is not common, check the next entry - if (!allResultsContainEntry) - continue; - - // Finally this match is common an can be put into the results - finalResult.push_back(std::make_pair(r->first, accMatches)); - } - } else {// Else do it without intersction - for ( const pair &result : resultsPerWord[0] ) - finalResult.push_back(std::make_pair(result.first, result.second)); - } - - // Sort em by relevance // TODO INTRODUCE RELEVANCE TO ITEMS - // std::sort(finalResult.begin(), finalResult.end(), - // [](QPair x, QPair y) - // {return x.second > y.second;}); - vector> result; - for (const pair &pair : finalResult) { - result.push_back(index_.at(pair.first)); - } - return result; -} - - diff -Nru albert-0.12.0/src/lib/albert/src/offlineindex/fuzzysearch.h albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/fuzzysearch.h --- albert-0.12.0/src/lib/albert/src/offlineindex/fuzzysearch.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/fuzzysearch.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include "prefixsearch.h" - -namespace Core { - -class FuzzySearch final : public PrefixSearch -{ -public: - - explicit FuzzySearch(uint q = 3, double d = 1.0/3); - explicit FuzzySearch(const PrefixSearch& rhs, uint q = 3, double d = 1.0/3); - ~FuzzySearch(); - - void add(std::shared_ptr idxble) override; - void clear() override; - std::vector> search(const QString &req) const override; - inline double delta() const {return delta_;} - inline void setDelta(double d){delta_=d;} - -private: - - // Map of qGrams, containing their word references and #occurences - typedef std::map> QGramIndex; - QGramIndex qGramIndex_; - - // Size of the slices - uint q_; - - // Maximum error - double delta_; -}; - -} diff -Nru albert-0.12.0/src/lib/albert/src/offlineindex/indeximpl.h albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/indeximpl.h --- albert-0.12.0/src/lib/albert/src/offlineindex/indeximpl.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/indeximpl.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include - -namespace Core { - -class Indexable; - -class IndexImpl -{ -public: - virtual ~IndexImpl() {} - virtual void add(std::shared_ptr idxble) = 0; - virtual void clear() = 0; - virtual std::vector> search(const QString &req) const = 0; - -protected: - static constexpr const char* SEPARATOR_REGEX = "[!?<>\"'=+*.:,;\\\\\\/ _\\-]+"; - -}; - -} diff -Nru albert-0.12.0/src/lib/albert/src/offlineindex/offlineindex.cpp albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/offlineindex.cpp --- albert-0.12.0/src/lib/albert/src/offlineindex/offlineindex.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/offlineindex.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -#include "offlineindex.h" -#include "indeximpl.h" -#include "indexable.h" -#include "prefixsearch.h" -#include "fuzzysearch.h" - - -/** ***************************************************************************/ -Core::OfflineIndex::OfflineIndex(bool fuzzy) { - (fuzzy) ? impl_ = new FuzzySearch() : impl_ = new PrefixSearch(); -} - - - -/** ***************************************************************************/ -Core::OfflineIndex::~OfflineIndex() { - delete impl_; -} - - - -/** ***************************************************************************/ -void Core::OfflineIndex::setFuzzy(bool fuzzy) { - if (dynamic_cast(impl_)) { - if (fuzzy) return; - FuzzySearch *old = dynamic_cast(impl_); - impl_ = new PrefixSearch(*old); - delete old; - } else if (dynamic_cast(impl_)) { - if (!fuzzy) return; - PrefixSearch *old = dynamic_cast(impl_); - impl_ = new FuzzySearch(*old); - delete old; - } else { - throw; //should not happen - } -} - - - -/** ***************************************************************************/ -bool Core::OfflineIndex::fuzzy() { - return dynamic_cast(impl_) != nullptr; -} - - - -/** ***************************************************************************/ -void Core::OfflineIndex::setDelta(double d) { - FuzzySearch* f = dynamic_cast(impl_); - if (f) - f->setDelta(d); -} - - - -/** ***************************************************************************/ -double Core::OfflineIndex::delta() { - FuzzySearch* f = dynamic_cast(impl_); - if (f) - return f->delta(); - return 0; -} - - - -/** ***************************************************************************/ -void Core::OfflineIndex::add(std::shared_ptr idxble) { - impl_->add(idxble); -} - - - -/** ***************************************************************************/ -void Core::OfflineIndex::clear() { - impl_->clear(); -} - - - -/** ***************************************************************************/ -std::vector > Core::OfflineIndex::search(const QString &req) const { - return impl_->search(req); -} diff -Nru albert-0.12.0/src/lib/albert/src/offlineindex/prefixsearch.cpp albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/prefixsearch.cpp --- albert-0.12.0/src/lib/albert/src/offlineindex/prefixsearch.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/prefixsearch.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include "indeximpl.h" -#include "indexable.h" -#include "prefixsearch.h" -using std::map; -using std::set; -using std::shared_ptr; -using std::vector; - - - -/** ***************************************************************************/ -Core::PrefixSearch::PrefixSearch(){ - -} - - - -/** ***************************************************************************/ -Core::PrefixSearch::PrefixSearch(const Core::PrefixSearch &rhs) { - index_ = rhs.index_; - invertedIndex_ = rhs.invertedIndex_; -} - - - -/** ***************************************************************************/ -Core::PrefixSearch::~PrefixSearch(){} - - - -/** ***************************************************************************/ -void Core::PrefixSearch::add(shared_ptr indexable) { - - // Add indexable to the index - index_.push_back(indexable); - uint id = static_cast(index_.size()-1); - - vector indexKeywords = indexable->indexKeywords(); - for (const auto &wkw : indexKeywords) { - // Build an inverted index - QStringList words = wkw.keyword.split(QRegularExpression(SEPARATOR_REGEX), QString::SkipEmptyParts); - for (const QString &w : words) { - invertedIndex_[w.toLower()].insert(id); - } - } -} - - - -/** ***************************************************************************/ -void Core::PrefixSearch::clear() { - invertedIndex_.clear(); - index_.clear(); -} - - - -/** ***************************************************************************/ -vector > Core::PrefixSearch::search(const QString &req) const { - - - // Split the query into words W - QStringList words = req.split(QRegularExpression(SEPARATOR_REGEX), QString::SkipEmptyParts); - - // Skip if there arent any // CONSTRAINT (2): |W| > 0 - if (words.empty()) - return vector>(); - - set resultsSet; - QStringList::iterator wordIterator = words.begin(); - - // Make lower for case insensitivity - QString word = wordIterator++->toLower(); - - // Get a word mapping once before going to handle intersections - for (std::map>::const_iterator lb = invertedIndex_.lower_bound(word); - lb != invertedIndex_.cend() && lb->first.startsWith(word); ++lb) - resultsSet.insert(lb->second.begin(), lb->second.end()); - - - for (;wordIterator != words.end(); ++wordIterator) { - - // Make lower for case insensitivity - word = wordIterator->toLower(); - - // Unite the sets that are mapped by words that begin with word - // w ∈ W. This set is called U_w - set wordMappingsUnion; - for (std::map>::const_iterator lb = invertedIndex_.lower_bound(word); - lb != invertedIndex_.cend() && lb->first.startsWith(word); ++lb) - wordMappingsUnion.insert(lb->second.begin(), lb->second.end()); - - - // Intersect all sets U_w with the results - set intersection; - std::set_intersection(resultsSet.begin(), resultsSet.end(), - wordMappingsUnion.begin(), wordMappingsUnion.end(), - std::inserter(intersection, intersection.begin())); - resultsSet = std::move(intersection); - } - - // Convert to a std::vector - - - - vector> resultsVector; - for (uint id : resultsSet) - resultsVector.emplace_back(index_.at(id)); - return resultsVector; -} diff -Nru albert-0.12.0/src/lib/albert/src/offlineindex/prefixsearch.h albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/prefixsearch.h --- albert-0.12.0/src/lib/albert/src/offlineindex/prefixsearch.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/offlineindex/prefixsearch.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include "indeximpl.h" - -namespace Core { - -class Indexable; - -class PrefixSearch : public IndexImpl -{ -public: - - PrefixSearch(); - PrefixSearch(const PrefixSearch &rhs); - virtual ~PrefixSearch(); - - void add(std::shared_ptr idxble) override; - void clear() override; - std::vector> search(const QString &req) const override; - -protected: - - std::vector> index_; - std::map> invertedIndex_; -}; - - - - - - - - - - - - - - - - - - - - - - - - -// class CaseInsensitiveCompare; -// class CaseInsensitiveComparePrefix; - -//template -//struct PrefixSearch::CaseInsensitiveCompare -//{ -// inline bool operator()( Posting const &lhs, Posting const &rhs ) const { -// return (*this)(lhs.first, rhs.first); -// } - -// inline bool operator()( QString const &lhs, Posting const &rhs ) const { -// return (*this)(lhs, rhs.first); -// } - -// inline bool operator()( Posting const &lhs, QString const &rhs ) const { -// return (*this)(lhs.first, rhs); -// } - -// inline bool operator()( QString const &lhs, QString const &rhs ) const { -// return lhs.compare(rhs, Qt::CaseInsensitive)<0; -// } -//}; - -///** ***************************************************************************/ -//template -//struct PrefixSearch::CaseInsensitiveComparePrefix -//{ -// inline bool operator()( Posting const &pre, Posting const &rhs ) const { -// return (*this)(pre.first, rhs.first); -// } - -// inline bool operator()( QString const &pre, Posting const &rhs ) const { -// return (*this)(pre, rhs.first); -// } - -// inline bool operator()( Posting const &pre, QString const &rhs ) const { -// return (*this)(pre.first, rhs); -// } - -// inline bool operator()( QString const& pre, QString const& rhs ) const { -// QString::const_iterator a,b; -// a = pre.cbegin(); -// b = rhs.cbegin(); -// QChar ca,cb; -// while (a != pre.cend() && b != rhs.cend()) { -// ca = a++->toLower(); -// cb = b++->toLower(); -// if (ca < cb) -// return true; -// if (ca > cb) -// return false; -// } -// return false; -// } -//}; - -} diff -Nru albert-0.12.0/src/lib/albert/src/standardobjects/standardaction.cpp albert-0.13.1+plugins1/src/lib/albert/src/standardobjects/standardaction.cpp --- albert-0.12.0/src/lib/albert/src/standardobjects/standardaction.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/standardobjects/standardaction.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "standardaction.h" -using std::function; - -Core::StandardAction::StandardAction(){ - -} - -Core::StandardAction::StandardAction(const QString &text, function f) - : text_(text), action_(f) { -} - -QString Core::StandardAction::text() const { - return text_; -} - -void Core::StandardAction::setText(const QString &text){ - text_ = text; -} - -const function &Core::StandardAction::action() { - return action_; -} - -void Core::StandardAction::setAction(function &&action){ - action_ = action; -} - -void Core::StandardAction::activate() { - action_(); -} diff -Nru albert-0.12.0/src/lib/albert/src/standardobjects/standardindexitem.cpp albert-0.13.1+plugins1/src/lib/albert/src/standardobjects/standardindexitem.cpp --- albert-0.12.0/src/lib/albert/src/standardobjects/standardindexitem.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/standardobjects/standardindexitem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "standardindexitem.h" -using std::vector; -using namespace Core; - -StandardIndexItem::StandardIndexItem(const QString &id) : StandardItem(id) { - -} - -std::vector StandardIndexItem::indexKeywords() const { - return indexKeywords_; -} - -void StandardIndexItem::setIndexKeywords(vector &&indexKeywords) { - indexKeywords_ = indexKeywords; -} diff -Nru albert-0.12.0/src/lib/albert/src/standardobjects/standarditem.cpp albert-0.13.1+plugins1/src/lib/albert/src/standardobjects/standarditem.cpp --- albert-0.12.0/src/lib/albert/src/standardobjects/standarditem.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/standardobjects/standarditem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "standarditem.h" -#include "action.h" -using std::vector; -using std::shared_ptr; - -Core::StandardItem::StandardItem(const QString &id) : id_(id) { } - -QString Core::StandardItem::id() const { - return id_; -} - -QString Core::StandardItem::text() const { - return text_; -} - -void Core::StandardItem::setText(const QString &text){ - text_ = text; -} - -QString Core::StandardItem::subtext() const { - return subtext_; -} - -void Core::StandardItem::setSubtext(const QString &subtext){ - subtext_ = subtext; -} - -QString Core::StandardItem::completionString() const { - return (completion_.isNull()) ? text_ : completion_; -} - -void Core::StandardItem::setCompletionString(const QString &completion) { - completion_ = completion; -} - -QString Core::StandardItem::iconPath() const { - return iconPath_; -} - -void Core::StandardItem::setIconPath(const QString &iconPath){ - iconPath_ = iconPath; -} - -vector> Core::StandardItem::actions(){ - return actions_; -} - -void Core::StandardItem::setActions(vector > &&actions){ - actions_ = actions; -} diff -Nru albert-0.12.0/src/lib/albert/src/util/shlex.cpp albert-0.13.1+plugins1/src/lib/albert/src/util/shlex.cpp --- albert-0.12.0/src/lib/albert/src/util/shlex.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albert/src/util/shlex.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "shlex.h" -#include - - -/******************************************************************************/ -QString Util::ShellLexer::quote(QString input) { - return QString("'%1'").arg(input.replace(R"(')", R"('"'"')")); -} - - -/******************************************************************************/ -QStringList Util::ShellLexer::split(const QString &input) { - - QString part; - QStringList result; - QString::const_iterator it = input.begin(); - - while(it != input.end()){ - - // Check for a backslash (escape) - if (*it == '\\'){ - if (++it == input.end()){ - qWarning() << "EOL detected. Excpected one of {\",`,\\,$, ,\\n,\\t,',<,>,~,|,&,;,*,?,#,(,)}"; - return QStringList(); - } - - switch (it->toLatin1()) { - case 'n': part.push_back('\n'); - break; - case 't': part.push_back('\t'); - break; - case ' ': - case '\'': - case '<': - case '>': - case '~': - case '|': - case '&': - case ';': - case '*': - case '?': - case '#': - case '(': - case ')': - case '"': - case '`': - case '\\': - case '$': part.push_back(*it); - break; - default: - qWarning() << "Invalid char following \\. Excpected one of {\",`,\\,$, ,\\n,\\t,',<,>,~,|,&,;,*,?,#,(,)}"; - return QStringList(); - } - } - - // Check for quoted strings - else if (*it == '"'){ - while (true){ - if (++it == input.end()){ - qWarning() << "Detected EOL inside a qoute."; - return QStringList(); - } - - // Leave the "quotation loop" on double qoute - else if (*it == '"') - break; - - // Check for a backslash (escape) - else if (*it == '\\'){ - if (++it == input.end()){ - qWarning() << "EOL detected. Excpected one of {\",`,\\,$}"; - return QStringList(); - } - - switch (it->toLatin1()) { - case '"': - case '`': - case '\\': - case '$': part.push_back(*it); - break; - default: - qWarning() << "Invalid char following \\. Excpected one of {\",`,\\,$}"; - return QStringList(); - } - } - - // Accept everything else - else { - part.push_back(*it); - } - } - } - - // Check for spaces (separators) - else if (*it == ' '){ - result.push_back(part); - part.clear(); - } - - // Rest of input alphabet, save and continue - else { - part.push_back(*it); - } - - ++it; - } - - if (!part.isEmpty()) - result.push_back(part); - - return result; -} diff -Nru albert-0.12.0/src/lib/albertcore/CMakeLists.txt albert-0.13.1+plugins1/src/lib/albertcore/CMakeLists.txt --- albert-0.12.0/src/lib/albertcore/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/CMakeLists.txt 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.1.3) + +project(albertcore) + +add_definitions(-DCORE) #export branch + +find_package(Qt5 5.5.0 REQUIRED COMPONENTS + Widgets + Concurrent + Network + Sql +) + +file(GLOB_RECURSE SRC include/* src/*) + +add_library(${PROJECT_NAME} SHARED ${SRC} resources.qrc) + +target_include_directories(${PROJECT_NAME} + PUBLIC + include/ + PRIVATE + include/core + include/util + src/ + src/core/ + src/core/settingswidget/ +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + ${Qt5Widgets_LIBRARIES} + ${Qt5Concurrent_LIBRARIES} + ${Qt5Network_LIBRARIES} + ${Qt5Sql_LIBRARIES} + globalshortcut + xdg +) + +# Set the RPATH for the library lookup +set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/albert") + +install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert) diff -Nru albert-0.12.0/src/lib/albertcore/include/core/action.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/action.h --- albert-0.12.0/src/lib/albertcore/include/core/action.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/action.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,40 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "core_globals.h" + +namespace Core { + +/** + * @brief The action interface + * A base class for actions (and items) + */ +class EXPORT_CORE Action +{ +public: + + virtual ~Action() {} + + /** A description */ + virtual QString text() const = 0; + + /** Activates the item */ + virtual void activate() = 0; +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/albert.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/albert.h --- albert-0.12.0/src/lib/albertcore/include/core/albert.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/albert.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,32 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include "core_globals.h" + +namespace Core { + +class AlbertApp +{ +public: + + static int EXPORT_CORE run(int argc, char **argv); + +}; + +} + + diff -Nru albert-0.12.0/src/lib/albertcore/include/core/extension.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/extension.h --- albert-0.12.0/src/lib/albertcore/include/core/extension.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/extension.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,88 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "plugin.h" +#include "core_globals.h" + +#define ALBERT_EXTENSION_IID ALBERT_PLUGIN_IID_PREFIX".extensionv1-alpha" + +namespace Core { + +struct Private; +class ExtensionManager; +class QueryHandler; +class FallbackProvider; + +/** + * @brief The extension interface + */ +class EXPORT_CORE Extension : public Plugin +{ +public: + + Extension(const QString &id); + ~Extension(); + + /** + * @brief A human readable name of the plugin + * @return The human readable name + */ + virtual QString name() const = 0; + + /** + * @brief The settings widget factory + * This has to return the widget that is accessible to the user from the + * albert settings plugin tab. If the return value is a nullptr there will + * be no settings widget available in the settings. + * @return The settings widget + */ + virtual QWidget* widget(QWidget *parent = nullptr) = 0; + +protected: + + /** + * @brief registerFallbackProvider + */ + void registerQueryHandler(QueryHandler*); + + /** + * @brief unregisterFallbackProvider + */ + void unregisterQueryHandler(QueryHandler*); + + /** + * @brief registerFallbackProvider + */ + void registerFallbackProvider(FallbackProvider*); + + /** + * @brief unregisterFallbackProvider + */ + void unregisterFallbackProvider(FallbackProvider*); + +private: + + std::unique_ptr d; + + static ExtensionManager *extensionManager; + friend class ExtensionManager; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/fallbackprovider.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/fallbackprovider.h --- albert-0.12.0/src/lib/albertcore/include/core/fallbackprovider.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/fallbackprovider.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,41 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "core_globals.h" + +namespace Core { + +class Item; + +class EXPORT_CORE FallbackProvider +{ +public: + + virtual ~FallbackProvider() {} + + /** + * @brief Fallbacks + * This items show up if a query yields no results + */ + virtual std::vector> fallbacks(const QString &) = 0; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/frontend.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/frontend.h --- albert-0.12.0/src/lib/albertcore/include/core/frontend.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/frontend.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,57 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "plugin.h" +#include "core_globals.h" + +#define ALBERT_FRONTEND_IID ALBERT_PLUGIN_IID_PREFIX".frontendv1-alpha" + +namespace Core { + +class EXPORT_CORE Frontend : public Plugin +{ + Q_OBJECT + +public: + + Frontend(const QString &id) : Plugin(id) {} + + virtual bool isVisible() = 0; + virtual void setVisible(bool visible = true) = 0; + + virtual QString input() = 0; + virtual void setInput(const QString&) = 0; + + virtual void setModel(QAbstractItemModel *) = 0; + + virtual QWidget *widget(QWidget *parent) = 0; + + void toggleVisibility() { setVisible(!isVisible()); } + +signals: + + void widgetShown(); + void widgetHidden(); + void inputChanged(QString qry); + void settingsWidgetRequested(); + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/history.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/history.h --- albert-0.12.0/src/lib/albertcore/include/core/history.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/history.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,46 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core_globals.h" + +namespace Core { + +class EXPORT_CORE History final : public QObject +{ + Q_OBJECT + +public: + + History(QObject *parent = 0); + + Q_INVOKABLE void add(QString str); + Q_INVOKABLE QString next(); + Q_INVOKABLE QString prev(); + Q_INVOKABLE void resetIterator(); + +private: + + void updateHistory(); + + QStringList lines_; + int currentLine_; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/indexable.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/indexable.h --- albert-0.12.0/src/lib/albertcore/include/core/indexable.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/indexable.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,45 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "item.h" +#include "core_globals.h" + +namespace Core { + +/** + * @brief The Indexable class + * The interface items need to be indexable by the offline index + */ +class EXPORT_CORE IndexableItem : public Item +{ + +public: + + struct IndexString { + IndexString(const QString& str, uint32_t rel) : string(str), relevance(rel){} + QString string; + uint32_t relevance; + }; + + virtual std::vector indexStrings() const = 0; + +}; + +} + diff -Nru albert-0.12.0/src/lib/albertcore/include/core/item.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/item.h --- albert-0.12.0/src/lib/albertcore/include/core/item.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/item.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,68 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "core_globals.h" + +namespace Core { + +class Action; + +/** **************************************************************************** + * @brief The item interface + * Subclass this class to make your object displayable in the results list. + */ +class EXPORT_CORE Item +{ + +public: + + /** + * An enumeration of urgency levels + * Notifications are placed on top. Alert too but additionally get an visual + * emphasis. Normal items are not handled in a special way. + */ + enum class Urgency : unsigned char { Normal, Notification, Alert }; + + virtual ~Item() {} + + /** An persistant, extensionwide unique identifier, "" if item is dynamic */ + virtual QString id() const = 0; + + /** The icon for the item */ + virtual QString iconPath() const = 0; + + /** The title for the item */ + virtual QString text() const = 0; + + /** The declarative subtext for the item */ + virtual QString subtext() const = 0; + + /** The string to use for completion */ + virtual QString completionString() const { return text(); } + + /** Urgency level of the item, defautls to "Normal" */ + virtual Urgency urgency() const { return Urgency::Normal; } + + /** The alternative actions of the item*/ + virtual std::vector> actions() = 0; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/itemroles.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/itemroles.h --- albert-0.12.0/src/lib/albertcore/include/core/itemroles.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/itemroles.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,32 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace Core { + +enum ItemRoles { + TextRole = 0, + ToolTipRole, + DecorationRole, + CompletionRole, // Note this is used as int in QML + ActionRole, + AltActionRole, + FallbackRole +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/plugin.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/plugin.h --- albert-0.12.0/src/lib/albertcore/include/core/plugin.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/plugin.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,84 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include "core_globals.h" + +#define ALBERT_PLUGIN_IID_PREFIX "org.albert.pluginv1-alpha" + +namespace Core { + +class PluginPrivate; + +class EXPORT_CORE Plugin : public QObject +{ + Q_OBJECT + +public: + + Plugin(const QString &id); + ~Plugin(); + + /** + * @brief id + * This is the global unique identifier of the plugin + * @return + */ + const QString &id() const; + + /** + * @brief cacheLocation + * @return The recommended cache location for the plugin. + * @note If the dir does not exist it will be crated. + */ + QDir cacheLocation() const; + + /** + * @brief configLocation + * @return The recommended config location for the plugin. + * @note If the dir does not exist it will be crated. + */ + QDir configLocation() const; + + /** + * @brief dataLocation + * @return The recommended data location for the plugin + * @note If the dir does not exist it will be crated. + */ + QDir dataLocation() const; + + /** + * @brief settings + * This is a convenience function returning the default settings object for this plugin. It is + * located in the config location defined in this plugin and has the basename "config". Note + * that QSettings is not thread-safe, so if you want to access the settings concurrently you + * should create a new instance with the path of this object. + * @return The settings object + */ + QSettings &settings(); + +private: + + std::unique_ptr d; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core/query.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/query.h --- albert-0.12.0/src/lib/albertcore/include/core/query.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/query.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,125 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include "core_globals.h" + + +namespace Core { + +class QueryPrivate; +class Item; + +/** + * @brief The Query class + * Represents a query to be handled by the query handlers + */ +class EXPORT_CORE Query final +{ +public: + + /** + * @brief The query string. + * This is the processed query string relevant for most of the handlers. If the raw query string + * is prefixed by a trigger string() returns the query string without the the trigger + * prefix. If there is no trigger string() is equivalent to rawString(). + */ + const QString &string() const; + + /** + * @brief The raw query string. + * This is the raw query string as the users entered it into the input line. + */ + const QString &rawString() const; + + /** + * @brief Indicates a triggered query. + */ + bool isTriggered() const; + + /** + * @brief The trigger of this query + * Note that if the trigger is set, string() differs from rawString(). + */ + const QString &trigger() const; + + /** + * @brief The validity of the query + * If the core cancelled the query for some reason the query gets invalid. Stop handling the + * query if it is not valid anymore to save resources for other queries. + * @return True if valid, else false. + */ + bool isValid() const; + + /** + * @brief addMatch + * Use the addMatches if you have a lot of items to add. + * @param item The to add to the results + * @param score The relevance factor (UINT_MAX -> 1) + * @see addMatches + */ + template + void addMatch(T&& item, uint score = 0) { + if ( isValid_ ) { + mutex_.lock(); + addMatchWithoutLock(std::forward(item), score); + mutex_.unlock(); + } + } + + /** + * @brief addMatches + * Cumulative addMatch function avoiding excessive mutex locking the results + * @param begin + * @param end + */ + template + void addMatches(Iterator begin, Iterator end) { + if ( isValid() ) { + mutex_.lock(); + for (; begin != end; ++begin) + // Must not use operator->() !!! dereferencing a pointer returns an lvalue + addMatchWithoutLock((*begin).first, (*begin).second); + mutex_.unlock(); + } + } + +private: + + void addMatchWithoutLock(const std::shared_ptr &item, uint score); + void addMatchWithoutLock(std::shared_ptr &&item, uint score); + + Query() = default; + ~Query() = default; + + std::vector, uint>> results_; + QMutex mutex_; + QString trigger_; + QString string_; + QString rawString_; + bool isValid_ = true; + + friend class QueryExecution; +}; + +} + + diff -Nru albert-0.12.0/src/lib/albertcore/include/core/queryhandler.h albert-0.13.1+plugins1/src/lib/albertcore/include/core/queryhandler.h --- albert-0.12.0/src/lib/albertcore/include/core/queryhandler.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core/queryhandler.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,95 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core_globals.h" + +namespace Core { + +class Query; + +class EXPORT_CORE QueryHandler +{ +public: + + QueryHandler(QString id) : id(id) {} + virtual ~QueryHandler() {} + + const QString id; + + /** + * @brief The triggers that makes the plugin beeing run exclusice + */ + virtual QStringList triggers() const { return QStringList(); } + + /** + * @brief The ExecutionType enum + * The execution type of a queryhandler determines the way the handler is run. Batch handlers + * are runned first. Query results are not displayed until all batch handlers finished. When all + * batch handlers finished the results are sorted and displayed. Batched handlers can be + * triggered or not. + * Realtime handlers are started and the model of the results is shown instantly. The results of + * the realtime handlers are not sorted and displayed instantly (well they are buffered for 50 + * ms). Realtime handler must have triggers otherwise they will never be started. + */ + enum class ExecutionType { Batch, Realtime }; + + /** + * @brief executionType + * @return The execution type of the queryhandler + * @see ExecutionType + */ + virtual ExecutionType executionType() const { return ExecutionType::Batch; } + + /** + * @brief Session setup + * Called when the users started a session, i.e. before the the main window + * is shown. Setup session stage has to be finished before the actual query + * handling will begin so do not do any long running jobs in here. If you + * really have to, do it asynchonous or threaded (only recommended if you + * know what you do). + */ + virtual void setupSession() {} + + /** + * @brief Session teardown + * Called when the user finshed a session, i.e. after the the main window + * has been hidden. Although the app is hidden now this method should not + * block since the user may want start another session immediately. + * @see setupSession + */ + virtual void teardownSession() {} + + /** + * @brief Query handling + * This method is called for every user input. Add the results to the query + * passed as parameter. The results are sorted by usage. After 100 ms + * they are just appended to not disturb the users interaction. Queries can + * get invalidated so make sure to regularly check isValid() to cancel + * long running operations. This method is called in a thread without event + * loop, be aware of the consequences (especially regarding signal/slot + * mechanism). + * Note that this method may run simultaneously in separate threads make + * sure that everything mutable you touch is threadsafe. + * @param query Holds the query context + */ + virtual void handleQuery(Query *query) const = 0; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/core_globals.h albert-0.13.1+plugins1/src/lib/albertcore/include/core_globals.h --- albert-0.12.0/src/lib/albertcore/include/core_globals.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/core_globals.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,36 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#if defined(_MSC_VER) + #define EXPORT __declspec(dllexport) + #define IMPORT __declspec(dllimport) +#elif defined(__GNUC__) + #define EXPORT __attribute__((visibility("default"))) + #define IMPORT +#else + #define EXPORT + #define IMPORT + #pragma warning Unknown dynamic link import/export semantics. +#endif + +#ifdef CORE + #define EXPORT_CORE EXPORT +#else + #define EXPORT_CORE IMPORT +#endif + diff -Nru albert-0.12.0/src/lib/albertcore/include/util/offlineindex.h albert-0.13.1+plugins1/src/lib/albertcore/include/util/offlineindex.h --- albert-0.12.0/src/lib/albertcore/include/util/offlineindex.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/util/offlineindex.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,104 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "core_globals.h" + +namespace Core { + +class SearchBase; +class IndexableItem; + +class EXPORT_CORE OfflineIndex final { + +public: + + /** + * @brief Contstructs a search + * @param fuzzy Sets the type of the search. Defaults to false. + */ + OfflineIndex(bool fuzzy = false); + OfflineIndex(const OfflineIndex &other) = delete; + OfflineIndex(OfflineIndex &&other); + OfflineIndex &operator=(const OfflineIndex & other) = delete; + OfflineIndex &operator=(OfflineIndex && other); + + /** + * @brief Destructs the search + * @param + */ + ~OfflineIndex(); + + /** + * @brief Sets the type of the search to fuzzy + * @param fuzzy The type to set. Defaults to true. + */ + void setFuzzy(bool fuzzy = true); + + /** + * @brief Type of the search + * @return True if the search is fuzzy else false. + */ + bool fuzzy(); + + /** + * @brief Set the error tolerance of the fuzzy search + * + * If the value d is >1, the search tolerates d errors. If the value d is <1, + * the search tolerates wordlength * d errors. The "amount of tolerance" is + * measures in maximal prefix edit distance. If the search is not set to fuzzy + * setDelta has no effect. + * + * @param t The amount of error tolerance + */ + void setDelta(double d); + + /** + * @brief The error tolerance of the fuzzy search + * @return The amount of error tolerance if search is fuzzy 0 else. + */ + double delta(); + + /** + * @brief Build the search index + * @param The items to index + */ + void add(const std::shared_ptr &idxble); + + /** + * @brief Clear the search index + */ + void clear(); + + /** + * @brief Perform a search on the index + * @param req The query string + */ + std::vector> search(const QString &req) const; + +private: + + std::unique_ptr impl_; + +}; + +} + + + diff -Nru albert-0.12.0/src/lib/albertcore/include/util/shutil.h albert-0.13.1+plugins1/src/lib/albertcore/include/util/shutil.h --- albert-0.12.0/src/lib/albertcore/include/util/shutil.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/util/shutil.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,32 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core_globals.h" + +namespace Core { + +namespace ShUtil { + +EXPORT_CORE QString quote(QString input); +EXPORT_CORE QStringList split(const QString &input); + +} + +} + diff -Nru albert-0.12.0/src/lib/albertcore/include/util/standardaction.h albert-0.13.1+plugins1/src/lib/albertcore/include/util/standardaction.h --- albert-0.12.0/src/lib/albertcore/include/util/standardaction.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/util/standardaction.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,53 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include "core/action.h" +#include "core_globals.h" + +namespace Core { + + +/** **************************************************************************** +* @brief A standard action +* If you dont need the flexibility subclassing the abstract classes provided, +* you can simply use this container, fill it with data. +*/ +struct EXPORT_CORE StandardAction final : public Action +{ +public: + + StandardAction(); + StandardAction(const QString &text, std::function f); + + QString text() const override; + void setText(const QString &text); + + const std::function &action(); + void setAction(std::function &&action); + + void activate() override; + +private: + + QString text_; + std::function action_; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/util/standardindexitem.h albert-0.13.1+plugins1/src/lib/albertcore/include/util/standardindexitem.h --- albert-0.12.0/src/lib/albertcore/include/util/standardindexitem.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/util/standardindexitem.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,67 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include "standarditem.h" +#include "core/indexable.h" + +namespace Core { + +/** **************************************************************************** +* @brief A standard index item +* If you dont need the flexibility subclassing the abstract classes provided, +* you can simply use this container, fill it with data. +*/ +class EXPORT_CORE StandardIndexItem final : public IndexableItem +{ +public: + + StandardIndexItem(const QString &id = QString()); + + QString id() const override final; + + QString text() const override; + void setText(const QString &text); + + QString subtext() const override; + void setSubtext(const QString &subtext); + + QString completionString() const override; + void setCompletionString(const QString &completion); + + QString iconPath() const override; + void setIconPath( const QString &iconPath); + + std::vector> actions() override; + void setActions(std::vector> &&actions); + + virtual std::vector indexStrings() const override; + virtual void setIndexKeywords(std::vector &&indexStrings); + +private: + + QString id_; + QString text_; + QString subtext_; + QString completion_; + QString iconPath_; + std::vector> actions_; + std::vector indexStrings_; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/include/util/standarditem.h albert-0.13.1+plugins1/src/lib/albertcore/include/util/standarditem.h --- albert-0.12.0/src/lib/albertcore/include/util/standarditem.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/include/util/standarditem.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,66 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "core/item.h" + +namespace Core { + +class Action; + +/** +* @brief A standard item +* If you dont need the flexibility subclassing the abstract classes provided, +* you can simply use this container, fill it with data. +*/ +class EXPORT_CORE StandardItem : public Item +{ +public: + + StandardItem(const QString &id = QString()); + + QString id() const override final; + + QString text() const override; + void setText(const QString &text); + + QString subtext() const override; + void setSubtext(const QString &subtext); + + QString completionString() const override; + void setCompletionString(const QString &completion); + + QString iconPath() const override; + void setIconPath( const QString &iconPath); + + std::vector> actions() override; + void setActions(std::vector> &&actions); + +protected: + + QString id_; + QString text_; + QString subtext_; + QString completion_; + QString iconPath_; + std::vector> actions_; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/resources/icons/albert.svg albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/albert.svg --- albert-0.12.0/src/lib/albertcore/resources/icons/albert.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/albert.svg 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/src/lib/albertcore/resources/icons/gear.svg albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/gear.svg --- albert-0.12.0/src/lib/albertcore/resources/icons/gear.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/gear.svg 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/lib/albertcore/resources/icons/plugin_error.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/plugin_error.png differ Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/lib/albertcore/resources/icons/plugin_notloaded.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/plugin_notloaded.png differ Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/lib/albertcore/resources/icons/plugin_ok.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/plugin_ok.png differ diff -Nru albert-0.12.0/src/lib/albertcore/resources/icons/unknown.svg albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/unknown.svg --- albert-0.12.0/src/lib/albertcore/resources/icons/unknown.svg 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/resources/icons/unknown.svg 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru albert-0.12.0/src/lib/albertcore/resources.qrc albert-0.13.1+plugins1/src/lib/albertcore/resources.qrc --- albert-0.12.0/src/lib/albertcore/resources.qrc 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/resources.qrc 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,10 @@ + + + resources/icons/plugin_error.png + resources/icons/plugin_notloaded.png + resources/icons/plugin_ok.png + resources/icons/albert.svg + resources/icons/gear.svg + resources/icons/unknown.svg + + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/albert.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/albert.cpp --- albert-0.12.0/src/lib/albertcore/src/core/albert.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/albert.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,566 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "albert.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extensionmanager.h" +#include "frontend.h" +#include "globalshortcut/hotkeymanager.h" +#include "frontendmanager.h" +#include "pluginspec.h" +#include "querymanager.h" +#include "settingswidget.h" +#include "trayicon.h" +#include "xdg/iconlookup.h" +using namespace Core; +using namespace GlobalShortcut; + +static void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &message); +static void dispatchMessage(); + +// Core components +static QApplication *app; +static ExtensionManager *extensionManager; +static FrontendManager *frontendManager; +static QueryManager *queryManager; +static HotkeyManager *hotkeyManager; +static SettingsWidget *settingsWidget; +static TrayIcon *trayIcon; +static QMenu *trayIconMenu; +static QLocalServer *localServer; + + +int Core::AlbertApp::run(int argc, char **argv) { + + { + bool showSettingsWhenInitialized = false; + + /* + * INITIALIZE APPLICATION + */ + + qInstallMessageHandler(myMessageOutput); + + qDebug() << "Initializing application"; + app = new QApplication(argc, argv); + app->setApplicationName("albert"); + app->setApplicationDisplayName("Albert"); + app->setApplicationVersion("v0.13.1"); + app->setQuitOnLastWindowClosed(false); + QString icon = XDG::IconLookup::iconPath("albert"); + if ( icon.isEmpty() ) icon = ":app_icon"; + app->setWindowIcon(QIcon(icon)); + + + /* + * PARSE COMMANDLINE + */ + + qDebug() << "Parsing commandline"; + QCommandLineParser parser; + parser.setApplicationDescription("Albert is still in alpha. These options may change in future versions."); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addOption(QCommandLineOption({"k", "hotkey"}, "Overwrite the hotkey to use.", "hotkey")); + parser.addOption(QCommandLineOption({"p", "plugin-dirs"}, "Set the plugin dirs to use. Comma separated.", "directory")); + parser.addPositionalArgument("command", "Command to send to a running instance, if any. (show, hide, toggle)", "[command]"); + parser.process(*app); + + + /* + * IPC/SINGLETON MECHANISM + */ + + qDebug() << "Checking for other instances"; + QString socketPath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/socket"; + const QStringList args = parser.positionalArguments(); + QLocalSocket socket; + socket.connectToServer(socketPath); + if ( socket.waitForConnected(500) ) { + // If there is a command send it + if ( args.count() == 1 ){ + socket.write(args.at(0).toLocal8Bit()); + socket.flush(); + socket.waitForReadyRead(500); + if (socket.bytesAvailable()) + qInfo() << socket.readAll(); + } + else + qInfo("There is another instance of albert running."); + socket.close(); + ::exit(EXIT_SUCCESS); + } else if ( args.count() == 1 ) { + qInfo("There is no other instance of albert running."); + ::exit(EXIT_FAILURE); + } + + // Remove pipes potentially leftover after crash + QLocalServer::removeServer(socketPath); + + // Create server and handle messages + qDebug() << "Creating IPC server"; + localServer = new QLocalServer; + if ( !localServer->listen(socketPath) ) + qWarning() << "Local server could not be created. IPC will not work! Reason:" + << localServer->errorString(); + + // Handle incoming messages + QObject::connect(localServer, &QLocalServer::newConnection, dispatchMessage); + + + /* + * INITIALIZE PATHS + */ + + // Make sure data, cache and config dir exists + qDebug() << "Initializing mandatory paths"; + QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + QString configLocation = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); + for ( const QString &location : {dataLocation, cacheLocation, configLocation} ) + if (!QDir(location).mkpath(".")) + qFatal("Could not create dir: %s", qPrintable(location)); + + // Move old config for user convenience TODO drop somewhen + QSettings::setPath(QSettings::defaultFormat(), QSettings::UserScope, + QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)); + QFileInfo oldcfg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/albert.conf"); + QFileInfo newcfg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation) + "/albert/albert.conf"); + if (oldcfg.exists()){ + if (newcfg.exists()) + QFile::remove(newcfg.filePath()); + QFile::rename(oldcfg.filePath(), newcfg.filePath()); + } + + + /* + * DETECT FIRST RUN AND VERSION CHANGE + */ + + // If there is a firstRun file, rename it to lastVersion (since v0.11) + if ( QFile::exists(QString("%1/firstrun").arg(dataLocation)) ) + qDebug() << "Renaming 'firstrun' to 'last_used_version'"; + QFile::rename(QString("%1/firstrun").arg(dataLocation), + QString("%1/last_used_version").arg(dataLocation)); + + // If there is a lastVersion file move it to config (since v0.13) + if ( QFile::exists(QString("%1/last_used_version").arg(dataLocation)) ) + qDebug() << "Moving 'last_used_version' to config path"; + QFile::rename(QString("%1/last_used_version").arg(dataLocation), + QString("%1/last_used_version").arg(configLocation)); + + qDebug() << "Checking last used version"; + QFile file(QString("%1/last_used_version").arg(configLocation)); + if ( file.exists() ) { + // Read last used version + if ( file.open(QIODevice::ReadOnly|QIODevice::Text) ) { + QString lastUsedVersion; + QTextStream(&file) >> lastUsedVersion; + file.close(); + + // Show newsbox in case of major version change + if ( app->applicationVersion().section('.', 1, 1) != lastUsedVersion.section('.', 1, 1) ){ + // Do whatever is neccessary on first run + QMessageBox(QMessageBox::Information, "Major version changed", + QString("You are now using Albert %1. Albert is still in the alpha " + "stage. This means things may change unexpectedly. Check " + "the " + "news to read about the things that changed.") + .arg(app->applicationVersion()) + ).exec(); + } + } + else + qCritical() << qPrintable(QString("Could not open file %1: %2,. Config migration may fail.") + .arg(file.fileName(), file.errorString())); + } else { + // Do whatever is neccessary on first run + if ( QMessageBox(QMessageBox::Information, "First run", + "Seems like this is the first time you run Albert. " + "Most probably you want to set a hotkey to show " + "Albert. Do you want to open the settings dialog?", + QMessageBox::No|QMessageBox::Yes).exec() == QMessageBox::Yes ) + showSettingsWhenInitialized = true; + } + + // Write the current version into the file + if ( file.open(QIODevice::WriteOnly|QIODevice::Text) ) { + QTextStream out(&file); + out << app->applicationVersion(); + file.close(); + } else + qCritical() << qPrintable(QString("Could not open file %1: %2").arg(file.fileName(), file.errorString())); + + + /* + * INITIALIZE DATABASE + */ + + qDebug() << "Initializing database"; + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); + if ( !db.isValid() ) + qFatal("No sqlite available"); + + if (!db.driver()->hasFeature(QSqlDriver::Transactions)) + qFatal("QSqlDriver::Transactions not available."); + + db.setDatabaseName(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)).filePath("core.db")); + if (!db.open()) + qFatal("Unable to establish a database connection."); + + db.transaction(); + + // Create tables + QSqlQuery q; + if (!q.exec("CREATE TABLE IF NOT EXISTS usages ( " + " input TEXT NOT NULL, " + " itemId TEXT, " + " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP " + ");")) + qFatal("Unable to create table 'usages': %s", q.lastError().text().toUtf8().constData()); + + if (!q.exec("CREATE TABLE IF NOT EXISTS runtimes ( " + " extensionId TEXT NOT NULL, " + " runtime INTEGER NOT NULL, " + " timestamp DATETIME DEFAULT CURRENT_TIMESTAMP " + ");")) + qFatal("Unable to create table 'runtimes': %s", q.lastError().text().toUtf8().constData()); + + // Do regular cleanup + if (!q.exec("DELETE FROM usages WHERE julianday('now')-julianday(timestamp)>90;")) + qWarning("Unable to cleanup usages table."); + + if (!q.exec("DELETE FROM runtimes WHERE julianday('now')-julianday(timestamp)>7;")) + qWarning("Unable to cleanup runtimes table."); + + db.commit(); + + + /* + * INITIALIZE APPLICATION COMPONENTS + */ + + qDebug() << "Initializing core components"; + + + // Define plugindirs + QStringList pluginDirs; + if ( parser.isSet("plugin-dirs") ) + pluginDirs = parser.value("plugin-dirs").split(','); + else { +#if defined __linux__ + QStringList dirs = { + QFileInfo("/usr/lib/").canonicalFilePath(), + QFileInfo("/usr/lib64/").canonicalFilePath(), + QFileInfo("/usr/local/lib/").canonicalFilePath(), + QFileInfo("/usr/local/lib64/").canonicalFilePath(), + QDir::home().filePath(".local/lib/"), + QDir::home().filePath(".local/lib64/") + }; + + dirs.removeDuplicates(); + + for ( const QString& dir : dirs ) { + QFileInfo fileInfo = QFileInfo(QDir(dir).filePath("albert/plugins")); + if ( fileInfo.isDir() ) + pluginDirs.push_back(fileInfo.canonicalFilePath()); + } +#elif defined __APPLE__ + throw "Not implemented"; +#elif defined _WIN32 + throw "Not implemented"; +#endif + } + + frontendManager = new FrontendManager(pluginDirs); + extensionManager = new ExtensionManager(pluginDirs); + + extensionManager->reloadExtensions(); + + hotkeyManager = new HotkeyManager; + queryManager = new QueryManager(extensionManager); + + + /* + * Build Tray Icon + */ + + qDebug() << "Initializing tray icon"; + trayIcon = new TrayIcon; + trayIconMenu = new QMenu; + QAction* showAction = new QAction("Show", trayIconMenu); + QAction* settingsAction = new QAction("Settings", trayIconMenu); + QAction* quitAction = new QAction("Quit", trayIconMenu); + + showAction->setIcon(app->style()->standardIcon(QStyle::SP_TitleBarMaxButton)); + settingsAction->setIcon(app->style()->standardIcon(QStyle::SP_FileDialogDetailedView)); + quitAction->setIcon(app->style()->standardIcon(QStyle::SP_TitleBarCloseButton)); + + trayIconMenu->addAction(showAction); + trayIconMenu->addAction(settingsAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); + + trayIcon->setContextMenu(trayIconMenu); + + + /* + * Standalone note + */ + + QSettings settings(qApp->applicationName()); + bool standsalone_note_shown = settings.value("standsalone_note_shown", false).toBool(); + if ( !standsalone_note_shown ) { + QMessageBox(QMessageBox::Information, "Note", + "This is standalone free and open source software. Albert is not " + "related or affiliated to any other projects or corporations.").exec(); + settings.setValue("standsalone_note_shown", true); + } + + + /* + * Hotkey + */ + + qDebug() << "Setting up hotkey"; + // Check for a command line override + QString hotkey; + if ( parser.isSet("hotkey") ) { + hotkey = parser.value("hotkey"); + if ( !hotkeyManager->registerHotkey(hotkey) ) + qFatal("Failed to set hotkey to %s.", hotkey.toLocal8Bit().constData()); + + // Check if the settings contains a hotkey entry + } else if ( settings.contains("hotkey") ) { + hotkey = settings.value("hotkey").toString(); + if ( !hotkeyManager->registerHotkey(hotkey) ){ + if ( QMessageBox(QMessageBox::Critical, "Error", + QString("Failed to set hotkey: '%1'. Do you want to open the settings?").arg(hotkey), + QMessageBox::No|QMessageBox::Yes).exec() == QMessageBox::Yes ) + showSettingsWhenInitialized = true; + } + } + + + /* + * MISC + */ + + // Quit gracefully on unix signals + qDebug() << "Setup signal handlers"; + for ( int sig : { SIGINT, SIGTERM, SIGHUP, SIGPIPE } ) { + signal(sig, [](int){ + QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection); + }); + } + + // Print a message if the app was not terminated graciously + qDebug() << "Creating running indicator file"; + QString filePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/running"; + if (QFile::exists(filePath)){ + qWarning() << "Application has not been terminated graciously."; + } else { + // Create the running indicator file + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly)) + qWarning() << "Could not create file:" << filePath; + file.close(); + } + + // Application is initialized create the settings widget + qDebug() << "Creating settings widget"; + settingsWidget = new SettingsWidget(extensionManager, + frontendManager, + queryManager, + hotkeyManager, + trayIcon); + + // If somebody requested the settings dialog open it + if ( showSettingsWhenInitialized ) + settingsWidget->show(); + + + /* + * SIGNALING + */ + + qDebug() << "Setting up signals"; + + // Connect tray menu (except for frontend stuff…) + QObject::connect(settingsAction, &QAction::triggered, + settingsWidget, &SettingsWidget::show); + + QObject::connect(settingsAction, &QAction::triggered, + settingsWidget, &SettingsWidget::raise); + + QObject::connect(quitAction, &QAction::triggered, + app, &QApplication::quit); + + + // Define a lambda that connects a new frontend + auto connectFrontend = [&](Frontend *f){ + + QObject::connect(hotkeyManager, &HotkeyManager::hotKeyPressed, + f, &Frontend::toggleVisibility); + + QObject::connect(queryManager, &QueryManager::resultsReady, + f, &Frontend::setModel); + + QObject::connect(showAction, &QAction::triggered, + f, &Frontend::setVisible); + + QObject::connect(trayIcon, &TrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){ + if( reason == QSystemTrayIcon::ActivationReason::Trigger) + f->toggleVisibility(); + }); + + QObject::connect(f, &Frontend::settingsWidgetRequested, [](){ + settingsWidget->show(); + settingsWidget->raise(); + settingsWidget->activateWindow(); + }); + + QObject::connect(f, &Frontend::widgetShown, [f](){ + queryManager->setupSession(); + queryManager->startQuery(f->input()); + }); + + QObject::connect(f, &Frontend::widgetHidden, + queryManager, &QueryManager::teardownSession); + + QObject::connect(f, &Frontend::inputChanged, + queryManager, &QueryManager::startQuery); + }; + + // Connect the current frontend + connectFrontend(frontendManager->currentFrontend()); + + // Connect new frontends + QObject::connect(frontendManager, &FrontendManager::frontendChanged, [&](Frontend *f) { + connectFrontend(f); + }); + } + + + /* + * ENTER EVENTLOOP + */ + + qDebug() << "Entering eventloop"; + int retval = app->exec(); + + + /* + * FINALIZE APPLICATION + */ + + qDebug() << "Cleaning up core components"; + delete settingsWidget; + delete trayIconMenu; + delete trayIcon; + delete queryManager; + delete hotkeyManager; + delete extensionManager; + delete frontendManager; + + qDebug() << "Shutting down IPC server"; + localServer->close(); + + // Delete the running indicator file + qDebug() << "Deleting running indicator file"; + QFile::remove(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/running"); + + qDebug() << "Quit"; + return retval; +} + + +/** ***************************************************************************/ +void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &message) { + switch (type) { + case QtDebugMsg: + fprintf(stdout, "[%s] \x1b[3m[DEBG] %s\x1b[0m\n", + QTime::currentTime().toString().toLocal8Bit().constData(), + message.toLocal8Bit().constData()); + fflush(stdout); + break; + case QtInfoMsg: + fprintf(stdout, "[%s] [INFO] %s\n", + QTime::currentTime().toString().toLocal8Bit().constData(), + message.toLocal8Bit().constData()); + fflush(stdout); + break; + case QtWarningMsg: + fprintf(stderr, "[%s] \x1b[33;1m[WARN]\x1b[0;1m %s -- [%s]\x1b[0m\n", + QTime::currentTime().toString().toLocal8Bit().constData(), + message.toLocal8Bit().constData(), + context.function); + break; + case QtCriticalMsg: + fprintf(stderr, "[%s] \x1b[31;1m[CRIT]\x1b[0;1m %s -- [%s]\x1b[0m\n", + QTime::currentTime().toString().toLocal8Bit().constData(), + message.toLocal8Bit().constData(), + context.function); + break; + case QtFatalMsg: + fprintf(stderr, "[%s] \x1b[41;30;4m[FATAL]\x1b[0;1m %s -- [%s]\x1b[0m\n", + QTime::currentTime().toString().toLocal8Bit().constData(), + message.toLocal8Bit().constData(), + context.function); + exit(1); + } +} + + +/** ***************************************************************************/ +void dispatchMessage() { + QLocalSocket* socket = localServer->nextPendingConnection(); // Should be safe + socket->waitForReadyRead(500); + if (socket->bytesAvailable()) { + QString msg = QString::fromLocal8Bit(socket->readAll()); + if ( msg == "show") { + frontendManager->currentFrontend()->setVisible(true); + socket->write("Application set visible."); + } else if ( msg == "hide") { + frontendManager->currentFrontend()->setVisible(false); + socket->write("Application set invisible."); + } else if ( msg == "toggle") { + frontendManager->currentFrontend()->toggleVisibility(); + socket->write("Visibility toggled."); + } else + socket->write("Command not supported."); + } + socket->flush(); + socket->close(); + socket->deleteLater(); +} + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/extension.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/extension.cpp --- albert-0.12.0/src/lib/albertcore/src/core/extension.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/extension.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,70 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "extension.h" +#include "extensionmanager.h" +using namespace std; + + +Core::ExtensionManager *Core::Extension::extensionManager = nullptr; + +struct Core::Private { + set registeredQueryHandlers; + set registeredFallbackProviders; +}; + + +/**************************************************************************************************/ +Core::Extension::Extension(const QString &id) : Plugin(id), d(new Private) { + +} + + +/**************************************************************************************************/ +Core::Extension::~Extension() { + // If the extensin did it not by itself unregister all the remaining handlers + for (auto ptr : d->registeredQueryHandlers) + unregisterQueryHandler(ptr); + for (auto ptr : d->registeredFallbackProviders) + unregisterFallbackProvider(ptr); +} + + +/**************************************************************************************************/ +void Core::Extension::registerQueryHandler(Core::QueryHandler *object) { + d->registeredQueryHandlers.insert(object); + extensionManager->registerQueryHandler(object); +} + + +/**************************************************************************************************/ +void Core::Extension::unregisterQueryHandler(Core::QueryHandler *object) { + extensionManager->unregisterQueryHandler(object); +} + + +/**************************************************************************************************/ +void Core::Extension::registerFallbackProvider(Core::FallbackProvider *object) { + d->registeredFallbackProviders.insert(object); + extensionManager->registerFallbackProvider(object); +} + + +/**************************************************************************************************/ +void Core::Extension::unregisterFallbackProvider(Core::FallbackProvider *object) { + extensionManager->unregisterFallbackProvider(object); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/extensionmanager.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/extensionmanager.cpp --- albert-0.12.0/src/lib/albertcore/src/core/extensionmanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/extensionmanager.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,204 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "extensionmanager.h" +#include "queryhandler.h" +#include "fallbackprovider.h" +#include "pluginspec.h" +using namespace std; +using namespace chrono; + + +/** ***************************************************************************/ +class Core::ExtensionManagerPrivate { +public: + vector> extensionSpecs_; + set loadedExtensions_; + set queryHandlers_; + set fallbackProviders_; +}; + + +/** ***************************************************************************/ +Core::ExtensionManager::ExtensionManager(QStringList pluginDirs) + : d(new ExtensionManagerPrivate) { + + Q_ASSERT( Extension::extensionManager == nullptr); + Extension::extensionManager = this; + + // Find plugins + for ( const QString &pluginDir : pluginDirs ) { + QDirIterator dirIterator(pluginDir, QDir::Files); + while (dirIterator.hasNext()) { + std::unique_ptr plugin(new PluginSpec(dirIterator.next())); + + if ( plugin->iid() != ALBERT_EXTENSION_IID ) + continue; + + if (std::any_of(d->extensionSpecs_.begin(), d->extensionSpecs_.end(), + [&](const unique_ptr &spec){ return plugin->id() == spec->id(); })) { + qWarning() << qPrintable(QString("Extension IDs already exists. Skipping. (%1)").arg(plugin->path())); + continue; + } + + d->extensionSpecs_.push_back(std::move(plugin)); + } + } + + // Sort alphabetically + std::sort(d->extensionSpecs_.begin(), + d->extensionSpecs_.end(), + [](const unique_ptr& lhs, const unique_ptr& rhs){ + return lhs->name() < rhs->name(); + }); +} + + +/** ***************************************************************************/ +Core::ExtensionManager::~ExtensionManager() { + for (unique_ptr & pluginSpec : d->extensionSpecs_) + unloadExtension(pluginSpec); +} + + +/** ***************************************************************************/ +const vector>& Core::ExtensionManager::extensionSpecs() const { + return d->extensionSpecs_; +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::reloadExtensions() { + + // Unload all extensions + for (unique_ptr & pluginSpec : d->extensionSpecs_) + unloadExtension(pluginSpec); + + // Load if enabled + QSettings settings(qApp->applicationName()); + for (unique_ptr & pluginSpec : d->extensionSpecs_) { + if ( settings.value(QString("%1/enabled").arg(pluginSpec->id()), false).toBool() ) + loadExtension(pluginSpec); + } +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::loadExtension(const unique_ptr &spec) { + if ( spec->state() != PluginSpec::State::Loaded ){ + + // Load + std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); + if ( !spec->load() ) { + qInfo() << QString("Loading %1 failed. (%2)").arg(spec->id(), spec->lastError()).toLocal8Bit().data(); + return; + } + qDebug() << qPrintable(QString("%1 loaded in %2 milliseconds").arg(spec->id()) + .arg(duration_cast(system_clock::now()-start).count())); + + Extension *extension = dynamic_cast(spec->instance()); + if (!extension) { + qInfo() << QString("Instance is not of tyoe Extension. (%2)").arg(spec->id()).toLocal8Bit().data(); + return; + } + + d->loadedExtensions_.insert(extension); + } +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::unloadExtension(const unique_ptr &spec) { + if (spec->state() == PluginSpec::State::NotLoaded) + return; + + if (spec->state() == PluginSpec::State::Loaded) + d->loadedExtensions_.erase(dynamic_cast(spec->instance())); + + spec->unload(); +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::enableExtension(const unique_ptr &pluginSpec) { + QSettings(qApp->applicationName()).setValue(QString("%1/enabled").arg(pluginSpec->id()), true); + loadExtension(pluginSpec); +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::disableExtension(const unique_ptr &pluginSpec) { + QSettings(qApp->applicationName()).setValue(QString("%1/enabled").arg(pluginSpec->id()), false); + unloadExtension(pluginSpec); +} + + +/** ***************************************************************************/ +bool Core::ExtensionManager::extensionIsEnabled(const unique_ptr &pluginSpec) { + QSettings settings(qApp->applicationName()); + return settings.value(QString("%1/enabled").arg(pluginSpec->id())).toBool(); +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::registerQueryHandler(Core::QueryHandler *queryHandler) { + d->queryHandlers_.insert(queryHandler); + emit queryHandlerRegistered(queryHandler); +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::unregisterQueryHandler(Core::QueryHandler *queryHandler) { + d->queryHandlers_.erase(queryHandler); + emit queryHandlerUnregistered(queryHandler); +} + + +/** ***************************************************************************/ +const std::set &Core::ExtensionManager::queryHandlers() { + return d->queryHandlers_; +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::registerFallbackProvider(Core::FallbackProvider *fallbackProvider) { + d->fallbackProviders_.insert(fallbackProvider); + emit fallbackProviderRegistered(fallbackProvider); + +} + + +/** ***************************************************************************/ +void Core::ExtensionManager::unregisterFallbackProvider(Core::FallbackProvider *fallbackProvider) { + d->fallbackProviders_.erase(fallbackProvider); + emit fallbackProviderUnregistered(fallbackProvider); +} + + +/** ***************************************************************************/ +const std::set &Core::ExtensionManager::fallbackProviders() { + return d->fallbackProviders_; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/extensionmanager.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/extensionmanager.h --- albert-0.12.0/src/lib/albertcore/src/core/extensionmanager.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/extensionmanager.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,76 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include +#include "extension.h" + +namespace Core { + +class Extension; +class QueryHandler; +class FallbackProvider; +class PluginSpec; +class ExtensionManagerPrivate; + +class ExtensionManager final : public QObject +{ + Q_OBJECT + +public: + + ExtensionManager(QStringList pluginroots); + ~ExtensionManager(); + + const std::vector> & extensionSpecs() const; + + void reloadExtensions(); + + void enableExtension(const std::unique_ptr &); + void disableExtension(const std::unique_ptr &); + bool extensionIsEnabled(const std::unique_ptr &); + + void registerQueryHandler(QueryHandler*); + void unregisterQueryHandler(QueryHandler*); + const std::set &queryHandlers(); + + void registerFallbackProvider(FallbackProvider*); + void unregisterFallbackProvider(FallbackProvider*); + const std::set &fallbackProviders(); + +private: + + void loadExtension(const std::unique_ptr &); + void unloadExtension(const std::unique_ptr &); + + std::unique_ptr d; + +signals: + + void queryHandlerRegistered(QueryHandler*); + void queryHandlerUnregistered(QueryHandler*); + + void fallbackProviderRegistered(FallbackProvider*); + void fallbackProviderUnregistered(FallbackProvider*); + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/frontendmanager.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/frontendmanager.cpp --- albert-0.12.0/src/lib/albertcore/src/core/frontendmanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/frontendmanager.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,153 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include "frontendmanager.h" +#include "frontend.h" +#include "pluginspec.h" +using std::unique_ptr; +using std::vector; + + +namespace { +const char* CFG_FRONTEND_ID = "frontendId"; +const char* DEF_FRONTEND_ID = "org.albert.frontend.boxmodel.widgets"; +} + + +/** ***************************************************************************/ +class Core::FrontendManagerPrivate { +public: + vector> frontendPlugins; + Frontend* currentFrontend; +}; + + +/** ***************************************************************************/ +Core::FrontendManager::FrontendManager(QStringList pluginDirs) + : d(new FrontendManagerPrivate) { + + // Find plugins + for ( const QString &pluginDir : pluginDirs ) { + QDirIterator dirIterator(pluginDir, QDir::Files); + while (dirIterator.hasNext()) { + std::unique_ptr plugin(new PluginSpec(dirIterator.next())); + + if ( plugin->iid() != ALBERT_FRONTEND_IID ) + continue; + + if (std::any_of(d->frontendPlugins.begin(), d->frontendPlugins.end(), + [&](const unique_ptr &spec){ return plugin->id() == spec->id(); })) { + qWarning() << qPrintable(QString("Frontend IDs already exists. Skipping. (%1)").arg(plugin->path())); + continue; + } + + d->frontendPlugins.push_back(std::move(plugin)); + } + } + + if ( d->frontendPlugins.empty() ) + qFatal("No frontends available"); + + // Find the configured frontend, fallback to default if not configured + QSettings s(qApp->applicationName()); + QString id = s.value(CFG_FRONTEND_ID, DEF_FRONTEND_ID).toString(); + vector>::iterator it = + std::find_if(d->frontendPlugins.begin(), d->frontendPlugins.end(), + [&](std::unique_ptr &plugin){ + return plugin->id() == id; + }); + + if ( it == d->frontendPlugins.end() ) { + it = d->frontendPlugins.begin(); + qWarning("Frontend '%s' could not be found. Using %s instead.", + qPrintable(id), qPrintable((*it)->id())); + s.setValue(CFG_FRONTEND_ID, (*it)->id()); + } + + if ( !(*it)->load() ) + qFatal("Failed loading frontend"); + + d->currentFrontend = dynamic_cast((*it)->instance()); + if (!d->currentFrontend) + qFatal("Could not cast plugin instance to frontend"); +} + + +/** ***************************************************************************/ +Core::FrontendManager::~FrontendManager() { + +} + + + +/** ***************************************************************************/ +const std::vector > &Core::FrontendManager::frontendSpecs() const { + return d->frontendPlugins; +} + + + +/** ***************************************************************************/ +Core::Frontend *Core::FrontendManager::currentFrontend() { + return d->currentFrontend; +} + + + +/** ***************************************************************************/ +bool Core::FrontendManager::setCurrentFrontend(QString id) { + + QSettings s(qApp->applicationName()); + s.setValue(CFG_FRONTEND_ID, id); + + // Find plugin + vector>::iterator it = + std::find_if(d->frontendPlugins.begin(), d->frontendPlugins.end(), + [&](std::unique_ptr &spec){ + return spec->id() == id; + }); + if ( it == d->frontendPlugins.end() ) { + qWarning("Frontend '%s' could not be found.", qPrintable(id)); + return false; + } + std::unique_ptr &newFrontendSpec = *it; + + it = std::find_if(d->frontendPlugins.begin(), d->frontendPlugins.end(), + [&](std::unique_ptr &spec){ + return spec->id() == d->currentFrontend->id(); + }); + std::unique_ptr &oldFrontendSpec = *it; + + newFrontendSpec->load(); + + Frontend *newFrontend = dynamic_cast(newFrontendSpec->instance()); + if (!newFrontend) + qFatal("Could not cast plugin instance to frontend"); + + d->currentFrontend = newFrontend; + + oldFrontendSpec->unload(); + + emit frontendChanged(d->currentFrontend); + + return true; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/frontendmanager.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/frontendmanager.h --- albert-0.12.0/src/lib/albertcore/src/core/frontendmanager.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/frontendmanager.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include + +namespace Core { + +class Frontend; +class PluginSpec; +class FrontendManagerPrivate; + +class FrontendManager : public QObject +{ + Q_OBJECT + +public: + + FrontendManager(QStringList pluginroots); + ~FrontendManager(); + + const std::vector > &frontendSpecs() const; + + Frontend *currentFrontend(); + bool setCurrentFrontend(QString id); + +private: + + std::unique_ptr d; + +signals: + + void frontendChanged(Frontend*); + +}; + +} + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/history.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/history.cpp --- albert-0.12.0/src/lib/albertcore/src/core/history.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/history.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,76 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include "history.h" + + +Core::History::History(QObject *parent) : QObject(parent) { + currentLine_ = -1; // This means historymode is not active +} + + +/** ***************************************************************************/ +void Core::History::add(QString str) { + if (!str.isEmpty()){ + if (lines_.contains(str)) + lines_.removeAll(str); // Remove dups + lines_.prepend(str); + } +} + + +/** ***************************************************************************/ +QString Core::History::next() { + // Update the history at the beginnig + if (currentLine_ == -1) + updateHistory(); + + if (currentLine_+1 < static_cast(lines_.size()) + && static_cast(lines_.size())!=0 ) { + ++currentLine_; + return lines_[currentLine_]; + } else return QString(); +} + + +/** ***************************************************************************/ +QString Core::History::prev() { + if (0 < currentLine_) { + --currentLine_; + return lines_[currentLine_]; + } else return QString(); +} + + +/** ***************************************************************************/ +void Core::History::resetIterator() { + currentLine_ = -1; +} + + +/** ***************************************************************************/ +void Core::History::updateHistory() { + lines_.clear(); + QSqlQuery query; + query.exec("SELECT input FROM usages GROUP BY input ORDER BY max(timestamp) DESC"); + while (query.next()) + lines_.append(query.value(0).toString()); +} + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/matchcompare.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/matchcompare.cpp --- albert-0.12.0/src/lib/albertcore/src/core/matchcompare.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/matchcompare.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,65 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include "item.h" +#include "matchcompare.h" +using namespace std; + + +/** ***************************************************************************/ +map Core::MatchCompare::order; + +/** ***************************************************************************/ +bool Core::MatchCompare::operator()(const pair, uint> &lhs, + const pair, uint> &rhs) { + // Compare urgency then score + if (lhs.first->urgency() != rhs.first->urgency()) + return lhs.first->urgency() > rhs.first->urgency(); + return lhs.second > rhs.second; // Compare match score +} + + +/***************************************************************************** + * @brief Core::MatchCompare::update + * Update the usage score: + * Score of a single usage is 1/(+1). + * Accumulate all scores groupes by itemId. + * Normalize the scores to the range of UINT_MAX. + */ +void Core::MatchCompare::update() { + order.clear(); + QSqlQuery query; + query.exec("SELECT itemId, SUM(1/(julianday('now')-julianday(timestamp)+1)) AS score " + "FROM usages WHERE itemId<>'' GROUP BY itemId ORDER BY score DESC"); + double max; + if ( !query.next() ) + return; + max = query.value(1).toDouble(); + + do { + MatchCompare::order.emplace(query.value(0).toString(), + static_cast(query.value(1).toDouble()*UINT_MAX/max)); + } while (query.next()); +} + +/** ***************************************************************************/ +const std::map &Core::MatchCompare::usageScores() { + return order; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/matchcompare.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/matchcompare.h --- albert-0.12.0/src/lib/albertcore/src/core/matchcompare.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/matchcompare.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,44 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "item.h" + +namespace Core { + +/** + * @brief The MatchOrder class + * The implements the order of the results + */ +class MatchCompare +{ +public: + + bool operator()(const std::pair, uint>& lhs, + const std::pair, uint>& rhs); + + static void update(); + static const std::map &usageScores(); + +private: + + static std::map order; +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/plugin.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/plugin.cpp --- albert-0.12.0/src/lib/albertcore/src/core/plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/plugin.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,105 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "plugin.h" + +class Core::PluginPrivate +{ +public: + QString id; + std::unique_ptr settings; +}; + +Core::Plugin::Plugin(const QString &id) : d(new PluginPrivate) +{ + d->id = id; +} + +Core::Plugin::~Plugin() +{ + +} + +const QString &Core::Plugin::id() const +{ + return d->id; +} + +QDir Core::Plugin::cacheLocation() const +{ + QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); + if ( !cacheDir.exists(d->id) ) + cacheDir.mkdir(d->id); + cacheDir.cd(d->id); + return cacheDir; +} + +QDir Core::Plugin::configLocation() const +{ + QDir configDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)); + if ( !configDir.exists(d->id) ) + configDir.mkdir(d->id); + configDir.cd(d->id); + return configDir; +} + +QDir Core::Plugin::dataLocation() const +{ + QDir dataDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + if ( !dataDir.exists(d->id) ) + dataDir.mkdir(d->id); + dataDir.cd(d->id); + return dataDir; +} + +QSettings &Core::Plugin::settings() +{ + if ( !d->settings ){ + +// // Create a settings instance +// d->settings.reset(new QSettings(configLocation().filePath("config"), +// QSettings::Format::IniFormat)); + +// // Define a function to port the config from one settings to another +// std::function portRecursively = +// [&portRecursively](QSettings &from, QSettings &to){ + +// for ( const QString & key : from.childKeys() ) { +// to.setValue(key, from.value(key)); +// from.remove(key); +// } + +// for ( const QString & group : from.childGroups() ){ +// from.beginGroup(group); +// to.beginGroup(group); +// portRecursively(from, to); +// to.endGroup(); +// from.endGroup(); +// } +// }; + +// // Port the settings from the global settings to the new one +// QSettings oldSettings(qApp->applicationName()); +// oldSettings.beginGroup(d->id); +// portRecursively(oldSettings, *d->settings); + + d->settings.reset(new QSettings(qApp->applicationName())); + d->settings->beginGroup(d->id); + } + return *d->settings; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/pluginspec.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/pluginspec.cpp --- albert-0.12.0/src/lib/albertcore/src/core/pluginspec.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/pluginspec.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,160 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include "pluginspec.h" +#include "plugin.h" + + +/** ***************************************************************************/ +Core::PluginSpec::PluginSpec(const QString &path) : loader_(path) { + iid_ = loader_.metaData()["IID"].toString(); + id_ = metadata("id").toString(); + name_ = metadata("name").toString("N/A"); + version_ = metadata("version").toString("N/A"); + author_ = metadata("author").toString("N/A"); + dependencies_ = metadata("dependencies").toVariant().toStringList(); + state_ = State::NotLoaded; +} + + +/** ***************************************************************************/ +Core::PluginSpec::~PluginSpec() { + if ( state_ != State::NotLoaded ) + unload(); +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::path() const { + return loader_.fileName(); +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::iid() const { + return iid_; +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::id() const { + return id_; +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::name() const { + return name_; +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::version() const { + return version_; +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::author() const { + return author_; +} + + +/** ***************************************************************************/ +QStringList Core::PluginSpec::dependencies() const { + return dependencies_; +} + + +/** ***************************************************************************/ +QJsonValue Core::PluginSpec::metadata(const QString &key) const { + return loader_.metaData()["MetaData"].toObject()[key]; +} + + +/** ***************************************************************************/ +bool Core::PluginSpec::load() { + + Plugin *plugin = nullptr; + if ( state_ != State::Loaded ) { + try { + if ( !loader_.instance() ) + lastError_ = loader_.errorString(); + else if ( ! (plugin = dynamic_cast(loader_.instance())) ) + lastError_ = "Plugin instance is not of type Plugin"; + else + state_ = State::Loaded; + } catch (const std::exception& ex) { + lastError_ = ex.what(); + } catch (const std::string& s) { + lastError_ = QString::fromStdString(s); + } catch (const QString& s) { + lastError_ = s; + } catch (const char *s) { + lastError_ = s; + } catch (...) { + lastError_ = "Unkown exception in plugin constructor."; + } + + if (!plugin) { + qWarning() << qPrintable(QString("Failed loading plugin: %1 [%2]").arg(path()).arg(lastError_)); + loader_.unload(); + state_ = State::Error; + } + } + + return state_ == State::Loaded; +} + + +/** ***************************************************************************/ +void Core::PluginSpec::unload(){ + + /* + * Never really unload a plugin, since otherwise all objects instanciated by + * this extension (items, widgets, etc) and spread all over the app would + * have to be deleted. This is a lot of work and nobody cares about that + * little amount of extra KBs in RAM until next restart. + */ + + if ( state_ == State::Loaded ) + delete loader_.instance(); + state_ = State::NotLoaded; +} + + +/** ***************************************************************************/ +Core::PluginSpec::State Core::PluginSpec::state() const { + return state_; +} + + +/** ***************************************************************************/ +QString Core::PluginSpec::lastError() const { + return state_ == State::Error ? lastError_ : QString(); +} + + +/** ***************************************************************************/ +QObject *Core::PluginSpec::instance() { + return (state_ == State::Loaded) ? loader_.instance() : nullptr; +} + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/pluginspec.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/pluginspec.h --- albert-0.12.0/src/lib/albertcore/src/core/pluginspec.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/pluginspec.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,75 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include + +namespace Core { + +class PluginSpec +{ +public: + + enum class State : char { + Loaded, + NotLoaded, + Error + }; + + PluginSpec(const QString &path); + ~PluginSpec(); + PluginSpec(const PluginSpec &other) = delete; + PluginSpec &operator=(const PluginSpec &other) = delete; + + QString path() const; + QString iid() const; + QString id() const; + QString name() const; + QString version() const; + QString author() const; + QStringList dependencies() const; + QJsonValue metadata(const QString & key) const; + + bool load(); + void unload(); + State state() const; + QString lastError() const; + + QObject *instance(); + +private: + + QPluginLoader loader_; + QString iid_; + QString id_; + QString name_; + QString version_; + QString author_; + QStringList dependencies_; + QString lastError_; + State state_; + +}; + +} + + + + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/query.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/query.cpp --- albert-0.12.0/src/lib/albertcore/src/core/query.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/query.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,69 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "query.h" +#include "matchcompare.h" + + +/** ***************************************************************************/ +const QString &Core::Query::string() const { + return string_; +} + + +/** ***************************************************************************/ +const QString &Core::Query::rawString() const { + return rawString_; +} + + +/** ***************************************************************************/ +bool Core::Query::isTriggered() const { + return !trigger_.isNull(); +} + + +/** ***************************************************************************/ +const QString &Core::Query::trigger() const { + return trigger_; +} + + +/** ***************************************************************************/ +bool Core::Query::isValid() const { + return isValid_; +} + + +/** ***************************************************************************/ +void Core::Query::addMatchWithoutLock(const std::shared_ptr &item, uint score) { + auto it = MatchCompare::usageScores().find(item->id()); + if ( it == MatchCompare::usageScores().end() ) + results_.emplace_back(item, score/2); + else + results_.emplace_back(item, (static_cast(score)+it->second)/2); +} + + +/** ***************************************************************************/ +void Core::Query::addMatchWithoutLock(std::shared_ptr &&item, uint score) { + auto it = MatchCompare::usageScores().find(item->id()); + if ( it == MatchCompare::usageScores().end() ) + results_.emplace_back(std::move(item), score/2); + else + results_.emplace_back(std::move(item), (static_cast(score)+it->second)/2); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/queryexecution.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/queryexecution.cpp --- albert-0.12.0/src/lib/albertcore/src/core/queryexecution.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/queryexecution.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,394 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include "queryhandler.h" +#include "fallbackprovider.h" +#include "queryexecution.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "action.h" +#include "matchcompare.h" +#include "item.h" +#include "itemroles.h" +using namespace std; +using namespace chrono; + +namespace { + const int FETCH_SIZE = 20; +} + + +/** ***************************************************************************/ +Core::QueryExecution::QueryExecution(const set & queryHandlers, + const set &fallbackProviders, + const QString &queryString, + bool fetchIncrementally) { + + fetchIncrementally_ = fetchIncrementally; + query_.rawString_ = queryString; + query_.string_ = queryString; + + // Run with a single handler if the trigger matches + for ( QueryHandler *handler : queryHandlers ) { + for ( const QString& trigger : handler->triggers() ) { + if ( !trigger.isEmpty() && queryString.startsWith(trigger) ) { + query_.trigger_ = trigger; + query_.string_ = queryString.mid(trigger.size()); + ( handler->executionType()==QueryHandler::ExecutionType::Batch ) + ? batchHandlers_.insert(handler) + : realtimeHandlers_.insert(handler); + return; + } + } + } + + // Else run all batched handlers + for ( QueryHandler *queryHandler : queryHandlers ) + if ( queryHandler->executionType()==QueryHandler::ExecutionType::Batch ) + batchHandlers_.insert(queryHandler); + + // Get fallbacks + if ( !query_.string_.trimmed().isEmpty() ) + for ( FallbackProvider *fallbackProvider : fallbackProviders ) + for ( shared_ptr & item : fallbackProvider->fallbacks(queryString) ) + fallbacks_.emplace_back(move(item), 0); +} + + +/** ***************************************************************************/ +Core::QueryExecution::~QueryExecution() { + +} + + +/** ***************************************************************************/ +const Core::Query *Core::QueryExecution::query() { + return &query_; +} + + +/** ***************************************************************************/ +const Core::QueryExecution::State &Core::QueryExecution::state() const { + return state_; +} + + +/** ***************************************************************************/ +void Core::QueryExecution::setState(State state) { + state_ = state; + emit stateChanged(state_); +} + + +/** ***************************************************************************/ +int Core::QueryExecution::rowCount(const QModelIndex &) const { + return fetchIncrementally_ ? sortedItems_ : static_cast(results_.size()); +} + + +/** ***************************************************************************/ +QHash Core::QueryExecution::roleNames() const { + QHash roles; + roles[static_cast(ItemRoles::TextRole)] = "itemTextRole"; + roles[static_cast(ItemRoles::ToolTipRole)] = "itemToolTipRole"; + roles[static_cast(ItemRoles::DecorationRole)] = "itemDecorationRole"; + roles[static_cast(ItemRoles::CompletionRole)] = "itemCompletionStringRole"; + roles[static_cast(ItemRoles::ActionRole)] = "itemActionRole"; // used to activate items as well + roles[static_cast(ItemRoles::AltActionRole)] = "itemAltActionsRole"; // used to activate items as well + roles[static_cast(ItemRoles::FallbackRole)] = "itemFallbackRole"; // used to activate items as well + return roles; +} + + +/** ***************************************************************************/ +QVariant Core::QueryExecution::data(const QModelIndex &index, int role) const { + if (index.isValid()) { + const shared_ptr &item = results_[static_cast(index.row())].first; + + switch ( role ) { + case ItemRoles::TextRole: + return item->text(); + case ItemRoles::ToolTipRole: + return item->subtext(); + case ItemRoles::DecorationRole: + return item->iconPath(); + case ItemRoles::CompletionRole: + return item->completionString(); + case ItemRoles::ActionRole: + return (0 < static_cast(item->actions().size())) + ? item->actions()[0]->text() + : item->subtext(); + case ItemRoles::AltActionRole: { // Actions list + QStringList actionTexts; + for (const shared_ptr &action : item->actions()) + actionTexts.append(action->text()); + return actionTexts; + } + case ItemRoles::FallbackRole: + return "Search '"+ query_.rawString_ +"' using default fallback"; + } + } + return QVariant(); +} + + +/** ***************************************************************************/ +bool Core::QueryExecution::canFetchMore(const QModelIndex & /* index */) const +{ + if (fetchIncrementally_ && sortedItems_ < static_cast(results_.size())) + return true; + else + return false; +} + + +/** ***************************************************************************/ +void Core::QueryExecution::fetchMore(const QModelIndex & /* index */) +{ + int sortUntil = min(sortedItems_ + FETCH_SIZE, static_cast(results_.size())); + partial_sort(results_.begin() + sortedItems_, + results_.begin() + sortUntil, + results_.end(), + MatchCompare()); + beginInsertRows(QModelIndex(), sortedItems_, sortUntil-1); + sortedItems_ = sortUntil; + endInsertRows(); +} + + +/** ***************************************************************************/ +bool Core::QueryExecution::setData(const QModelIndex &index, const QVariant &value, int role) { + + if (index.isValid()) { + shared_ptr &item = results_[static_cast(index.row())].first; + QString activateditemId; + + switch ( role ) { + case ItemRoles::ActionRole:{ + if (0U < item->actions().size()){ + item->actions()[0]->activate(); + activateditemId = item->id(); + } + break; + } + case ItemRoles::AltActionRole:{ + size_t actionValue = static_cast(value.toInt()); + if (actionValue < item->actions().size()) { + item->actions()[actionValue]->activate(); + activateditemId = item->id(); + } + break; + } + case ItemRoles::FallbackRole:{ + if (0U < fallbacks_.size() && 0U < item->actions().size()) { + fallbacks_[0].first->actions()[0]->activate(); + activateditemId = fallbacks_[0].first->id(); + } + break; + } + } + + // Save usage + QSqlQuery query; + query.prepare("INSERT INTO usages (input, itemId) VALUES (:input, :itemId);"); + query.bindValue(":input", query_.rawString_); + query.bindValue(":itemId", item->id()); + if (!query.exec()) + qWarning() << query.lastError(); + return true; + } + return false; +} + + +/** ***************************************************************************/ +const map &Core::QueryExecution::runtimes() { + return runtimes_; +} + + +/** ***************************************************************************/ +void Core::QueryExecution::run() { + + setState(State::Running); + + if ( !batchHandlers_.empty() ) + return runBatchHandlers(); + + emit resultsReady(this); + + if ( !realtimeHandlers_.empty() ) + return runRealtimeHandlers(); + + setState(State::Finished); +} + + +/** ***************************************************************************/ +void Core::QueryExecution::cancel() { + futureWatcher_.disconnect(); + future_.cancel(); + query_.isValid_ = false; +} + + +/** ***************************************************************************/ +void Core::QueryExecution::runBatchHandlers() { + + // Call onBatchHandlersFinished when all handlers finished + connect(&futureWatcher_, &QFutureWatcher>::finished, + this, &QueryExecution::onBatchHandlersFinished); + + // Run the handlers concurrently and measure the runtimes + function(QueryHandler*)> func = [this](QueryHandler* queryHandler){ + system_clock::time_point start = system_clock::now(); + queryHandler->handleQuery(&query_); + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs MATCHES [%2]").arg(duration, 6).arg(queryHandler->id)); + return make_pair(queryHandler, static_cast(duration)); + }; + future_ = QtConcurrent::mapped(batchHandlers_.begin(), batchHandlers_.end(), func); + futureWatcher_.setFuture(future_); +} + + +/** ***************************************************************************/ +void Core::QueryExecution::onBatchHandlersFinished() { + + // Save the runtimes of the current future + for ( auto it = future_.begin(); it != future_.end(); ++it ) + runtimes_.emplace(it->first->id, it->second); + + // Move the items of the "pending results" into "results" + query_.mutex_.lock(); + swap(query_.results_, results_); + query_.results_.clear(); + query_.mutex_.unlock(); + + // Sort the results + if ( fetchIncrementally_ ) { + int sortUntil = min(sortedItems_ + FETCH_SIZE, static_cast(results_.size())); + partial_sort(results_.begin() + sortedItems_, results_.begin() + sortUntil, + results_.end(), MatchCompare()); + sortedItems_ = sortUntil; + } + else + std::sort(results_.begin(), results_.end(), MatchCompare()); + + if ( realtimeHandlers_.empty() ){ + if( results_.empty() && !query_.rawString_.isEmpty() ){ + beginInsertRows(QModelIndex(), 0, static_cast(fallbacks_.size()-1)); + results_ = std::move(fallbacks_); + endInsertRows(); + fetchIncrementally_ = false; + } + emit resultsReady(this); + setState(State::Finished); + } + else + { + emit resultsReady(this); + runRealtimeHandlers(); + } +} + + +/** ***************************************************************************/ +void Core::QueryExecution::runRealtimeHandlers() { + + // Call onRealtimeHandlersFinsished when all handlers finished + disconnect(&futureWatcher_, &QFutureWatcher>::finished, + this, &QueryExecution::onBatchHandlersFinished); + + connect(&futureWatcher_, &QFutureWatcher>::finished, + this, &QueryExecution::onRealtimeHandlersFinsished); + + // Run the handlers concurrently and measure the runtimes + function(QueryHandler*)> func = [this](QueryHandler* queryHandler){ + system_clock::time_point start = system_clock::now(); + queryHandler->handleQuery(&query_); + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs MATCHES REALTIME [%2]").arg(duration, 6).arg(queryHandler->id)); + return make_pair(queryHandler, static_cast(duration)); + }; + future_ = QtConcurrent::mapped(realtimeHandlers_.begin(), realtimeHandlers_.end(), func); + futureWatcher_.setFuture(future_); + + // Insert pending results every 50 milliseconds + connect(&fiftyMsTimer_, &QTimer::timeout, this, &QueryExecution::insertPendingResults); + fiftyMsTimer_.start(50); +} + + +/** ***************************************************************************/ +void Core::QueryExecution::onRealtimeHandlersFinsished() { + + // Save the runtimes of the current future + for ( auto it = future_.begin(); it != future_.end(); ++it ) + runtimes_.emplace(it->first->id, it->second); + + // Finally done + fiftyMsTimer_.stop(); + fiftyMsTimer_.disconnect(); + insertPendingResults(); + + if( results_.empty() && !query_.rawString_.isEmpty() ){ + beginInsertRows(QModelIndex(), 0, static_cast(fallbacks_.size()-1)); + results_ = std::move(fallbacks_); + endInsertRows(); + fetchIncrementally_ = false; + } + setState(State::Finished); +} + + +/** ***************************************************************************/ +void Core::QueryExecution::insertPendingResults() { + + if(query_.results_.size()) { + + QMutexLocker lock(&query_.mutex_); + + // When fetching incrementally, only emit if this is in the fetched range + if ( !fetchIncrementally_ || sortedItems_ == static_cast(results_.size())) + beginInsertRows(QModelIndex(), + static_cast(results_.size()), + static_cast(results_.size()+query_.results_.size()-1)); + + // Preallocate space to avoid multiple allocatoins + results_.reserve(results_.size() + query_.results_.size()); + + // Copy the items of the matches into the results + move(query_.results_.begin(), query_.results_.end(), back_inserter(results_)); + + // When fetching incrementally, only emit if this is in the fetched range + if ( !fetchIncrementally_ || sortedItems_ == static_cast(results_.size())) + endInsertRows(); + + // Clear the empty matches + query_.results_.clear(); + } +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/queryexecution.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/queryexecution.h --- albert-0.12.0/src/lib/albertcore/src/core/queryexecution.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/queryexecution.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,107 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "query.h" + +namespace Core { + +class QueryHandler; +class FallbackProvider; +class Extension; +class Item; + +/** + * @brief The QueryExecution class + * Represents the execution of a query + */ +class QueryExecution : public QAbstractListModel +{ + Q_OBJECT + +public: + + enum class State { Idle, Running, Finished }; + + QueryExecution(const std::set &, + const std::set &, + const QString &queryString, + bool fetchIncrementally); + ~QueryExecution(); + + const State &state() const; + + const Query *query(); + + void run(); + void cancel(); + + // Model interface + int rowCount(const QModelIndex &) const override; + QHash roleNames() const override; + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + bool canFetchMore(const QModelIndex &) const override; + void fetchMore(const QModelIndex &) override; + + const std::map &runtimes(); + +private: + + void setState(State state); + + void runBatchHandlers(); + void onBatchHandlersFinished(); + void runRealtimeHandlers(); + void onRealtimeHandlersFinsished(); + void insertPendingResults(); + + Query query_; + State state_; + + std::set batchHandlers_; + std::set realtimeHandlers_; + + mutable std::vector, uint>> results_; + mutable std::vector, uint>> fallbacks_; + mutable int sortedItems_ = 0; + bool fetchIncrementally_ = false; + + QTimer fiftyMsTimer_; + std::map runtimes_; + + QFuture> future_; + QFutureWatcher> futureWatcher_; + +signals: + + void resultsReady(QAbstractItemModel*); + void stateChanged(State state); + +}; + +} + + diff -Nru albert-0.12.0/src/lib/albertcore/src/core/querymanager.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/querymanager.cpp --- albert-0.12.0/src/lib/albertcore/src/core/querymanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/querymanager.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,181 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include "extension.h" +#include "extensionmanager.h" +#include "item.h" +#include "matchcompare.h" +#include "queryexecution.h" +#include "querymanager.h" +#include "queryhandler.h" +#include "fallbackprovider.h" +using namespace Core; +using namespace std; +using namespace std::chrono; + +namespace { +const char* CFG_INCREMENTAL_SORT = "incrementalSort"; +const bool DEF_INCREMENTAL_SORT = false; +} + +/** ***************************************************************************/ +Core::QueryManager::QueryManager(ExtensionManager* em, QObject *parent) + : QObject(parent), + extensionManager_(em) { + + // Initialize the order + Core::MatchCompare::update(); + + QSettings s(qApp->applicationName()); + incrementalSort_ = s.value(CFG_INCREMENTAL_SORT, DEF_INCREMENTAL_SORT).toBool(); +} + + +/** ***************************************************************************/ +QueryManager::~QueryManager() { + +} + + +/** ***************************************************************************/ +void Core::QueryManager::setupSession() { + + qDebug() << "========== SESSION SETUP STARTED =========="; + + system_clock::time_point start = system_clock::now(); + + // Call all setup routines + for (Core::QueryHandler *handler : extensionManager_->queryHandlers()) { + system_clock::time_point start = system_clock::now(); + handler->setupSession(); + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs SESSION SETUP [%2]").arg(duration, 6).arg(handler->id)); + } + + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs SESSION SETUP OVERALL").arg(duration, 6)); +} + + +/** ***************************************************************************/ +void Core::QueryManager::teardownSession() { + + qDebug() << "========== SESSION TEARDOWN STARTED =========="; + + system_clock::time_point start = system_clock::now(); + + // Call all teardown routines + for (Core::QueryHandler *handler : extensionManager_->queryHandlers()) { + system_clock::time_point start = system_clock::now(); + handler->teardownSession(); + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs SESSION TEARDOWN [%2]").arg(duration, 6).arg(handler->id)); + } + + // Clear views + emit resultsReady(nullptr); + + // Open database to store the runtimes + QSqlDatabase db = QSqlDatabase::database(); + QSqlQuery sqlQuery; + db.transaction(); + + // Delete finished queries and prepare sql transaction containing runtimes + decltype(pastQueries_)::iterator it = pastQueries_.begin(); + while ( it != pastQueries_.end()){ + if ( (*it)->state() != QueryExecution::State::Running ) { + + // Store the runtimes + for ( const pair &handlerRuntime : (*it)->runtimes() ) { + sqlQuery.prepare("INSERT INTO runtimes (extensionId, runtime) VALUES (:extensionId, :runtime);"); + sqlQuery.bindValue(":extensionId", handlerRuntime.first); + sqlQuery.bindValue(":runtime", handlerRuntime.second); + if (!sqlQuery.exec()) + qWarning() << sqlQuery.lastError(); + } + + // Delete the query + it = pastQueries_.erase(it); + } else + ++it; + } + + // Finally send the sql transaction + db.commit(); + + // Compute new match rankings + Core::MatchCompare::update(); + + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs SESSION TEARDOWN OVERALL").arg(duration, 6)); +} + + +/** ***************************************************************************/ +void Core::QueryManager::startQuery(const QString &searchTerm) { + + qDebug() << "========== QUERY:" << searchTerm << " =========="; + + if ( pastQueries_.size() ) { + // Stop last query + disconnect(pastQueries_.back().get(), &QueryExecution::resultsReady, + this, &QueryManager::resultsReady); + pastQueries_.back()->cancel(); + } + + system_clock::time_point start = system_clock::now(); + + // Start query + QueryExecution *currentQuery = new QueryExecution(extensionManager_->queryHandlers(), + extensionManager_->fallbackProviders(), + searchTerm, incrementalSort_); + connect(currentQuery, &QueryExecution::resultsReady, this, &QueryManager::resultsReady); + currentQuery->run(); + + connect(currentQuery, &QueryExecution::stateChanged, [start](QueryExecution::State state){ + if ( state == QueryExecution::State::Finished ) { + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs QUERY OVERALL").arg(duration, 6)); + } + }); + + pastQueries_.emplace_back(currentQuery); + + + long duration = duration_cast(system_clock::now()-start).count(); + qDebug() << qPrintable(QString("TIME: %1 µs SESSION TEARDOWN OVERALL").arg(duration, 6)); +} + + +/** ***************************************************************************/ +bool QueryManager::incrementalSort(){ + return incrementalSort_; +} + + +/** ***************************************************************************/ +void QueryManager::setIncrementalSort(bool value){ + QSettings(qApp->applicationName()).setValue(CFG_INCREMENTAL_SORT, value); + incrementalSort_ = value; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/querymanager.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/querymanager.h --- albert-0.12.0/src/lib/albertcore/src/core/querymanager.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/querymanager.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,55 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include + +namespace Core { + +class ExtensionManager; +class QueryExecution; + +class QueryManager final : public QObject +{ + Q_OBJECT + +public: + + QueryManager(ExtensionManager* em, QObject *parent = 0); + ~QueryManager(); + + void setupSession(); + void teardownSession(); + void startQuery(const QString &searchTerm); + + bool incrementalSort(); + void setIncrementalSort(bool value); + +private: + + ExtensionManager *extensionManager_; + std::list> pastQueries_; + bool incrementalSort_; + +signals: + + void resultsReady(QAbstractItemModel*); +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/grabkeybutton.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/grabkeybutton.cpp --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/grabkeybutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/grabkeybutton.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,104 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "grabkeybutton.h" + +/** ***************************************************************************/ + +Core::GrabKeyButton::GrabKeyButton(QWidget * parent) : QPushButton(parent) { + waitingForHotkey_ = false; + connect(this, &QPushButton::clicked, + this, &GrabKeyButton::onClick); +} + + + +/** ***************************************************************************/ +Core::GrabKeyButton::~GrabKeyButton() { +} + + + +/** ***************************************************************************/ +void Core::GrabKeyButton::onClick() { + oldText_ = text(); + setText("?"); + grabAll(); +} + + + +/** ***************************************************************************/ +void Core::GrabKeyButton::grabAll() { + grabKeyboard(); + grabMouse(); + waitingForHotkey_ = true; +} + + + +/** ***************************************************************************/ +void Core::GrabKeyButton::releaseAll() { + releaseKeyboard(); + releaseMouse(); + waitingForHotkey_ = false; +} + + + +/** ***************************************************************************/ +void Core::GrabKeyButton::keyPressEvent(QKeyEvent *event) { + if ( waitingForHotkey_ ) { + // Modifier pressed -> update the label + int key = event->key(); + int mods = event->modifiers(); + if(key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Meta ) { + setText(QKeySequence((mods&~Qt::GroupSwitchModifier)|Qt::Key_Question).toString());//QTBUG-45568 + event->accept(); + return; + } + + if(key == Qt::Key_Escape && mods == Qt::NoModifier) { + event->accept(); + setText(oldText_); + releaseAll(); // Can not be before since window closes on esc + return; + } + releaseAll(); + + setText(QKeySequence((mods&~Qt::GroupSwitchModifier)|key).toString()); //QTBUG-45568 + emit keyCombinationPressed(mods|key); + return; + } +// QWidget::keyPressEvent( event ); +} + + + +/** ***************************************************************************/ +void Core::GrabKeyButton::keyReleaseEvent(QKeyEvent *event) { + if ( waitingForHotkey_ ) { + // Modifier released -> update the label + int key = event->key(); + if(key == Qt::Key_Control || key == Qt::Key_Shift || key == Qt::Key_Alt || key == Qt::Key_Meta) { + setText(QKeySequence((event->modifiers()&~Qt::GroupSwitchModifier)|Qt::Key_Question).toString());//QTBUG-45568 + event->accept(); + return; + } + return; + } + QWidget::keyReleaseEvent( event ); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/grabkeybutton.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/grabkeybutton.h --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/grabkeybutton.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/grabkeybutton.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,46 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include + +namespace Core { + +class GrabKeyButton final : public QPushButton +{ + Q_OBJECT + +public: + GrabKeyButton(QWidget * parent = 0); + ~GrabKeyButton(); + +private: + bool waitingForHotkey_; + QString oldText_; + + void grabAll(); + void releaseAll(); + void onClick(); + void keyPressEvent (QKeyEvent *) override; + void keyReleaseEvent ( QKeyEvent* ) override; + +signals: + void keyCombinationPressed(int); +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/loadermodel.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/loadermodel.cpp --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/loadermodel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/loadermodel.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,104 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "loadermodel.h" +#include "extensionmanager.h" +#include "pluginspec.h" +using std::unique_ptr; +using namespace Core; + + + +/** ***************************************************************************/ +Core::LoaderModel::LoaderModel(ExtensionManager* pm, QObject *parent) + : QAbstractListModel(parent), extensionManager_(pm){ +} + + + +/** ***************************************************************************/ +int Core::LoaderModel::rowCount(const QModelIndex &) const { + return static_cast(extensionManager_->extensionSpecs().size()); +} + + + +/** ***************************************************************************/ +QVariant Core::LoaderModel::data(const QModelIndex &index, int role) const { + if (!index.isValid() || index.row() < 0 || rowCount() <= index.row()) + return QVariant(); + + const unique_ptr &loader = extensionManager_->extensionSpecs()[index.row()]; + + switch (role) { + case Qt::DisplayRole: + return loader->name(); + case Qt::ToolTipRole:{ + QString toolTip; + toolTip = QString("ID: %1\nVersion: %2\nAuthor: %3\n").arg(loader->id(), loader->version(), loader->author()); + if (!loader->lastError().isEmpty()) + toolTip.append(QString("Error: %1\n").arg(loader->lastError())); + if (!loader->dependencies().empty()) + toolTip.append(QString("Dependencies: %1\n").arg(loader->dependencies().join(", "))); + toolTip.append(QString("Path: %1").arg(loader->path())); + return toolTip; + } + case Qt::DecorationRole: + switch (loader->state()) { + case PluginSpec::State::Loaded: + return QIcon(":plugin_loaded"); + case PluginSpec::State::NotLoaded: + return QIcon(":plugin_notloaded"); + case PluginSpec::State::Error: + return QIcon(":plugin_error"); + } + case Qt::CheckStateRole: + return (extensionManager_->extensionIsEnabled(loader))?Qt::Checked:Qt::Unchecked; + default: + return QVariant(); + } +} + + + +/** ***************************************************************************/ +bool Core::LoaderModel::setData(const QModelIndex &index, const QVariant &value, int role) { + if (!index.isValid() || index.row() < 0 || rowCount() <= index.row()) + return false; + + switch (role) { + case Qt::CheckStateRole: + if (value == Qt::Checked) + extensionManager_->enableExtension(extensionManager_->extensionSpecs()[index.row()]); + else + extensionManager_->disableExtension(extensionManager_->extensionSpecs()[index.row()]); + dataChanged(index, index, {Qt::CheckStateRole}); + return true; + default: + return false; + } +} + + + +/** ***************************************************************************/ +Qt::ItemFlags Core::LoaderModel::flags(const QModelIndex &) const { + return Qt::ItemIsSelectable + |Qt::ItemIsUserCheckable + |Qt::ItemIsEnabled + |Qt::ItemNeverHasChildren; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/loadermodel.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/loadermodel.h --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/loadermodel.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/loadermodel.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,36 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include + +namespace Core { + +class ExtensionManager; + +class LoaderModel final : public QAbstractListModel +{ +public: + LoaderModel(Core::ExtensionManager* pm, QObject *parent = nullptr); + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex & index) const override; +private: + Core::ExtensionManager *extensionManager_; +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/settingswidget.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/settingswidget.cpp --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/settingswidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/settingswidget.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,314 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core_globals.h" +#include "extension.h" +#include "extensionmanager.h" +#include "frontend.h" +#include "frontendmanager.h" +#include "globalshortcut/hotkeymanager.h" +#include "loadermodel.h" +#include "pluginspec.h" +#include "querymanager.h" +#include "settingswidget.h" +#include "trayicon.h" +using namespace std; +using namespace Core; +using namespace GlobalShortcut; + +namespace { +const char* CFG_TERM = "terminal"; +const char* DEF_TERM = "xterm -e"; +} + +EXPORT_CORE QString terminalCommand; + + +/** ***************************************************************************/ +Core::SettingsWidget::SettingsWidget(ExtensionManager *extensionManager, + FrontendManager *frontendManager, + QueryManager *queryManager, + HotkeyManager *hotkeyManager, + TrayIcon *systemTrayIcon, + QWidget *parent, Qt::WindowFlags f) + : QWidget(parent, f), + extensionManager_(extensionManager), + frontendManager_(frontendManager), + queryManager_(queryManager), + hotkeyManager_(hotkeyManager), + trayIcon_(systemTrayIcon) { + + ui.setupUi(this); + + + /* + * GENERAL + */ + + // HOTKEY + QSet hks = hotkeyManager->hotkeys(); + if (hks.size() < 1) + ui.grabKeyButton_hotkey->setText("Press to set hotkey"); + else + ui.grabKeyButton_hotkey->setText(QKeySequence(*hks.begin()).toString()); // OMG + connect(ui.grabKeyButton_hotkey, &GrabKeyButton::keyCombinationPressed, + this, &SettingsWidget::changeHotkey); + + // TRAY + ui.checkBox_showTray->setChecked(trayIcon_->isVisible()); + connect(ui.checkBox_showTray, &QCheckBox::toggled, + trayIcon_, &TrayIcon::setVisible); + + // INCREMENTAL SORT + ui.checkBox_incrementalSort->setChecked(queryManager_->incrementalSort()); + connect(ui.checkBox_incrementalSort, &QCheckBox::toggled, + queryManager_, &QueryManager::setIncrementalSort); + + // FRONTEND + for ( const unique_ptr &plugin : frontendManager_->frontendSpecs() ){ + + // Add item (text and id) + ui.comboBox_frontend->addItem(plugin->name(), plugin->id()); + + // Add tooltip + ui.comboBox_frontend->setItemData(ui.comboBox_frontend->count()-1, + QString("%1\nID: %2\nVersion: %3\nAuthor: %4\nDependencies: %5") + .arg(plugin->name(), + plugin->id(), + plugin->version(), + plugin->author(), + plugin->dependencies().join(", ")), + Qt::ToolTipRole); + // Set to current if ids match + if ( plugin->id() == frontendManager_->currentFrontend()->id() ) + ui.comboBox_frontend->setCurrentIndex(ui.comboBox_frontend->count()-1); + } + + ui.tabGeneral->layout()->addWidget(frontendManager_->currentFrontend()->widget(ui.tabGeneral)); + + connect(ui.comboBox_frontend, static_cast(&QComboBox::currentIndexChanged), + [this](int i){ + QString id = ui.comboBox_frontend->itemData(i, Qt::UserRole).toString(); + frontendManager_->setCurrentFrontend(id); + + QLayoutItem* item; + for ( int i = ui.tabGeneral->layout()->count() - 1; i > 0; --i ) { + item = ui.tabGeneral->layout()->takeAt(i); + delete item->widget(); + delete item; + } + + ui.tabGeneral->layout()->addWidget(frontendManager_->currentFrontend()->widget(ui.tabGeneral)); + + }); + + + // TERM CMD (TOOOOOOOOOOODOOOOOOOOOO CENTRALIZE THIS) + // Define the (global extern) terminal command + terminalCommand = QSettings(qApp->applicationName()).value(CFG_TERM, DEF_TERM).toString(); + + // Available terms + std::vector> terms { + {"Cool Retro Term", "cool-retro-term -e"}, + {"Gnome Terminal", "gnome-terminal -x"}, + {"Konsole", "konsole -e"}, + {"LXTerminal", "lxterminal -e"}, + {"Mate-Termial", "mate-terminal -x"}, + {"RoxTerm", "roxterm -x"}, + {"Terminator", "terminator -x"}, + {"urxvt", "urxvt -e"}, + {"UXTerm", "uxterm -e"}, + {"XFCE-Terminal", "xfce4-terminal -x"}, + {"XTerm", "xterm -e"} + }; + + // Fill checkbox + for ( ulong i = 0; i < terms.size(); ++i ) { + if ( !QStandardPaths::findExecutable(terms[i].second.split(' ').first()).isEmpty() ){ + ui.comboBox_term->addItem(terms[i].first, terms[i].second); + if ( terms[i].second == terminalCommand ) + ui.comboBox_term->setCurrentIndex(static_cast(ui.comboBox_term->count()-1)); + } + } + ui.comboBox_term->insertSeparator(ui.comboBox_term->count()); + ui.comboBox_term->addItem(tr("Custom")); + + ui.lineEdit_term->setText(terminalCommand); + ui.lineEdit_term->setEnabled(ui.comboBox_term->currentIndex() == ui.comboBox_term->count()-1); + connect(ui.comboBox_term, static_cast(&QComboBox::currentIndexChanged), + [this](int index){ + if ( index != ui.comboBox_term->count()-1) { + terminalCommand = ui.comboBox_term->currentData(Qt::UserRole).toString(); + QSettings(qApp->applicationName()).setValue(CFG_TERM, terminalCommand); + } + ui.lineEdit_term->setEnabled(index == ui.comboBox_term->count()-1); + ui.lineEdit_term->setText(terminalCommand); + }); + + connect(ui.lineEdit_term, &QLineEdit::textEdited, [](QString str){ + terminalCommand = str; + QSettings(qApp->applicationName()).setValue(CFG_TERM, terminalCommand); + }); + + // Cache + connect(ui.pushButton_clearHistory, &QPushButton::clicked, [](){ + QSqlQuery("DELETE FROM usages;"); + }); + + + /* + * PLUGINS + */ + + // Show the plugins. This* widget takes ownership of the model + ui.listView_plugins->setModel(new LoaderModel(extensionManager_, ui.listView_plugins)); + + // Update infos when item is changed + connect(ui.listView_plugins->selectionModel(), &QItemSelectionModel::currentChanged, + this, &SettingsWidget::updatePluginInformations); + + connect(ui.listView_plugins->model(), &QAbstractListModel::dataChanged, + this, &SettingsWidget::onPluginDataChanged); + + // Initially hide the title label + ui.label_pluginTitle->hide(); + + + /* + * ABOUT + */ + + ui.about_text->setText(QString(ui.about_text->text()).replace("___versionstring___", qApp->applicationVersion())); + + QDesktopWidget *dw = QApplication::desktop(); + move(dw->availableGeometry(dw->screenNumber(QCursor::pos())).center() + -QPoint(width()/2,height()/2)); + raise(); + activateWindow(); +} + + + +/** ***************************************************************************/ +void SettingsWidget::updatePluginInformations(const QModelIndex & current) { + // Hidde the placehodler text + QLayoutItem *i = ui.widget_pluginInfos->layout()->takeAt(1); + delete i->widget(); + delete i; + + if ( extensionManager_->extensionSpecs()[static_cast(current.row())]->state() + == PluginSpec::State::Loaded ){ + Extension *extension = dynamic_cast( + extensionManager_->extensionSpecs()[static_cast(current.row())]->instance()); + if (!extension){ + qWarning() << "Cannot cast an object of extension spec to an extension!"; + return; // Should no happen + } + QWidget *pw = extension->widget(); + if ( pw->layout() != nullptr) + pw->layout()->setMargin(0); + ui.widget_pluginInfos->layout()->addWidget(pw);// Takes ownership + ui.label_pluginTitle->setText(extension->name()); + ui.label_pluginTitle->show(); + } + else{ + QString msg("Plugin not loaded.\n%1"); + QLabel *lbl = new QLabel(msg.arg(extensionManager_->extensionSpecs()[static_cast(current.row())]->lastError())); + lbl->setEnabled(false); + lbl->setAlignment(Qt::AlignCenter); + ui.widget_pluginInfos->layout()->addWidget(lbl); + ui.label_pluginTitle->hide(); + } +} + + + +/** ***************************************************************************/ +void SettingsWidget::changeHotkey(int newhk) { + int oldhk = *hotkeyManager_->hotkeys().begin(); //TODO Make cool sharesdpointer design + + // Try to set the hotkey + if (hotkeyManager_->registerHotkey(newhk)) { + QString hkText(QKeySequence((newhk&~Qt::GroupSwitchModifier)).toString());//QTBUG-45568 + ui.grabKeyButton_hotkey->setText(hkText); + QSettings(qApp->applicationName()).setValue("hotkey", hkText); + hotkeyManager_->unregisterHotkey(oldhk); + } else { + ui.grabKeyButton_hotkey->setText(QKeySequence(oldhk).toString()); + QMessageBox(QMessageBox::Critical, "Error", + QKeySequence(newhk).toString() + " could not be registered.", + QMessageBox::NoButton, + this).exec(); + } +} + + + +/** ***************************************************************************/ +void SettingsWidget::onPluginDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { + Q_UNUSED(bottomRight) + if (topLeft == ui.listView_plugins->currentIndex()) + for (int role : roles) + if (role == Qt::CheckStateRole) + updatePluginInformations(topLeft); +} + + + +/** ***************************************************************************/ +void SettingsWidget::keyPressEvent(QKeyEvent *event) { + if (event->modifiers() == Qt::NoModifier && event->key() == Qt::Key_Escape ) { + close(); + } +} + + + +/** ***************************************************************************/ +void SettingsWidget::closeEvent(QCloseEvent *event) { + if (hotkeyManager_->hotkeys().empty()) { + QMessageBox msgBox(QMessageBox::Critical, "Error", + "Hotkey is invalid, please set it. Press Ok to go "\ + "back to the settings, or press Cancel to quit albert.", + QMessageBox::Close|QMessageBox::Ok, + this); + msgBox.exec(); + if ( msgBox.result() == QMessageBox::Ok ) { + ui.tabs->setCurrentIndex(0); + show(); + } + else + qApp->quit(); + event->ignore(); + return; + } + event->accept(); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/settingswidget.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/settingswidget.h --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/settingswidget.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/settingswidget.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,60 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include "ui_settingswidget.h" + +namespace GlobalShortcut { +class HotkeyManager; +} +namespace Core { +class ExtensionManager; +class FrontendManager; +class QueryManager; +class MainWindow; +class TrayIcon; + +class SettingsWidget final : public QWidget +{ + Q_OBJECT + +public: + + SettingsWidget(ExtensionManager *extensionManager, + FrontendManager *frontendManager, + QueryManager *queryManager, + GlobalShortcut::HotkeyManager *hotkeyManager, + TrayIcon *trayIcon, + QWidget * parent = 0, Qt::WindowFlags f = 0); + +private: + + void keyPressEvent(QKeyEvent * event) override; + void closeEvent(QCloseEvent * event) override; + void onPluginDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); + void changeHotkey(int); + void updatePluginInformations(const QModelIndex & curr); + + ExtensionManager *extensionManager_; + FrontendManager *frontendManager_; + QueryManager *queryManager_; + GlobalShortcut::HotkeyManager *hotkeyManager_; + TrayIcon *trayIcon_; + Ui::SettingsDialog ui; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/settingswidget/settingswidget.ui albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/settingswidget.ui --- albert-0.12.0/src/lib/albertcore/src/core/settingswidget/settingswidget.ui 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/settingswidget/settingswidget.ui 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,440 @@ + + + Core::SettingsDialog + + + + 0 + 0 + 800 + 480 + + + + + 720 + 400 + + + + + 1280 + 720 + + + + Settings + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + General + + + + + + + + + 0 + 0 + + + + General + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Hotkey: + + + grabKeyButton_hotkey + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + Press to set hotkey. + + + + + + + + + + Frontend: + + + comboBox_frontend + + + + + + + + 0 + 0 + + + + Choose the frontend to use. + + + + + + + Ter&minal: + + + comboBox_term + + + + + + + + 0 + 0 + + + + Choose the terminal to use. + + + + + + + Terminal command: + + + lineEdit_term + + + + + + + This is the command that is used to start +terminal. Chose "Custom" in the checkbox +above to set it manually. + + + + + + + Show tray icon: + + + checkBox_showTray + + + + + + + If this option is enabled, albert displays +an icon in the system tray. + + + + + + + + + + I&ncremental sort: + + + checkBox_incrementalSort + + + + + + + If this option is enabled only the visble items are sorted. +This improves the performance when displaying huge +result sets. However the size of the scrollbar will be less +intuitive since the height of the scrollbar is determined by +the sorted results instead of the actual amount of results. + + + + + + + &Clear history: + + + pushButton_clearHistory + + + + + + + + 0 + 0 + + + + Clears the history database. Note that this will +reset your sort order of recently used items too. + + + Clear + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + Extensions + + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + Qt::ScrollBarAlwaysOff + + + true + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + font-size: 12pt;padding-bottom: 5px; + + + + + + + false + + + Select a plugin. + + + Qt::AlignCenter + + + + + + + + + + + About + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + :/app_icon + + + false + + + Qt::AlignCenter + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html> +<head> +<meta name="qrichtext" content="1" /> +<style type="text/css"> +p, li { white-space: pre-wrap; } +a { color: "#00CCCC"; } +</style> +</head> +<body> +<h2>Albert launcher ___versionstring___</h2> +<p>If you encounter bugs or think you have suggestions for improvement, tell me at <a href="https://github.com/albertlauncher/albert/issues">Github</a>.</p> +<p>If you really like this software please consider a donation via <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&amp;hosted_button_id=W74BQPKPGNSNC">PayPal</a> or become a <a href="https://www.patreon.com/albertlauncher">patron</a>.</p> +<p>I'd like to thank all <a href="https://github.com/albertlauncher/albert/graphs/contributors">contributors</a>, <a href="https://albertlauncher.github.io/docs/contributing/#supporters">supporters</a> and users. You keep this project going on.</p> +</body> +</html> + + + Qt::AlignCenter + + + true + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + GrabKeyButton + QPushButton +
grabkeybutton.h
+
+
+ + tabs + grabKeyButton_hotkey + comboBox_frontend + comboBox_term + lineEdit_term + checkBox_showTray + checkBox_incrementalSort + listView_plugins + + + + + + +
diff -Nru albert-0.12.0/src/lib/albertcore/src/core/trayicon.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/core/trayicon.cpp --- albert-0.12.0/src/lib/albertcore/src/core/trayicon.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/trayicon.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,39 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "trayicon.h" + +namespace { + const char* CFG_SHOWTRAY = "showTray"; + const bool DEF_SHOWTRAY = true; +} + +/** ***************************************************************************/ +Core::TrayIcon::TrayIcon() { + setIcon(qApp->windowIcon()); + if (QSettings(qApp->applicationName()).value(CFG_SHOWTRAY, DEF_SHOWTRAY).toBool()) + setVisible(true); +} + + +/** ***************************************************************************/ +void Core::TrayIcon::setVisible(bool enable) { + QSettings(qApp->applicationName()).setValue(CFG_SHOWTRAY, enable); + QSystemTrayIcon::setVisible(enable); + emit stateChanged(enable); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/core/trayicon.h albert-0.13.1+plugins1/src/lib/albertcore/src/core/trayicon.h --- albert-0.12.0/src/lib/albertcore/src/core/trayicon.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/core/trayicon.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,39 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include + +namespace Core { + +class TrayIcon : public QSystemTrayIcon +{ + Q_OBJECT + +public: + + TrayIcon(); + + void setVisible(bool = true); + +signals: + + void stateChanged(bool); +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/fuzzysearch.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/fuzzysearch.cpp --- albert-0.12.0/src/lib/albertcore/src/util/fuzzysearch.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/fuzzysearch.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,247 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include "fuzzysearch.h" +#include "indexable.h" +#include "prefixsearch.h" +using std::map; +using std::set; +using std::pair; +using std::shared_ptr; +using std::vector; + +namespace { + +bool checkPrefixEditDistance(const QString &prefix, const QString &str, uint delta) { + uint n = prefix.size() + 1; + uint m = std::min(prefix.size() + delta + 1, static_cast(str.size()) + 1); + + uint* matrix = new uint[n*m]; + + // Initialize left and top row. + for (uint i = 0; i < n; ++i) { matrix[i*m+0] = i; } + for (uint i = 0; i < m; ++i) { matrix[0*m+i] = i; } + + // Now fill the whole matrix. + for (uint i = 1; i < n; ++i) { + for (uint j = 1; j < m; ++j) { + uint dia = matrix[(i-1)*m+j-1] + (prefix[i-1] == str[j-1] ? 0 : 1); + matrix[i*m+j] = std::min(std::min( + dia, + matrix[i*m+j-1] + 1), + matrix[(i-1)*m+j] + 1); + } + } + + // Check the last row if there is an entry <= delta. + bool result = false; + for (uint j = 0; j < m; ++j) { + if (matrix[(n-1)*m+j] <= delta) { + result = true; + break; + } + } + delete[] matrix; + return result; +} + +} + + + +/** ***************************************************************************/ +Core::FuzzySearch::FuzzySearch(uint q, double d) : q_(q), delta_(d) { + +} + + + +/** ***************************************************************************/ +Core::FuzzySearch::FuzzySearch(const Core::PrefixSearch &rhs, uint q, double d) + : PrefixSearch(rhs), q_(q), delta_(d) { + // Iterate over the inverted index and build the qGramindex + for ( const std::pair> &invertedIndexEntry : invertedIndex_ ) { + QString spaced = QString(q_-1,' ').append(invertedIndexEntry.first); + for (uint i = 0 ; i < static_cast(invertedIndexEntry.first.size()); ++i) + ++qGramIndex_[spaced.mid(i,q_)][invertedIndexEntry.first]; + } +} + + + +/** ***************************************************************************/ +Core::FuzzySearch::~FuzzySearch() { + +} + + + +/** ***************************************************************************/ +void Core::FuzzySearch::add(const std::shared_ptr &indexable) { + + // Add indexable to the index + index_.push_back(indexable); + uint id = static_cast(index_.size()-1); + + // Add a mappings to the inverted index which maps on t. + vector indexStrings = indexable->indexStrings(); + for (const auto &idxStr : indexStrings) { + set words = splitString(idxStr.string); + for (const QString &w : words) { + + // Add word to inverted index (map word to item) + this->invertedIndex_[w].insert(id); + + // Build a qGram index (map substring to word) + QString spaced = QString(q_-1,' ').append(w); + for (uint i = 0 ; i < static_cast(w.size()); ++i) + ++qGramIndex_[spaced.mid(i,q_)][w]; //FIXME Currently occurences are not uses + } + } +} + + + +/** ***************************************************************************/ +void Core::FuzzySearch::clear() { + qGramIndex_.clear(); + invertedIndex_.clear(); + index_.clear(); +} + + + +/** ***************************************************************************/ +vector > Core::FuzzySearch::search(const QString &query) const { + + // Make words unique, lower and prefixfree + set words = splitString(query); + + // Quit if there are no words in query + if (words.empty()) + return vector>(); + + vector> resultsPerWord; // id, count + for ( const QString &word : words ) { + + uint delta = static_cast((delta_ < 1)? word.size()*delta_ : delta_); + + // Generate the qGrams of this word + map qGrams; + QString spaced(q_-1,' '); + spaced.append(word); + for ( uint i = 0; i < static_cast(word.size()); ++i ) + ++qGrams[spaced.mid(i,q_)]; + + // Get the words referenced by each qGram and count the references + map wordMatches; + for ( const pair &qGram : qGrams ) { + + // Find the qGram in the index, skip if nothing found + decltype(qGramIndex_)::const_iterator qGramIndexIt = qGramIndex_.find(qGram.first); + if ( qGramIndexIt == qGramIndex_.end() ) + continue; + + // Iterate over the set of words referenced by this qGram + for (const pair &indexEntry : qGramIndexIt->second) { + // CRUCIAL: The match can contain only the commom amount of qGrams + wordMatches[indexEntry.first] += std::min(qGram.second, indexEntry.second); + } + } + + // Unite the items referenced by the words accumulating their #matches + map results; // id, count + for (const pair &wordMatch : wordMatches) { + + /* + * Do some kind of (cheap) preselection by mathematical bound + * If the matched word has less than |word|-δ*q matching qGrams + * it cannot be a match. + * This is because a single error can reduce the common qGram by + * maximum q. δ errors can therefore reduce the common qGrams by + * maximum δ*q. If the common qGrams are less than |word|-δ*q this + * implies that there are more errors than δ. + */ + if (wordMatch.second < (word.size()-delta*q_) ) + continue; + + // Now check the (expensive) prefix edit distance + if (!checkPrefixEditDistance(word, wordMatch.first, delta)) + continue; + + // Checks should not be neccessary since this builds on the index + for(uint id : invertedIndex_.at(wordMatch.first)) { + results[id] += wordMatch.second; + } + } + + resultsPerWord.push_back(std::move(results)); + } + + // Intersect the set of items references by the (referenced) words + // This assusmes that there is at least one word (the query would not have + // been started elsewise) + vector> finalResult; + if (resultsPerWord.size() > 1) { + // Get the smallest list for intersection (performance) + uint smallest=0; + for (uint i = 1; i < static_cast(resultsPerWord.size()); ++i) + if (resultsPerWord[i].size() < resultsPerWord[smallest].size()) + smallest = i; + + bool allResultsContainEntry; + for (map::const_iterator r = resultsPerWord[smallest].begin(); + r != resultsPerWord[smallest].cend(); ++r) { + // Check if all results contain this entry + allResultsContainEntry=true; + uint accMatches = resultsPerWord[smallest][r->first]; + for (uint i = 0; i < static_cast(resultsPerWord.size()); ++i) { + // Ignore itself + if (i==smallest) + continue; + + // If it is in: check next relutlist + if (resultsPerWord[i].find(r->first) != resultsPerWord[i].end() ) { + // Accumulate matches + accMatches += resultsPerWord[i][r->first]; + continue; + } + + allResultsContainEntry = false; + break; + } + + // If this is not common, check the next entry + if (!allResultsContainEntry) + continue; + + // Finally this match is common an can be put into the results + finalResult.emplace_back(r->first, accMatches); + } + } else {// Else do it without intersction + for ( const pair &result : resultsPerWord[0] ) + finalResult.emplace_back(result.first, result.second); + } + + vector> result; + for (const pair &pair : finalResult) { + result.emplace_back(index_.at(pair.first)); + } + return result; +} + + diff -Nru albert-0.12.0/src/lib/albertcore/src/util/fuzzysearch.h albert-0.13.1+plugins1/src/lib/albertcore/src/util/fuzzysearch.h --- albert-0.12.0/src/lib/albertcore/src/util/fuzzysearch.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/fuzzysearch.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,52 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include "prefixsearch.h" + +namespace Core { + +class FuzzySearch final : public PrefixSearch +{ +public: + + explicit FuzzySearch(uint q = 3, double d = 1.0/3); + explicit FuzzySearch(const PrefixSearch& rhs, uint q = 3, double d = 1.0/3); + ~FuzzySearch(); + + void add(const std::shared_ptr &idxble) override; + void clear() override; + std::vector> search(const QString &req) const override; + inline double delta() const {return delta_;} + inline void setDelta(double d){delta_=d;} + +private: + + // Map of qGrams, containing their word references and #occurences + std::map> qGramIndex_; + + // Size of the slices + uint q_; + + // Maximum error + double delta_; +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/offlineindex.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/offlineindex.cpp --- albert-0.12.0/src/lib/albertcore/src/util/offlineindex.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/offlineindex.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,101 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +#include "offlineindex.h" +#include "indexable.h" +#include "prefixsearch.h" +#include "fuzzysearch.h" + + +/** ***************************************************************************/ +Core::OfflineIndex::OfflineIndex(bool fuzzy) + : impl_((fuzzy) ? new FuzzySearch() : new PrefixSearch()){ +} + + +/** ***************************************************************************/ +Core::OfflineIndex::OfflineIndex(OfflineIndex &&other) { + impl_ = std::move(other.impl_); +} + + +/** ***************************************************************************/ +Core::OfflineIndex &Core::OfflineIndex::operator=(Core::OfflineIndex &&other) { + impl_ = std::move(other.impl_); + return *this; +} + + +/** ***************************************************************************/ +Core::OfflineIndex::~OfflineIndex() { + +} + + +/** ***************************************************************************/ +void Core::OfflineIndex::setFuzzy(bool fuzzy) { + if (dynamic_cast(impl_.get())) { + if (fuzzy) return; + impl_.reset(new PrefixSearch(*dynamic_cast(impl_.get()))); + } else if (dynamic_cast(impl_.get())) { + if (!fuzzy) return; + impl_.reset(new FuzzySearch(*dynamic_cast(impl_.get()))); + } else { + throw; //should not happen + } +} + + +/** ***************************************************************************/ +bool Core::OfflineIndex::fuzzy() { + return dynamic_cast(impl_.get()) != nullptr; +} + + +/** ***************************************************************************/ +void Core::OfflineIndex::setDelta(double d) { + FuzzySearch* f = dynamic_cast(impl_.get()); + if (f) + f->setDelta(d); +} + + +/** ***************************************************************************/ +double Core::OfflineIndex::delta() { + FuzzySearch* f = dynamic_cast(impl_.get()); + if (f) + return f->delta(); + return 0; +} + + +/** ***************************************************************************/ +void Core::OfflineIndex::add(const std::shared_ptr &idxble) { + impl_->add(idxble); +} + + +/** ***************************************************************************/ +void Core::OfflineIndex::clear() { + impl_->clear(); +} + + +/** ***************************************************************************/ +std::vector > Core::OfflineIndex::search(const QString &req) const { + return impl_->search(req); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/prefixsearch.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/prefixsearch.cpp --- albert-0.12.0/src/lib/albertcore/src/util/prefixsearch.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/prefixsearch.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,116 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include "indexable.h" +#include "prefixsearch.h" +using std::map; +using std::set; +using std::shared_ptr; +using std::vector; + + + +/** ***************************************************************************/ +Core::PrefixSearch::PrefixSearch(){ + +} + + +/** ***************************************************************************/ +Core::PrefixSearch::PrefixSearch(const Core::PrefixSearch &rhs) { + index_ = rhs.index_; + invertedIndex_ = rhs.invertedIndex_; +} + + +/** ***************************************************************************/ +Core::PrefixSearch::~PrefixSearch(){} + + +/** ***************************************************************************/ +void Core::PrefixSearch::add(const std::shared_ptr &indexable) { + + // Add indexable to the index + index_.push_back(indexable); + uint id = static_cast(index_.size()-1); + + vector indexStrings = indexable->indexStrings(); + for (const auto &idxStr : indexStrings) { + // Build an inverted index + QStringList words = idxStr.string.split(QRegularExpression(SEPARATOR_REGEX), QString::SkipEmptyParts); + for (const QString &w : words) { + invertedIndex_[w.toLower()].insert(id); + } + } +} + + +/** ***************************************************************************/ +void Core::PrefixSearch::clear() { + invertedIndex_.clear(); + index_.clear(); +} + + +/** ***************************************************************************/ +vector > Core::PrefixSearch::search(const QString &query) const { + + // Make words unique, lower and prefixfree + set words = splitString(query); + + // Skip if there arent any // CONSTRAINT (2): |W| > 0 + if (words.empty()) + return vector>(); + + set resultsSet; + set::iterator wordIt = words.begin(); + + // Get a word mapping once before going to handle intersections + for (std::map>::const_iterator lb = invertedIndex_.lower_bound(*wordIt); + lb != invertedIndex_.cend() && lb->first.startsWith(*wordIt); ++lb) + resultsSet.insert(lb->second.begin(), lb->second.end()); + wordIt++; + + for (;wordIt != words.end(); ++wordIt) { + + // Unite the sets that are mapped by words that begin with word + // w ∈ W. This set is called U_w + set wordMappingsUnion; + for (std::map>::const_iterator lb = invertedIndex_.lower_bound(*wordIt); + lb != invertedIndex_.cend() && lb->first.startsWith(*wordIt); ++lb) + wordMappingsUnion.insert(lb->second.begin(), lb->second.end()); + + // Intersect all sets U_w with the results + set intersection; + std::set_intersection(resultsSet.begin(), resultsSet.end(), + wordMappingsUnion.begin(), wordMappingsUnion.end(), + std::inserter(intersection, intersection.begin())); + + // Break if intersection is empty + if (intersection.empty()) + return vector>(); + + resultsSet = std::move(intersection); + } + + // Convert to a std::vector + vector> resultsVector; + for (uint id : resultsSet) + resultsVector.emplace_back(index_.at(id)); + return resultsVector; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/prefixsearch.h albert-0.13.1+plugins1/src/lib/albertcore/src/util/prefixsearch.h --- albert-0.12.0/src/lib/albertcore/src/util/prefixsearch.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/prefixsearch.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,125 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include +#include "searchbase.h" + +namespace Core { + +class IndexableItem; + +class PrefixSearch : public SearchBase +{ +public: + + PrefixSearch(); + PrefixSearch(const PrefixSearch &rhs); + ~PrefixSearch(); + + void add(const std::shared_ptr &idxble) override; + void clear() override; + std::vector> search(const QString &req) const override; + +protected: + + std::vector> index_; + std::map> invertedIndex_; +}; + + + + + + + + + + + + + + + + + + + + + + + + +// class CaseInsensitiveCompare; +// class CaseInsensitiveComparePrefix; + +//template +//struct PrefixSearch::CaseInsensitiveCompare +//{ +// inline bool operator()( Posting const &lhs, Posting const &rhs ) const { +// return (*this)(lhs.first, rhs.first); +// } + +// inline bool operator()( QString const &lhs, Posting const &rhs ) const { +// return (*this)(lhs, rhs.first); +// } + +// inline bool operator()( Posting const &lhs, QString const &rhs ) const { +// return (*this)(lhs.first, rhs); +// } + +// inline bool operator()( QString const &lhs, QString const &rhs ) const { +// return lhs.compare(rhs, Qt::CaseInsensitive)<0; +// } +//}; + +///** ***************************************************************************/ +//template +//struct PrefixSearch::CaseInsensitiveComparePrefix +//{ +// inline bool operator()( Posting const &pre, Posting const &rhs ) const { +// return (*this)(pre.first, rhs.first); +// } + +// inline bool operator()( QString const &pre, Posting const &rhs ) const { +// return (*this)(pre, rhs.first); +// } + +// inline bool operator()( Posting const &pre, QString const &rhs ) const { +// return (*this)(pre.first, rhs); +// } + +// inline bool operator()( QString const& pre, QString const& rhs ) const { +// QString::const_iterator a,b; +// a = pre.cbegin(); +// b = rhs.cbegin(); +// QChar ca,cb; +// while (a != pre.cend() && b != rhs.cend()) { +// ca = a++->toLower(); +// cb = b++->toLower(); +// if (ca < cb) +// return true; +// if (ca > cb) +// return false; +// } +// return false; +// } +//}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/searchbase.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/searchbase.cpp --- albert-0.12.0/src/lib/albertcore/src/util/searchbase.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/searchbase.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,45 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include "searchbase.h" +using std::set; + +Core::SearchBase::~SearchBase() { + +} + +std::set Core::SearchBase::splitString(const QString &str) const { + + // Split the query into words W + QStringList wordlist = str.toLower().split(QRegularExpression(SEPARATOR_REGEX), QString::SkipEmptyParts); + + // Make words unique + set words(wordlist.begin(), wordlist.end()); + + // Drop all words that are prefixes of others (since this an ordered set the next word) + for (auto it = words.begin(); it != words.end();) { + auto next = std::next(it); + if ( next != words.end() && next->startsWith(*it) ) + it = words.erase(it); + else + ++it; + } + + return words; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/searchbase.h albert-0.13.1+plugins1/src/lib/albertcore/src/util/searchbase.h --- albert-0.12.0/src/lib/albertcore/src/util/searchbase.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/searchbase.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,44 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include + +namespace Core { + +class IndexableItem; + +class SearchBase +{ +public: + + virtual ~SearchBase(); + virtual void add(const std::shared_ptr &idxble) = 0; + virtual void clear() = 0; + virtual std::vector> search(const QString &req) const = 0; + +protected: + + std::set splitString(const QString &) const; + + static constexpr const char* SEPARATOR_REGEX = "[!?<>\"'=+*.:,;\\\\\\/ _\\-]+"; + +}; + +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/shutil.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/shutil.cpp --- albert-0.12.0/src/lib/albertcore/src/util/shutil.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/shutil.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,128 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "shutil.h" +#include + + +/******************************************************************************/ +QString Core::ShUtil::quote(QString input) { + return QString("'%1'").arg(input.replace(R"(')", R"('"'"')")); +} + + +/******************************************************************************/ +QStringList Core::ShUtil::split(const QString &input) { + + QString part; + QStringList result; + QString::const_iterator it = input.begin(); + + while(it != input.end()){ + + // Check for a backslash (escape) + if (*it == '\\'){ + if (++it == input.end()){ + qWarning() << "EOL detected. Excpected one of {\",`,\\,$, ,\\n,\\t,',<,>,~,|,&,;,*,?,#,(,)}"; + return QStringList(); + } + + switch (it->toLatin1()) { + case 'n': part.push_back('\n'); + break; + case 't': part.push_back('\t'); + break; + case ' ': + case '\'': + case '<': + case '>': + case '~': + case '|': + case '&': + case ';': + case '*': + case '?': + case '#': + case '(': + case ')': + case '"': + case '`': + case '\\': + case '$': part.push_back(*it); + break; + default: + qWarning() << "Invalid char following \\. Excpected one of {\",`,\\,$, ,\\n,\\t,',<,>,~,|,&,;,*,?,#,(,)}"; + return QStringList(); + } + } + + // Check for quoted strings + else if (*it == '"'){ + while (true){ + if (++it == input.end()){ + qWarning() << "Detected EOL inside a qoute."; + return QStringList(); + } + + // Leave the "quotation loop" on double qoute + else if (*it == '"') + break; + + // Check for a backslash (escape) + else if (*it == '\\'){ + if (++it == input.end()){ + qWarning() << "EOL detected. Excpected one of {\",`,\\,$}"; + return QStringList(); + } + + switch (it->toLatin1()) { + case '"': + case '`': + case '\\': + case '$': part.push_back(*it); + break; + default: + qWarning() << "Invalid char following \\. Excpected one of {\",`,\\,$}"; + return QStringList(); + } + } + + // Accept everything else + else { + part.push_back(*it); + } + } + } + + // Check for spaces (separators) + else if (*it == ' '){ + result.push_back(part); + part.clear(); + } + + // Rest of input alphabet, save and continue + else { + part.push_back(*it); + } + + ++it; + } + + if (!part.isEmpty()) + result.push_back(part); + + return result; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/standardaction.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/standardaction.cpp --- albert-0.12.0/src/lib/albertcore/src/util/standardaction.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/standardaction.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,46 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "standardaction.h" +using std::function; + +Core::StandardAction::StandardAction(){ + +} + +Core::StandardAction::StandardAction(const QString &text, function f) + : text_(text), action_(f) { +} + +QString Core::StandardAction::text() const { + return text_; +} + +void Core::StandardAction::setText(const QString &text){ + text_ = text; +} + +const function &Core::StandardAction::action() { + return action_; +} + +void Core::StandardAction::setAction(function &&action){ + action_ = action; +} + +void Core::StandardAction::activate() { + action_(); +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/standardindexitem.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/standardindexitem.cpp --- albert-0.12.0/src/lib/albertcore/src/util/standardindexitem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/standardindexitem.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,75 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "standardindexitem.h" +#include "action.h" +using std::vector; +using std::shared_ptr; +using namespace Core; + +Core::StandardIndexItem::StandardIndexItem(const QString &id) : id_(id) { } + +QString Core::StandardIndexItem::id() const { + return id_; +} + +QString Core::StandardIndexItem::text() const { + return text_; +} + +void Core::StandardIndexItem::setText(const QString &text){ + text_ = text; +} + +QString Core::StandardIndexItem::subtext() const { + return subtext_; +} + +void Core::StandardIndexItem::setSubtext(const QString &subtext){ + subtext_ = subtext; +} + +QString Core::StandardIndexItem::completionString() const { + return (completion_.isNull()) ? text_ : completion_; +} + +void Core::StandardIndexItem::setCompletionString(const QString &completion) { + completion_ = completion; +} + +QString Core::StandardIndexItem::iconPath() const { + return iconPath_; +} + +void Core::StandardIndexItem::setIconPath(const QString &iconPath){ + iconPath_ = iconPath; +} + +vector> Core::StandardIndexItem::actions(){ + return actions_; +} + +void Core::StandardIndexItem::setActions(vector > &&actions){ + actions_ = actions; +} + +std::vector StandardIndexItem::indexStrings() const { + return indexStrings_; +} + +void StandardIndexItem::setIndexKeywords(vector &&indexStrings) { + indexStrings_ = indexStrings; +} diff -Nru albert-0.12.0/src/lib/albertcore/src/util/standarditem.cpp albert-0.13.1+plugins1/src/lib/albertcore/src/util/standarditem.cpp --- albert-0.12.0/src/lib/albertcore/src/util/standarditem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/albertcore/src/util/standarditem.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,66 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "standarditem.h" +#include "action.h" +using std::vector; +using std::shared_ptr; + +Core::StandardItem::StandardItem(const QString &id) : id_(id) { } + +QString Core::StandardItem::id() const { + return id_; +} + +QString Core::StandardItem::text() const { + return text_; +} + +void Core::StandardItem::setText(const QString &text){ + text_ = text; +} + +QString Core::StandardItem::subtext() const { + return subtext_; +} + +void Core::StandardItem::setSubtext(const QString &subtext){ + subtext_ = subtext; +} + +QString Core::StandardItem::completionString() const { + return (completion_.isNull()) ? text_ : completion_; +} + +void Core::StandardItem::setCompletionString(const QString &completion) { + completion_ = completion; +} + +QString Core::StandardItem::iconPath() const { + return iconPath_; +} + +void Core::StandardItem::setIconPath(const QString &iconPath){ + iconPath_ = iconPath; +} + +vector> Core::StandardItem::actions(){ + return actions_; +} + +void Core::StandardItem::setActions(vector > &&actions){ + actions_ = std::move(actions); +} diff -Nru albert-0.12.0/src/lib/CMakeLists.txt albert-0.13.1+plugins1/src/lib/CMakeLists.txt --- albert-0.12.0/src/lib/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/CMakeLists.txt 2017-09-30 09:43:39.000000000 +0000 @@ -2,6 +2,6 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) -add_subdirectory(albert) +add_subdirectory(albertcore) add_subdirectory(xdg) add_subdirectory(globalshortcut) diff -Nru albert-0.12.0/src/lib/globalshortcut/CMakeLists.txt albert-0.13.1+plugins1/src/lib/globalshortcut/CMakeLists.txt --- albert-0.12.0/src/lib/globalshortcut/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/CMakeLists.txt 2017-09-30 09:43:39.000000000 +0000 @@ -1,48 +1,38 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.3) project(globalshortcut) + add_definitions(-DGLOBALSHORTCUT) #export branch -# Get Qt libraries -find_package(Qt5 5.2.0 REQUIRED COMPONENTS Gui) +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Gui) -# List files in the source directory set(SRC - include/export_globalshortcut.h - include/hotkeymanager.h + include/globalshortcut/globalshortcut_globals.h + include/globalshortcut/hotkeymanager.h src/hotkeymanager.cpp ) -set(LIB - ${Qt5Gui_LIBRARIES} -) +set(LIB ${Qt5Gui_LIBRARIES}) -# Do platform specific pre target stuff if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - - find_package(Qt5 5.2.0 REQUIRED X11Extras) - + find_package(Qt5 5.5.0 REQUIRED X11Extras) set(SRC ${SRC} src/hotkeymanager_x11.cpp) set(LIB ${LIB} ${Qt5X11Extras_LIBRARIES} X11) - -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(SRC ${SRC} src/hotkey/hotkeymanager_win.cpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE") +endif() -endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - -# Define the target add_library(${PROJECT_NAME} SHARED ${SRC}) -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS target_include_directories(${PROJECT_NAME} - PUBLIC include - PRIVATE src + PUBLIC + include/ + PRIVATE + include/globalshortcut/ + src/ ) -# Link target to libraries target_link_libraries(${PROJECT_NAME} PRIVATE ${LIB}) -# Install target install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert) diff -Nru albert-0.12.0/src/lib/globalshortcut/include/export_globalshortcut.h albert-0.13.1+plugins1/src/lib/globalshortcut/include/export_globalshortcut.h --- albert-0.12.0/src/lib/globalshortcut/include/export_globalshortcut.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/include/export_globalshortcut.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#if defined(_MSC_VER) - #define EXPORT __declspec(dllexport) - #define IMPORT __declspec(dllimport) -#elif defined(__GNUC__) - #define EXPORT __attribute__((visibility("default"))) - #define IMPORT -#else - #define EXPORT - #define IMPORT - #pragma warning Unknown dynamic link import/export semantics. -#endif - -#ifdef GLOBALSHORTCUT - #define EXPORT_GLOBALSHORTCUT EXPORT -#else - #define EXPORT_GLOBALSHORTCUT IMPORT -#endif diff -Nru albert-0.12.0/src/lib/globalshortcut/include/globalshortcut/globalshortcut_globals.h albert-0.13.1+plugins1/src/lib/globalshortcut/include/globalshortcut/globalshortcut_globals.h --- albert-0.12.0/src/lib/globalshortcut/include/globalshortcut/globalshortcut_globals.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/include/globalshortcut/globalshortcut_globals.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,35 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#if defined(_MSC_VER) + #define EXPORT __declspec(dllexport) + #define IMPORT __declspec(dllimport) +#elif defined(__GNUC__) + #define EXPORT __attribute__((visibility("default"))) + #define IMPORT +#else + #define EXPORT + #define IMPORT + #pragma warning Unknown dynamic link import/export semantics. +#endif + +#ifdef GLOBALSHORTCUT + #define EXPORT_GLOBALSHORTCUT EXPORT +#else + #define EXPORT_GLOBALSHORTCUT IMPORT +#endif diff -Nru albert-0.12.0/src/lib/globalshortcut/include/globalshortcut/hotkeymanager.h albert-0.13.1+plugins1/src/lib/globalshortcut/include/globalshortcut/hotkeymanager.h --- albert-0.12.0/src/lib/globalshortcut/include/globalshortcut/hotkeymanager.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/include/globalshortcut/hotkeymanager.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,59 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "globalshortcut_globals.h" + +namespace GlobalShortcut { + +class HotkeyManagerPrivate; + +class EXPORT_GLOBALSHORTCUT HotkeyManager final : public QObject +{ + Q_OBJECT + +public: + HotkeyManager(QObject *parent = 0); + ~HotkeyManager(); + + bool registerHotkey(const QString&); + bool registerHotkey(const QKeySequence&); + bool registerHotkey(const int); + bool unregisterHotkey(const QString&); + bool unregisterHotkey(const QKeySequence&); + void unregisterHotkey(const int); + QSet hotkeys() {return hotkeys_;} + void enable(){ setEnabled(true); } + void disable(){ setEnabled(false); } + void setEnabled(bool enabled = true){enabled_ = enabled;} + bool isEnabled() const {return enabled_;} + +private: + void onHotkeyPressed(); + + bool enabled_; + QSet hotkeys_; + + std::unique_ptr d; + +signals: + void hotKeyPressed(); +}; + +} diff -Nru albert-0.12.0/src/lib/globalshortcut/include/hotkeymanager.h albert-0.13.1+plugins1/src/lib/globalshortcut/include/hotkeymanager.h --- albert-0.12.0/src/lib/globalshortcut/include/hotkeymanager.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/include/hotkeymanager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "export_globalshortcut.h" - -class HotkeyManagerPrivate; - -class EXPORT_GLOBALSHORTCUT HotkeyManager final : public QObject -{ - Q_OBJECT - -public: - HotkeyManager(QObject *parent = 0); - ~HotkeyManager(); - - bool registerHotkey(const QString&); - bool registerHotkey(const QKeySequence&); - bool registerHotkey(const int); - bool unregisterHotkey(const QString&); - bool unregisterHotkey(const QKeySequence&); - void unregisterHotkey(const int); - QSet hotkeys() {return hotkeys_;} - void enable(){ setEnabled(true); } - void disable(){ setEnabled(false); } - void setEnabled(bool enabled = true){enabled_ = enabled;} - bool isEnabled() const {return enabled_;} - -private: - void onHotkeyPressed(); - - bool enabled_; - QSet hotkeys_; - - std::unique_ptr d; - -signals: - void hotKeyPressed(); -}; diff -Nru albert-0.12.0/src/lib/globalshortcut/src/hotkeymanager.cpp albert-0.13.1+plugins1/src/lib/globalshortcut/src/hotkeymanager.cpp --- albert-0.12.0/src/lib/globalshortcut/src/hotkeymanager.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/src/hotkeymanager.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -14,45 +14,41 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "hotkeymanager.h" +#include "globalshortcut/hotkeymanager.h" #if defined __linux__ #include "hotkeymanager_x11.h" #elif defined __APPLE__ #elif defined _WIN32 #include "hotkeymanager_win.h" #endif - - - - #include /** ***************************************************************************/ -HotkeyManager::HotkeyManager(QObject *parent) : +GlobalShortcut::HotkeyManager::HotkeyManager(QObject *parent) : QObject(parent), d(new HotkeyManagerPrivate) { connect(d.get(), &HotkeyManagerPrivate::hotKeyPressed, this, &HotkeyManager::onHotkeyPressed); enabled_ = true; } /** ***************************************************************************/ -HotkeyManager::~HotkeyManager() { +GlobalShortcut::HotkeyManager::~HotkeyManager() { } /** ***************************************************************************/ -bool HotkeyManager::registerHotkey(const QString &hk) { +bool GlobalShortcut::HotkeyManager::registerHotkey(const QString &hk) { return registerHotkey(QKeySequence(hk)); } /** ***************************************************************************/ -bool HotkeyManager::registerHotkey(const QKeySequence &hk) { +bool GlobalShortcut::HotkeyManager::registerHotkey(const QKeySequence &hk) { if (hk.count() != 1) return false; return registerHotkey(hk[0]); } /** ***************************************************************************/ -bool HotkeyManager::registerHotkey(const int hk) { +bool GlobalShortcut::HotkeyManager::registerHotkey(const int hk) { if (hotkeys_.contains(hk)) return true; if (d->registerNativeHotkey(hk)) { @@ -63,12 +59,12 @@ } /** ***************************************************************************/ -bool HotkeyManager::unregisterHotkey(const QString &hk) { +bool GlobalShortcut::HotkeyManager::unregisterHotkey(const QString &hk) { return unregisterHotkey(QKeySequence(hk)); } /** ***************************************************************************/ -bool HotkeyManager::unregisterHotkey(const QKeySequence &hk) { +bool GlobalShortcut::HotkeyManager::unregisterHotkey(const QKeySequence &hk) { if (hk.count() != 1) return false; unregisterHotkey(hk[0]); @@ -76,7 +72,7 @@ } /** ***************************************************************************/ -void HotkeyManager::unregisterHotkey(const int hk) { +void GlobalShortcut::HotkeyManager::unregisterHotkey(const int hk) { if (!hotkeys_.contains(hk)) return; d->unregisterNativeHotkey(hk); @@ -84,7 +80,7 @@ } /** ***************************************************************************/ -void HotkeyManager::onHotkeyPressed() { +void GlobalShortcut::HotkeyManager::onHotkeyPressed() { if (enabled_) emit hotKeyPressed(); } diff -Nru albert-0.12.0/src/lib/globalshortcut/src/hotkeymanager_x11.cpp albert-0.13.1+plugins1/src/lib/globalshortcut/src/hotkeymanager_x11.cpp --- albert-0.12.0/src/lib/globalshortcut/src/hotkeymanager_x11.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/src/hotkeymanager_x11.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -26,83 +26,317 @@ #include "xcb/xcb.h" #include "xcb/xproto.h" #include "hotkeymanager_x11.h" +#include "X11/keysymdef.h" +#include "X11/XF86keysym.h" namespace { // http://cep.xray.aps.anl.gov/software/qt4-x11-4.2.2-browser/dc/d02/qkeymapper__x11_8cpp-source.html static std::map> QtToXSymsMap = { - { Qt::Key_Escape, { XK_Escape }}, // misc keys - { Qt::Key_Tab, { XK_Tab }}, - //{ Qt::Key_Backtab, { XK_}}, - { Qt::Key_Backspace, { XK_BackSpace }}, - { Qt::Key_Return, { XK_Return }}, - { Qt::Key_Enter, { XK_KP_Enter }}, - { Qt::Key_Insert, { XK_Insert, }}, - { Qt::Key_Delete, { XK_Delete }}, - { Qt::Key_Pause, { XK_Pause }}, - { Qt::Key_Print, { XK_Print }}, - { Qt::Key_SysReq, { XK_Sys_Req}}, - { Qt::Key_Clear, { XK_Clear}}, - { Qt::Key_Home, { XK_Home}},// cursor movement - { Qt::Key_End, { XK_End }}, - { Qt::Key_Left, { XK_Left }}, - { Qt::Key_Up, { XK_Up }}, - { Qt::Key_Right, { XK_Right }}, - { Qt::Key_Down, { XK_Down }}, - { Qt::Key_PageUp, { XK_Prior }}, - { Qt::Key_PageDown, { XK_Next }}, - { Qt::Key_Shift, { XK_Shift_L, XK_Shift_R, XK_Shift_Lock }},// modifiers - { Qt::Key_Control, { XK_Control_L, XK_Control_R }}, - { Qt::Key_Meta, { XK_Meta_L, XK_Meta_R }}, - { Qt::Key_Alt, { XK_Alt_L, XK_Alt_R }}, - { Qt::Key_CapsLock, { XK_Caps_Lock }}, - { Qt::Key_NumLock, { XK_Num_Lock }}, - { Qt::Key_ScrollLock, { XK_Scroll_Lock }}, - { Qt::Key_F1, { XK_F1 }}, // function keys - { Qt::Key_F2, { XK_F2 }}, - { Qt::Key_F3, { XK_F3 }}, - { Qt::Key_F4, { XK_F4 }}, - { Qt::Key_F5, { XK_F5 }}, - { Qt::Key_F6, { XK_F6 }}, - { Qt::Key_F7, { XK_F7 }}, - { Qt::Key_F8, { XK_F8 }}, - { Qt::Key_F9, { XK_F9 }}, - { Qt::Key_F10, { XK_F10 }}, - { Qt::Key_F11, { XK_F11 }}, - { Qt::Key_F12, { XK_F12 }}, - { Qt::Key_F13, { XK_F13 }}, - { Qt::Key_F14, { XK_F14 }}, - { Qt::Key_F15, { XK_F15 }}, - { Qt::Key_F16, { XK_F16 }}, - { Qt::Key_F17, { XK_F17 }}, - { Qt::Key_F18, { XK_F18 }}, - { Qt::Key_F19, { XK_F19 }}, - { Qt::Key_F20, { XK_F20 }}, - { Qt::Key_F21, { XK_F21 }}, - { Qt::Key_F22, { XK_F22 }}, - { Qt::Key_F23, { XK_F23 }}, - { Qt::Key_F24, { XK_F24 }}, - { Qt::Key_F25, { XK_F25 }}, // F25 .. F35 only on X11 - { Qt::Key_F26, { XK_F26 }}, - { Qt::Key_F27, { XK_F27 }}, - { Qt::Key_F28, { XK_F28 }}, - { Qt::Key_F29, { XK_F29 }}, - { Qt::Key_F30, { XK_F30 }}, - { Qt::Key_F31, { XK_F31 }}, - { Qt::Key_F32, { XK_F32 }}, - { Qt::Key_F33, { XK_F33 }}, - { Qt::Key_F34, { XK_F34 }}, - { Qt::Key_F35, { XK_F35 }}, - { Qt::Key_Super_L, { XK_Super_L }}, // extra keys - { Qt::Key_Super_R, { XK_Super_R }}, - { Qt::Key_Menu, { XK_Menu }}, - { Qt::Key_Hyper_L, { XK_Hyper_L }}, - { Qt::Key_Hyper_R, { XK_Hyper_R }}, - { Qt::Key_Help, { XK_Help }}, -// { Qt::Key_Direction_L, { XK_}}, -// { Qt::Key_Direction_R, { XK_}} - /* ascii 0x20 to 0xff */ + {Qt::Key_Escape, { XK_Escape }}, // misc keys + {Qt::Key_Tab, { XK_Tab }}, + {Qt::Key_Backtab, { XK_BackSpace }}, + {Qt::Key_Backspace, { XK_BackSpace }}, + {Qt::Key_Return, { XK_Return }}, + {Qt::Key_Enter, { XK_KP_Enter }}, + {Qt::Key_Insert, { XK_Insert, }}, + {Qt::Key_Delete, { XK_Delete }}, + {Qt::Key_Pause, { XK_Pause }}, + {Qt::Key_Print, { XK_Print }}, + {Qt::Key_SysReq, { XK_Sys_Req}}, + {Qt::Key_Clear, { XK_Clear}}, + {Qt::Key_Home, { XK_Home}},// cursor movement + {Qt::Key_End, { XK_End }}, + {Qt::Key_Left, { XK_Left }}, + {Qt::Key_Up, { XK_Up }}, + {Qt::Key_Right, { XK_Right }}, + {Qt::Key_Down, { XK_Down }}, + {Qt::Key_PageUp, { XK_Prior }}, + {Qt::Key_PageDown, { XK_Next }}, + {Qt::Key_Shift, { XK_Shift_L, XK_Shift_R, XK_Shift_Lock }},// modifiers + {Qt::Key_Control, { XK_Control_L, XK_Control_R }}, + {Qt::Key_Meta, { XK_Meta_L, XK_Meta_R }}, + {Qt::Key_Alt, { XK_Alt_L, XK_Alt_R }}, + {Qt::Key_AltGr, { XK_ISO_Level3_Shift }}, + {Qt::Key_CapsLock, { XK_Caps_Lock }}, + {Qt::Key_NumLock, { XK_Num_Lock }}, + {Qt::Key_ScrollLock, { XK_Scroll_Lock }}, + {Qt::Key_F1, { XK_F1 }}, // function keys + {Qt::Key_F2, { XK_F2 }}, + {Qt::Key_F3, { XK_F3 }}, + {Qt::Key_F4, { XK_F4 }}, + {Qt::Key_F5, { XK_F5 }}, + {Qt::Key_F6, { XK_F6 }}, + {Qt::Key_F7, { XK_F7 }}, + {Qt::Key_F8, { XK_F8 }}, + {Qt::Key_F9, { XK_F9 }}, + {Qt::Key_F10, { XK_F10 }}, + {Qt::Key_F11, { XK_F11 }}, + {Qt::Key_F12, { XK_F12 }}, + {Qt::Key_F13, { XK_F13 }}, + {Qt::Key_F14, { XK_F14 }}, + {Qt::Key_F15, { XK_F15 }}, + {Qt::Key_F16, { XK_F16 }}, + {Qt::Key_F17, { XK_F17 }}, + {Qt::Key_F18, { XK_F18 }}, + {Qt::Key_F19, { XK_F19 }}, + {Qt::Key_F20, { XK_F20 }}, + {Qt::Key_F21, { XK_F21 }}, + {Qt::Key_F22, { XK_F22 }}, + {Qt::Key_F23, { XK_F23 }}, + {Qt::Key_F24, { XK_F24 }}, + {Qt::Key_F25, { XK_F25 }}, // F25 .. F35 only on X11 + {Qt::Key_F26, { XK_F26 }}, + {Qt::Key_F27, { XK_F27 }}, + {Qt::Key_F28, { XK_F28 }}, + {Qt::Key_F29, { XK_F29 }}, + {Qt::Key_F30, { XK_F30 }}, + {Qt::Key_F31, { XK_F31 }}, + {Qt::Key_F32, { XK_F32 }}, + {Qt::Key_F33, { XK_F33 }}, + {Qt::Key_F34, { XK_F34 }}, + {Qt::Key_F35, { XK_F35 }}, + {Qt::Key_Super_L, { XK_Super_L }}, // extra keys + {Qt::Key_Super_R, { XK_Super_R }}, + {Qt::Key_Menu, { XK_Menu }}, + {Qt::Key_Hyper_L, { XK_Hyper_L }}, + {Qt::Key_Hyper_R, { XK_Hyper_R }}, + {Qt::Key_Help, { XK_Help }}, +// {Qt::Key_Direction_L, { XF86XK_D }}, +// {Qt::Key_Direction_R, { XK_ }}, + {Qt::Key_Multi_key, {XK_Multi_key}}, + {Qt::Key_Codeinput, {XK_Codeinput}}, + {Qt::Key_SingleCandidate, {XK_SingleCandidate}}, + {Qt::Key_MultipleCandidate, {XK_MultipleCandidate}}, + {Qt::Key_PreviousCandidate, {XK_PreviousCandidate}}, + {Qt::Key_Mode_switch, {XK_Mode_switch}}, + {Qt::Key_Kanji, {XK_Kanji}}, + {Qt::Key_Muhenkan, {XK_Muhenkan}}, + {Qt::Key_Henkan, {XK_Henkan}}, + {Qt::Key_Romaji, {XK_Romaji}}, + {Qt::Key_Hiragana, {XK_Hiragana}}, + {Qt::Key_Katakana, {XK_Katakana}}, + {Qt::Key_Hiragana_Katakana, {XK_Hiragana_Katakana}}, + {Qt::Key_Zenkaku, {XK_Zenkaku}}, + {Qt::Key_Hankaku, {XK_Hankaku}}, + {Qt::Key_Zenkaku_Hankaku, {XK_Zenkaku_Hankaku}}, + {Qt::Key_Touroku, {XK_Touroku}}, + {Qt::Key_Massyo, {XK_Massyo}}, + {Qt::Key_Kana_Lock, {XK_Kana_Lock}}, + {Qt::Key_Kana_Shift, {XK_Kana_Shift}}, + {Qt::Key_Eisu_Shift, {XK_Eisu_Shift}}, + {Qt::Key_Eisu_toggle, {XK_Eisu_toggle}}, + {Qt::Key_Hangul, {XK_Hangul}}, + {Qt::Key_Hangul_Start, {XK_Hangul_Start}}, + {Qt::Key_Hangul_End, {XK_Hangul_End}}, + {Qt::Key_Hangul_Hanja, {XK_Hangul_Hanja}}, + {Qt::Key_Hangul_Jamo, {XK_Hangul_Jamo}}, + {Qt::Key_Hangul_Romaja, {XK_Hangul_Romaja}}, + {Qt::Key_Hangul_Jeonja, {XK_Hangul_Jeonja}}, + {Qt::Key_Hangul_Banja, {XK_Hangul_Banja}}, + {Qt::Key_Hangul_PreHanja, {XK_Hangul_PreHanja}}, + {Qt::Key_Hangul_PostHanja, {XK_Hangul_PostHanja}}, + {Qt::Key_Hangul_Special, {XK_Hangul_Special}}, + {Qt::Key_Dead_Grave, {XK_dead_grave}}, + {Qt::Key_Dead_Acute, {XK_dead_acute}}, + {Qt::Key_Dead_Circumflex, {XK_dead_circumflex}}, + {Qt::Key_Dead_Tilde, {XK_dead_tilde}}, + {Qt::Key_Dead_Macron, {XK_dead_macron}}, + {Qt::Key_Dead_Breve, {XK_dead_breve}}, + {Qt::Key_Dead_Abovedot, {XK_dead_abovedot}}, + {Qt::Key_Dead_Diaeresis, {XK_dead_diaeresis}}, + {Qt::Key_Dead_Abovering, {XK_dead_abovering}}, + {Qt::Key_Dead_Doubleacute, {XK_dead_doubleacute}}, + {Qt::Key_Dead_Caron, {XK_dead_caron}}, + {Qt::Key_Dead_Cedilla, {XK_dead_cedilla}}, + {Qt::Key_Dead_Ogonek, {XK_dead_ogonek}}, + {Qt::Key_Dead_Iota, {XK_dead_iota}}, + {Qt::Key_Dead_Voiced_Sound, {XK_dead_voiced_sound}}, + {Qt::Key_Dead_Semivoiced_Sound, {XK_dead_semivoiced_sound}}, + {Qt::Key_Dead_Belowdot, {XK_dead_belowdot}}, + {Qt::Key_Dead_Hook, {XK_dead_hook}}, + {Qt::Key_Dead_Horn, {XK_dead_horn}}, + {Qt::Key_Back, {XF86XK_Back}}, + {Qt::Key_Forward, {XF86XK_Forward}}, + {Qt::Key_Stop, {XF86XK_Stop}}, + {Qt::Key_Refresh, {XF86XK_Refresh}}, + {Qt::Key_VolumeDown, {XF86XK_AudioLowerVolume}}, + {Qt::Key_VolumeMute, {XF86XK_AudioMute}}, + {Qt::Key_VolumeUp, {XF86XK_AudioRaiseVolume}}, +// {Qt::Key_BassBoost, {}}, +// {Qt::Key_BassUp, {}}, +// {Qt::Key_BassDown, {}}, +// {Qt::Key_TrebleUp, {}}, +// {Qt::Key_TrebleDown, {}}, + {Qt::Key_MediaPlay, {XF86XK_AudioPlay}}, + {Qt::Key_MediaStop, {XF86XK_AudioStop}}, + {Qt::Key_MediaPrevious, {XF86XK_AudioPrev}}, + {Qt::Key_MediaNext, {XF86XK_AudioNext}}, + {Qt::Key_MediaRecord, {XF86XK_AudioRecord}}, + {Qt::Key_MediaPause, {XF86XK_AudioPause}}, +// {Qt::Key_MediaTogglePlayPause, {}}, + {Qt::Key_HomePage, {XF86XK_HomePage}}, + {Qt::Key_Favorites, {XF86XK_Favorites}}, + {Qt::Key_Search, {XF86XK_Search}}, + {Qt::Key_Standby, {XF86XK_Standby}}, + {Qt::Key_OpenUrl, {XF86XK_OpenURL}}, + {Qt::Key_LaunchMail, {XF86XK_Mail}}, +// {Qt::Key_LaunchMedia, {}}, + {Qt::Key_Launch0, {XF86XK_Launch0}}, + {Qt::Key_Launch1, {XF86XK_Launch1}}, + {Qt::Key_Launch2, {XF86XK_Launch2}}, + {Qt::Key_Launch3, {XF86XK_Launch3}}, + {Qt::Key_Launch4, {XF86XK_Launch4}}, + {Qt::Key_Launch5, {XF86XK_Launch5}}, + {Qt::Key_Launch6, {XF86XK_Launch6}}, + {Qt::Key_Launch7, {XF86XK_Launch7}}, + {Qt::Key_Launch8, {XF86XK_Launch8}}, + {Qt::Key_Launch9, {XF86XK_Launch9}}, + {Qt::Key_LaunchA, {XF86XK_LaunchA}}, + {Qt::Key_LaunchB, {XF86XK_LaunchB}}, + {Qt::Key_LaunchC, {XF86XK_LaunchC}}, + {Qt::Key_LaunchD, {XF86XK_LaunchD}}, + {Qt::Key_LaunchE, {XF86XK_LaunchE}}, + {Qt::Key_LaunchF, {XF86XK_LaunchF}}, +// {Qt::Key_LaunchG, {}}, +// {Qt::Key_LaunchH, {}}, + {Qt::Key_MonBrightnessUp, {XF86XK_MonBrightnessUp}}, + {Qt::Key_MonBrightnessDown, {XF86XK_MonBrightnessDown}}, + {Qt::Key_KeyboardLightOnOff, {XF86XK_KbdLightOnOff}}, + {Qt::Key_KeyboardBrightnessUp, {XF86XK_KbdBrightnessUp}}, + {Qt::Key_KeyboardBrightnessDown, {XF86XK_KbdBrightnessDown}}, + {Qt::Key_PowerOff, {XF86XK_PowerOff}}, + {Qt::Key_WakeUp, {XF86XK_WakeUp}}, + {Qt::Key_Eject, {XF86XK_Eject}}, + {Qt::Key_ScreenSaver, {XF86XK_ScreenSaver}}, + {Qt::Key_WWW, {XF86XK_WWW}}, + {Qt::Key_Memo, {XF86XK_Memo}}, + {Qt::Key_LightBulb, {XF86XK_LightBulb}}, + {Qt::Key_Shop, {XF86XK_Shop}}, + {Qt::Key_History, {XF86XK_History}}, + {Qt::Key_AddFavorite, {XF86XK_AddFavorite}}, + {Qt::Key_HotLinks, {XF86XK_HotLinks}}, + {Qt::Key_BrightnessAdjust, {XF86XK_BrightnessAdjust}}, + {Qt::Key_Finance, {XF86XK_Finance}}, + {Qt::Key_Community, {XF86XK_Community}}, + {Qt::Key_AudioRewind, {XF86XK_AudioRewind}}, + {Qt::Key_BackForward, {XF86XK_BackForward}}, + {Qt::Key_ApplicationLeft, {XF86XK_ApplicationLeft}}, + {Qt::Key_ApplicationRight, {XF86XK_ApplicationRight}}, + {Qt::Key_Book, {XF86XK_Book}}, + {Qt::Key_CD, {XF86XK_CD}}, + {Qt::Key_Calculator, {XF86XK_Calculator}}, + {Qt::Key_ToDoList, {XF86XK_ToDoList}}, + {Qt::Key_ClearGrab, {XF86XK_ClearGrab}}, + {Qt::Key_Close, {XF86XK_Close}}, + {Qt::Key_Copy, {XF86XK_Copy}}, + {Qt::Key_Cut, {XF86XK_Cut}}, + {Qt::Key_Display, {XF86XK_Display}}, + {Qt::Key_DOS, {XF86XK_DOS}}, + {Qt::Key_Documents, {XF86XK_Documents}}, + {Qt::Key_Excel, {XF86XK_Excel}}, + {Qt::Key_Explorer, {XF86XK_Explorer}}, + {Qt::Key_Game, {XF86XK_Game}}, + {Qt::Key_Go, {XF86XK_Go}}, + {Qt::Key_iTouch, {XF86XK_iTouch}}, + {Qt::Key_LogOff, {XF86XK_LogOff}}, + {Qt::Key_Market, {XF86XK_Market}}, + {Qt::Key_Meeting, {XF86XK_Meeting}}, + {Qt::Key_MenuKB, {XF86XK_MenuKB}}, + {Qt::Key_MenuPB, {XF86XK_MenuPB}}, + {Qt::Key_MySites, {XF86XK_MySites}}, + {Qt::Key_News, {XF86XK_News}}, + {Qt::Key_OfficeHome, {XF86XK_OfficeHome}}, + {Qt::Key_Option, {XF86XK_Option}}, + {Qt::Key_Paste, {XF86XK_Paste}}, + {Qt::Key_Phone, {XF86XK_Phone}}, + {Qt::Key_Calendar, {XF86XK_Calendar}}, + {Qt::Key_Reply, {XF86XK_Reply}}, + {Qt::Key_Reload, {XF86XK_Reload}}, + {Qt::Key_RotateWindows, {XF86XK_RotateWindows}}, + {Qt::Key_RotationPB, {XF86XK_RotationPB}}, + {Qt::Key_RotationKB, {XF86XK_RotationKB}}, + {Qt::Key_Save, {XF86XK_Save}}, + {Qt::Key_Send, {XF86XK_Send}}, + {Qt::Key_Spell, {XF86XK_Spell}}, + {Qt::Key_SplitScreen, {XF86XK_SplitScreen}}, + {Qt::Key_Support, {XF86XK_Support}}, + {Qt::Key_TaskPane, {XF86XK_TaskPane}}, + {Qt::Key_Terminal, {XF86XK_Terminal}}, + {Qt::Key_Tools, {XF86XK_Tools}}, + {Qt::Key_Travel, {XF86XK_Travel}}, + {Qt::Key_Video, {XF86XK_Video}}, + {Qt::Key_Word, {XF86XK_Word}}, + {Qt::Key_Xfer, {XF86XK_Xfer}}, + {Qt::Key_ZoomIn, {XF86XK_ZoomIn}}, + {Qt::Key_ZoomOut, {XF86XK_ZoomOut}}, + {Qt::Key_Away, {XF86XK_Away}}, + {Qt::Key_Messenger, {XF86XK_Messenger}}, + {Qt::Key_WebCam, {XF86XK_WebCam}}, + {Qt::Key_MailForward, {XF86XK_MailForward}}, + {Qt::Key_Pictures, {XF86XK_Pictures}}, + {Qt::Key_Music, {XF86XK_Music}}, + {Qt::Key_Battery, {XF86XK_Battery}}, + {Qt::Key_Bluetooth, {XF86XK_Bluetooth}}, + {Qt::Key_WLAN, {XF86XK_WLAN}}, + {Qt::Key_UWB, {XF86XK_UWB}}, + {Qt::Key_AudioForward, {XF86XK_AudioForward}}, + {Qt::Key_AudioRepeat, {XF86XK_AudioRepeat}}, + {Qt::Key_AudioRandomPlay, {XF86XK_AudioRandomPlay}}, + {Qt::Key_Subtitle, {XF86XK_Subtitle}}, + {Qt::Key_AudioCycleTrack, {XF86XK_AudioCycleTrack}}, + {Qt::Key_Time, {XF86XK_Time}}, + {Qt::Key_Hibernate, {XF86XK_Hibernate}}, + {Qt::Key_View, {XF86XK_View}}, + {Qt::Key_TopMenu, {XF86XK_TopMenu}}, + {Qt::Key_PowerDown, {XF86XK_PowerDown}}, + {Qt::Key_Suspend, {XF86XK_Suspend}}, + {Qt::Key_ContrastAdjust, {XF86XK_ContrastAdjust}}, + {Qt::Key_TouchpadToggle, {XF86XK_TouchpadToggle}}, + {Qt::Key_TouchpadOn, {XF86XK_TouchpadOn}}, + {Qt::Key_TouchpadOff, {XF86XK_TouchpadOff}}, + {Qt::Key_MicMute, {XF86XK_AudioMicMute}}, + {Qt::Key_Red, {XF86XK_Red}}, + {Qt::Key_Green, {XF86XK_Green}}, + {Qt::Key_Yellow, {XF86XK_Yellow}}, + {Qt::Key_Blue, {XF86XK_Blue}}, +// {Qt::Key_ChannelUp, {}}, +// {Qt::Key_ChannelDown, {}}, +// {Qt::Key_Guide, {}}, +// {Qt::Key_Info, {}}, +// {Qt::Key_Settings, {}}, +// {Qt::Key_MicVolumeUp, {}}, +// {Qt::Key_MicVolumeDown, {}}, + {Qt::Key_New, {XF86XK_New}}, + {Qt::Key_Open, {XF86XK_Open}}, + {Qt::Key_Find, {XK_Find}}, + {Qt::Key_Undo, {XK_Undo}}, + {Qt::Key_Redo, {XK_Redo}}, +// {Qt::Key_MediaLast, {}}, +// {Qt::Key_unknown, {}}, + {Qt::Key_Call, {XF86XK_Phone}}, + {Qt::Key_Camera, {XF86XK_WebCam}}, +// {Qt::Key_CameraFocus, {}}, +// {Qt::Key_Context1, {}}, +// {Qt::Key_Context2, {}}, +// {Qt::Key_Context3, {}}, +// {Qt::Key_Context4, {}}, +// {Qt::Key_Flip, {}}, +// {Qt::Key_Hangup, {}}, +// {Qt::Key_No, {}}, + {Qt::Key_Select, {XF86XK_Select}}, + {Qt::Key_Yes, {}}, + {Qt::Key_ToggleCallHangup, {}}, + {Qt::Key_VoiceDial, {}}, + {Qt::Key_LastNumberRedial, {}}, + {Qt::Key_Execute, {XK_Execute}}, +// {Qt::Key_Printer, {}}, +// {Qt::Key_Play, {}}, + {Qt::Key_Sleep, {XF86XK_Sleep}}, + {Qt::Key_Zoom, {XF86XK_ZoomIn}}, + {Qt::Key_Exit, {XK_Cancel}}, + {Qt::Key_Cancel, {XK_Cancel}} }; @@ -164,7 +398,7 @@ } /** ***************************************************************************/ -HotkeyManagerPrivate::HotkeyManagerPrivate(QObject *parent) +GlobalShortcut::HotkeyManagerPrivate::HotkeyManagerPrivate(QObject *parent) : QObject(parent) { Display* dpy = QX11Info::display(); @@ -268,14 +502,14 @@ /** ***************************************************************************/ -HotkeyManagerPrivate::~HotkeyManagerPrivate() { +GlobalShortcut::HotkeyManagerPrivate::~HotkeyManagerPrivate() { } /** ***************************************************************************/ -bool HotkeyManagerPrivate::registerNativeHotkey(uint hotkey) { +bool GlobalShortcut::HotkeyManagerPrivate::registerNativeHotkey(uint hotkey) { // Convert to native format std::set keysX = nativeKeycodes(hotkey & ~Qt::KeyboardModifierMask); @@ -342,7 +576,7 @@ /** ***************************************************************************/ -void HotkeyManagerPrivate::unregisterNativeHotkey(uint hotkey) { +void GlobalShortcut::HotkeyManagerPrivate::unregisterNativeHotkey(uint hotkey) { // Convert to native format std::set keysX = nativeKeycodes(hotkey & ~Qt::KeyboardModifierMask); @@ -374,7 +608,7 @@ /** ***************************************************************************/ -std::set HotkeyManagerPrivate::nativeKeycodes(uint qtKey) { +std::set GlobalShortcut::HotkeyManagerPrivate::nativeKeycodes(uint qtKey) { /* Translate key symbol ( Qt -> X ) */ // Use latin if possible if (qtKey >= 0x20 && qtKey <= 0xff) @@ -393,7 +627,7 @@ /** ***************************************************************************/ -uint HotkeyManagerPrivate::nativeModifiers(uint qtMods) { +uint GlobalShortcut::HotkeyManagerPrivate::nativeModifiers(uint qtMods) { uint ret = 0; // if (qtMods & Qt::ShiftModifier) ret |= XCB_MOD_MASK_SHIFT; // if (qtMods & Qt::ControlModifier) ret |= XCB_MOD_MASK_CONTROL; @@ -409,7 +643,7 @@ /** ***************************************************************************/ -bool HotkeyManagerPrivate::nativeEventFilter(const QByteArray &eventType, void *message, long *) { +bool GlobalShortcut::HotkeyManagerPrivate::nativeEventFilter(const QByteArray &eventType, void *message, long *) { if ( eventType == "xcb_generic_event_t" ) { xcb_generic_event_t* ev = static_cast(message); if ( (ev->response_type & 127) == XCB_KEY_PRESS ) { diff -Nru albert-0.12.0/src/lib/globalshortcut/src/hotkeymanager_x11.h albert-0.13.1+plugins1/src/lib/globalshortcut/src/hotkeymanager_x11.h --- albert-0.12.0/src/lib/globalshortcut/src/hotkeymanager_x11.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/globalshortcut/src/hotkeymanager_x11.h 2017-09-30 09:43:39.000000000 +0000 @@ -22,6 +22,8 @@ struct _XDisplay; typedef _XDisplay Display; +namespace GlobalShortcut { + class HotkeyManagerPrivate final : public QObject, public QAbstractNativeEventFilter { Q_OBJECT @@ -57,3 +59,4 @@ void hotKeyPressed(); }; +} diff -Nru albert-0.12.0/src/lib/xdg/CMakeLists.txt albert-0.13.1+plugins1/src/lib/xdg/CMakeLists.txt --- albert-0.12.0/src/lib/xdg/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/CMakeLists.txt 2017-09-30 09:43:39.000000000 +0000 @@ -1,36 +1,23 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.1.3) project(xdg) -add_definitions(-DXDG) #export branch -# Get Qt libraries -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Core - Gui -) +add_definitions(-DXDG_DEF) #export branch -# List files in the source directory -FILE(GLOB SRC src/* include/*) +find_package(Qt5 5.5.0 REQUIRED COMPONENTS Gui) -# Do not export symbols by default -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) +file(GLOB SRC src/* include/*) -# Define the target add_library(${PROJECT_NAME} SHARED ${SRC}) -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS target_include_directories(${PROJECT_NAME} - PUBLIC include/ - PRIVATE src/ -) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} + PUBLIC + include/ PRIVATE - ${Qt5Core_LIBRARIES} - ${Qt5Gui_LIBRARIES} + include/xdg/ + src/ ) -# Install target +target_link_libraries(${PROJECT_NAME} PRIVATE ${Qt5Gui_LIBRARIES}) + install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert) diff -Nru albert-0.12.0/src/lib/xdg/include/export_xdg.h albert-0.13.1+plugins1/src/lib/xdg/include/export_xdg.h --- albert-0.12.0/src/lib/xdg/include/export_xdg.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/include/export_xdg.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#if defined(_MSC_VER) - #define EXPORT __declspec(dllexport) - #define IMPORT __declspec(dllimport) -#elif defined(__GNUC__) - #define EXPORT __attribute__((visibility("default"))) - #define IMPORT -#else - #define EXPORT - #define IMPORT - #pragma warning Unknown dynamic link import/export semantics. -#endif - -#ifdef XDG - #define EXPORT_XDG EXPORT -#else - #define EXPORT_XDG IMPORT -#endif diff -Nru albert-0.12.0/src/lib/xdg/include/xdg/iconlookup.h albert-0.13.1+plugins1/src/lib/xdg/include/xdg/iconlookup.h --- albert-0.12.0/src/lib/xdg/include/xdg/iconlookup.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/include/xdg/iconlookup.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,59 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once +#include +#include +#include +#include "xdg_globals.h" + +namespace XDG { + +class EXPORT_XDG IconLookup +{ +public: + + /** + * @brief iconPath Does XDG icon lookup for the given icon name + * @param iconName The icon name to lookup + * @param themeName The theme to use + * @return If an icon was found the path to the icon, else an empty string + */ + static QString iconPath(QString iconName, QString themeName = QIcon::themeName()); + + /** + * @brief iconPath Does XDG icon lookup for the given icon names, stops on success + * @param iconNames A list of icon names to lookup + * @param themeName The theme to use + * @return If one of the icons was found the path to the icon, else an empty string + */ + static QString iconPath(std::initializer_list iconNames, QString themeName = QIcon::themeName()); + +private: + + IconLookup(); + static IconLookup *instance(); + + QString themeIconPath(QString iconName, QString themeName = QIcon::themeName()); + QString doRecursiveIconLookup(const QString &iconName, const QString &theme, QStringList *checked); + QString doIconLookup(const QString &iconName, const QString &themeFile); + QString lookupThemeFile(const QString &themeName); + + QStringList iconDirs_; + QMap iconCache_; +}; + +} diff -Nru albert-0.12.0/src/lib/xdg/include/xdg/xdg_globals.h albert-0.13.1+plugins1/src/lib/xdg/include/xdg/xdg_globals.h --- albert-0.12.0/src/lib/xdg/include/xdg/xdg_globals.h 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/include/xdg/xdg_globals.h 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,35 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#if defined(_MSC_VER) + #define EXPORT __declspec(dllexport) + #define IMPORT __declspec(dllimport) +#elif defined(__GNUC__) + #define EXPORT __attribute__((visibility("default"))) + #define IMPORT +#else + #define EXPORT + #define IMPORT + #pragma warning Unknown dynamic link import/export semantics. +#endif + +#ifdef XDG_DEF + #define EXPORT_XDG EXPORT +#else + #define EXPORT_XDG IMPORT +#endif diff -Nru albert-0.12.0/src/lib/xdg/include/xdgiconlookup.h albert-0.13.1+plugins1/src/lib/xdg/include/xdgiconlookup.h --- albert-0.12.0/src/lib/xdg/include/xdgiconlookup.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/include/xdgiconlookup.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "export_xdg.h" - -class EXPORT_XDG XdgIconLookup -{ -public: - - static QString iconPath(QString iconName, QString themeName = QIcon::themeName()); - -private: - - XdgIconLookup(); - static XdgIconLookup *instance(); - - QString themeIconPath(QString iconName, QString themeName = QIcon::themeName()); - QString doRecursiveIconLookup(const QString &iconName, const QString &theme, QStringList *checked); - QString doIconLookup(const QString &iconName, const QString &themeFile); - QString lookupThemeFile(const QString &themeName); - - QStringList iconDirs_; - QMap iconCache_; -}; diff -Nru albert-0.12.0/src/lib/xdg/src/iconlookup.cpp albert-0.13.1+plugins1/src/lib/xdg/src/iconlookup.cpp --- albert-0.12.0/src/lib/xdg/src/iconlookup.cpp 1970-01-01 00:00:00.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/src/iconlookup.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -0,0 +1,216 @@ +// albert - a simple application launcher for linux +// Copyright (C) 2014-2017 Manuel Schneider +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include +#include "themefileparser.h" +#include "iconlookup.h" + + +namespace { + QStringList icon_extensions = {"png", "svg", "xpm"}; +} + + +/** ***************************************************************************/ +QString XDG::IconLookup::iconPath(QString iconName, QString themeName){ + return instance()->themeIconPath(iconName, themeName); +} + + + +/** ***************************************************************************/ +QString XDG::IconLookup::iconPath(std::initializer_list iconNames, QString themeName) { + for ( const QString &iconName : iconNames ) { + QString result = instance()->themeIconPath(iconName, themeName); + if ( !result.isEmpty() ) + return result; + } + return QString(); +} + + + +/** ***************************************************************************/ +XDG::IconLookup::IconLookup() +{ + /* + * Icons and themes are looked for in a set of directories. By default, + * apps should look in $HOME/.icons (for backwards compatibility), in + * $XDG_DATA_DIRS/icons and in /usr/share/pixmaps (in that order). + */ + + QString path = QDir::home().filePath(".icons"); + if (QFile::exists(path)) + iconDirs_.append(path); + + for (const QString &basedir : QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation)){ + path = QDir(basedir).filePath("icons"); + if (QFile::exists(path)) + iconDirs_.append(path); + } + + path = "/usr/share/pixmaps"; + if (QFile::exists(path)) + iconDirs_.append(path); +} + + + +/** ***************************************************************************/ +XDG::IconLookup *XDG::IconLookup::instance() +{ + static IconLookup *instance_ = nullptr; + if (!instance_) + instance_ = new IconLookup(); + return instance_; +} + + + +/** ***************************************************************************/ +QString XDG::IconLookup::themeIconPath(QString iconName, QString themeName){ + + // if we have an absolute path, just return it + if ( iconName[0]=='/' ){ + if ( QFile::exists(iconName) ) + return iconName; + else + return QString(); + } + + // check if it has an extension and strip it + for (const QString &ext : icon_extensions) + if (iconName.endsWith(QString(".").append(ext))) + iconName.chop(4); + + // Check cache + QString iconPath = iconCache_.value(iconName); + if (!iconPath.isNull()) + return iconPath; + + // Lookup themefile + QStringList checkedThemes; + iconPath = doRecursiveIconLookup(iconName, themeName, &checkedThemes); + if (!iconPath.isNull()){ + iconCache_.insert(iconName, iconPath); + return iconPath; + } + + // Lookup in hicolor + iconPath = doRecursiveIconLookup(iconName, "hicolor", &checkedThemes); + if (!iconPath.isNull()){ + iconCache_.insert(iconName, iconPath); + return iconPath; + } + + // Now search unsorted + for (const QString &iconDir : iconDirs_){ + for (const QString &ext : icon_extensions){ + QString filename = QString("%1/%2.%3").arg(iconDir, iconName, ext); + if (QFile(filename).exists()){ + return filename; + } + } + } + + return QString(); +} + + + +/** ***************************************************************************/ +QString XDG::IconLookup::doRecursiveIconLookup(const QString &iconName, const QString &themeName, QStringList *checked){ + + // Exlude multiple scans + if (checked->contains(themeName)) + return QString(); + checked->append(themeName); + + // Check if theme exists + QString themeFile = lookupThemeFile(themeName); + if (themeFile.isNull()) + return QString(); + + // Check if icon exists + QString iconPath; + iconPath = doIconLookup(iconName, themeFile); + if (!iconPath.isNull()) + return iconPath; + + // Check its parents too + for (const QString &parent : ThemeFileParser(themeFile).inherits()){ + iconPath = doRecursiveIconLookup(iconName, parent, checked); + if (!iconPath.isNull()) + return iconPath; + } + + return QString(); +} + + + +/** ***************************************************************************/ +QString XDG::IconLookup::doIconLookup(const QString &iconName, const QString &themeFile) { + + ThemeFileParser themeFileParser(themeFile); + QDir themeDir = QFileInfo(themeFile).dir(); + QString themeName = themeDir.dirName(); + + // Get the sizes of the dirs + std::vector> dirsAndSizes; + for (const QString &subdir : themeFileParser.directories()) + dirsAndSizes.push_back(std::make_pair(subdir, themeFileParser.size(subdir))); + + // Sort them by size + std::sort(dirsAndSizes.begin(), dirsAndSizes.end(), + [](std::pair a, std::pair b) { + return a.second > b.second; + }); + + // Well now search for a file beginning with the greatest + QString filename; + QFile file; + for (const auto &dirAndSize : dirsAndSizes){ + for (const QString &iconDir : iconDirs_){ + for (const QString &ext : icon_extensions){ + filename = QString("%1/%2/%3/%4.%5").arg(iconDir, themeName, dirAndSize.first, iconName, ext); + if (file.exists(filename)){ + return filename; + } + } + } + } + + return QString(); +} + + +/** ***************************************************************************/ +QString XDG::IconLookup::lookupThemeFile(const QString &themeName) +{ + // Lookup themefile + for (const QString &iconDir : iconDirs_){ + QString indexFile = QString("%1/%2/index.theme").arg(iconDir, themeName); + if (QFile(indexFile).exists()) + return indexFile; + } + return QString(); +} diff -Nru albert-0.12.0/src/lib/xdg/src/themefileparser.cpp albert-0.13.1+plugins1/src/lib/xdg/src/themefileparser.cpp --- albert-0.12.0/src/lib/xdg/src/themefileparser.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/src/themefileparser.cpp 2017-09-30 09:43:39.000000000 +0000 @@ -17,31 +17,31 @@ #include "themefileparser.h" /** ***************************************************************************/ -ThemeFileParser::ThemeFileParser(const QString& iniFilePath) +XDG::ThemeFileParser::ThemeFileParser(const QString& iniFilePath) : iniFile_(iniFilePath, QSettings::IniFormat) { } /** ***************************************************************************/ -QString ThemeFileParser::path() { +QString XDG::ThemeFileParser::path() { return iniFile_.fileName(); } /** ***************************************************************************/ -QString ThemeFileParser::name() { +QString XDG::ThemeFileParser::name() { return iniFile_.value("Icon Theme/Name").toString(); } /** ***************************************************************************/ -QString ThemeFileParser::comment() { +QString XDG::ThemeFileParser::comment() { return iniFile_.value("Icon Theme/Comment").toString(); } /** ***************************************************************************/ -QStringList ThemeFileParser::inherits() { +QStringList XDG::ThemeFileParser::inherits() { QStringList inherits = iniFile_.value("Icon Theme/Inherits").toStringList(); if ( inherits.isEmpty() && name() != "hicolor" ) inherits << "hicolor"; @@ -50,19 +50,19 @@ /** ***************************************************************************/ -QStringList ThemeFileParser::directories() { +QStringList XDG::ThemeFileParser::directories() { return iniFile_.value("Icon Theme/Directories").toStringList(); } /** ***************************************************************************/ -bool ThemeFileParser::hidden() { +bool XDG::ThemeFileParser::hidden() { return iniFile_.value("Icon Theme/Hidden").toBool(); } /** ***************************************************************************/ -int ThemeFileParser::size(const QString& directory) { +int XDG::ThemeFileParser::size(const QString& directory) { iniFile_.beginGroup(directory); int result = iniFile_.value("Size").toInt(); iniFile_.endGroup(); @@ -71,7 +71,7 @@ /** ***************************************************************************/ -QString ThemeFileParser::context(const QString& directory) { +QString XDG::ThemeFileParser::context(const QString& directory) { iniFile_.beginGroup(directory); QString result = iniFile_.value("Context").toString(); iniFile_.endGroup(); @@ -80,7 +80,7 @@ /** ***************************************************************************/ -QString ThemeFileParser::type(const QString& directory) { +QString XDG::ThemeFileParser::type(const QString& directory) { iniFile_.beginGroup(directory); QString result = iniFile_.contains("Type") ? iniFile_.value("Type").toString() : "Threshold"; @@ -90,7 +90,7 @@ /** ***************************************************************************/ -int ThemeFileParser::maxSize(const QString& directory) { +int XDG::ThemeFileParser::maxSize(const QString& directory) { iniFile_.beginGroup(directory); int result = iniFile_.contains("MaxSize") ? iniFile_.value("MaxSize").toInt() : size(directory); @@ -100,7 +100,7 @@ /** ***************************************************************************/ -int ThemeFileParser::minSize(const QString& directory) { +int XDG::ThemeFileParser::minSize(const QString& directory) { iniFile_.beginGroup(directory); int result = iniFile_.contains("MinSize") ? iniFile_.value("MinSize").toInt() : size(directory); @@ -110,7 +110,7 @@ /** ***************************************************************************/ -int ThemeFileParser::threshold(const QString& directory) { +int XDG::ThemeFileParser::threshold(const QString& directory) { iniFile_.beginGroup(directory); int result = iniFile_.contains("Threshold") ? iniFile_.value("Threshold").toInt() : 2; diff -Nru albert-0.12.0/src/lib/xdg/src/themefileparser.h albert-0.13.1+plugins1/src/lib/xdg/src/themefileparser.h --- albert-0.12.0/src/lib/xdg/src/themefileparser.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/src/themefileparser.h 2017-09-30 09:43:39.000000000 +0000 @@ -18,6 +18,8 @@ #include #include +namespace XDG { + class ThemeFileParser { public: @@ -42,3 +44,5 @@ QSettings iniFile_; }; + +} diff -Nru albert-0.12.0/src/lib/xdg/src/xdgiconlookup.cpp albert-0.13.1+plugins1/src/lib/xdg/src/xdgiconlookup.cpp --- albert-0.12.0/src/lib/xdg/src/xdgiconlookup.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/lib/xdg/src/xdgiconlookup.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include "themefileparser.h" -#include "xdgiconlookup.h" - - -namespace { - QStringList icon_extensions = {"png", "svg", "xpm"}; -} - - -/** ***************************************************************************/ -QString XdgIconLookup::iconPath(QString iconName, QString themeName){ - return instance()->themeIconPath(iconName, themeName); -} - -/** ***************************************************************************/ -XdgIconLookup::XdgIconLookup() -{ - /* - * Icons and themes are looked for in a set of directories. By default, - * apps should look in $HOME/.icons (for backwards compatibility), in - * $XDG_DATA_DIRS/icons and in /usr/share/pixmaps (in that order). - */ - - QString path = QDir::home().filePath(".icons"); - if (QFile::exists(path)) - iconDirs_.append(path); - - for (const QString &basedir : QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation)){ - path = QDir(basedir).filePath("icons"); - if (QFile::exists(path)) - iconDirs_.append(path); - } - - path = "/usr/share/pixmaps"; - if (QFile::exists(path)) - iconDirs_.append(path); -} - - - - -/** ***************************************************************************/ -XdgIconLookup *XdgIconLookup::instance() -{ - static XdgIconLookup *instance_ = nullptr; - if (!instance_) - instance_ = new XdgIconLookup(); - return instance_; -} - - -/** ***************************************************************************/ -QString XdgIconLookup::themeIconPath(QString iconName, QString themeName){ - - // if we have an absolute path, just return it - if ( iconName[0]=='/' ){ - if ( QFile::exists(iconName) ) - return iconName; - else - return QString(); - } - - // check if it has an extension and strip it - for (const QString &ext : icon_extensions) - if (iconName.endsWith(QString(".").append(ext))) - iconName.chop(4); - - // Check cache - QString iconPath = iconCache_.value(iconName); - if (!iconPath.isNull()) - return iconPath; - - // Lookup themefile - QStringList checkedThemes; - iconPath = doRecursiveIconLookup(iconName, themeName, &checkedThemes); - if (!iconPath.isNull()){ - iconCache_.insert(iconName, iconPath); - return iconPath; - } - - // Lookup in hicolor - iconPath = doRecursiveIconLookup(iconName, "hicolor", &checkedThemes); - if (!iconPath.isNull()){ - iconCache_.insert(iconName, iconPath); - return iconPath; - } - - // Now search unsorted - for (const QString &iconDir : iconDirs_){ - for (const QString &ext : icon_extensions){ - QString filename = QString("%1/%2.%3").arg(iconDir, iconName, ext); - if (QFile(filename).exists()){ - return filename; - } - } - } - - return QString(); -} - - - -/** ***************************************************************************/ -QString XdgIconLookup::doRecursiveIconLookup(const QString &iconName, const QString &themeName, QStringList *checked){ - - // Exlude multiple scans - if (checked->contains(themeName)) - return QString(); - checked->append(themeName); - - // Check if theme exists - QString themeFile = lookupThemeFile(themeName); - if (themeFile.isNull()) - return QString(); - - // Check if icon exists - QString iconPath; - iconPath = doIconLookup(iconName, themeFile); - if (!iconPath.isNull()) - return iconPath; - - // Check its parents too - for (const QString &parent : ThemeFileParser(themeFile).inherits()){ - iconPath = doRecursiveIconLookup(iconName, parent, checked); - if (!iconPath.isNull()) - return iconPath; - } - - return QString(); -} - - - -/** ***************************************************************************/ -QString XdgIconLookup::doIconLookup(const QString &iconName, const QString &themeFile) { - - ThemeFileParser themeFileParser(themeFile); - QDir themeDir = QFileInfo(themeFile).dir(); - QString themeName = themeDir.dirName(); - - // Get the sizes of the dirs - std::vector> dirsAndSizes; - for (const QString &subdir : themeFileParser.directories()) - dirsAndSizes.push_back(std::make_pair(subdir, themeFileParser.size(subdir))); - - // Sort them by size - std::sort(dirsAndSizes.begin(), dirsAndSizes.end(), - [](std::pair a, std::pair b) { - return a.second > b.second; - }); - - // Well now search for a file beginning with the greatest - QString filename; - QFile file; - for (const auto &dirAndSize : dirsAndSizes){ - for (const QString &iconDir : iconDirs_){ - for (const QString &ext : icon_extensions){ - filename = QString("%1/%2/%3/%4.%5").arg(iconDir, themeName, dirAndSize.first, iconName, ext); - if (file.exists(filename)){ - return filename; - } - } - } - } - - return QString(); -} - - -/** ***************************************************************************/ -QString XdgIconLookup::lookupThemeFile(const QString &themeName) -{ - // Lookup themefile - for (const QString &iconDir : iconDirs_){ - QString indexFile = QString("%1/%2/index.theme").arg(iconDir, themeName); - if (QFile(indexFile).exists()) - return indexFile; - } - return QString(); -} diff -Nru albert-0.12.0/src/plugins/applications/applications.qrc albert-0.13.1+plugins1/src/plugins/applications/applications.qrc --- albert-0.12.0/src/plugins/applications/applications.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/applications.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/application-x-executable.svg - - diff -Nru albert-0.12.0/src/plugins/applications/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/applications/CMakeLists.txt --- albert-0.12.0/src/plugins/applications/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(applications) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Concurrent - Widgets -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -qt5_wrap_ui(UI - configwidget.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${QRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Concurrent_LIBRARIES} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) - diff -Nru albert-0.12.0/src/plugins/applications/configwidget.ui albert-0.13.1+plugins1/src/plugins/applications/configwidget.ui --- albert-0.12.0/src/plugins/applications/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ - - - Applications::ConfigWidget - - - - 0 - 0 - 800 - 600 - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html> -<head> -</head> -<body> -<p>Applications are looked up in the &quot;<span style=" font-style:italic;">applications/&quot;</span> directories in the $XDG_DATA_HOME and $XDG_DATA_DIRS, which are set in the environment variables. Your current environment configuration results in the following applications directories: <span style=" font-weight:600; font-style:italic;">__XDG_DATA_DIRS__</span>. </p> -<p>Every application is represented by a desktop file which has an ID. The desktop file ID is built using the path of the desktop file relative to the applications directory and turning '/' into '-'. If multiple files have the same desktop file ID, the first one in the precedence order given above is used. For more details check the <a href="https://specifications.freedesktop.org/desktop-entry-spec/latest/">desktop entry specification</a>.</p></body></html> - - - true - - - - - - - - - - - - - Ignore OnlyShowIn/NotShowIn keys - - - - - - - Fuzzy - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/applications/metadata.json albert-0.13.1+plugins1/src/plugins/applications/metadata.json --- albert-0.12.0/src/plugins/applications/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.applications", - "name" : "Applications", - "version" : "1.1", - "platform" : "Linux", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : ["gksu"], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/applications/resources/application-x-executable.svg albert-0.13.1+plugins1/src/plugins/applications/resources/application-x-executable.svg --- albert-0.12.0/src/plugins/applications/resources/application-x-executable.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/resources/application-x-executable.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/applications/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/applications/src/configwidget.cpp --- albert-0.12.0/src/plugins/applications/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include "configwidget.h" - -/** ***************************************************************************/ -Applications::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); - - // Show the app dirs in the label - QStringList standardPaths = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); - ui.label->setText(ui.label->text().replace("__XDG_DATA_DIRS__", standardPaths.join(", "))); -} diff -Nru albert-0.12.0/src/plugins/applications/src/configwidget.h albert-0.13.1+plugins1/src/plugins/applications/src/configwidget.h --- albert-0.12.0/src/plugins/applications/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace Applications -{ -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - Ui::ConfigWidget ui; -}; -} diff -Nru albert-0.12.0/src/plugins/applications/src/main.cpp albert-0.13.1+plugins1/src/plugins/applications/src/main.cpp --- albert-0.12.0/src/plugins/applications/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,660 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "main.h" -#include "offlineindex.h" -#include "query.h" -#include "queryhandler.h" -#include "standardaction.h" -#include "standardindexitem.h" -#include "xdgiconlookup.h" -#include "shlex.h" -using std::map; -using std::pair; -using std::vector; -using std::shared_ptr; -using namespace Core; - -extern QString terminalCommand; - - -namespace { - -const char* CFG_FUZZY = "fuzzy"; -const bool DEF_FUZZY = false; -const char* CFG_IGNORESHOWINKEYS = "ignore_show_in_keys"; -const bool DEF_IGNORESHOWINKEYS = false; - -/******************************************************************************/ -QStringList expandedFieldCodes(const QStringList & unexpandedFields, - const QString & icon, - const QString & name, - const QString & path) { - /* - * A number of special field codes have been defined which will be expanded - * by the file manager or program launcher when encountered in the command - * line. Field codes consist of the percentage character ("%") followed by - * an alpha character. Literal percentage characters must be escaped as %%. - * Deprecated field codes should be removed from the command line and - * ignored. Field codes are expanded only once, the string that is used to - * replace the field code should not be checked for field codes itself. - * - * http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html - */ - QStringList expandedFields; - - for (const QString & field : unexpandedFields){ - - if (field == "%i" && !icon.isEmpty()) { - expandedFields.push_back("--icon"); - expandedFields.push_back(icon); - } - - QString tmpstr; - QString::const_iterator it = field.begin(); - - while (it != field.end()) { - if (*it == '%'){ - ++it; - if (it == field.end()) - break; - else if (*it=='%') - tmpstr.push_back("%"); - else if (*it=='c') - tmpstr.push_back(name); - else if (*it=='k') - tmpstr.push_back(path); - // TODO Unhandled f F u U - } - else - tmpstr.push_back(*it); - ++it; - } - if (!tmpstr.isEmpty()) - expandedFields.push_back(std::move(tmpstr)); - } - return expandedFields; -} - -/******************************************************************************/ -QString xdgStringEscape(const QString & unescaped) { - /* - * The escape sequences \s, \n, \t, \r, and \\ are supported for values of - * type string and localestring, meaning ASCII space, newline, tab, carriage - * return, and backslash, respectively. - * - * http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s03.html - */ - QString result; - QString::const_iterator it = unescaped.begin(); - while (it != unescaped.end()) { - if (*it == '\\'){ - ++it; - if (it == unescaped.end()) - break; - else if (*it=='s') - result.append(' '); - else if (*it=='n') - result.append('\n'); - else if (*it=='t') - result.append('\t'); - else if (*it=='r') - result.append('\r'); - else if (*it=='\\') - result.append('\\'); - } - else - result.append(*it); - ++it; - } - return result; -} - -/******************************************************************************/ -QString getLocalizedKey(const QString &key, const map &entries, const QLocale &loc) { - map::const_iterator it; - if ( (it = entries.find(QString("%1[%2]").arg(key, loc.name()))) != entries.end() - || (it = entries.find(QString("%1[%2]").arg(key, loc.name().left(2)))) != entries.end() - || (it = entries.find(key)) != entries.end()) - return it->second; - return QString(); -} - - - - -/** ***************************************************************************/ -vector> indexApplications(bool ignoreShowInKeys) { - - // Get a new index [O(n)] - vector> desktopEntries; - QStringList xdg_current_desktop = QString(getenv("XDG_CURRENT_DESKTOP")).split(':',QString::SkipEmptyParts); - QLocale loc; - QStringList xdgAppDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); - - // Iterate over all desktop files - for ( const QString &dir : xdgAppDirs ) { - QDirIterator fIt(dir, QStringList("*.desktop"), QDir::Files, - QDirIterator::Subdirectories|QDirIterator::FollowSymlinks); - while (fIt.hasNext()) { - fIt.next(); - - map> sectionMap; - map>::iterator sectionIterator; - - // Build the id - - QString id; - - // If file is in standard path use standard method else filename to build id - if ( std::any_of(xdgAppDirs.begin(), xdgAppDirs.end(), - [&fIt](const QString &dir){ return fIt.filePath().startsWith(dir); }) ) - id = fIt.filePath().remove(QRegularExpression("^.*applications/")).replace("/","-"); - else - id = fIt.fileName(); - - // Skip duplicate ids - if ( std::find_if(desktopEntries.begin(), desktopEntries.end(), - [&id](const shared_ptr & desktopEntry){ - return id == desktopEntry->id(); - }) != desktopEntries.end()) - continue; - - /* - * Get the data from the desktop file - */ - - // Read the file into a map - { - QFile file(fIt.filePath()); - if (!file.open(QIODevice::ReadOnly| QIODevice::Text)) continue; - QTextStream stream(&file); - QString currentGroup; - for (QString line=stream.readLine(); !line.isNull(); line=stream.readLine()) { - line = line.trimmed(); - if (line.startsWith('#') || line.isEmpty()) - continue; - if (line.startsWith("[")){ - currentGroup = line.mid(1,line.size()-2).trimmed(); - continue; - } - sectionMap[currentGroup].emplace(line.section('=', 0,0).trimmed(), - line.section('=', 1, -1).trimmed()); - } - file.close(); - } - - - // Skip if there is no "Desktop Entry" section - if ((sectionIterator = sectionMap.find("Desktop Entry")) == sectionMap.end()) - continue; - - map const &entryMap = sectionIterator->second; - map::const_iterator entryIterator; - - // Skip, if type is not found or not application - if ((entryIterator = entryMap.find("Type")) == entryMap.end() || - entryIterator->second != "Application") - continue; - - // Skip, if this desktop entry must not be shown - if ((entryIterator = entryMap.find("NoDisplay")) != entryMap.end() - && entryIterator->second == "true") - continue; - - if (!ignoreShowInKeys) { - // Skip if the current desktop environment is specified in "NotShowIn" - if ((entryIterator = entryMap.find("NotShowIn")) != entryMap.end()) - for (const QString &str : entryIterator->second.split(';',QString::SkipEmptyParts)) - if (xdg_current_desktop.contains(str)) - continue; - - // Skip if the current desktop environment is not specified in "OnlyShowIn" - if ((entryIterator = entryMap.find("OnlyShowIn")) != entryMap.end()) { - bool found = false; - for (const QString &str : entryIterator->second.split(';',QString::SkipEmptyParts)) - if (xdg_current_desktop.contains(str)){ - found = true; - break; - } - if (!found) - continue; - } - } - - bool term; - QString name; - QString genericName; - QString comment; - QString icon; - QString exec; - QString workingDir; - QStringList keywords; - QStringList actionIdentifiers; - - // Try to get the localized name, skip if empty - name = xdgStringEscape(getLocalizedKey("Name", entryMap, loc)); - if (name.isNull()) - continue; - - // Try to get the exec key, skip if not existant - if ((entryIterator = entryMap.find("Exec")) != entryMap.end()) - exec = xdgStringEscape(entryIterator->second); - else - continue; - - // Try to get the localized icon, skip if empty - icon = xdgStringEscape(getLocalizedKey("Icon", entryMap, loc)); - if (icon.isNull()) - continue; - - // Check if this is a terminal app - term = (entryIterator = entryMap.find("Terminal")) != entryMap.end() - && entryIterator->second=="true"; - - // Try to get the localized genericName - genericName = xdgStringEscape(getLocalizedKey("GenericName", entryMap, loc)); - - // Try to get the localized comment - comment = xdgStringEscape(getLocalizedKey("Comment", entryMap, loc)); - - // Try to get the keywords - keywords = xdgStringEscape(getLocalizedKey("Keywords", entryMap, loc)).split(';',QString::SkipEmptyParts); - - // Try to get the workindir - if ((entryIterator = entryMap.find("Path")) != entryMap.end()) - workingDir = xdgStringEscape(entryIterator->second); - - // Try to get the keywords - if ((entryIterator = entryMap.find("Actions")) != entryMap.end()) - actionIdentifiers = xdgStringEscape(entryIterator->second).split(';',QString::SkipEmptyParts); - -// // Try to get the mimetypes -// if ((valueIterator = entryMap.find("MimeType")) != entryMap.end()) -// keywords = xdgStringEscape(valueIterator->second).split(';',QString::SkipEmptyParts); - - /* - * Default action - */ - - vector> actions; - - // Unquote arguments and expand field codes - QStringList commandline = expandedFieldCodes(Util::ShellLexer::split(exec), - icon, - name, - fIt.filePath()); - - shared_ptr sa = std::make_shared(); - sa->setText(QString("Run %1").arg(name)); - if (term){ - sa->setAction([commandline, workingDir](){ - QStringList arguments = Util::ShellLexer::split(terminalCommand); - arguments.append(commandline); - QString command = arguments.takeFirst(); - QProcess::startDetached(command, arguments, workingDir); - }); - } else { - sa->setAction([commandline, workingDir](){ - QStringList arguments = commandline; - QString command = arguments.takeFirst(); - QProcess::startDetached(command, arguments, workingDir); - }); - } - - actions.push_back(sa); - - - /* - * Root action - */ - - if (term){ - sa = std::make_shared(); - sa->setText(QString("Run %1 as root").arg(name)); - sa->setAction([commandline, workingDir](){ - QStringList arguments = Util::ShellLexer::split(terminalCommand); - arguments.append(QString("sudo %1").arg(commandline.join(' '))); - QString command = arguments.takeFirst(); - QProcess::startDetached(command, arguments, workingDir); - }); - actions.push_back(sa); - } -// else { -// Root action. (FistComeFirstsServed. TODO: more sophisticated solution) -// for (const QString &s : supportedGraphicalSudo){ -// QProcess p; -// p.start("which", {s}); -// p.waitForFinished(-1); -// if (p.exitCode() == 0){ -// actions_.push_back(std::make_shared( -// this, QString("Run %1 as root").arg(name_), -// QString("%1 \"%2\"").arg(s, exec_))); -// break; -// } -// } -// sa->setAction([commandline, workingDir](){ -// QStringList arguments = commandline; -// QString command = arguments.takeFirst(); -// QProcess::startDetached(command, arguments, workingDir); -// }); -// } - - - /* - * Desktop Actions - */ - - for (const QString &actionIdentifier: actionIdentifiers){ - - sa = std::make_shared(); - - // Get iterator to action section - if ((sectionIterator = sectionMap.find(QString("Desktop Action %1").arg(actionIdentifier))) == sectionMap.end()) - continue; - map &valueMap = sectionIterator->second; - - // Try to get the localized action name - QString actionName = xdgStringEscape(getLocalizedKey("Name", valueMap, loc)); - if (actionName.isNull()) - continue; - sa->setText(actionName); - - // Get action command - if ((entryIterator = valueMap.find("Exec")) == valueMap.end()) - continue; - - // Unquote arguments and expand field codes - QStringList commandline = expandedFieldCodes(Util::ShellLexer::split(entryIterator->second), - icon, - name, - fIt.filePath()); - - if (term){ - sa->setAction([commandline, workingDir](){ - QStringList arguments = Util::ShellLexer::split(terminalCommand); - arguments.append(commandline); - QString command = arguments.takeFirst(); - QProcess::startDetached(command, arguments, workingDir); - }); - } else { - sa->setAction([commandline, workingDir](){ - QStringList arguments = commandline; - QString command = arguments.takeFirst(); - QProcess::startDetached(command, arguments, workingDir); - }); - } - actions.push_back(sa); - } - - - /* - * Build the item - */ - - // Finally we got everything, build the item - shared_ptr ssii = std::make_shared(id); - - // Set Name - ssii->setText(name); - - // Set subtext/tootip - if (comment.isEmpty()) - if (genericName.isEmpty()) - ssii->setSubtext(exec); - else - ssii->setSubtext(genericName); - else - ssii->setSubtext(comment); - - // Set icon - icon = XdgIconLookup::iconPath(icon); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("exec"); - if (icon.isEmpty()) - icon = ":application-x-executable"; - ssii->setIconPath(icon); - - // Set keywords - vector indexKeywords; - indexKeywords.emplace_back(name, USHRT_MAX); - if (!genericName.isEmpty()) - indexKeywords.emplace_back(genericName, USHRT_MAX*0.9); - for (auto & kw : keywords) - indexKeywords.emplace_back(kw, USHRT_MAX*0.8); -// if (!comment.isEmpty()) -// indexKeywords.emplace_back(comment, USHRT_MAX*0.5); - ssii->setIndexKeywords(std::move(indexKeywords)); - - // Set actions - ssii->setActions(std::move(actions)); - - desktopEntries.push_back(std::move(ssii)); - } - } - return desktopEntries; -} - -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -class Applications::ApplicationsPrivate -{ -public: - ApplicationsPrivate(Extension *q) : q(q) {} - - Extension *q; - - QPointer widget; - QFileSystemWatcher watcher; - - vector> index; - OfflineIndex offlineIndex; - - QFutureWatcher>> futureWatcher; - bool rerun = false; - bool ignoreShowInKeys; - - void finishIndexing(); - void startIndexing(); -}; - - - -/** ***************************************************************************/ -void Applications::ApplicationsPrivate::startIndexing() { - - // Never run concurrent - if ( futureWatcher.future().isRunning() ) { - rerun = true; - return; - } - - // Run finishIndexing when the indexing thread finished - futureWatcher.disconnect(); - QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, - std::bind(&ApplicationsPrivate::finishIndexing, this)); - - // Run the indexer thread - futureWatcher.setFuture(QtConcurrent::run(indexApplications, ignoreShowInKeys)); - - // Notification - qDebug() << "Start indexing applications."; - emit q->statusInfo("Indexing applications ..."); -} - - - -/** ***************************************************************************/ -void Applications::ApplicationsPrivate::finishIndexing() { - - // Get the thread results - index = futureWatcher.future().result(); - - // Rebuild the offline index - offlineIndex.clear(); - for (const auto &item : index) - offlineIndex.add(item); - - // Finally update the watches (maybe folders changed) - if (!watcher.directories().isEmpty()) - watcher.removePaths(watcher.directories()); - QStringList xdgAppDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); - for (const QString &path : xdgAppDirs) { - watcher.addPath(path); - QDirIterator dit(path, QDir::Dirs|QDir::NoDotAndDotDot); - while (dit.hasNext()) - watcher.addPath(dit.next()); - } - - // Notification - qDebug() << qPrintable(QString("Indexed %1 applications.").arg(index.size())); - emit q->statusInfo(QString("%1 applications indexed.").arg(index.size())); - - if ( rerun ) { - startIndexing(); - rerun = false; - } -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -Applications::Extension::Extension() - : Core::Extension("org.albert.extension.applications"), - Core::QueryHandler(Core::Extension::id), - d(new ApplicationsPrivate(this)) { - - qunsetenv("DESKTOP_AUTOSTART_ID"); - - // Load settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - d->offlineIndex.setFuzzy(s.value(CFG_FUZZY, DEF_FUZZY).toBool()); - d->ignoreShowInKeys = s.value(CFG_IGNORESHOWINKEYS, DEF_IGNORESHOWINKEYS).toBool(); - - // If the filesystem changed, trigger the scan - connect(&d->watcher, &QFileSystemWatcher::directoryChanged, - std::bind(&ApplicationsPrivate::startIndexing, d.get())); - - // Trigger initial update - updateIndex(); -} - - - -/** ***************************************************************************/ -Applications::Extension::~Extension() { - d->futureWatcher.waitForFinished(); -} - - - -/** ***************************************************************************/ -QWidget *Applications::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) { - d->widget = new ConfigWidget(parent); - - // Fuzzy - d->widget->ui.checkBox_fuzzy->setChecked(d->offlineIndex.fuzzy()); - connect(d->widget->ui.checkBox_fuzzy, &QCheckBox::toggled, - this, &Extension::setFuzzy); - - // Ignore onlyshowin notshowin keys - d->widget->ui.checkBox_ignoreShowInKeys->setChecked(d->ignoreShowInKeys); - connect(d->widget->ui.checkBox_ignoreShowInKeys, &QCheckBox::toggled, - this, [this](bool checked){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_IGNORESHOWINKEYS), checked); - d->ignoreShowInKeys = checked ; - d->startIndexing(); - }); - - // Status bar - ( d->futureWatcher.isRunning() ) - ? d->widget->ui.label_statusbar->setText("Indexing applications ...") - : d->widget->ui.label_statusbar->setText(QString("%1 applications indexed.").arg(d->index.size())); - connect(this, &Extension::statusInfo, d->widget->ui.label_statusbar, &QLabel::setText); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void Applications::Extension::handleQuery(Core::Query * query) { - - // Search for matches - const vector> &indexables = d->offlineIndex.search(query->searchTerm().toLower()); - - // Add results to query - vector,short>> results; - for (const shared_ptr &item : indexables) - // TODO `Search` has to determine the relevance. Set to 0 for now - results.emplace_back(std::static_pointer_cast(item), 1); - - query->addMatches(results.begin(), results.end()); -} - - - -/** ***************************************************************************/ -bool Applications::Extension::fuzzy() { - return d->offlineIndex.fuzzy(); -} - - - -/** ***************************************************************************/ -void Applications::Extension::setFuzzy(bool b) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_FUZZY), b); - d->offlineIndex.setFuzzy(b); -} - - - -/** ***************************************************************************/ -void Applications::Extension::updateIndex() { - d->startIndexing(); -} diff -Nru albert-0.12.0/src/plugins/applications/src/main.h albert-0.13.1+plugins1/src/plugins/applications/src/main.h --- albert-0.12.0/src/plugins/applications/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/applications/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace Applications { - -class ApplicationsPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of interfaces - */ - - QString name() const override { return "Applications"; } - QWidget *widget(QWidget *parent = nullptr) override; - void handleQuery(Core::Query * query) override; - - /* - * Extension specific members - */ - - bool fuzzy(); - void setFuzzy(bool b = true); - - void updateIndex(); - -private: - - std::unique_ptr d; - -signals: - - void statusInfo(const QString&); - -}; -} diff -Nru albert-0.12.0/src/plugins/calculator/calculator.qrc albert-0.13.1+plugins1/src/plugins/calculator/calculator.qrc --- albert-0.12.0/src/plugins/calculator/calculator.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/calculator.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/calc.svg - - diff -Nru albert-0.12.0/src/plugins/calculator/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/calculator/CMakeLists.txt --- albert-0.12.0/src/plugins/calculator/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(calculator) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS Widgets) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -qt5_wrap_ui(UI - configwidget.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${QRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - albertcore - muparser - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/calculator/configwidget.ui albert-0.13.1+plugins1/src/plugins/calculator/configwidget.ui --- albert-0.12.0/src/plugins/calculator/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ - - - Calculator::ConfigWidget - - - - 0 - 0 - 800 - 600 - - - - - - - Show group separators - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/calculator/metadata.json albert-0.13.1+plugins1/src/plugins/calculator/metadata.json --- albert-0.12.0/src/plugins/calculator/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.calculator", - "name" : "Calculator", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : ["libmuparser"], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/calculator/resources/calc.svg albert-0.13.1+plugins1/src/plugins/calculator/resources/calc.svg --- albert-0.12.0/src/plugins/calculator/resources/calc.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/resources/calc.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/calculator/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/calculator/src/configwidget.cpp --- albert-0.12.0/src/plugins/calculator/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -Calculator::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); -} - diff -Nru albert-0.12.0/src/plugins/calculator/src/configwidget.h albert-0.13.1+plugins1/src/plugins/calculator/src/configwidget.h --- albert-0.12.0/src/plugins/calculator/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace Calculator { - -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - Ui::ConfigWidget ui; -}; - -} diff -Nru albert-0.12.0/src/plugins/calculator/src/main.cpp albert-0.13.1+plugins1/src/plugins/calculator/src/main.cpp --- albert-0.12.0/src/plugins/calculator/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,186 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "main.h" -#include "muParser.h" -#include "query.h" -#include "standarditem.h" -#include "standardaction.h" -#include "xdgiconlookup.h" -using std::vector; -using std::shared_ptr; -using namespace Core; - - - -namespace { -const QString CFG_SEPS = "group_separators"; -const bool CFG_SEPS_DEF = false; -} - - - -class Calculator::CalculatorPrivate -{ -public: - QPointer widget; - std::unique_ptr parser; - QLocale locale; - QString iconPath; -}; - - - -/** ***************************************************************************/ -Calculator::Extension::Extension() - : Core::Extension("org.albert.extension.calculator"), - Core::QueryHandler(Core::Extension::id), - d(new CalculatorPrivate){ - - // FIXME Qt6 Workaround for https://bugreports.qt.io/browse/QTBUG-58504 - d->locale = QLocale(QLocale::system().name()); - - // Load settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - d->locale.setNumberOptions( - (s.value(CFG_SEPS, CFG_SEPS_DEF).toBool()) - ? d->locale.numberOptions() & ~QLocale::OmitGroupSeparator - : d->locale.numberOptions() | QLocale::OmitGroupSeparator ); - s.endGroup(); - - QString iconPath = XdgIconLookup::iconPath("calc"); - d->iconPath = iconPath.isNull() ? ":calc" : iconPath; - - d->parser.reset(new mu::Parser); - d->parser->SetDecSep(d->locale.decimalPoint().toLatin1()); - d->parser->SetThousandsSep(d->locale.groupSeparator().toLatin1()); -} - - - -/** ***************************************************************************/ -Calculator::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *Calculator::Extension::widget(QWidget *parent) { - if (d->widget.isNull()){ - d->widget = new ConfigWidget(parent); - - d->widget->ui.checkBox_groupsep->setChecked(!(d->locale.numberOptions() & QLocale::OmitGroupSeparator)); - connect(d->widget->ui.checkBox_groupsep, &QCheckBox::toggled, [this](bool checked){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_SEPS), checked); - d->locale.setNumberOptions( (checked) ? d->locale.numberOptions() & ~QLocale::OmitGroupSeparator - : d->locale.numberOptions() | QLocale::OmitGroupSeparator ); - }); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void Calculator::Extension::handleQuery(Core::Query * query) { - d->parser->SetExpr(query->searchTerm().toLower().toStdString()); - QString result; - try { - result = d->locale.toString(d->parser->Eval(), 'G', 16); - } - catch (mu::Parser::exception_type &e) { - return; -// http://beltoforion.de/article.php?a=muparser&p=errorhandling -// ecUNEXPECTED_OPERATOR 0 Unexpected binary operator found -// ecUNASSIGNABLE_TOKEN 1 Token cant be identified -// ecUNEXPECTED_EOF 2 Unexpected end of formula. (Example: "2+sin(") -// ecUNEXPECTED_ARG_SEP 3 An unexpected argument separator has been found. (Example: "1,23") -// ecUNEXPECTED_ARG 4 An unexpected argument has been found -// ecUNEXPECTED_VAL 5 An unexpected value token has been found -// ecUNEXPECTED_VAR 6 An unexpected variable token has been found -// ecUNEXPECTED_PARENS 7 Unexpected parenthesis, opening or closing -// ecUNEXPECTED_STR 8 A string has been found at an inapropriate position -// ecSTRING_EXPECTED 9 A string function has been called with a different type of argument -// ecVAL_EXPECTED 10 A numerical function has been called with a non value type of argument -// ecMISSING_PARENS 11 Missing parens. (Example: "3*sin(3") -// ecUNEXPECTED_FUN 12 Unexpected function found. (Example: "sin(8)cos(9)") -// ecUNTERMINATED_STRING 13 unterminated string constant. (Example: "3*valueof("hello)") -// ecTOO_MANY_PARAMS 14 Too many function parameters -// ecTOO_FEW_PARAMS 15 Too few function parameters. (Example: "ite(1<2,2)") -// ecOPRT_TYPE_CONFLICT 16 binary operators may only be applied to value items of the same type -// ecSTR_RESULT 17 result is a string -// ecINVALID_NAME 18 Invalid function, variable or constant name. -// ecINVALID_BINOP_IDENT 19 Invalid binary operator identifier. -// ecINVALID_INFIX_IDENT 20 Invalid infix operator identifier. -// ecINVALID_POSTFIX_IDENT 21 Invalid postfix operator identifier. -// ecBUILTIN_OVERLOAD 22 Trying to overload builtin operator -// ecINVALID_FUN_PTR 23 Invalid callback function pointer -// ecINVALID_VAR_PTR 24 Invalid variable pointer -// ecEMPTY_EXPRESSION 25 The expression string is empty -// ecNAME_CONFLICT 26 Name conflict -// ecOPT_PRI 27 Invalid operator priority -// ecDOMAIN_ERROR 28 catch division by zero, sqrt(-1), log(0) (currently unused) -// ecDIV_BY_ZERO 29 Division by zero (currently unused) -// ecGENERIC 30 Error that does not fit any other code but is not an internal error -// ecLOCALE 31 Conflict with current locale -// ecUNEXPECTED_CONDITIONAL 32 Unexpected if then else operator -// ecMISSING_ELSE_CLAUSE 33 Missing else clause -// ecMISPLACED_COLON 34 Misplaced colon -// ecINTERNAL_ERROR 35 Internal error of any kind. - } - - shared_ptr calcItem = std::make_shared("muparser-eval"); - calcItem->setText(result); - calcItem->setSubtext(QString("Result of '%1'").arg(query->searchTerm())); - calcItem->setIconPath(d->iconPath); - - // Build actions - vector> actions; - - shared_ptr action = std::make_shared(); - action->setText(QString("Copy '%1' to clipboard").arg(result)); - action->setAction([=](){ - QApplication::clipboard()->setText(result); }); - actions.push_back(action); - - // Make searchterm a lvalue that can be captured by the lambda - QString text = query->searchTerm(); - action = std::make_shared(); - action->setText(QString("Copy '%1' to clipboard").arg(text)); - action->setAction([=](){ - QApplication::clipboard()->setText(text); }); - actions.push_back(action); - - text = QString("%1 = %2").arg(query->searchTerm(), result); - action = std::make_shared(); - action->setText(QString("Copy '%1' to clipboard").arg(text)); - action->setAction([=](){ - QApplication::clipboard()->setText(text); }); - actions.push_back(action); - - calcItem->setActions(std::move(actions)); - - query->addMatch(calcItem, SHRT_MAX); -} diff -Nru albert-0.12.0/src/plugins/calculator/src/main.h albert-0.13.1+plugins1/src/plugins/calculator/src/main.h --- albert-0.12.0/src/plugins/calculator/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/calculator/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace Calculator { - -class CalculatorPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "Calculator"; } - QWidget *widget(QWidget *parent = nullptr) override; - void handleQuery(Core::Query * query) override; - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/chromebookmarks/chromebookmarks.qrc albert-0.13.1+plugins1/src/plugins/chromebookmarks/chromebookmarks.qrc --- albert-0.12.0/src/plugins/chromebookmarks/chromebookmarks.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/chromebookmarks.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/favicon.png - - diff -Nru albert-0.12.0/src/plugins/chromebookmarks/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/chromebookmarks/CMakeLists.txt --- albert-0.12.0/src/plugins/chromebookmarks/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(chromebookmarks) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Concurrent - Widgets -) - -qt5_wrap_ui(UI - configwidget.ui -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Concurrent_LIBRARIES} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/chromebookmarks/configwidget.ui albert-0.13.1+plugins1/src/plugins/chromebookmarks/configwidget.ui --- albert-0.12.0/src/plugins/chromebookmarks/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ - - - ChromeBookmarks::ConfigWidget - - - - - - Path to bookmarkfile - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - - - - - - - Fuzzy - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 50 - 0 - - - - Edit - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/chromebookmarks/metadata.json albert-0.13.1+plugins1/src/plugins/chromebookmarks/metadata.json --- albert-0.12.0/src/plugins/chromebookmarks/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.chromebookmarks", - "name" : "Chrome bookmarks", - "version" : "1.0", - "platform" : "Linux", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": false -} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/plugins/chromebookmarks/resources/favicon.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/plugins/chromebookmarks/resources/favicon.png differ diff -Nru albert-0.12.0/src/plugins/chromebookmarks/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/configwidget.cpp --- albert-0.12.0/src/plugins/chromebookmarks/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include "configwidget.h" - -/** ***************************************************************************/ -ChromeBookmarks::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); - - connect(ui.pushButton_editPath, &QPushButton::clicked, - this, &ConfigWidget::onButton_EditPath); -} - -/** ***************************************************************************/ -ChromeBookmarks::ConfigWidget::~ConfigWidget() { - -} - -/** ***************************************************************************/ -void ChromeBookmarks::ConfigWidget::onButton_EditPath() { - QString path = QFileDialog::getOpenFileName(this, tr("Choose path")); - if(path.isEmpty()) return; - emit requestEditPath(path); -} diff -Nru albert-0.12.0/src/plugins/chromebookmarks/src/configwidget.h albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/configwidget.h --- albert-0.12.0/src/plugins/chromebookmarks/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace ChromeBookmarks { - -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; - -private: - void onButton_EditPath(); - -signals: - void requestEditPath(const QString&); -}; -} diff -Nru albert-0.12.0/src/plugins/chromebookmarks/src/main.cpp albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/main.cpp --- albert-0.12.0/src/plugins/chromebookmarks/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,365 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "main.h" -#include "indexable.h" -#include "offlineindex.h" -#include "query.h" -#include "queryhandler.h" -#include "standardaction.h" -#include "standardindexitem.h" -#include "xdgiconlookup.h" -using std::shared_ptr; -using std::vector; -using std::pair; -using namespace Core; - -namespace { - -const char* CFG_PATH = "bookmarkfile"; -const char* CFG_FUZZY = "fuzzy"; -const bool DEF_FUZZY = false; - -/** ***************************************************************************/ -vector> indexChromeBookmarks(const QString &bookmarksPath) { - - // Build a new index - vector> bookmarks; - - // Define a recursive bookmark indexing lambda - std::function rec_bmsearch = - [&rec_bmsearch, &bookmarks](const QJsonObject &json) { - QJsonValue type = json["type"]; - if (type == QJsonValue::Undefined) - return; - if (type.toString() == "folder"){ - QJsonArray jarr = json["children"].toArray(); - for (const QJsonValue &i : jarr) - rec_bmsearch(i.toObject()); - } - if (type.toString() == "url") { - QString name = json["name"].toString(); - QString urlstr = json["url"].toString(); - - shared_ptr ssii = std::make_shared(json["id"].toString()); - ssii->setText(name); - ssii->setSubtext(urlstr); - QString icon = XdgIconLookup::iconPath("www"); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("web-browser"); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("emblem-web"); - if (icon.isEmpty()) - icon = ":favicon"; - ssii->setIconPath(icon); - - vector weightedKeywords; - QUrl url(urlstr); - QString host = url.host(); - weightedKeywords.emplace_back(name, USHRT_MAX); - weightedKeywords.emplace_back(host.left(host.size()-url.topLevelDomain().size()), USHRT_MAX/2); - ssii->setIndexKeywords(std::move(weightedKeywords)); - - vector> actions; - shared_ptr action = std::make_shared(); - action->setText("Open URL in your browser"); - action->setAction([urlstr](){ - QDesktopServices::openUrl(QUrl(urlstr)); - }); - actions.push_back(std::move(action)); - - action = std::make_shared(); - action->setText("Copy URL to clipboard"); - action->setAction([urlstr](){ - QApplication::clipboard()->setText(urlstr); - }); - actions.push_back(std::move(action)); - - ssii->setActions(std::move(actions)); - - bookmarks.push_back(std::move(ssii)); - } - }; - - QFile f(bookmarksPath); - if (!f.open(QIODevice::ReadOnly)) { - qWarning() << qPrintable(QString("Could not open Chrome bookmarks file '%1'.").arg(bookmarksPath)); - return vector>(); - } - - QJsonObject json = QJsonDocument::fromJson(f.readAll()).object(); - QJsonObject roots = json.value("roots").toObject(); - for (const QJsonValue &i : roots) - if (i.isObject()) - rec_bmsearch(i.toObject()); - - f.close(); - - return bookmarks; -} - -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -class ChromeBookmarks::ChromeBookmarksPrivate -{ -public: - ChromeBookmarksPrivate(Extension *q) : q(q) {} - - Extension *q; - - QPointer widget; - QFileSystemWatcher fileSystemWatcher; - QString bookmarksFile; - - vector> index; - Core::OfflineIndex offlineIndex; - QFutureWatcher>> futureWatcher; - - void finishIndexing(); - void startIndexing(); -}; - - - -/** ***************************************************************************/ -void ChromeBookmarks::ChromeBookmarksPrivate::startIndexing() { - - // Never run concurrent - if ( futureWatcher.future().isRunning() ) - return; - - // Run finishIndexing when the indexing thread finished - futureWatcher.disconnect(); - QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, - std::bind(&ChromeBookmarksPrivate::finishIndexing, this)); - - // Run the indexer thread - futureWatcher.setFuture(QtConcurrent::run(indexChromeBookmarks, bookmarksFile)); - - // Notification - qDebug() << "Start indexing Chrome bookmarks."; - emit q->statusInfo("Indexing bookmarks ..."); - -} - - - -/** ***************************************************************************/ -void ChromeBookmarks::ChromeBookmarksPrivate::finishIndexing() { - - // Get the thread results - index = futureWatcher.future().result(); - - // Rebuild the offline index - offlineIndex.clear(); - for (const auto &item : index) - offlineIndex.add(item); - - /* - * Finally update the watches (maybe folders changed) - * Note that QFileSystemWatcher stops monitoring files once they have been - * renamed or removed from disk, and directories once they have been removed - * from disk. - * Chromium seems to mv the file (inode change). - */ - if ( fileSystemWatcher.files().empty() ) - if( !fileSystemWatcher.addPath(bookmarksFile)) - qWarning() << qPrintable(QString("%1 can not be watched. Changes in this path will not be noticed.").arg(bookmarksFile)); - - // Notification - qDebug() << qPrintable(QString("Indexed %1 Chrome bookmarks.").arg(index.size())); - emit q->statusInfo(QString("%1 bookmarks indexed.").arg(index.size())); -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -ChromeBookmarks::Extension::Extension() - : Core::Extension("org.albert.extension.chromebookmarks"), - Core::QueryHandler(Core::Extension::id), - d(new ChromeBookmarksPrivate(this)) { - - // Load settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - d->offlineIndex.setFuzzy(s.value(CFG_FUZZY, DEF_FUZZY).toBool()); - - // Load and set a valid path - QVariant v = s.value(CFG_PATH); - if (v.isValid() && v.canConvert(QMetaType::QString) && QFileInfo(v.toString()).exists()) - setPath(v.toString()); - else - restorePath(); - - // If the path changed write it to the settings - connect(this, &Extension::pathChanged, [this](const QString& path){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_PATH), path); - }); - - s.endGroup(); - - // Update index if bookmark file changed - connect(&d->fileSystemWatcher, &QFileSystemWatcher::fileChanged, - this, &Extension::updateIndex); - - // Update index if bookmark file's path changed - connect(this, &Extension::pathChanged, - this, &Extension::updateIndex); - - // Trigger an initial update - updateIndex(); -} - - - -/** ***************************************************************************/ -ChromeBookmarks::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *ChromeBookmarks::Extension::widget(QWidget *parent) { - if (d->widget.isNull()){ - d->widget = new ConfigWidget(parent); - - // Paths - d->widget->ui.lineEdit_path->setText(d->bookmarksFile); - connect(d->widget.data(), &ConfigWidget::requestEditPath, this, &Extension::setPath); - connect(this, &Extension::pathChanged, d->widget->ui.lineEdit_path, &QLineEdit::setText); - - // Fuzzy - d->widget->ui.checkBox_fuzzy->setChecked(fuzzy()); - connect(d->widget->ui.checkBox_fuzzy, &QCheckBox::toggled, this, &Extension::setFuzzy); - - // Status bar - ( d->futureWatcher.isRunning() ) - ? d->widget->ui.label_statusbar->setText("Indexing bookmarks ...") - : d->widget->ui.label_statusbar->setText(QString("%1 bookmarks indexed.").arg(d->index.size())); - connect(this, &Extension::statusInfo, d->widget->ui.label_statusbar, &QLabel::setText); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void ChromeBookmarks::Extension::handleQuery(Core::Query * query) { - - // Search for matches - const vector> &indexables = d->offlineIndex.search(query->searchTerm().toLower()); - - // Add results to query - vector,short>> results; - for (const shared_ptr &item : indexables) - results.emplace_back(std::static_pointer_cast(item), 0); - - query->addMatches(results.begin(), results.end()); -} - - - -/** ***************************************************************************/ -const QString &ChromeBookmarks::Extension::path() { - return d->bookmarksFile; -} - - - -/** ***************************************************************************/ -void ChromeBookmarks::Extension::setPath(const QString &path) { - - QFileInfo fi(path); - if (!(fi.exists() && fi.isFile())) - return; - - d->bookmarksFile = path; - - emit pathChanged(path); -} - - - -/** ***************************************************************************/ -void ChromeBookmarks::Extension::restorePath() { - // Find a bookmark file (Take first one) - for (const QString &browser : {"chromium","google-chrome"}){ - QString root = QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)).filePath(browser); - QDirIterator it(root, {"Bookmarks"}, QDir::Files, QDirIterator::Subdirectories); - while (it.hasNext()) { - setPath(it.next()); - return; - } - } -} - - - -/** ***************************************************************************/ -bool ChromeBookmarks::Extension::fuzzy() { - return d->offlineIndex.fuzzy(); -} - - - -/** ***************************************************************************/ -void ChromeBookmarks::Extension::updateIndex() { - d->startIndexing(); -} - - - -/** ***************************************************************************/ -void ChromeBookmarks::Extension::setFuzzy(bool b) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_FUZZY), b); - d->offlineIndex.setFuzzy(b); -} - diff -Nru albert-0.12.0/src/plugins/chromebookmarks/src/main.h albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/main.h --- albert-0.12.0/src/plugins/chromebookmarks/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/chromebookmarks/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - - -namespace ChromeBookmarks { - -class ChromeBookmarksPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "Chrome bookmarks"; } - QWidget *widget(QWidget *parent = nullptr) override; - void handleQuery(Core::Query * query) override; - - /* - * Extension specific members - */ - - const QString &path(); - void setPath(const QString &path); - void restorePath(); - - bool fuzzy(); - void setFuzzy(bool b = true); - - void updateIndex(); - -private: - - std::unique_ptr d; - -signals: - - void pathChanged(const QString&); - void statusInfo(const QString&); - -}; -} diff -Nru albert-0.12.0/src/plugins/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/CMakeLists.txt --- albert-0.12.0/src/plugins/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -# Do not export symbols by default -set(CMAKE_CXX_VISIBILITY_PRESET hidden) -set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) - -# Set the RPATH for the library lookup -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/albert") - -add_subdirectory(applications) -add_subdirectory(calculator) -add_subdirectory(chromebookmarks) -add_subdirectory(externalextensions) -add_subdirectory(files) -add_subdirectory(firefoxbookmarks) -add_subdirectory(ssh) -add_subdirectory(mpris) -add_subdirectory(system) -add_subdirectory(terminal) -add_subdirectory(virtualbox) -add_subdirectory(websearch) - -# Non-release plugins -if(${BUILD_DEBUG_EXTENSIONS}) - add_subdirectory(templateExtension) - add_subdirectory(debug) -endif(${BUILD_DEBUG_EXTENSIONS}) - diff -Nru albert-0.12.0/src/plugins/create_plugin.py albert-0.13.1+plugins1/src/plugins/create_plugin.py --- albert-0.12.0/src/plugins/create_plugin.py 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/create_plugin.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -#!/usr/bin/python - -import os -import re -import sys -import string -from shutil import copyfile - -ID_KEYWORD = "projectid" -NAMESPACE_KEYWORD = "ProjectNamespace" -PRETTYNAME_KEYWORD = "Template" -ID_PATTERN = "^([a-z0-9]+)$" -NAMESPACE_PATTERN = "^([A-Za-z][A-Za-z0-9]+)$" -PRETTYNAME_PATTERN = "^([A-Za-z0-9 _\\-]+)$" -TEMPLATE_EXTENSION_BASE = "templateExtension/" -CMAKE_PATTERN = "^add_subdirectory\(([^\)]+)\)$" - -if len(sys.argv) != 4: - u = "Usage: create_plugin.py \n" - sys.stderr.write(u) - sys.exit(1) - -id_regex = re.compile(ID_PATTERN) -namespace_regex = re.compile(NAMESPACE_PATTERN) -prettyname_regex = re.compile(PRETTYNAME_PATTERN) -cmake_regex = re.compile(CMAKE_PATTERN) - -id_string = sys.argv[1] -namespace_string = sys.argv[2] -prettyname_string = sys.argv[3] - -if not id_regex.match(id_string): - e = "ID has to match " + ID_PATTERN + "\n" - sys.stderr.write(e) - sys.exit(1) - -if not namespace_regex.match(namespace_string): - e = "Namespace has to match " + NAMESPACE_PATTERN + "\n" - sys.stderr.write(e) - sys.exit(1) - -if not prettyname_regex.match(prettyname_string): - e = "Pretty Name has to match " + PRETTYNAME_PATTERN + "\n" - sys.stderr.write(e) - sys.exit(1) - -raw_input("Are we in the src/plugins directory? If not do not proceed because it won't work! ") - -print("Creating directory . . .") -os.mkdir(id_string) -os.chdir(id_string) - -baseDir = os.path.join("..", TEMPLATE_EXTENSION_BASE) -filesToPrepare = [] - -def scanDir(toscan): - global filesToPrepare - global baseDir - if toscan: - template = os.path.join(baseDir, toscan) - else: - template = baseDir - ext = toscan - files = os.listdir(template) - for nextFile in files: - path = os.path.join(template, nextFile) - pathNew = os.path.join(ext, nextFile) - if os.path.isdir(path): - print("Creating directory " + pathNew) - os.mkdir(pathNew) - scanDir(os.path.join(toscan, nextFile)) - else: - print("Copying file " + pathNew) - copyfile(path, pathNew) - filesToPrepare.append(pathNew) - -scanDir("") - -for localFile in filesToPrepare: - print("Preparing file " + localFile) - with open(localFile) as fd: - tmpfile = localFile + ".tmp" - tmp = open(tmpfile, "w") - for line in fd: - tmp.write(re.sub(ID_KEYWORD, id_string, - re.sub(NAMESPACE_KEYWORD, namespace_string, - re.sub(PRETTYNAME_KEYWORD, prettyname_string, line)))) - tmp.close() - os.rename(tmpfile, localFile) - -print("Leaving directory . . .") -os.chdir("..") -print("Updating CMakeLists.txt . . . ") -existingExtensions = [] -preLines = [] -postLines = [] -preSubdir = True -postSubdir = False -with open("CMakeLists.txt", "r") as makelist: - for line in makelist: - match = cmake_regex.match(line) - if match: - preSubdir = False - existingExtensions.append(match.group(1)) - else: - postSubdir = not preSubdir - - if preSubdir: - preLines.append(line) - elif postSubdir: - postLines.append(line) - -existingExtensions.append(id_string) -existingExtensions.sort() - -cmakefile = open("CMakeLists.txt", "w") -for line in preLines: - cmakefile.write(line) # The newline is already in the line, because it didn't get stripped - -for ext in existingExtensions: - cmakefile.write("add_subdirectory(") - cmakefile.write(ext) - cmakefile.write(")\n") - -for line in postLines: - cmakefile.write(line) # The newline is already in the line, because it didn't get stripped - -cmakefile.close() diff -Nru albert-0.12.0/src/plugins/create_plugin.sh albert-0.13.1+plugins1/src/plugins/create_plugin.sh --- albert-0.12.0/src/plugins/create_plugin.sh 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/create_plugin.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -#!/bin/bash - -usage(){ - echo "Usage:" - echo "$0 " -} - -if [ ! $# -eq 3 ]; then - usage - exit 1 -fi - -ID="$1" -NAMESPACE="$2" -PRETTY="$3" - -if [[ ! "$ID" =~ ^[a-z0-9]+$ ]]; then - echo -e "\e[31mid has to be alphanumeric and all lowercase\e[0m" - usage - exit 1 -fi - -if [[ ! "$NAMESPACE" =~ ^[A-Za-z][A-Za-z0-9]+$ ]]; then - echo -e "\e[31mNamespace id has to be alphanumeric and must not begin with a number\e[0m" - usage - exit 1 -fi - - -echo "Clone template" -cp -r "templateExtension" "$ID" - -echo "Adjust metadata.json" -sed -e "s/template/${ID}/" -e "s/Template/${PRETTY}/" "templateExtension/metadata.json" > "${ID}/metadata.json" - -echo "Adjust CMakeListss.txt" -sed -e "s/template/${ID}/" "templateExtension/CMakeLists.txt" > "${ID}/CMakeLists.txt" - -echo "Adjust namespaces" - - -for FILE in $( ls templateExtension | grep -e ".cpp$" -e ".h$" -e ".ui$" ); do - sed \ - -e "s/namespace Template/namespace ${NAMESPACE}/" \ - -e "s/Template::/${NAMESPACE}::/" \ - "templateExtension/${FILE}" > "${ID}/${FILE}" -done diff -Nru albert-0.12.0/src/plugins/debug/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/debug/CMakeLists.txt --- albert-0.12.0/src/plugins/debug/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(debug) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets -) - -set(LIB - ${Qt5Widgets_LIBRARIES} - albertcore -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -qt5_wrap_ui(UI configwidget.ui) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} ${LIB}) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/debug/configwidget.ui albert-0.13.1+plugins1/src/plugins/debug/configwidget.ui --- albert-0.12.0/src/plugins/debug/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,113 +0,0 @@ - - - Debug::ConfigWidget - - - - 0 - 0 - 800 - 600 - - - - - - - - - Trigger - - - - - - - dbg - - - - - - - - 0 - 0 - - - - Count of repeats - - - - - - - - 0 - 0 - - - - 1 - - - 1000000 - - - - - - - - - Asyn&chronous - - - true - - - - - - Delay in ms - - - - - - - 50 - - - 1000 - - - 50 - - - 100 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/debug/debug.qrc albert-0.13.1+plugins1/src/plugins/debug/debug.qrc --- albert-0.12.0/src/plugins/debug/debug.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/debug.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/debug.png - - diff -Nru albert-0.12.0/src/plugins/debug/metadata.json albert-0.13.1+plugins1/src/plugins/debug/metadata.json --- albert-0.12.0/src/plugins/debug/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.debug", - "name" : "Debug", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": false -} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/plugins/debug/resources/debug.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/plugins/debug/resources/debug.png differ diff -Nru albert-0.12.0/src/plugins/debug/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/debug/src/configwidget.cpp --- albert-0.12.0/src/plugins/debug/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include "configwidget.h" - -Debug::ConfigWidget::ConfigWidget(Extension * extension, QWidget * parent) - : QWidget(parent), extension_(extension) -{ - ui.setupUi(this); - ui.spinBox_delay->setValue(extension_->delay()); - connect(ui.spinBox_delay, static_cast(&QSpinBox::valueChanged), - extension_, &Extension::setDelay); - - ui.spinBox_count->setValue(extension_->count()); - connect(ui.spinBox_count, static_cast(&QSpinBox::valueChanged), - extension_, &Extension::setCount); - - ui.groupBox_async->setChecked(extension_->async()); - connect(ui.groupBox_async, &QGroupBox::toggled, - extension_, &Extension::setAsync); - - ui.lineEdit_trigger->setText(extension_->trigger()); - connect(ui.lineEdit_trigger, &QLineEdit::textChanged, - extension_, &Extension::setTrigger); -} diff -Nru albert-0.12.0/src/plugins/debug/src/configwidget.h albert-0.13.1+plugins1/src/plugins/debug/src/configwidget.h --- albert-0.12.0/src/plugins/debug/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" -#include "main.h" - -namespace Debug -{ -class ConfigWidget final : public QWidget -{ - Q_OBJECT - -public: - - explicit ConfigWidget(Extension * extension_, QWidget * parent = 0); - -private: - - Ui::ConfigWidget ui; - Extension * extension_; - -}; -} diff -Nru albert-0.12.0/src/plugins/debug/src/main.cpp albert-0.13.1+plugins1/src/plugins/debug/src/main.cpp --- albert-0.12.0/src/plugins/debug/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "main.h" -#include "query.h" -#include "standarditem.h" -using Core::StandardItem; - - -class Debug::DebugPrivate -{ -public: - QPointer widget; - int delay; - int count; - bool async; - QString trigger; -}; - - - - -/** ***************************************************************************/ -Debug::Extension::Extension() - : Core::Extension("org.albert.extension.debug"), - Core::QueryHandler(Core::Extension::id), - d(new DebugPrivate) { - QSettings s(qApp->applicationName()); - s.beginGroup(Core::QueryHandler::id); - d->delay = s.value("delay", 50).toInt(); - d->count = s.value("count", 100).toInt(); - d->async = s.value("async", true).toBool(); - d->trigger = s.value("trigger", "dbg").toString(); - s.endGroup(); -} - - - -/** ***************************************************************************/ -Debug::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *Debug::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) - d->widget = new ConfigWidget(this, parent); - return d->widget; -} - - - -/** ***************************************************************************/ -QStringList Debug::Extension::triggers() const { - return {d->trigger}; -} - - - -/** ***************************************************************************/ -const QString& Debug::Extension::trigger() const { - return d->trigger; -} - - - -/** ***************************************************************************/ -void Debug::Extension::handleQuery(Core::Query * query) { - - // This extension must run only triggered - if ( !query->isTriggered() ) - return; - - for (int i = 0 ; i < d->count; ++i){ - - if (d->async) - std::this_thread::sleep_for(std::chrono::milliseconds(d->delay)); - - if (!query->isValid()) - return; - - std::shared_ptr item = std::make_shared(QString::number(i)); - item->setText(QString("Das Item #%1").arg(i)); - item->setSubtext(QString("Toll, das Item #%1").arg(i)); - item->setIconPath(":debug"); - query->addMatch(item, 0); - } -} - - - -/** ***************************************************************************/ -bool Debug::Extension::isLongRunning() const { - return d->async; -} - - - -/** ***************************************************************************/ -int Debug::Extension::count() const{ - return d->count; -} - - - -/** ***************************************************************************/ -void Debug::Extension::setCount(const int &count){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::QueryHandler::id, "count"), count); - d->count = count; -} - - - -/** ***************************************************************************/ -bool Debug::Extension::async() const{ - return d->async; -} - - - -/** ***************************************************************************/ -void Debug::Extension::setAsync(bool async){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::QueryHandler::id, "async"), async); - d->async = async; -} - - - -/** ***************************************************************************/ -int Debug::Extension::delay() const { - return d->delay; -} - - - -/** ***************************************************************************/ -void Debug::Extension::setDelay(const int &delay) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::QueryHandler::id, "delay"), delay); - d->delay = delay; -} - - - -/** ***************************************************************************/ -void Debug::Extension::setTrigger(const QString &trigger){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::QueryHandler::id, "trigger"), trigger); - d->trigger = trigger; -} - - diff -Nru albert-0.12.0/src/plugins/debug/src/main.h albert-0.13.1+plugins1/src/plugins/debug/src/main.h --- albert-0.12.0/src/plugins/debug/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/debug/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace Debug { - -class DebugPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "Debug"; } - QWidget *widget(QWidget *parent = nullptr) override; - QStringList triggers() const override; - void handleQuery(Core::Query * query) override; - bool isLongRunning() const override; - - /* - * Extension specific members - */ - - int count() const; - void setCount(const int &count); - - bool async() const; - void setAsync(bool async); - - int delay() const; - void setDelay(const int &delay); - - const QString& trigger() const; - void setTrigger(const QString &trigger); - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/externalextensions/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/externalextensions/CMakeLists.txt --- albert-0.12.0/src/plugins/externalextensions/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(externalextensions) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets -) - -qt5_wrap_ui(UI - configwidget.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/externalextensions/configwidget.ui albert-0.13.1+plugins1/src/plugins/externalextensions/configwidget.ui --- albert-0.12.0/src/plugins/externalextensions/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ - - - ExternalExtensions::ConfigWidget - - - - 0 - 0 - 274 - 210 - - - - - - - <html><head/><body><p><span style=" color:#808080;">External extensions allow the user to rapidly write custom extensions. External extensions are basically programs that follow a specific communication protocol. For the details see the wiki. The list below contains the found extensions.</span></p></body></html> - - - true - - - - - - - QAbstractScrollArea::AdjustToContents - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - Qt::ElideLeft - - - false - - - false - - - false - - - true - - - false - - - - - - - - diff -Nru albert-0.12.0/src/plugins/externalextensions/metadata.json albert-0.13.1+plugins1/src/plugins/externalextensions/metadata.json --- albert-0.12.0/src/plugins/externalextensions/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.externalextensions", - "name" : "External extensions", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": false -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/externalextensions/src/configwidget.cpp --- albert-0.12.0/src/plugins/externalextensions/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -ExternalExtensions::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); - ui.tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - ui.tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); -} - - - -/** ***************************************************************************/ -ExternalExtensions::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/configwidget.h albert-0.13.1+plugins1/src/plugins/externalextensions/src/configwidget.h --- albert-0.12.0/src/plugins/externalextensions/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace ExternalExtensions { - -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; -}; - -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/externalextension.cpp albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextension.cpp --- albert-0.12.0/src/plugins/externalextensions/src/externalextension.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextension.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,399 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "externalextension.h" -#include "standardaction.h" -#include "standarditem.h" -#include "query.h" -#include "xdgiconlookup.h" -using std::pair; -using std::shared_ptr; -using std::vector; -using namespace Core; - -#define EXTERNAL_EXTENSION_IID "org.albert.extension.external/v2.0" - -namespace { - -bool runProcess (QString path, - std::map *variables, - QByteArray *out, - QString *errorString) { - - // Run the process - QProcess process; - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - for ( auto & entry : *variables ) - env.insert(entry.first, entry.second); - process.setProcessEnvironment(env); - process.setProgram(path); - process.start(); - process.waitForFinished(-1); - - if ( process.exitStatus() != QProcess::NormalExit ) { - *errorString = QString("Process crashed."); - return false; - } - - if ( process.exitCode() != 0 ) { - - *errorString = QString("Exit code is %1.").arg(process.exitCode()); - - QByteArray cout = process.readAllStandardOutput(); - QByteArray cerr = process.readAllStandardError(); - - if (!cout.isEmpty()) - errorString->append(QString("\n%1").arg(QString(cout))); - - if (!cerr.isEmpty()) - errorString->append(QString("\n%1").arg(QString(cerr))); - - return false; - } - - *out = process.readAllStandardOutput(); - - return true; -} - - -bool parseJsonObject (const QByteArray &json, - QJsonObject *object, - QString *errorString) { - - // Parse stdout - QJsonParseError error; - QJsonDocument document = QJsonDocument::fromJson(json, &error); - if ( document.isNull() ) { - *errorString = QString("Invalid JSON at %1: %2").arg(error.offset).arg(error.errorString()); - return false; - } - - *object = document.object(); - if ( object->isEmpty() ) { - *errorString = QString("Expected json object, but received an array."); - return false; - } - - return true; -} - - -bool saveVariables (QJsonObject *object, - std::map *variables, - QString *errorString) { - - variables->clear(); - - if ( !object->contains("variables") ) - return true; - - if ( !object->operator[]("variables").isObject() ) { - *errorString = "'variables' is not a JSON object"; - return false; - } - - QJsonObject vars = object->operator[]("variables").toObject(); - for (auto it = vars.begin(); it != vars.end(); ++it) - if ( it.value().isString() ) - variables->emplace(it.key(), it.value().toString()); - - return true; -} - -} - -/** ***************************************************************************/ -ExternalExtensions::ExternalExtension::ExternalExtension(const QString &path, const QString &id) - : QueryHandler(id), path_(path) { - - // Never run the extension concurrent - QMutexLocker lock (&processMutex_); - - - /* - * Get the metadata - */ - - // Run the process - variables_["ALBERT_OP"] = "METADATA"; - QString errorString; - QByteArray out; - if ( !runProcess(path_, &variables_, &out, &errorString) ) - throw QString("Getting metadata failed: %1 (%2)").arg(errorString, path_); - - // Parse stdout - QJsonObject object; - if ( !parseJsonObject(out, &object, &errorString) ) - throw QString("Getting metadata failed: %1 (%2)").arg(errorString, path_); - - // Check for a sane interface ID (IID) - if (object["iid"].isUndefined()) - throw QString("Getting metadata failed: Does not contain an interface id. (%1)").arg(path_); - - QString iid = object["iid"].toString(); - if (iid != EXTERNAL_EXTENSION_IID) - throw QString("Getting metadata failed: Interface id '%1' does not match '%2'. (%3)").arg(iid, EXTERNAL_EXTENSION_IID, path_); - - // Get opional data - QJsonValue val; - - val = object["trigger"]; - trigger_ = val.isString() ? val.toString() : QString(); - - val = object["name"]; - name_ = val.isString() ? val.toString() : id; - - val = object["version"]; - version_ = val.isString() ? val.toString() : "N/A"; - - val = object["author"]; - author_ = val.isString() ? val.toString() : "N/A"; - - QStringList dependencies; - for (const QJsonValue & value : object["dependencies"].toArray()) - dependencies.append(value.toString()); - - - /* - * Initialize the extension - */ - - // Run the process - variables_["ALBERT_OP"] = "INITIALIZE"; - if ( !runProcess(path, &variables_, &out, &errorString) ) - throw QString("Initialization failed: %1 (%2)").arg(errorString, path_); - - if ( out.isEmpty() ) - return; - - // Parse stdout - if ( !parseJsonObject(out, &object, &errorString) ) - throw QString("Initialization failed: %1 (%2)").arg(errorString, path_); - - // Finally save the variables, if any - if ( !saveVariables(&object, &variables_, &errorString) ) - qWarning() << qPrintable(QString("Initialization: %1 (%2)").arg(errorString, path_)); -} - - -/** ***************************************************************************/ -ExternalExtensions::ExternalExtension::~ExternalExtension() { - - // Never run the extension concurrent - QMutexLocker lock (&processMutex_); - QString errorString; - QJsonObject object; - QByteArray out; - - // Run the process - variables_["ALBERT_OP"] = "FINALIZE"; - if ( !runProcess(path_, &variables_, &out, &errorString) ) { - qWarning() << qPrintable(QString("Finalization failed: %1 (%2)").arg(errorString, path_)); - return; - } - - if ( out.isEmpty() ) - return; - - // Parse stdout - if ( !parseJsonObject(out, &object, &errorString) ) { - qWarning() << qPrintable(QString("Finalization failed: %1 (%2)").arg(errorString, path_)); - return; - } - - // Save the variables, if any - if ( !saveVariables(&object, &variables_, &errorString) ){ - qWarning() << qPrintable(QString("Finalization: %1 (%2)").arg(errorString, path_)); - return; - } -} - - -/** ***************************************************************************/ -void ExternalExtensions::ExternalExtension::setupSession() { - - // Never run the extension concurrent - QMutexLocker lock (&processMutex_); - QString errorString; - QJsonObject object; - QByteArray out; - - // Run the process - variables_["ALBERT_OP"] = "SETUPSESSION"; - if ( !runProcess(path_, &variables_, &out, &errorString) ) { - qWarning() << qPrintable(QString("Session setup failed: %1 (%2)").arg(errorString, path_)); - return; - } - - if ( out.isEmpty() ) - return; - - // Parse stdout - if ( !parseJsonObject(out, &object, &errorString) ) { - qWarning() << qPrintable(QString("Session setup failed: %1 (%2)").arg(errorString, path_)); - return; - } - - // Save the variables, if any - if ( !saveVariables(&object, &variables_, &errorString) ){ - qWarning() << qPrintable(QString("Session setup: %1 (%2)").arg(errorString, path_)); - return; - } -} - - -/** ***************************************************************************/ -void ExternalExtensions::ExternalExtension::teardownSession() { - - // Never run the extension concurrent - QMutexLocker lock (&processMutex_); - QString errorString; - QJsonObject object; - QByteArray out; - - // Run the process - variables_["ALBERT_OP"] = "TEARDOWNSESSION"; - if ( !runProcess(path_, &variables_, &out, &errorString) ) { - qWarning() << qPrintable(QString("Session teardown failed: %1 (%2)").arg(errorString, path_)); - return; - } - - if ( out.isEmpty() ) - return; - - // Parse stdout - if ( !parseJsonObject(out, &object, &errorString) ) { - qWarning() << qPrintable(QString("Session teardown failed: %1 (%2)").arg(errorString, path_)); - return; - } - - // Save the variables, if any - if ( !saveVariables(&object, &variables_, &errorString) ){ - qWarning() << qPrintable(QString("Session teardown: %1 (%2)").arg(errorString, path_)); - return; - } -} - - -/** ***************************************************************************/ -void ExternalExtensions::ExternalExtension::handleQuery(Query* query) { - - // External extension must run only when triggered, since they are to ressource heavy - if ( !query->isTriggered() ) - return; - - // Never run the extension concurrent - QMutexLocker lock (&processMutex_); - QString errorString; - QJsonObject object; - QByteArray out; - - // Run the process - variables_["ALBERT_OP"] = "QUERY"; - variables_["ALBERT_QUERY"] = query->searchTerm(); - if ( !runProcess(path_, &variables_, &out, &errorString) ) { - qWarning() << qPrintable(QString("Handle query failed: %1 (%2)").arg(errorString, path_)); - return; - } - - // Parse stdout - if ( !parseJsonObject(out, &object, &errorString) ) { - qWarning() << qPrintable(QString("Handle query failed: %1 (%2)").arg(errorString, path_)); - return; - } - - if ( out.isEmpty() ) - return; - - // Save the variables, if any - if ( !saveVariables(&object, &variables_, &errorString) ){ - qWarning() << qPrintable(QString("Handle query: %1 (%2)").arg(errorString, path_)); - return; - } - - // Check existance of items - if ( !object.contains("items") ) { - qWarning() << qPrintable(QString("Handle query failed: Result contains no items (%1)").arg(path_)); - return; - } - - // Check type of items - if ( !object["items"].isArray() ) { - qWarning() << qPrintable(QString("Handle query failed: 'items' is not an array (%1)").arg(path_)); - return; - } - - // Iterate over the results - shared_ptr standardItem; - shared_ptr standardAction; - vector> standardActionVector; - vector,short>> results; - - for (const QJsonValue & itemValue : object["items"].toArray() ){ - - if ( !itemValue.isObject() ) { - qWarning() << qPrintable(QString("Item is not a json object. (%1)").arg(path_)); - continue; - } - object = itemValue.toObject(); - - // Build the item from the json object - standardItem = std::make_shared(object["id"].toString()); - standardItem->setText(object["name"].toString()); - standardItem->setSubtext(object["description"].toString()); - standardItem->setCompletionString(object["completion"].toString()); - QString iconPath; - if ( !(iconPath = XdgIconLookup::iconPath(object["icon"].toString())).isNull() ) - standardItem->setIconPath(iconPath); - else if ( !(iconPath = XdgIconLookup::iconPath("unknown")).isNull() ) - standardItem->setIconPath(iconPath); - else - standardItem->setIconPath(":unknown"); - - - // Build the actions - standardActionVector.clear(); - for (const QJsonValue & value : object["actions"].toArray()){ - object = value.toObject(); - standardAction = std::make_shared(); - standardAction->setText(object["name"].toString()); - QString command = object["command"].toString(); - QStringList arguments; - for (const QJsonValue & value : object["arguments"].toArray()) - arguments.append(value.toString()); - standardAction->setAction(std::bind(static_cast(&QProcess::startDetached), command, arguments)); - standardActionVector.push_back(standardAction); - } - standardItem->setActions(std::move(standardActionVector)); - - results.emplace_back(std::move(standardItem), 0); - } - - query->addMatches(results.begin(), results.end()); -} - diff -Nru albert-0.12.0/src/plugins/externalextensions/src/externalextension.h albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextension.h --- albert-0.12.0/src/plugins/externalextensions/src/externalextension.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextension.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include "queryhandler.h" - -namespace ExternalExtensions { - -class ExternalExtension final : public QObject, public Core::QueryHandler -{ - -public: - - ExternalExtension(const QString &path, const QString &id); - ~ExternalExtension(); - - /* - * Implementation of extension interface - */ - - QStringList triggers() const override { return {trigger_}; } - void setupSession() override; - void teardownSession() override; - void handleQuery(Core::Query *query) override; - - /* - * Extension specific members - */ - - - const QString &path() { return path_; } - const QString &id() { return id_; } - const QString &name() { return name_; } - const QString &author() { return author_; } - const QString &version() { return version_; } - const QStringList &dependencies() { return dependencies_; } - -private: - - QString runOperation(const QString &); - - QString path_; - QString id_; - QString name_; - QString author_; - QString version_; - QStringList dependencies_; - QString trigger_; - std::map variables_; - QMutex processMutex_; -}; - -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/externalextensionmodel.cpp albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextensionmodel.cpp --- albert-0.12.0/src/plugins/externalextensions/src/externalextensionmodel.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextensionmodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include "externalextensionmodel.h" -#include "externalextension.h" - -/** ***************************************************************************/ -int ExternalExtensions::ExternalExtensionsModel::rowCount(const QModelIndex &) const { - return static_cast(externalExtensions_.size()); -} - - - -/** ***************************************************************************/ -int ExternalExtensions::ExternalExtensionsModel::columnCount(const QModelIndex &) const { - return static_cast(Section::Count); -} - - - -/** ***************************************************************************/ -QVariant ExternalExtensions::ExternalExtensionsModel::headerData(int section, Qt::Orientation orientation, int role) const { - // No sanity check necessary since - if ( section<0 || static_cast(Section::Count)<=section ) - return QVariant(); - - - if (orientation == Qt::Horizontal){ - switch (static_cast
(section)) { - case Section::Name:{ - switch (role) { - case Qt::DisplayRole: return "Name"; - case Qt::ToolTipRole: return "The name of the extension."; - default: return QVariant(); - } - - } - case Section::Trigger:{ - switch (role) { - case Qt::DisplayRole: return "Trigger"; - case Qt::ToolTipRole: return "The term that triggers this extension."; - default: return QVariant(); - } - - } - case Section::Path:{ - switch (role) { - case Qt::DisplayRole: return "Path"; - case Qt::ToolTipRole: return "The path of this extension."; - default: return QVariant(); - } - - } - default: return QVariant(); - } - } - return QVariant(); -} - - - -/** ***************************************************************************/ -QVariant ExternalExtensions::ExternalExtensionsModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() - || index.row() >= static_cast(externalExtensions_.size()) - || index.column() >= static_cast(static_cast(Section::Count))) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: { - switch (static_cast
(index.column())) { - case Section::Name: return externalExtensions_[index.row()]->name(); - case Section::Trigger: return externalExtensions_[index.row()]->triggers()[0] ; - case Section::Path: return externalExtensions_[index.row()]->path(); - default: return QVariant(); - } - } - case Qt::EditRole: { - switch (static_cast
(index.column())) { - case Section::Name: return externalExtensions_[index.row()]->name(); - case Section::Trigger: return externalExtensions_[index.row()]->triggers()[0]; - case Section::Path: return externalExtensions_[index.row()]->path(); - default: return QVariant(); - } - } - case Qt::ToolTipRole: { - switch (static_cast
(index.column())) { - default: return "Double click to edit"; - } - } - default: - return QVariant(); - } -} - - -/** ***************************************************************************/ -Qt::ItemFlags ExternalExtensions::ExternalExtensionsModel::flags(const QModelIndex &index) const { - if ( !index.isValid() ) - return Qt::NoItemFlags; - return Qt::ItemIsSelectable|Qt::ItemIsEnabled; -} - - -/** ***************************************************************************/ -void ExternalExtensions::ExternalExtensionsModel::onActivated(const QModelIndex &index) { - QDesktopServices::openUrl(QUrl(externalExtensions_[index.row()]->path())); -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/externalextensionmodel.h albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextensionmodel.h --- albert-0.12.0/src/plugins/externalextensions/src/externalextensionmodel.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/externalextensionmodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include "externalextension.h" - -namespace ExternalExtensions { - -class ExternalExtensionsModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - - ExternalExtensionsModel(const std::vector> &exts, QObject *parent = Q_NULLPTR) - : QAbstractTableModel(parent), externalExtensions_(exts) {} - - int rowCount(const QModelIndex & parent = QModelIndex()) const override; - int columnCount(const QModelIndex & parent = QModelIndex()) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex & index) const override; - - void onActivated(const QModelIndex &); - -private: - - const std::vector> &externalExtensions_; - enum class Section{Name, Trigger, Path, Count}; -}; - -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/main.cpp albert-0.13.1+plugins1/src/plugins/externalextensions/src/main.cpp --- albert-0.12.0/src/plugins/externalextensions/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,145 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "externalextension.h" -#include "externalextensionmodel.h" -#include "extensionmanager.h" -#include "main.h" - - - -class ExternalExtensions::ExternalExtensionsPrivate -{ -public: - QStringList pluginDirs; - std::vector> externalExtensions; - QFileSystemWatcher fileSystemWatcher; - QPointer widget; -}; - - - - -/** ***************************************************************************/ -ExternalExtensions::Extension::Extension() - : Core::Extension("org.albert.extension.externalextensions"), - d(new ExternalExtensionsPrivate) { - - d->pluginDirs = QStandardPaths::locateAll( - QStandardPaths::DataLocation, "external", - QStandardPaths::LocateDirectory); - - d->fileSystemWatcher.addPaths(d->pluginDirs); - - connect(&d->fileSystemWatcher, &QFileSystemWatcher::fileChanged, - this, &Extension::reloadExtensions); - - connect(&d->fileSystemWatcher, &QFileSystemWatcher::directoryChanged, - this, &Extension::reloadExtensions); - - reloadExtensions(); -} - - - -/** ***************************************************************************/ -ExternalExtensions::Extension::~Extension() { - - // Unregister and delete all extensions - auto it = d->externalExtensions.rbegin(); - while (it != d->externalExtensions.rend()) { - Core::ExtensionManager::instance->unregisterObject(it->get()); - it = std::reverse_iteratorexternalExtensions)::iterator>(d->externalExtensions.erase(std::next(it).base())); - } -} - - - -/** ***************************************************************************/ -QWidget *ExternalExtensions::Extension::widget(QWidget *parent) { - if (d->widget.isNull()){ - d->widget = new ConfigWidget(parent); - - ExternalExtensionsModel *model = new ExternalExtensionsModel(d->externalExtensions, d->widget->ui.tableView); - d->widget->ui.tableView->setModel(model); - - connect(d->widget->ui.tableView, &QTableView::activated, - model, &ExternalExtensionsModel::onActivated); - - // Reset the widget when - connect(this, &Extension::extensionsUpdated, - d->widget->ui.tableView, &QTableView::reset); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void ExternalExtensions::Extension::reloadExtensions() { - - // Unregister and delete all extensions - auto it = d->externalExtensions.rbegin(); - while (it != d->externalExtensions.rend()) { - Core::ExtensionManager::instance->unregisterObject(it->get()); - it = std::reverse_iteratorexternalExtensions)::iterator>(d->externalExtensions.erase(std::next(it).base())); - } - - // Remove all watches - if ( !d->fileSystemWatcher.files().isEmpty() ) - d->fileSystemWatcher.removePaths(d->fileSystemWatcher.files()); - - // Iterate over all files in the plugindirs - for (const QString &pluginDir : d->pluginDirs) { - QDirIterator dirIterator(pluginDir, QDir::Files|QDir::Executable, QDirIterator::NoIteratorFlags); - while (dirIterator.hasNext()) { - - QString path = dirIterator.next(); - QString id = dirIterator.fileInfo().fileName(); - - // Skip if this id already exists - if ( std::find_if(d->externalExtensions.begin(), - d->externalExtensions.end(), - [&id](const std::unique_ptr & rhs){ - return id == rhs->id(); }) != d->externalExtensions.end()) - continue; - - try { - d->externalExtensions.emplace_back(new ExternalExtension(path, id)); - d->fileSystemWatcher.addPath(path); - } catch ( QString s ) { - qWarning("Failed to initialize external extension: %s", s.toLocal8Bit().data()); - } - } - } - - for ( std::unique_ptr &obj : d->externalExtensions ) - Core::ExtensionManager::instance->registerObject(obj.get()); - - emit extensionsUpdated(); -} diff -Nru albert-0.12.0/src/plugins/externalextensions/src/main.h albert-0.13.1+plugins1/src/plugins/externalextensions/src/main.h --- albert-0.12.0/src/plugins/externalextensions/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/externalextensions/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "externalextension.h" - -namespace ExternalExtensions { - -class ExternalExtensionsPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "External extensions"; } - QWidget *widget(QWidget *parent = nullptr) override; - - /* - * Extension specific members - */ - - void reloadExtensions(); - -private: - - std::unique_ptr d; - -signals: - - void extensionsUpdated(); - -}; -} diff -Nru albert-0.12.0/src/plugins/files/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/files/CMakeLists.txt --- albert-0.12.0/src/plugins/files/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(files) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Concurrent - Widgets -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -qt5_wrap_ui(UI - forms/configwidget.ui - forms/mimetypedialog.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${QRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/ forms/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Concurrent_LIBRARIES} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/files/files.qrc albert-0.13.1+plugins1/src/plugins/files/files.qrc --- albert-0.12.0/src/plugins/files/files.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/files.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/inode-directory.svg - - diff -Nru albert-0.12.0/src/plugins/files/forms/configwidget.ui albert-0.13.1+plugins1/src/plugins/files/forms/configwidget.ui --- albert-0.12.0/src/plugins/files/forms/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/forms/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ - - - Files::ConfigWidget - - - - - - - - Paths - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - true - - - true - - - - - - - - - - 0 - 0 - - - - - .. - - - - - - - - 0 - 0 - - - - - .. - - - - - - - Restore - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - - - - - - - - Scan interval - - - - 5 - - - - - 0 - - - 1440 - - - 5 - - - 60 - - - - - - - minutes - - - - - - - - - - Indexed MIME types - - - - - - Documents - - - - - - - Folders - - - - - - - Images - - - - - - - Video - - - - - - - Audio - - - - - - - Advanced - - - - - - - - - - Misc settings - - - - - - Fuzzy Search - - - - - - - Index hidden files - - - - - - - Follow symlinks - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - Update index - - - - - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/files/forms/mimetypedialog.ui albert-0.13.1+plugins1/src/plugins/files/forms/mimetypedialog.ui --- albert-0.12.0/src/plugins/files/forms/mimetypedialog.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/forms/mimetypedialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ - - - Files::MimeTypeDialog - - - Dialog - - - - 4 - - - 4 - - - 4 - - - 4 - - - - - - - - - Qt::ScrollBarAlwaysOn - - - QAbstractItemView::EditKeyPressed - - - QAbstractItemView::DropOnly - - - true - - - - - - - Filter for the mimetypes… - - - - - - - - - - - > - - - - .. - - - - - - - - - - - Drop files into the list to add their mimetypes or choose a mimetype from the complete list using the "Add mimetype" button. - - - Qt::ScrollBarAlwaysOn - - - - - - - - - <html><head/><body><p><span style=" color:#808080;">This is the list of patterns that is used to filter the indexed files by matching their mime type.</span></p></body></html> - - - true - - - - - - - - .. - - - - - - - - .. - - - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - Files::MimeTypeDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Files::MimeTypeDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -Nru albert-0.12.0/src/plugins/files/metadata.json albert-0.13.1+plugins1/src/plugins/files/metadata.json --- albert-0.12.0/src/plugins/files/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.files", - "name" : "Files", - "version" : "1.1", - "platform" : "All", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/files/resources/inode-directory.svg albert-0.13.1+plugins1/src/plugins/files/resources/inode-directory.svg --- albert-0.12.0/src/plugins/files/resources/inode-directory.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/resources/inode-directory.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/files/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/files/src/configwidget.cpp --- albert-0.12.0/src/plugins/files/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,246 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include "configwidget.h" -#include "main.h" -#include "mimetypedialog.h" - -/** ***************************************************************************/ -Files::ConfigWidget::ConfigWidget(Extension *_extension, QWidget *_parent) - : QWidget(_parent), extension(_extension) { - ui.setupUi(this); - - - // Paths - QStringListModel *pathsModel = new QStringListModel(this); - pathsModel->setStringList(extension->paths()); - ui.listView_paths->setModel(pathsModel); - - connect(pathsModel, &QStringListModel::dataChanged, - [=](){ extension->setPaths(pathsModel->stringList()); }); - - connect(pathsModel, &QStringListModel::rowsInserted, - [=](){ extension->setPaths(pathsModel->stringList()); }); - - connect(pathsModel, &QStringListModel::rowsRemoved, - [=](){ extension->setPaths(pathsModel->stringList()); }); - - // Buttons - connect(ui.pushButton_add, &QPushButton::clicked, [=](){ - QString path = QFileDialog::getExistingDirectory( - this, - tr("Choose path"), - QStandardPaths::writableLocation(QStandardPaths::HomeLocation)); - - if(path.isEmpty()) - return; - - if ( pathsModel->match(pathsModel->index(0, 0), Qt::DisplayRole, - QVariant::fromValue(path)).isEmpty() ) { - pathsModel->insertRow(pathsModel->rowCount()); - pathsModel->setData(pathsModel->index(pathsModel->rowCount()-1,0), path); - } - }); - - connect(ui.pushButton_remove, &QPushButton::clicked, [=](){ - if ( !ui.listView_paths->currentIndex().isValid() ) - return; - pathsModel->removeRow(ui.listView_paths->currentIndex().row()); - }); - - connect(ui.pushButton_update, &QPushButton::clicked, - extension, &Extension::updateIndex); - - connect(ui.pushButton_restore, &QPushButton::clicked, - extension, &Extension::restorePaths); - - /* - * Initialize the indexing options - */ - - ui.checkBox_hidden->setChecked(extension->indexHidden()); - connect(ui.checkBox_hidden, &QCheckBox::toggled, extension, &Extension::setIndexHidden); - - ui.checkBox_followSymlinks->setChecked(extension->followSymlinks()); - connect(ui.checkBox_followSymlinks, &QCheckBox::toggled, extension, &Extension::setFollowSymlinks); - - ui.checkBox_fuzzy->setChecked(extension->fuzzy()); - connect(ui.checkBox_fuzzy, &QCheckBox::toggled, extension, &Extension::setFuzzy); - - ui.spinBox_interval->setValue(static_cast(extension->scanInterval())); - connect(ui.spinBox_interval, static_cast(&QSpinBox::valueChanged), - extension, &Extension::setScanInterval); - - /* - * Initialize the mime options - */ - - if (extension->filters().contains("audio/*")) - ui.checkBox_audio->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("audio/"); })) - ui.checkBox_audio->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_audio->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("video/*")) - ui.checkBox_video->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("video/"); })) - ui.checkBox_video->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_video->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("image/*")) - ui.checkBox_image->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("image/"); })) - ui.checkBox_image->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_image->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("application/*")) - ui.checkBox_docs->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("application/"); })) - ui.checkBox_docs->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_docs->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("inode/directory")) - ui.checkBox_dirs->setCheckState(Qt::Checked); - else - ui.checkBox_dirs->setCheckState(Qt::Unchecked); - - /* - * Set the actions for checking the mime options - */ - - connect(ui.checkBox_audio, &QCheckBox::clicked, extension, [this]() { - ui.checkBox_audio->setTristate(false); - QStringList filters = extension->filters(); - filters.erase(std::remove_if(filters.begin(), filters.end(), - [](const QString &str){ return str.startsWith("audio/"); }), - filters.end()); - if (ui.checkBox_audio->checkState() == Qt::Checked) - filters.push_back("audio/*"); - extension->setFilters(filters); - }); - - connect(ui.checkBox_video, &QCheckBox::clicked, extension, [this]() { - ui.checkBox_video->setTristate(false); - QStringList filters = extension->filters(); - filters.erase(std::remove_if(filters.begin(), filters.end(), - [](const QString &str){ return str.startsWith("video/"); }), - filters.end()); - if (ui.checkBox_video->checkState() == Qt::Checked) - filters.push_back("video/*"); - extension->setFilters(filters); - }); - - connect(ui.checkBox_image, &QCheckBox::clicked, extension, [this]() { - ui.checkBox_image->setTristate(false); - QStringList filters = extension->filters(); - filters.erase(std::remove_if(filters.begin(), filters.end(), - [](const QString &str){ return str.startsWith("image/"); }), - filters.end()); - if (ui.checkBox_image->checkState() == Qt::Checked) - filters.push_back("image/*"); - extension->setFilters(filters); - }); - - connect(ui.checkBox_docs, &QCheckBox::clicked, extension, [this]() { - ui.checkBox_docs->setTristate(false); - QStringList filters = extension->filters(); - filters.erase(std::remove_if(filters.begin(), filters.end(), - [](const QString &str){ return str.startsWith("application/"); }), - filters.end()); - if (ui.checkBox_docs->checkState() == Qt::Checked) - filters.push_back("application/*"); - extension->setFilters(filters); - }); - - connect(ui.checkBox_dirs, &QCheckBox::toggled, extension, [=](bool checked){ - QStringList filters = extension->filters(); - filters.removeAll("inode/directory"); - if (checked) - filters.push_back("inode/directory"); - extension->setFilters(filters); - }); - - // The advanced button action - connect(ui.pushButton_advanced, &QPushButton::clicked, [=](){ - - MimeTypeDialog dialog(extension->filters(), this); - dialog.setWindowModality(Qt::WindowModal); - if ( dialog.exec() ) { - - // If the dialog has been accepted, update extension and checkboxes - extension->setFilters(dialog.filters()); - - // Set the shortcuts - if (extension->filters().contains("audio/*")) - ui.checkBox_audio->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("audio/"); })) - ui.checkBox_audio->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_audio->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("video/*")) - ui.checkBox_video->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("video/"); })) - ui.checkBox_video->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_video->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("image/*")) - ui.checkBox_image->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("image/"); })) - ui.checkBox_image->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_image->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("application/*")) - ui.checkBox_docs->setCheckState(Qt::Checked); - else if (std::any_of(extension->filters().begin(), extension->filters().end(), - [](const QString & str){ return str.startsWith("application/"); })) - ui.checkBox_docs->setCheckState(Qt::PartiallyChecked); - else - ui.checkBox_docs->setCheckState(Qt::Unchecked); - - if (extension->filters().contains("inode/directory")) - ui.checkBox_dirs->setCheckState(Qt::Checked); - else - ui.checkBox_dirs->setCheckState(Qt::Unchecked); - } - }); - - // Status bar - connect(extension, &Extension::statusInfo, ui.label_statusbar, &QLabel::setText); -} - - - -/** ***************************************************************************/ -Files::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/files/src/configwidget.h albert-0.13.1+plugins1/src/plugins/files/src/configwidget.h --- albert-0.12.0/src/plugins/files/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ - -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "ui_configwidget.h" - -namespace Files { - -class Extension; - -class ConfigWidget final : public QWidget -{ - Q_OBJECT - -public: - - explicit ConfigWidget(Extension *ext, QWidget *parent = 0); - ~ConfigWidget(); - -private: - - Extension *extension; - Ui::ConfigWidget ui; - -signals: - - void requestAddPath(const QString&); - void requestRemovePath(const QString&); - -}; - -} diff -Nru albert-0.12.0/src/plugins/files/src/fileactions.cpp albert-0.13.1+plugins1/src/plugins/files/src/fileactions.cpp --- albert-0.12.0/src/plugins/files/src/fileactions.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/fileactions.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include "fileactions.h" - -/******************************************************************************/ - -Files::FileAction::FileAction(Files::File *file) : file_(file) { - -} - -Files::FileAction::~FileAction() { - -} - -/******************************************************************************/ - -Files::OpenFileAction::OpenFileAction(Files::File *file) : FileAction(file) { - -} - -QString Files::OpenFileAction::text() const { - return "Open with default application"; -} - -void Files::OpenFileAction::activate() { - QDesktopServices::openUrl(QUrl::fromLocalFile(file_->path())); -} - -/******************************************************************************/ - -Files::RevealFileAction::RevealFileAction(Files::File *file) : FileAction(file) { - -} - -QString Files::RevealFileAction::text() const { - return "Reveal in file browser"; -} - -void Files::RevealFileAction::activate() { - QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(file_->path()).path())); -} - -/******************************************************************************/ - -Files::CopyFileAction::CopyFileAction(Files::File *file) : FileAction(file) { - -} - -QString Files::CopyFileAction::text() const { - return "Copy to clipboard"; -} - -void Files::CopyFileAction::activate() { - // Get clipboard - QClipboard *cb = QApplication::clipboard(); - - // Ownership of the new data is transferred to the clipboard. - QMimeData* newMimeData = new QMimeData(); - - // Copy old mimedata - const QMimeData* oldMimeData = cb->mimeData(); - for (const QString &f : oldMimeData->formats()) - newMimeData->setData(f, oldMimeData->data(f)); - - // Copy path of file - newMimeData->setText(file_->path()); - - // Copy file - newMimeData->setUrls({QUrl::fromLocalFile(file_->path())}); - - // Copy file (f*** you gnome) - QByteArray gnomeFormat = QByteArray("copy\n").append(QUrl::fromLocalFile(file_->path()).toEncoded()); - newMimeData->setData("x-special/gnome-copied-files", gnomeFormat); - - // Set the mimedata - cb->setMimeData(newMimeData); -} - -/******************************************************************************/ - -Files::CopyPathAction::CopyPathAction(Files::File *file) - : FileAction(file) { -} - -QString Files::CopyPathAction::text() const { - return "Copy path to clipboard"; -} - -void Files::CopyPathAction::activate() { - QApplication::clipboard()->setText(file_->path()); -} - -/******************************************************************************/ - -extern QString terminalCommand; - -Files::TerminalFileAction::TerminalFileAction(Files::File *file) - : FileAction(file) { -} - -QString Files::TerminalFileAction::text() const { - return "Open terminal at this path"; - -} - -void Files::TerminalFileAction::activate() { - QFileInfo fileInfo(file_->path()); - QStringList commandLine = terminalCommand.trimmed().split(' '); - if ( commandLine.size() == 0 ) - return; - if ( fileInfo.isDir() ) - QProcess::startDetached(commandLine[0], {}, fileInfo.filePath()); - else - QProcess::startDetached(commandLine[0], {}, fileInfo.path()); -} diff -Nru albert-0.12.0/src/plugins/files/src/fileactions.h albert-0.13.1+plugins1/src/plugins/files/src/fileactions.h --- albert-0.12.0/src/plugins/files/src/fileactions.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/fileactions.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include -#include -#include "file.h" -#include "action.h" - -namespace Files { - -/** ***************************************************************************/ -struct FileAction : public Core::Action -{ - FileAction(File *file); - ~FileAction(); - File const * const file_; -}; - - - -/** ***************************************************************************/ -struct OpenFileAction final : public FileAction -{ - OpenFileAction(File *file); - QString text() const override; - void activate() override; -}; - - - -/** ***************************************************************************/ -struct RevealFileAction final : public FileAction -{ - RevealFileAction(File *file); - QString text() const override; - void activate() override; -}; - - - -/** ***************************************************************************/ -struct TerminalFileAction final : public FileAction -{ - TerminalFileAction(File *file); - QString text() const override; - void activate() override; -}; - - - -/** ***************************************************************************/ -struct CopyFileAction final : public FileAction -{ - CopyFileAction(File *file); - QString text() const override; - void activate() override; -}; - - - -/** ***************************************************************************/ -struct CopyPathAction final : public FileAction -{ - CopyPathAction(File *file); - QString text() const override; - void activate() override; -}; - - -} diff -Nru albert-0.12.0/src/plugins/files/src/file.cpp albert-0.13.1+plugins1/src/plugins/files/src/file.cpp --- albert-0.12.0/src/plugins/files/src/file.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/file.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include "file.h" -#include "fileactions.h" -#include "xdgiconlookup.h" -using std::vector; -using std::shared_ptr; - -std::map Files::File::iconCache_; - -/** ***************************************************************************/ -QString Files::File::text() const { - return QFileInfo(path_).fileName(); -} - - - -/** ***************************************************************************/ -QString Files::File::subtext() const { - return path_; -} - - - -/** ***************************************************************************/ -QString Files::File::completionString() const { - QString result = ( QFileInfo(path_).isDir() ) ? QString("%1/").arg(path_) : path_; -#ifdef __linux__ - if ( result.startsWith(QDir::homePath()) ) - result.replace(QDir::homePath(), "~"); -#endif - return result; -} - - - -/** ***************************************************************************/ -QString Files::File::iconPath() const { - - const QString xdgIconName = mimetype_.iconName(); - - // First check if icon exists - auto search = iconCache_.find(xdgIconName); - if(search != iconCache_.end()) - return search->second; - - QString iconPath; - if ( !(iconPath = XdgIconLookup::iconPath(xdgIconName)).isNull() // Lookup iconName - || !(iconPath = XdgIconLookup::iconPath(mimetype_.genericIconName())).isNull() // Lookup genericIconName - || !(iconPath = XdgIconLookup::iconPath("unknown")).isNull()) { // Lookup "unknown" - iconCache_.emplace(xdgIconName, iconPath); - return iconPath; - } - - // Nothing found, return a fallback icon - if ( xdgIconName == "inode-directory" ) { - iconPath = ":directory"; - iconCache_.emplace(xdgIconName, iconPath); - } else { - iconPath = ":unknown"; - iconCache_.emplace(xdgIconName, iconPath); - } - return iconPath; -} - - -/** ***************************************************************************/ -vector> Files::File::actions() { - vector> actions; - actions.push_back(std::make_shared(this)); - actions.push_back(std::make_shared(this)); - actions.push_back(std::make_shared(this)); - actions.push_back(std::make_shared(this)); - actions.push_back(std::make_shared(this)); - return actions; -} - - - -/** ***************************************************************************/ -vector Files::File::indexKeywords() const { - std::vector res; - res.emplace_back(QFileInfo(path_).fileName(), USHRT_MAX); - // TODO ADD PATH - return res; -} diff -Nru albert-0.12.0/src/plugins/files/src/file.h albert-0.13.1+plugins1/src/plugins/files/src/file.h --- albert-0.12.0/src/plugins/files/src/file.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/file.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include -#include -#include "indexable.h" -#include "item.h" - -namespace Files { - -class File final : public Core::Item, public Core::Indexable -{ -public: - - File() {} - File(QString path, QMimeType mimetype) - : path_(path), mimetype_(mimetype){} - - /* - * Implementation of Item interface - */ - - QString id() const override { return path_; } - QString text() const override; - QString subtext() const override; - QString completionString() const override; - QString iconPath() const override; - std::vector indexKeywords() const override; - std::vector> actions() override; - - /* - * Item specific members - */ - - /** Return the path of the file */ - const QString &path() const { return path_; } - - /** Return the mimetype of the file */ - const QMimeType &mimetype() const { return mimetype_; } - -private: - - QString path_; - QMimeType mimetype_; - static std::map iconCache_; -}; - -} diff -Nru albert-0.12.0/src/plugins/files/src/main.cpp albert-0.13.1+plugins1/src/plugins/files/src/main.cpp --- albert-0.12.0/src/plugins/files/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,566 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "file.h" -#include "main.h" -#include "offlineindex.h" -#include "query.h" -#include "queryhandler.h" -#include "standarditem.h" -#include "standardaction.h" -using std::pair; -using std::shared_ptr; -using std::vector; -using namespace Core; - - -namespace { - -const char* CFG_PATHS = "paths"; -const char* CFG_FILTERS = "filters"; -const QStringList DEF_FILTERS = { "inode/directory", "application/*" }; -const char* CFG_FUZZY = "fuzzy"; -const bool DEF_FUZZY = false; -const char* CFG_INDEX_HIDDEN = "indexhidden"; -const bool DEF_INDEX_HIDDEN = false; -const char* CFG_FOLLOW_SYMLINKS = "follow_symlinks"; -const bool DEF_FOLLOW_SYMLINKS = false; -const char* CFG_SCAN_INTERVAL = "scan_interval"; -const uint DEF_SCAN_INTERVAL = 60; -const char* IGNOREFILE = ".albertignore"; - -struct IndexSettings { - QStringList rootDirs; - QStringList filters; - bool indexHidden; - bool followSymlinks; -}; - -enum class PatternType { - Include, - Exclude -}; - -struct IgnoreEntry { - IgnoreEntry(QRegularExpression regex, PatternType type) : regex(regex), type(type) {} - QRegularExpression regex; - PatternType type; -}; - -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -class Files::FilesPrivate -{ -public: - FilesPrivate(Extension *q) : q(q), abort(false), rerun(false) {} - - Extension *q; - - QPointer widget; - - vector> index; - Core::OfflineIndex offlineIndex; - QFutureWatcher>> futureWatcher; - QTimer indexIntervalTimer; - bool abort; - bool rerun; - - IndexSettings indexSettings; - - void finishIndexing(); - void startIndexing(); - vector> indexFiles(const IndexSettings &indexSettings) const; -}; - - - -/** ***************************************************************************/ -void Files::FilesPrivate::startIndexing() { - - // Abort and rerun - if ( futureWatcher.future().isRunning() ) { - emit q->statusInfo("Waiting for indexer to shut down ..."); - abort = true; - rerun = true; - return; - } - - // Run finishIndexing when the indexing thread finished - futureWatcher.disconnect(); - QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, - std::bind(&FilesPrivate::finishIndexing, this)); - - // Restart the timer (Index update may have been started manually) - if (indexIntervalTimer.interval() != 0) - indexIntervalTimer.start(); - - // Run the indexer thread - qDebug() << "Start indexing files."; - futureWatcher.setFuture(QtConcurrent::run(this, &FilesPrivate::indexFiles, indexSettings)); - - // Notification - emit q->statusInfo("Indexing files ..."); -} - - - -/** ***************************************************************************/ -void Files::FilesPrivate::finishIndexing() { - - // In case of abortion the returned data is invalid - if ( !abort ) { - // Get the thread results - index = futureWatcher.future().result(); - - // Rebuild the offline index - offlineIndex.clear(); - for (const auto &item : index) - offlineIndex.add(item); - - // Notification - qDebug() << qPrintable(QString("Indexed %1 files.").arg(index.size())); - emit q->statusInfo(QString("%1 files indexed.").arg(index.size())); - } - - abort = false; - - if ( rerun ) { - rerun = false; - startIndexing(); - } -} - - - -/** ***************************************************************************/ -vector> -Files::FilesPrivate::indexFiles(const IndexSettings &indexSettings) const { - - // Get a new index - std::vector> newIndex; - std::set indexedDirs; - QMimeDatabase mimeDatabase; - std::vector mimeFilters; - for (const QString &re : indexSettings.filters) - mimeFilters.emplace_back(re, Qt::CaseInsensitive, QRegExp::Wildcard); - - // Prepare the iterator properties - QDir::Filters filters = QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot; - if (indexSettings.indexHidden) - filters |= QDir::Hidden; - - // Anonymous function that implemnents the index recursion - std::function)> indexRecursion = - [&](const QFileInfo& fileInfo, const vector &ignoreEntries){ - - if (abort) return; - - const QString canonicalPath = fileInfo.canonicalFilePath(); - const QMimeType mimetype = mimeDatabase.mimeTypeForFile(canonicalPath); - const QString mimeName = mimetype.name(); - - // If the file matches the index options, index it - if ( std::any_of(mimeFilters.begin(), mimeFilters.end(), - [&](const QRegExp &re){ return re.exactMatch(mimeName); }) ) - newIndex.push_back(std::make_shared(canonicalPath, mimetype)); - - if (fileInfo.isDir()) { - - emit q->statusInfo(QString("Indexing %1.").arg(canonicalPath)); - - // Skip if this dir has already been indexed - if ( indexedDirs.find(canonicalPath) != indexedDirs.end() ) - return; - - // Remember that this dir has been indexed to avoid loops - indexedDirs.insert(canonicalPath); - - // Read the ignore file, see http://doc.qt.io/qt-5/qregexp.html#wildcard-matching - vector localIgnoreEntries = ignoreEntries; - QFile file(QDir(canonicalPath).filePath(IGNOREFILE)); - if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { - QTextStream in(&file); - while ( !in.atEnd() ) { - QString pattern = QDir::cleanPath(in.readLine()); - - if ( pattern.isEmpty() || pattern.startsWith("#") ) - continue; - - // Replace ** and * by their regex analogons - pattern.replace(QRegularExpression("(? ignores = {IgnoreEntry( - QRegularExpression(QString("%1$").arg(IGNOREFILE)), - PatternType::Exclude)}; - indexRecursion(QFileInfo(rootDir), ignores); - if ( abort ) - return vector>(); - } - - // Serialize data - QFile file(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)). - filePath(QString("%1.txt").arg(q->Core::Extension::id))); - if ( file.open(QIODevice::WriteOnly|QIODevice::Text) ) { - qDebug() << qPrintable(QString("Serializing files to '%1'").arg(file.fileName())); - QTextStream out(&file); - for (const shared_ptr &item : newIndex) - out << item->path() << endl << item->mimetype().name() << endl; - } else - qWarning() << qPrintable(QString("Could not write to file '%1': %2").arg(file.fileName(), file.errorString())); - - return newIndex; -} - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -Files::Extension::Extension() - : Core::Extension("org.albert.extension.files"), - Core::QueryHandler(Core::Extension::id), - d(new FilesPrivate(this)) { - - // Load settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - d->indexSettings.filters = s.value(CFG_FILTERS, DEF_FILTERS).toStringList(); - d->indexSettings.indexHidden = s.value(CFG_INDEX_HIDDEN, DEF_INDEX_HIDDEN).toBool(); - d->indexSettings.followSymlinks = s.value(CFG_FOLLOW_SYMLINKS, DEF_FOLLOW_SYMLINKS).toBool(); - d->offlineIndex.setFuzzy(s.value(CFG_FUZZY, DEF_FUZZY).toBool()); - d->indexIntervalTimer.setInterval(s.value(CFG_SCAN_INTERVAL, DEF_SCAN_INTERVAL).toInt()*60000); // Will be started in the initial index update - d->indexSettings.rootDirs = s.value(CFG_PATHS).toStringList(); - if (d->indexSettings.rootDirs.isEmpty()) - restorePaths(); - s.endGroup(); - - // Deserialize data - QFile file(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)). - filePath(QString("%1.txt").arg(Core::Extension::id))); - if (file.exists()) { - if (file.open(QIODevice::ReadOnly| QIODevice::Text)) { - qDebug() << qPrintable(QString("Deserializing files from '%1'.").arg(file.fileName())); - QTextStream in(&file); - QMimeDatabase mimedatabase; - while (!in.atEnd()) - d->index.emplace_back(new File(in.readLine(), mimedatabase.mimeTypeForName(in.readLine()))); - file.close(); - - // Build the offline index - for (const auto &item : d->index) - d->offlineIndex.add(item); - } else - qWarning() << qPrintable(QString("Could not read from file '%1': %2").arg(file.fileName(), file.errorString())); - } - - // Index timer - connect(&d->indexIntervalTimer, &QTimer::timeout, this, &Extension::updateIndex); - - // If the root dirs change write it to the settings - connect(this, &Extension::rootDirsChanged, [this](const QStringList& dirs){ - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_PATHS), dirs); - }); - - // Trigger an initial update - updateIndex(); -} - - - -/** ***************************************************************************/ -Files::Extension::~Extension() { - - // The indexer thread has sideeffects wait for termination - d->abort = true; - d->rerun = false; - d->futureWatcher.waitForFinished(); -} - - - -/** ***************************************************************************/ -QWidget *Files::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) - d->widget = new ConfigWidget(this, parent); - return d->widget; -} - - - -/** ***************************************************************************/ -void Files::Extension::handleQuery(Core::Query * query) { - - - if ( query->searchTerm().startsWith('/') || query->searchTerm().startsWith("~") ) { - - QFileInfo queryFileInfo(query->searchTerm()); - - // Substitute tilde - if ( query->searchTerm()[0] == '~' ) - queryFileInfo.setFile(QDir::homePath()+query->searchTerm().right(query->searchTerm().size()-1)); - - // Get all matching files - QFileInfo pathInfo(queryFileInfo.path()); - if ( pathInfo.exists() && pathInfo.isDir() ) { - QMimeDatabase mimeDatabase; - QDir dir(pathInfo.filePath()); - for (const QFileInfo& fileinfo : dir.entryInfoList(QDir::AllEntries|QDir::Hidden|QDir::NoDotAndDotDot, - QDir::DirsFirst|QDir::Name|QDir::IgnoreCase) ) { - if ( fileinfo.fileName().startsWith(queryFileInfo.fileName()) ) { - QMimeType mimetype = mimeDatabase.mimeTypeForFile(fileinfo.filePath()); - query->addMatch(std::make_shared(fileinfo.filePath(), mimetype), - static_cast(SHRT_MAX * static_cast(queryFileInfo.fileName().size()) / fileinfo.fileName().size())); - } - } - } - } - else - { - if ( QString("albert scan files").startsWith(query->searchTerm()) ) { - shared_ptr standardItem = std::make_shared("org.albert.extension.files.action.index"); - standardItem->setText("albert scan files"); - standardItem->setSubtext("Update the file index"); - standardItem->setIconPath(":app_icon"); - - shared_ptr standardAction = std::make_shared(); - standardAction->setText("Update the file index"); - standardAction->setAction([this](){ this->updateIndex(); }); - - standardItem->setActions({standardAction}); - - query->addMatch(standardItem); - } - - // Search for matches - const vector> &indexables = d->offlineIndex.search(query->searchTerm().toLower()); - - // Add results to query - vector,short>> results; - for (const shared_ptr &item : indexables) - // TODO `Search` has to determine the relevance. Set to 0 for now - results.emplace_back(std::static_pointer_cast(item), -1); - - query->addMatches(results.begin(), results.end()); - } -} - - - -/** ***************************************************************************/ -const QStringList &Files::Extension::paths() const { - return d->indexSettings.rootDirs; -} - - - -/** ***************************************************************************/ -void Files::Extension::setPaths(const QStringList &paths) { - - d->indexSettings.rootDirs.clear(); - - // Check sanity and add path - for ( const QString& path : paths ) { - - QFileInfo fileInfo(path); - QString absPath = fileInfo.absoluteFilePath(); - - if (d->indexSettings.rootDirs.contains(absPath)) { - qWarning() << QString("Duplicate paths: %1.").arg(path); - continue; - } - - if (!fileInfo.exists()) { - qWarning() << QString("Path does not exist: %1.").arg(path); - continue; - } - - if(!fileInfo.isDir()) { - qWarning() << QString("Path is not a directory: %1.").arg(path); - continue; - } - - d->indexSettings.rootDirs << absPath; - } - - // Store to settings - QSettings(qApp->applicationName()) - .setValue(QString("%1/%2").arg(Core::Extension::id, CFG_PATHS), d->indexSettings.rootDirs); -} - - - -/** ***************************************************************************/ -void Files::Extension::restorePaths() { - // Add standard path - d->indexSettings.rootDirs.clear(); - d->indexSettings.rootDirs << QStandardPaths::writableLocation(QStandardPaths::HomeLocation); -} - - - -/** ***************************************************************************/ -void Files::Extension::updateIndex() { - d->startIndexing(); -} - - - -/** ***************************************************************************/ -bool Files::Extension::indexHidden() const { - return d->indexSettings.indexHidden; -} - - - -/** ***************************************************************************/ -void Files::Extension::setIndexHidden(bool b) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_INDEX_HIDDEN), b); - d->indexSettings.indexHidden = b; -} - - - -/** ***************************************************************************/ -bool Files::Extension::followSymlinks() const { - return d->indexSettings.followSymlinks; -} - - - -/** ***************************************************************************/ -void Files::Extension::setFollowSymlinks(bool b) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_FOLLOW_SYMLINKS), b); - d->indexSettings.followSymlinks = b; -} - - - -/** ***************************************************************************/ -unsigned int Files::Extension::scanInterval() const { - return d->indexIntervalTimer.interval()/60000; -} - - - -/** ***************************************************************************/ -void Files::Extension::setScanInterval(uint minutes) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_SCAN_INTERVAL), minutes); - (minutes == 0) ? d->indexIntervalTimer.stop() : d->indexIntervalTimer.start(minutes*60000); -} - - - -/** ***************************************************************************/ -bool Files::Extension::fuzzy() const { - return d->offlineIndex.fuzzy(); -} - - - -/** ***************************************************************************/ -void Files::Extension::setFuzzy(bool b) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_FUZZY), b); -} - - - -/** ***************************************************************************/ -const QStringList &Files::Extension::filters() const { - return d->indexSettings.filters; -} - - - -/** ***************************************************************************/ -void Files::Extension::setFilters(const QStringList &filters) { - QSettings(qApp->applicationName()) - .setValue(QString("%1/%2").arg(Core::Extension::id, CFG_FILTERS), filters); - d->indexSettings.filters = filters; -} diff -Nru albert-0.12.0/src/plugins/files/src/main.h albert-0.13.1+plugins1/src/plugins/files/src/main.h --- albert-0.12.0/src/plugins/files/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace Files { - -class FilesPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "Files"; } - QStringList triggers() const override { return {"/", "~"}; } - QWidget *widget(QWidget *parent = nullptr) override; - void handleQuery(Core::Query * query) override; - - /* - * Extension specific members - */ - - const QStringList &paths() const; - void setPaths(const QStringList &); - void restorePaths(); - - bool indexHidden() const; - void setIndexHidden(bool b = true); - - bool followSymlinks() const; - void setFollowSymlinks(bool b = true); - - uint scanInterval() const; - void setScanInterval(uint minutes); - - bool fuzzy() const; - void setFuzzy(bool b = true); - - const QStringList &filters() const; - void setFilters(const QStringList &); - - void updateIndex(); - -private: - - std::unique_ptr d; - -signals: - - void rootDirsChanged(const QStringList&); - void statusInfo(const QString&); - -}; -} diff -Nru albert-0.12.0/src/plugins/files/src/mimetypedialog.cpp albert-0.13.1+plugins1/src/plugins/files/src/mimetypedialog.cpp --- albert-0.12.0/src/plugins/files/src/mimetypedialog.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/mimetypedialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include "mimetypedialog.h" -#include "ui_mimetypedialog.h" - - -/** ***************************************************************************/ -Files::MimeTypeDialog::MimeTypeDialog(const QStringList &filters, QWidget *parent) : - QDialog(parent), ui(new Ui::MimeTypeDialog) { - ui->setupUi(this); - - // Populate a standard itemmodel with mime types - QStandardItemModel *standardItemModel = new QStandardItemModel(this); - for (QMimeType mimeType : QMimeDatabase().allMimeTypes()) { - QStandardItem *item = new QStandardItem; - item->setText(mimeType.name()); - item->setToolTip(mimeType.filterString()); - standardItemModel->appendRow(item); - } - standardItemModel->sort(0); - - // Add a proxy model for mimtype filtering - QSortFilterProxyModel *mimeFilterModel = new QSortFilterProxyModel(this); - mimeFilterModel->setSourceModel(standardItemModel); - ui->listView_mimeTypes->setModel(mimeFilterModel); - - // Add a stinglist model to the filter model - filtersModel = new QStringListModel(filters, this); - ui->listView_filters->setModel(filtersModel); - - // Set the filter for the proxymodel if the users typed something - connect(ui->lineEdit, &QLineEdit::textChanged, - mimeFilterModel, &QSortFilterProxyModel::setFilterFixedString); - - // On mimetype list activation add the mimetype to the filter list - connect(ui->listView_mimeTypes, &QListView::activated, [this](const QModelIndex &index){ - filtersModel->insertRow(filtersModel->rowCount()); - filtersModel->setData(filtersModel->index(filtersModel->rowCount()-1,0), index.data()); - }); - - // On ">" button click add the mimetype to the filter list - connect(ui->toolButton_copyMimetype, &QToolButton::clicked, [this](){ - QModelIndex index = ui->listView_mimeTypes->currentIndex(); - filtersModel->insertRow(filtersModel->rowCount()); - filtersModel->setData(filtersModel->index(filtersModel->rowCount()-1,0), index.data()); - }); - - // Add a new line on "+" - connect(ui->toolButton_add, &QToolButton::clicked, [this](){ - int row = filtersModel->rowCount(); - filtersModel->insertRow(row); - ui->listView_filters->setCurrentIndex(filtersModel->index(row, 0)); - ui->listView_filters->edit(filtersModel->index(row, 0)); - }); - - // Remove the selected line on "-" - connect(ui->toolButton_remove, &QToolButton::clicked, [this](){ - QModelIndex index = ui->listView_filters->currentIndex(); - if ( index.isValid() ) - filtersModel->removeRow(index.row()); - }); - - // Let the listview intercept the input of the filter line edit (for navigation and activation) - ui->lineEdit->installEventFilter(this); -} - - - -/** ***************************************************************************/ -Files::MimeTypeDialog::~MimeTypeDialog() { - delete ui; -} - - - -/** ***************************************************************************/ -QStringList Files::MimeTypeDialog::filters() const { - return filtersModel->stringList(); -} - - - -/** ***************************************************************************/ -bool Files::MimeTypeDialog::eventFilter(QObject * /*theres only the linedit*/, QEvent *event) { - - if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - switch (keyEvent->key()) { - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Enter: - case Qt::Key_Return: - QApplication::sendEvent(ui->listView_mimeTypes, keyEvent); - return true; - default: - return false; - } - } - return false; -} - - - -/** ***************************************************************************/ -void Files::MimeTypeDialog::keyPressEvent(QKeyEvent *evt) { - // Eat keys for desired behaviour - switch ( evt->key() ) { - case Qt::Key_Enter: - case Qt::Key_Return: - case Qt::Key_Escape: - return; - } - QDialog::keyPressEvent(evt); -} diff -Nru albert-0.12.0/src/plugins/files/src/mimetypedialog.h albert-0.13.1+plugins1/src/plugins/files/src/mimetypedialog.h --- albert-0.12.0/src/plugins/files/src/mimetypedialog.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/files/src/mimetypedialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include - -namespace Files{ -namespace Ui { -class MimeTypeDialog; -} - -class MimeTypeDialog : public QDialog -{ - Q_OBJECT - -public: - - explicit MimeTypeDialog(const QStringList &filters, QWidget *parent = 0); - ~MimeTypeDialog(); - - QStringList filters() const; - -protected: - - bool eventFilter(QObject *watched, QEvent *event) override; - void keyPressEvent(QKeyEvent *evt) override; - - QStringListModel *filtersModel; - Ui::MimeTypeDialog *ui; - -}; -} diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/CMakeLists.txt --- albert-0.12.0/src/plugins/firefoxbookmarks/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(firefoxbookmarks) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Concurrent - Sql - Widgets -) - -qt5_wrap_ui(UI - configwidget.ui -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Concurrent_LIBRARIES} - ${Qt5Sql_LIBRARIES} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/configwidget.ui albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/configwidget.ui --- albert-0.12.0/src/plugins/firefoxbookmarks/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ - - - FirefoxBookmarks::ConfigWidget - - - - 0 - 0 - 480 - 320 - - - - - - - Select your firefox profile: - - - - - - - - - - Fuzzy Search - - - true - - - - - - - Open with firefox by default - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/firefoxbookmarks.qrc albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/firefoxbookmarks.qrc --- albert-0.12.0/src/plugins/firefoxbookmarks/firefoxbookmarks.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/firefoxbookmarks.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/favicon.png - - diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/metadata.json albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/metadata.json --- albert-0.12.0/src/plugins/firefoxbookmarks/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.firefoxbookmarks", - "name" : "Firefox bookmarks", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Martin Buergmann, Manuel Schneider", - "dependencies" : ["firefox"], - "enabledbydefault": false -} Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/plugins/firefoxbookmarks/resources/favicon.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/resources/favicon.png differ diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/configwidget.cpp --- albert-0.12.0/src/plugins/firefoxbookmarks/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -FirefoxBookmarks::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); -} - - - -/** ***************************************************************************/ -FirefoxBookmarks::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/src/configwidget.h albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/configwidget.h --- albert-0.12.0/src/plugins/firefoxbookmarks/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace FirefoxBookmarks { -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; -}; -} diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/src/main.cpp albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/main.cpp --- albert-0.12.0/src/plugins/firefoxbookmarks/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,453 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "main.h" -#include "configwidget.h" -#include "extension.h" -#include "item.h" -#include "offlineindex.h" -#include "standardaction.h" -#include "standardindexitem.h" -#include "query.h" -#include "xdgiconlookup.h" -using std::pair; -using std::shared_ptr; -using std::vector; -using namespace Core; - -namespace { -const QString CFG_PROFILE = "profile"; -const QString CFG_FUZZY = "fuzzy"; -const bool DEF_FUZZY = false; -const QString CFG_USE_FIREFOX = "openWithFirefox"; -const bool DEF_USE_FIREFOX = false; -const uint UPDATE_DELAY = 60000; -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -class FirefoxBookmarks::FirefoxBookmarksPrivate -{ -public: - FirefoxBookmarksPrivate(Extension *q) : q(q) {} - - Extension *q; - - bool openWithFirefox; - QPointer widget; - QString firefoxExecutable; - QString profilesIniPath; - QString currentProfileId; - QFileSystemWatcher databaseWatcher; - - vector> index; - Core::OfflineIndex offlineIndex; - - QTimer updateDelayTimer; - void startIndexing(); - void finishIndexing(); - QFutureWatcher>> futureWatcher; - std::vector> indexFirefoxBookmarks() const; -}; - - -/** ***************************************************************************/ -void FirefoxBookmarks::FirefoxBookmarksPrivate::startIndexing() { - - // Never run concurrent - if ( futureWatcher.future().isRunning() ) - return; - - // Run finishIndexing when the indexing thread finished - futureWatcher.disconnect(); - QObject::connect(&futureWatcher, &QFutureWatcher>>::finished, - std::bind(&FirefoxBookmarksPrivate::finishIndexing, this)); - - // Run the indexer thread - futureWatcher.setFuture(QtConcurrent::run(this, &FirefoxBookmarksPrivate::indexFirefoxBookmarks)); - - // Notification - qDebug() << "Start indexing Firefox bookmarks."; - emit q->statusInfo("Indexing bookmarks ..."); -} - - -/** ***************************************************************************/ -void FirefoxBookmarks::FirefoxBookmarksPrivate::finishIndexing() { - - // Get the thread results - index = futureWatcher.future().result(); - - // Rebuild the offline index - offlineIndex.clear(); - for (const auto &item : index) - offlineIndex.add(item); - - // Notification - qDebug() << qPrintable(QString("Indexed %1 Firefox bookmarks.").arg(index.size())); - emit q->statusInfo(QString("%1 bookmarks indexed.").arg(index.size())); -} - - - -/** ***************************************************************************/ -vector> -FirefoxBookmarks::FirefoxBookmarksPrivate::indexFirefoxBookmarks() const { - - QSqlDatabase database = QSqlDatabase::database(q->Core::Extension::id); - - if (!database.open()) { - qWarning() << qPrintable(QString("Could not open Firefox database: %1").arg(database.databaseName())); - return vector>(); - } - - // Build a new index - vector> bookmarks; - - QSqlQuery result(database); - - if ( !result.exec("SELECT b.guid, b.title, p.url " - "FROM moz_bookmarks b " - "JOIN moz_places p ON b.fk = p.id " // attach place (which has the url) - "WHERE p.url NOT LIKE 'place%'") ) { // Those with place:... will not work with xdg-open - qWarning() << qPrintable(QString("Querying Firefox bookmarks failed: %1").arg(result.lastError().text())); - return vector>(); - } - - // Find an appropriate icon - QString icon = XdgIconLookup::iconPath("www"); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("web-browser"); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("emblem-web"); - if (icon.isEmpty()) - icon = ":favicon"; // Fallback - - while (result.next()) { - - // Url will be used more often - QString urlstr = result.value(2).toString(); - - // Create item - shared_ptr ssii = std::make_shared(result.value(0).toString()); - ssii->setText(result.value(1).toString()); - ssii->setSubtext(urlstr); - ssii->setIconPath(icon); - - // Add severeal secondary index keywords - vector weightedKeywords; - QUrl url(urlstr); - QString host = url.host(); - weightedKeywords.emplace_back(ssii->text(), USHRT_MAX); - weightedKeywords.emplace_back(host.left(host.size()-url.topLevelDomain().size()), USHRT_MAX/2); - weightedKeywords.emplace_back(result.value(2).toString(), USHRT_MAX/4); // parent dirname - ssii->setIndexKeywords(std::move(weightedKeywords)); - - // Add actions - vector> actions; - - shared_ptr actionDefault = std::make_shared(); - actionDefault->setText("Open URL in your default browser"); - actionDefault->setAction([urlstr](){ - QDesktopServices::openUrl(QUrl(urlstr)); - }); - - shared_ptr actionFirefox = std::make_shared(); - actionFirefox->setText("Open URL in Firefox"); - actionFirefox->setAction([urlstr, this](){ - QProcess::startDetached(firefoxExecutable, {urlstr}); - }); - - shared_ptr action = std::make_shared(); - action->setText("Copy url to clipboard"); - action->setAction([urlstr](){ QApplication::clipboard()->setText(urlstr); }); - - // Set the order of the actions - if ( openWithFirefox ) { - actions.push_back(std::move(actionFirefox)); - actions.push_back(std::move(actionDefault)); - } else { - actions.push_back(std::move(actionDefault)); - actions.push_back(std::move(actionFirefox)); - } - actions.push_back(std::move(action)); - - ssii->setActions(std::move(actions)); - - bookmarks.push_back(std::move(ssii)); - } - - return bookmarks; -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -FirefoxBookmarks::Extension::Extension() - : Core::Extension("org.albert.extension.firefoxbookmarks"), - Core::QueryHandler(Core::Extension::id), - d(new FirefoxBookmarksPrivate(this)){ - - // Add a sqlite database connection for this extension, check requirements - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", Core::Extension::id); - if ( !db.isValid() ) - throw "Firefox executable not found."; - if (!db.driver()->hasFeature(QSqlDriver::Transactions)) - throw "Firefox executable not found."; - - // Find firefox executable - d->firefoxExecutable = QStandardPaths::findExecutable("firefox"); - if (d->firefoxExecutable.isEmpty()) - throw "Firefox executable not found."; - - // Locate profiles ini - d->profilesIniPath = QStandardPaths::locate(QStandardPaths::HomeLocation, - ".mozilla/firefox/profiles.ini", - QStandardPaths::LocateFile); - if (d->profilesIniPath.isEmpty()) // Try a windowsy approach - d->profilesIniPath = QStandardPaths::locate(QStandardPaths::DataLocation, - "Mozilla/firefox/profiles.ini", - QStandardPaths::LocateFile); - if (d->profilesIniPath.isEmpty()) - throw "Could not locate profiles.ini."; - - // Load the settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - d->currentProfileId = s.value(CFG_PROFILE).toString(); - d->offlineIndex.setFuzzy(s.value(CFG_FUZZY, DEF_FUZZY).toBool()); - d->openWithFirefox = s.value(CFG_USE_FIREFOX, DEF_USE_FIREFOX).toBool(); - - // If the id does not exist find a proper default - QSettings profilesIni(d->profilesIniPath, QSettings::IniFormat); - if ( !profilesIni.contains(d->currentProfileId) ){ - - d->currentProfileId = QString(); - - QStringList ids = profilesIni.childGroups(); - if ( ids.isEmpty() ) - qWarning() << "No Firefox profiles found."; - else { - - // Use the last used profile - if ( d->currentProfileId.isNull() ) { - for (QString &id : ids) { - profilesIni.beginGroup(id); - if ( profilesIni.contains("Default") - && profilesIni.value("Default").toBool() ) { - d->currentProfileId = id; - } - profilesIni.endGroup(); - } - } - - // Use the default profile - if ( d->currentProfileId.isNull() && ids.contains("default")) { - d->currentProfileId = "default"; - } - - // Use the first - d->currentProfileId = ids[0]; - } - } - - // Set the profile - setProfile(d->currentProfileId); - - // Delay the indexing to avoid excessice resource consumption - d->updateDelayTimer.setInterval(UPDATE_DELAY); - d->updateDelayTimer.setSingleShot(true); - - // If the database changed, trigger the update delay - connect(&d->databaseWatcher, &QFileSystemWatcher::fileChanged, - &d->updateDelayTimer, static_cast(&QTimer::start)); - - // If the update delay passed, update the index - connect(&d->updateDelayTimer, &QTimer::timeout, - std::bind(&FirefoxBookmarksPrivate::startIndexing, d.get())); -} - - - -/** ***************************************************************************/ -FirefoxBookmarks::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *FirefoxBookmarks::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) { - d->widget = new ConfigWidget(parent); - - // Get the profiles keys - QSettings profilesIni(d->profilesIniPath, QSettings::IniFormat); - QStringList groups = profilesIni.childGroups(); - - // Extract all profiles and names and put it in the checkbox - QComboBox *cmb = d->widget->ui.comboBox; - for (QString &profileId : groups) { - profilesIni.beginGroup(profileId); - - // Use name if available else id - if ( profilesIni.contains("Name") ) - cmb->addItem( QString("%1 (%2)").arg(profilesIni.value("Name").toString(), profileId), profileId); - else { - cmb->addItem(profileId, profileId); - qWarning() << qPrintable(QString("Firefox profile '%1' does not contain a name.").arg(profileId)); - } - - // If the profileId match set the current item of the checkbox - if (profileId == d->currentProfileId) - cmb->setCurrentIndex(cmb->count() - 1); - - profilesIni.endGroup(); - } - - connect(cmb, static_cast(&QComboBox::currentIndexChanged), - this, &Extension::setProfile); - - // Fuzzy - QCheckBox *ckb = d->widget->ui.fuzzy; - ckb->setChecked(d->offlineIndex.fuzzy()); - connect(ckb, &QCheckBox::clicked, this, &Extension::changeFuzzyness); - - // Which app to use - ckb = d->widget->ui.openWithFirefox; - ckb->setChecked(d->openWithFirefox); - connect(ckb, &QCheckBox::clicked, this, &Extension::changeOpenPolicy); - - // Status bar - ( d->futureWatcher.isRunning() ) - ? d->widget->ui.label_statusbar->setText("Indexing bookmarks ...") - : d->widget->ui.label_statusbar->setText(QString("%1 bookmarks indexed.").arg(d->index.size())); - connect(this, &Extension::statusInfo, d->widget->ui.label_statusbar, &QLabel::setText); - - } - return d->widget; -} - - - -/** ***************************************************************************/ -void FirefoxBookmarks::Extension::handleQuery(Core::Query *query) { - - // Search for matches - const vector> &indexables = d->offlineIndex.search(query->searchTerm().toLower()); - - // Add results to query. - vector,short>> results; - for (const shared_ptr &item : indexables) - results.emplace_back(std::static_pointer_cast(item), 0); - - query->addMatches(results.begin(), results.end()); -} - - - -/** ***************************************************************************/ -void FirefoxBookmarks::Extension::setProfile(const QString& profile) { - - d->currentProfileId = profile; - - QSettings profilesIni(d->profilesIniPath, QSettings::IniFormat); - - // Check if profile id is in profiles file - if ( !profilesIni.childGroups().contains(d->currentProfileId) ){ - qWarning() << qPrintable(QString("Firefox user profile '%2' not found.").arg(d->currentProfileId)); - return; - } - - // Enter the group - profilesIni.beginGroup(d->currentProfileId); - - // Check if the profile contains a path key - if ( !profilesIni.contains("Path") ){ - qWarning() << qPrintable(QString("Firefox profile '%2' does not contain a path.").arg(d->currentProfileId)); - return; - } - - // Get the correct absolute profile path - QString profilePath = ( profilesIni.contains("IsRelative") && profilesIni.value("IsRelative").toBool()) - ? QFileInfo(d->profilesIniPath).dir().absoluteFilePath(profilesIni.value("Path").toString()) - : profilesIni.value("Path").toString(); - - // Build the database path - QString dbPath = QString("%1/places.sqlite").arg(profilePath); - - // Set the databases path - QSqlDatabase db = QSqlDatabase::database(Core::Extension::id); - db.setDatabaseName(dbPath); - - // Set a file system watcher on the database monitoring changes - if (!d->databaseWatcher.files().isEmpty()) - d->databaseWatcher.removePaths(d->databaseWatcher.files()); - d->databaseWatcher.addPath(dbPath); - - d->startIndexing(); - - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_PROFILE), d->currentProfileId); -} - - - -/** ***************************************************************************/ -void FirefoxBookmarks::Extension::changeFuzzyness(bool fuzzy) { - d->offlineIndex.setFuzzy(fuzzy); - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_FUZZY), fuzzy); -} - - - -/** ***************************************************************************/ -void FirefoxBookmarks::Extension::changeOpenPolicy(bool useFirefox) { - d->openWithFirefox = useFirefox; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_USE_FIREFOX), useFirefox); - d->startIndexing(); -} diff -Nru albert-0.12.0/src/plugins/firefoxbookmarks/src/main.h albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/main.h --- albert-0.12.0/src/plugins/firefoxbookmarks/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/firefoxbookmarks/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "extension.h" -#include "queryhandler.h" -#include -#include -namespace Core { -class StandardIndexItem; -} - -namespace FirefoxBookmarks { - -class FirefoxBookmarksPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of interfaces - */ - - QString name() const override { return "Firefox bookmarks"; } - QWidget *widget(QWidget *parent = nullptr) override; - void handleQuery(Core::Query * query) override; - - /* - * Extension specific members - */ - - void setProfile(const QString &profile); - void changeFuzzyness(bool fuzzy); - void changeOpenPolicy(bool withFirefox); - -private: - - std::unique_ptr d; - -signals: - - void statusInfo(const QString&); -}; -} diff -Nru albert-0.12.0/src/plugins/mpris/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/mpris/CMakeLists.txt --- albert-0.12.0/src/plugins/mpris/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 2.8.11) - -PROJECT(mpris) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets - DBus -) - -qt5_wrap_ui(UI - forms/configwidget.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - ${Qt5DBus_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/mpris/forms/configwidget.ui albert-0.13.1+plugins1/src/plugins/mpris/forms/configwidget.ui --- albert-0.12.0/src/plugins/mpris/forms/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/forms/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ - - - MPRIS::ConfigWidget - - - - 0 - 0 - 480 - 320 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p align="center"><span style=" color:#808080;">How to use MPRIS Control Center:</span></p><p align="center"><span style=" color:#808080;">If you have MPRIS-capable media players running (like Rhythmbox, VLC, ...) just type any of &quot;play&quot;, &quot;pause&quot;, &quot;stop&quot;, &quot;next&quot;, &quot;previous&quot; and you can send these commands directly to your player from albert.</span></p></body></html> - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/mpris/metadata.json albert-0.13.1+plugins1/src/plugins/mpris/metadata.json --- albert-0.12.0/src/plugins/mpris/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -{ - "id" : "org.albert.extension.mpris", - "name" : "MPRIS Control", - "version" : "1.0", - "platform" : "Linux", - "group" : "Extensions", - "author" : "Martin Buergmann", - "dependencies" : ["dbus-daemon"] -} diff -Nru albert-0.12.0/src/plugins/mpris/mpris.qrc albert-0.13.1+plugins1/src/plugins/mpris/mpris.qrc --- albert-0.12.0/src/plugins/mpris/mpris.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/mpris.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ - - - resources/1485099680_playback-play.svg - resources/1485099683_playback-fast-forward.svg - resources/1485099687_playback-rewind.svg - resources/1485099690_playback-pause.svg - resources/1485100510_primitive-square.svg - - diff -Nru albert-0.12.0/src/plugins/mpris/resources/1485099680_playback-play.svg albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099680_playback-play.svg --- albert-0.12.0/src/plugins/mpris/resources/1485099680_playback-play.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099680_playback-play.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/mpris/resources/1485099683_playback-fast-forward.svg albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099683_playback-fast-forward.svg --- albert-0.12.0/src/plugins/mpris/resources/1485099683_playback-fast-forward.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099683_playback-fast-forward.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/mpris/resources/1485099687_playback-rewind.svg albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099687_playback-rewind.svg --- albert-0.12.0/src/plugins/mpris/resources/1485099687_playback-rewind.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099687_playback-rewind.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/mpris/resources/1485099690_playback-pause.svg albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099690_playback-pause.svg --- albert-0.12.0/src/plugins/mpris/resources/1485099690_playback-pause.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/resources/1485099690_playback-pause.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/mpris/resources/1485100510_primitive-square.svg albert-0.13.1+plugins1/src/plugins/mpris/resources/1485100510_primitive-square.svg --- albert-0.12.0/src/plugins/mpris/resources/1485100510_primitive-square.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/resources/1485100510_primitive-square.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/mpris/src/command.cpp albert-0.13.1+plugins1/src/plugins/mpris/src/command.cpp --- albert-0.12.0/src/plugins/mpris/src/command.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/command.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "command.h" -#include -#include -#include -#include -#include "item.h" - -/** ***************************************************************************/ -MPRIS::Command::Command(const QString &label, const QString &title, const QString &subtext, const QString &method, QString iconpath) - : label_(label), title_(title), subtext_(subtext), method_(method), iconpath_(iconpath) { -} - - - -/** ***************************************************************************/ -QString& MPRIS::Command::getIconPath() { - return iconpath_; -} - - - -/** ***************************************************************************/ -MPRIS::Command &MPRIS::Command::applicableWhen(const char* path, const char *property, const QVariant expectedValue, bool positivity) { - path_ = path; - property_ = property; - expectedValue_ = expectedValue; - positivity_ = positivity; - applicableCheck_ = true; - return *this; -} - - - -/** ***************************************************************************/ -SharedItem MPRIS::Command::produceAlbertItem(Player &player) const { - QDBusMessage msg = QDBusMessage::createMethodCall(player.getBusId(), "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", method_); - SharedItem ptr(new MPRIS::Item(player, title_, subtext_, iconpath_, msg)); - return ptr; -} - - - -/** ***************************************************************************/ -bool MPRIS::Command::isApplicable(Player &p) const { - // Check the applicable-option if given - if (!applicableCheck_) - return true; - - // split DBus interface and property into seperate strings - int splitAt = property_.lastIndexOf('.'); - QString ifaceName = property_.left(splitAt); - QString propertyName = property_.right(property_.length() - splitAt -1); - - // Compose Get-Property-Message - QDBusMessage mesg = QDBusMessage::createMethodCall( - p.getBusId(), //"org.mpris.MediaPlayer2.rhythmbox", - path_, //"/org/mpris/MediaPlayer2", - "org.freedesktop.DBus.Properties", - "Get"); - QList args; - // Specify DBus interface to get the property from and the property-name - args.append(ifaceName); //"org.mpris.MediaPlayer2.Player"); - args.append(propertyName); //"CanGoNext"); - mesg.setArguments(args); - - // Query the property - QDBusMessage reply = QDBusConnection::sessionBus().call(mesg); - - // Check if the result is as expected - if ( reply.type() != QDBusMessage::ReplyMessage ){ - qWarning() << "Error while querying the property 'PlaybackStatus'"; - return true; - } - - if ( reply.arguments().empty() ) { - qWarning() << "Reply query 'PlaybackStatus' is empty"; - return true; - } - - return (reply.arguments().at(0).value().variant() == expectedValue_) == positivity_; -} - - - -/** ***************************************************************************/ -QString& MPRIS::Command::getLabel() { - return label_; -} - - - -/** ***************************************************************************/ -QString& MPRIS::Command::getMethod() { - return method_; -} - - - -/** ***************************************************************************/ -QString& MPRIS::Command::getTitle() { - return title_; -} - diff -Nru albert-0.12.0/src/plugins/mpris/src/command.h albert-0.13.1+plugins1/src/plugins/mpris/src/command.h --- albert-0.12.0/src/plugins/mpris/src/command.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/command.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#include -#include -#include -#include "query.h" -#include "player.h" -using std::function; -typedef std::shared_ptr SharedItem; - -namespace MPRIS { - -class Command -{ -public: - /** - * @brief Command Constructs a DBus command to launch from albert with the given parameters. - * @param label An internal variable to query at a later point. Not needed for the DBus query. - * @param title The title of the StandardItem which will be created. - * @param subtext The subtext of the StandardItem which will be created. - * @param method The DBus method to invoke when this command is performed. - * @param iconpath The path to the icon which the StandardItem will get. - */ - Command(const QString& label, const QString& title, const QString& subtext, const QString& method, QString iconpath); - - QString& getLabel(); - QString& getTitle(); - QString& getMethod(); - QString& getIconPath(); - - /** - * @brief applicableWhen Configure this command to be only appicable under a certian (given) conditions. - * @param path The path to query the property from. - * @param property The name of the property. This property will be checked as condition. - * @param expectedValue The value of the property. - * @param positivity The result of the equality-check (queriedValue == expectedValue). Here you can negate the result. - * @return Returns itself, but now configured for applicability-check - */ - Command& applicableWhen(const char *path, const char* property, const QVariant expectedValue, bool positivity); - - /** - * @brief produceStandardItem Produces an instance of AlbertItem for this command to invoke on a given Player. - * @return Returns a shared_ptr on this AlbertItem. - */ - SharedItem produceAlbertItem(Player &) const; - - /** - * @brief isApplicable If configured, checks if the given property meets the expected criteria. - * @return True if not configured or match, false if the property is different than expected. - */ - bool isApplicable(Player&) const; - -private: - QString label_, title_, subtext_, method_, iconpath_; - bool applicableCheck_; - QString path_; - QString property_; - QVariant expectedValue_; - bool positivity_; -}; - -} // namespace MPRIS diff -Nru albert-0.12.0/src/plugins/mpris/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/mpris/src/configwidget.cpp --- albert-0.12.0/src/plugins/mpris/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -MPRIS::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); -} - - - -/** ***************************************************************************/ -MPRIS::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/mpris/src/configwidget.h albert-0.13.1+plugins1/src/plugins/mpris/src/configwidget.h --- albert-0.12.0/src/plugins/mpris/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace MPRIS { -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; -}; -} diff -Nru albert-0.12.0/src/plugins/mpris/src/item.cpp albert-0.13.1+plugins1/src/plugins/mpris/src/item.cpp --- albert-0.12.0/src/plugins/mpris/src/item.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/item.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "item.h" -#include "standardaction.h" -using Core::StandardAction; -#include - - -/** ***************************************************************************/ -MPRIS::Item::Item(Player &p, const QString &title, const QString &subtext, const QString &iconPath, const QDBusMessage &msg) - : iconPath_(iconPath), message_(msg) { - if (title.contains("%1")) - text_ = title.arg(p.getName()); - else - text_ = title; - if (subtext.contains("%1")) - subtext_ = subtext.arg(p.getName()); - else - subtext_ = subtext; - actions_.push_back(shared_ptr(new StandardAction(subtext_, [this](){ - QDBusConnection::sessionBus().send(message_); -// flags->hideWidget = hideAfter_; -// flags->clearInput = hideAfter_; - }))); - if (p.canRaise()) { - actions_.push_back(shared_ptr(new StandardAction("Raise Window", [&p](){ - QString busid = p.getBusId(); - QDBusMessage raise = QDBusMessage::createMethodCall(busid, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Raise"); - if (!QDBusConnection::sessionBus().send(raise)) { - qWarning("Error calling raise method on dbus://%s", busid.toStdString().c_str()); - } - }))); - } - id_ = "extension.mpris.item:%1.%2"; - id_ = id_.arg(p.getBusId()).arg(msg.member()); -} - - - -/** ***************************************************************************/ -MPRIS::Item::~Item() { - -} - - - -/** ***************************************************************************/ -vector> MPRIS::Item::actions() { - return actions_; -} - diff -Nru albert-0.12.0/src/plugins/mpris/src/item.h albert-0.13.1+plugins1/src/plugins/mpris/src/item.h --- albert-0.12.0/src/plugins/mpris/src/item.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -using std::vector; -#include "standarditem.h" -#include "player.h" -#include -using std::shared_ptr; -using Core::Action; - -namespace MPRIS { -class Item final : public Core::Item -{ -public: - Item(Player &p, const QString& title, const QString& subtext, const QString& iconPath, const QDBusMessage& msg); - ~Item(); - - QString id() const override { return id_; } - QString text() const override { return text_; } - QString subtext() const override { return subtext_; } - QString iconPath() const override { return iconPath_; } - vector> actions() override; - -private: - QString id_; - QString text_; - QString subtext_; - QString iconPath_; - QDBusMessage message_; - vector> actions_; -}; -} diff -Nru albert-0.12.0/src/plugins/mpris/src/main.cpp albert-0.13.1+plugins1/src/plugins/mpris/src/main.cpp --- albert-0.12.0/src/plugins/mpris/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,238 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include "main.h" -#include "configwidget.h" -#include "query.h" -#include "xdgiconlookup.h" -#include "command.h" -#include "private.h" - -#define themeOr(name, fallbk) XdgIconLookup::iconPath(name).isEmpty() ? fallbk : XdgIconLookup::iconPath(name) - - -QDBusMessage MPRIS::MPRISPrivate::findPlayerMsg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames"); - - - -/** ***************************************************************************/ -MPRIS::MPRISPrivate::~MPRISPrivate() { - // If there are still media player objects, delete them - qDeleteAll(mediaPlayers); - // Don't need to destruct the command objects. - // This is done by the destructor of QMap -} - - - -/** ***************************************************************************/ -QDBusMessage MPRIS::MPRISPrivate::call(QDBusMessage &toDispatch) { - return QDBusConnection::sessionBus().call(toDispatch, QDBus::Block, DBUS_TIMEOUT); -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -MPRIS::Extension::Extension() - : Core::Extension("org.albert.extension.mpris"), - Core::QueryHandler(Core::Extension::id), - d(new MPRIS::MPRISPrivate) { - qDebug("[%s] Initialize extension", d->name); - - QString icon; - - // Setup the DBus commands - icon = themeOr("media-playback-start", ":play"); - Command* nextToAdd = new Command( - "play", // Label - "Play", // Title - "Start playing on %1", // Subtext - "Play", // DBus Method - icon - ); - nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.PlaybackStatus", "Playing", false); - d->commands.append("play"); - d->commandObjects.insert("play", *nextToAdd); - - icon = themeOr("media-playback-pause", ":pause"); - nextToAdd = new Command( - "pause", - "Pause", - "Pause %1", - "Pause", - icon - ); - nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.PlaybackStatus", "Playing", true); - d->commands.append("pause"); - d->commandObjects.insert("pause", *nextToAdd); - - icon = themeOr("media-playback-stop", ":stop"); - nextToAdd = new Command( - "stop", - "Stop", - "Stop %1", - "Stop", - icon - ); - nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.PlaybackStatus", "Playing", true); - d->commands.append("stop"); - d->commandObjects.insert("stop", *nextToAdd); - - icon = themeOr("media-skip-forward", ":next"); - nextToAdd = new Command( - "next track", - "Next track", - "Play next track on %1", - "Next", - icon - ); - nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.CanGoNext", true, true); - //.fireCallback([](){qDebug("NEXT");}) - d->commands.append("next track"); - d->commandObjects.insert("next track", *nextToAdd); - - icon = themeOr("media-skip-backward", ":prev"); - nextToAdd = new Command( - "previous track", - "Previous track", - "Play previous track on %1", - "Previous", - icon - ); - nextToAdd->applicableWhen("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player.CanGoPrevious", true, true); - d->commands.append("previous track"); - d->commandObjects.insert("previous track", *nextToAdd); - - qDebug("[%s] Extension initialized", d->name); -} - - - -/** ***************************************************************************/ -MPRIS::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *MPRIS::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) { - d->widget = new ConfigWidget(parent); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void MPRIS::Extension::setupSession() { - - // Clean the memory - qDeleteAll(d->mediaPlayers); - d->mediaPlayers.clear(); - - // If there is no session bus, abort - if (!QDBusConnection::sessionBus().isConnected()) - return; - - // Querying the DBus to list all available services - QDBusMessage response = d->call(MPRISPrivate::findPlayerMsg); - - // Do some error checking - if (response.type() == QDBusMessage::ReplyMessage) { - QList args = response.arguments(); - if (args.length() == 1) { - QVariant arg = args.at(0); - if (!arg.isNull() && arg.isValid()) { - QStringList runningBusEndpoints = arg.toStringList(); - if (!runningBusEndpoints.isEmpty()) { - // No errors - - // Filter all mpris capable - //names = names.filter(filterRegex); - QStringList busids; - for (QString& id: runningBusEndpoints) { - if (id.startsWith("org.mpris.MediaPlayer2.")) - busids.append(id); - } - - for (QString& busid : busids) { - // And add their player object to the list - d->mediaPlayers.append(new Player(busid)); - } - - - } else { - qCritical("[%s] DBus error: Argument is either not type of QStringList or is empty!", d->name); - } - } else { - qCritical("[%s] DBus error: Reply argument not valid or null!", d->name); - } - } else { - qCritical("[%s] DBus error: Expected 1 argument for DBus reply. Got %d", d->name, args.length()); - } - } else { - qCritical("[%s] DBus error: %s", d->name, response.errorMessage().toStdString().c_str()); - } -} - - - -/** ***************************************************************************/ -void MPRIS::Extension::handleQuery(Query *query) { - // Do not proceed if there are no players running. Why would you even? - if (d->mediaPlayers.isEmpty()) - return; - - const QString& q = query->searchTerm().toLower(); - - // Filter applicable commands - QStringList cmds; - for (QString& cmd : d->commands) { - if (cmd.startsWith(q)) - cmds.append(cmd); - } - - - // For every option create entries for every player - short percentage = 0; - for (QString& cmd: cmds) { - // Calculate how many percent of the query match the command - percentage = (float)q.length() / (float)cmd.length() *100; - - // Get the command - Command& toExec = d->commandObjects.find(cmd).value(); - // For every player: - for (Player* p: d->mediaPlayers) { - // See if it's applicable for this player - if (toExec.isApplicable(*p)) - // And add a match if so - query->addMatch(toExec.produceAlbertItem(*p), percentage); - } - } -} - - - -/** ***************************************************************************/ -QString MPRIS::Extension::name() const { - return d->name; -} diff -Nru albert-0.12.0/src/plugins/mpris/src/main.h albert-0.13.1+plugins1/src/plugins/mpris/src/main.h --- albert-0.12.0/src/plugins/mpris/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "player.h" -#include "command.h" -#include "extension.h" -#include "queryhandler.h" -#include -using Core::Query; - -class QDBusMessage; - -namespace MPRIS { - -class MPRISPrivate; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QWidget *widget(QWidget *parent = nullptr) override; - void setupSession() override; - void handleQuery(Query *query) override; - QString name() const override; - - - /* - * Extension specific members - */ - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/mpris/src/player.cpp albert-0.13.1+plugins1/src/plugins/mpris/src/player.cpp --- albert-0.12.0/src/plugins/mpris/src/player.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/player.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "player.h" -#include -#include -#include "private.h" - -/** ***************************************************************************/ -MPRIS::Player::Player(QString &busid) : busid_(busid), name_(busid) { - // Query the name of the media player of which we have the bus id. - QDBusInterface iface(busid, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2"); - iface.setTimeout(MPRIS::MPRISPrivate::DBUS_TIMEOUT); - - QVariant prop = iface.property("Identity"); - if (prop.isValid() && !prop.isNull() && prop.canConvert(QVariant::String)) { - name_ = prop.toString(); - } else { - qWarning("DBus: Name is either invalid, null or not instanceof string"); - } - - prop = iface.property("CanRaise"); - if (prop.isValid() && !prop.isNull() && prop.canConvert(QVariant::Bool)) { - canRaise_ = prop.toBool(); - } else { - canRaise_ = false; - qWarning("DBus: CanRaise is either invalid, null or not instanceof bool"); - } -} diff -Nru albert-0.12.0/src/plugins/mpris/src/player.h albert-0.13.1+plugins1/src/plugins/mpris/src/player.h --- albert-0.12.0/src/plugins/mpris/src/player.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/player.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#include - -namespace MPRIS { - -class Player -{ -public: - Player(QString& busid); - const QString& getName() const { return name_; } - const QString& getBusId() const { return busid_; } - bool canRaise() const { return canRaise_; } - -private: - QString busid_, name_; - bool canRaise_; -}; - -} // namespace MPRIS - diff -Nru albert-0.12.0/src/plugins/mpris/src/private.h albert-0.13.1+plugins1/src/plugins/mpris/src/private.h --- albert-0.12.0/src/plugins/mpris/src/private.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/mpris/src/private.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -// albert extension mpris - a mpris interface plugin for albert -// Copyright (C) 2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include - - -namespace MPRIS { - -class ConfigWidget; -class Player; -class Command; - -class MPRISPrivate { -public: - ~MPRISPrivate(); - - - const char* name = "MPRIS Control"; - static QDBusMessage findPlayerMsg; - QPointer widget; - QList mediaPlayers; - QStringList commands; - QMap commandObjects; - - static const int DBUS_TIMEOUT = 25 /* ms */; - - QDBusMessage call(QDBusMessage &toDispatch); - -}; - -} // namespace MPRIS diff -Nru albert-0.12.0/src/plugins/ssh/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/ssh/CMakeLists.txt --- albert-0.12.0/src/plugins/ssh/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(ssh) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets -) - -qt5_wrap_ui(UI - configwidget.ui -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/ssh/configwidget.ui albert-0.13.1+plugins1/src/plugins/ssh/configwidget.ui --- albert-0.12.0/src/plugins/ssh/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ - - - Ssh::ConfigWidget - - - - 0 - 0 - 480 - 320 - - - - - - - <html> -<head/> -<body> -<p>This extension scans your /etc/ssh/config and ~/.ssh/config<br>and makes your ssh hosts accessible by Albert.</p> -</body> -</html> - - - true - - - - - - - Use 'known_hosts' - - - - - - - - 0 - 0 - - - - Rescan - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/ssh/metadata.json albert-0.13.1+plugins1/src/plugins/ssh/metadata.json --- albert-0.12.0/src/plugins/ssh/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.ssh", - "name" : "Secure Shell", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/ssh/resources/ssh.svg albert-0.13.1+plugins1/src/plugins/ssh/resources/ssh.svg --- albert-0.12.0/src/plugins/ssh/resources/ssh.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/resources/ssh.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,741 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/ssh/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/ssh/src/configwidget.cpp --- albert-0.12.0/src/plugins/ssh/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -Ssh::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); -} - - - -/** ***************************************************************************/ -Ssh::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/ssh/src/configwidget.h albert-0.13.1+plugins1/src/plugins/ssh/src/configwidget.h --- albert-0.12.0/src/plugins/ssh/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace Ssh { - -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; -}; - -} diff -Nru albert-0.12.0/src/plugins/ssh/src/main.cpp albert-0.13.1+plugins1/src/plugins/ssh/src/main.cpp --- albert-0.12.0/src/plugins/ssh/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "standardaction.h" -#include "standarditem.h" -#include "main.h" -#include "query.h" -#include "shlex.h" -#include "xdgiconlookup.h" -using std::shared_ptr; -using std::vector; -using namespace Core; - -extern QString terminalCommand; - -namespace { - -const char* CFG_USE_KNOWN_HOSTS = "use_known_hosts"; -const bool DEF_USE_KNOWN_HOSTS = true; - -// Function to extract the hosts of a ssh config file -std::set getSshHostsFromConfig(const QString& path) { - std::set hosts; - QFile file(path); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QTextStream in(&file); - while ( !in.atEnd() ) { - QStringList fields = in.readLine().split(QRegularExpression("\\s+"), QString::SkipEmptyParts); - if ( fields.size() > 1 && fields[0] == "Host") - for ( int i = 1; i < fields.size(); ++i ){ - if ( !(fields[i].contains('*') || fields[i].contains('?')) ) - hosts.insert(fields[i]); - } - } - file.close(); - } - return hosts; -} - -// Function to extract the hosts of a ssh known_hosts file -std::set getSshHostsFromKnownHosts(const QString& path) { - std::set hosts; - QFile file(path); - if ( file.open(QIODevice::ReadOnly | QIODevice::Text) ) { - QRegularExpression re ("^[a-zA-Z0-9\\.]*(?=(,.*)*\\s)"); - QTextStream in(&file); - while ( !in.atEnd() ) { - QString line = in.readLine(); - QRegularExpressionMatch match = re.match(line); - if ( match.hasMatch() ) - hosts.insert(match.captured(0)); - } - file.close(); - } - return hosts; -} - -} - - - -class Ssh::SshPrivate -{ -public: - QString icon; - QPointer widget; - QFileSystemWatcher fileSystemWatcher; - vector> hosts; - bool useKnownHosts; -}; - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -Ssh::Extension::Extension() - : Core::Extension("org.albert.extension.ssh"), - Core::QueryHandler(Core::Extension::id), - d(new SshPrivate) { - - // Load settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - d->useKnownHosts = s.value(CFG_USE_KNOWN_HOSTS, DEF_USE_KNOWN_HOSTS).toBool(); - s.endGroup(); - - // Find ssh - if (QStandardPaths::findExecutable("ssh").isNull()) - throw QString("[%s] ssh not found.").arg(Core::Extension::id); - - // Find an appropriate icon - d->icon = XdgIconLookup::iconPath("ssh"); - if (d->icon.isEmpty()) - d->icon = XdgIconLookup::iconPath("terminal"); - if (d->icon.isEmpty()) - d->icon = ":ssh"; // Fallback - - rescan(); -} - - - -/** ***************************************************************************/ -Ssh::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *Ssh::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) { - d->widget = new ConfigWidget(parent); - - // Checkboxes - d->widget->ui.checkBox_knownhosts->setChecked(useKnownHosts()); - connect(d->widget->ui.checkBox_knownhosts, &QCheckBox::toggled, - this, &Extension::setUseKnownHosts); - - connect(d->widget->ui.pushButton_rescan, &QPushButton::clicked, - this, &Extension::rescan); - - } - return d->widget; -} - - - -/** ***************************************************************************/ -void Ssh::Extension::handleQuery(Core::Query * query) { - - // This extension must run only triggered - if ( !query->isTriggered() ) - return; - - QStringList queryTerms = query->searchTerm().split(' ',QString::SkipEmptyParts); - - // Add all hosts if there are no arguments - if ( queryTerms.size() == 1) - for ( shared_ptr& host : d->hosts ) - query->addMatch(host, 1); - - if ( queryTerms.size() != 2) - return; - - // Add all hosts that the query is a prefix of - for ( shared_ptr& host : d->hosts ) - if ( host->text().startsWith(queryTerms[1]) ) - query->addMatch(host, SHRT_MAX * static_cast(query->searchTerm().size())/host->text().size()); - - // Add the quick connect item - std::shared_ptr item = std::make_shared(""); - item->setText(queryTerms[1]); - item->setSubtext(QString("Connect to '%1' using ssh").arg(queryTerms[1])); - item->setCompletionString(QString("ssh %1").arg(queryTerms[1])); - item->setIconPath(d->icon); - - shared_ptr action = std::make_shared(); - action->setText(QString("Connect to '%1' using ssh").arg(queryTerms[1])); - action->setAction([queryTerms](){ - QStringList tokens; - tokens << Util::ShellLexer::split(terminalCommand) - << "ssh" - << Util::ShellLexer::split(queryTerms[1]); - QProcess::startDetached(tokens.takeFirst(), tokens); - }); - item->setActions({action}); - - query->addMatch(item, 0); -} - - - -/** ***************************************************************************/ -void Ssh::Extension::rescan() { - - // Build a new index - vector> sshHosts; - - // Get the hosts in config - std::set hosts; - for ( const QString& path : {QString("/etc/ssh/config"), QDir::home().filePath(".ssh/config")} ) - if ( QFile::exists(path) ) - for ( const QString& host : getSshHostsFromConfig(path) ) - hosts.insert(host); - - // Get the hosts in known_hosts - if ( d->useKnownHosts ) { - const QString& path = QDir::home().filePath(".ssh/known_hosts"); - if ( QFile::exists(path) ) - for ( const QString& host : getSshHostsFromKnownHosts(path) ) - hosts.insert(host); - } - - - for ( const QString& host : hosts ){ - - // Create item - std::shared_ptr si = std::make_shared(host); - si->setText(host); - si->setSubtext(QString("Connect to '%1' using ssh").arg(host)); - si->setCompletionString(QString("ssh %1").arg(host)); - si->setIconPath(d->icon); - - shared_ptr sa = std::make_shared(); - sa->setText(QString("Connect to '%1' using ssh").arg(host)); - sa->setAction([host](){ - QStringList tokens; - tokens << Util::ShellLexer::split(terminalCommand) - << "ssh" - << Util::ShellLexer::split(host); - QProcess::startDetached(tokens.takeFirst(), tokens); - }); - si->setActions({sa}); - - sshHosts.push_back(std::move(si)); - } - - d->hosts = std::move(sshHosts); -} - - - -/** ***************************************************************************/ -bool Ssh::Extension::useKnownHosts() { - return d->useKnownHosts; -} - - - -/** ***************************************************************************/ -void Ssh::Extension::setUseKnownHosts(bool b) { - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, CFG_USE_KNOWN_HOSTS), b); - d->useKnownHosts = b; - rescan(); -} diff -Nru albert-0.12.0/src/plugins/ssh/src/main.h albert-0.13.1+plugins1/src/plugins/ssh/src/main.h --- albert-0.12.0/src/plugins/ssh/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace Ssh { - -class SshPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "SecureShell"; } - QWidget *widget(QWidget *parent = nullptr) override; - QStringList triggers() const override { return {"ssh "}; } - void handleQuery(Core::Query * query) override; - - /* - * Extension specific members - */ - - void rescan(); - - bool useKnownHosts(); - void setUseKnownHosts(bool b = true); - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/ssh/ssh.qrc albert-0.13.1+plugins1/src/plugins/ssh/ssh.qrc --- albert-0.12.0/src/plugins/ssh/ssh.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/ssh/ssh.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/ssh.svg - - diff -Nru albert-0.12.0/src/plugins/system/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/system/CMakeLists.txt --- albert-0.12.0/src/plugins/system/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(system) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets -) - -qt5_wrap_ui(UI - configwidget.ui -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/system/configwidget.ui albert-0.13.1+plugins1/src/plugins/system/configwidget.ui --- albert-0.12.0/src/plugins/system/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ - - - System::ConfigWidget - - - - 0 - 0 - 480 - 320 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Suspend: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Lock: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - Logout: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Shutdown: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Reboot: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - - - - <html><head/><body><p><span style=" color:#808080;">Be aware that on most distributions the standard commands to control your systems state (e.g. reboot, shutdown, systemctl etc) do not shutdown your desktop session gracefully. Try to use your desktop session managers interface. If you think you know good defaults for your desktop environment, please suggest it on </span><a href="https://github.com/ManuelSchneid3r/albert/issues"><span style=" text-decoration: underline; color:#0000ff;">github</span></a><span style=" color:#808080;">.</span></p></body></html> - - - true - - - - - - - Hibernate: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/system/metadata.json albert-0.13.1+plugins1/src/plugins/system/metadata.json --- albert-0.12.0/src/plugins/system/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.system", - "name" : "System", - "version" : "1.0", - "platform" : "Linux", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/system/resources/hibernate.svg albert-0.13.1+plugins1/src/plugins/system/resources/hibernate.svg --- albert-0.12.0/src/plugins/system/resources/hibernate.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/resources/hibernate.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/system/resources/lock.svg albert-0.13.1+plugins1/src/plugins/system/resources/lock.svg --- albert-0.12.0/src/plugins/system/resources/lock.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/resources/lock.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/system/resources/logout.svg albert-0.13.1+plugins1/src/plugins/system/resources/logout.svg --- albert-0.12.0/src/plugins/system/resources/logout.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/resources/logout.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/system/resources/poweroff.svg albert-0.13.1+plugins1/src/plugins/system/resources/poweroff.svg --- albert-0.12.0/src/plugins/system/resources/poweroff.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/resources/poweroff.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/system/resources/reboot.svg albert-0.13.1+plugins1/src/plugins/system/resources/reboot.svg --- albert-0.12.0/src/plugins/system/resources/reboot.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/resources/reboot.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/system/resources/suspend.svg albert-0.13.1+plugins1/src/plugins/system/resources/suspend.svg --- albert-0.12.0/src/plugins/system/resources/suspend.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/resources/suspend.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/system/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/system/src/configwidget.cpp --- albert-0.12.0/src/plugins/system/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -System::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); -} - - - -/** ***************************************************************************/ -System::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/system/src/configwidget.h albert-0.13.1+plugins1/src/plugins/system/src/configwidget.h --- albert-0.12.0/src/plugins/system/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace System { -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; -}; -} diff -Nru albert-0.12.0/src/plugins/system/src/main.cpp albert-0.13.1+plugins1/src/plugins/system/src/main.cpp --- albert-0.12.0/src/plugins/system/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,265 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "main.h" -#include "standardaction.h" -#include "standarditem.h" -#include "query.h" -#include "xdgiconlookup.h" -using std::vector; - - -namespace { - -vector configNames = { - "lock", - "logout", - "suspend", - "hibernate", - "reboot", - "shutdown" -}; - -vector itemTitles = { - "Lock", - "Logout", - "Suspend", - "Hibernate", - "Reboot", - "Shutdown" -}; - -vector itemDescriptions = { - "Lock the session.", - "Quit the session.", - "Suspend the machine.", - "Hibernate the machine.", - "Reboot the machine.", - "Shutdown the machine.", -}; - -vector iconNames = { - "system-lock-screen", - "system-log-out", - "system-suspend", - "system-suspend-hibernate", - "system-reboot", - "system-shutdown" -}; - -enum SupportedCommands { LOCK, LOGOUT, SUSPEND, HIBERNATE, REBOOT, POWEROFF, NUMCOMMANDS }; - -QString defaultCommand(SupportedCommands command){ - - QString de = getenv("XDG_CURRENT_DESKTOP"); - - switch (command) { - case LOCK: - if (de == "Unity" || de == "Pantheon" || de == "Gnome") - return "gnome-screensaver-command --lock"; - else if (de == "XFCE") - return "xflock4"; - if (de == "X-Cinnamon") - return "cinnamon-screensaver-command --lock"; - else if (de == "MATE") - return "mate-screensaver-command --lock"; - else - return "notify-send \"Error.\" \"Lock command is not set.\" --icon=system-lock-screen"; - - case LOGOUT: - if (de == "Unity" || de == "Pantheon" || de == "Gnome") - return "gnome-session-quit --logout"; - else if (de == "kde-plasma") - return "qdbus org.kde.ksmserver /KSMServer logout 0 0 0"; - else if (de == "X-Cinnamon") - return "cinnamon-session-quit --logout"; - else if (de == "XFCE") - return "xfce4-session-logout --logout"; - else if (de == "MATE") - return "mate-session-save --logout"; - else - return "notify-send \"Error.\" \"Logout command is not set.\" --icon=system-log-out"; - - case SUSPEND: - if (de == "XFCE") - return "xfce4-session-logout --suspend"; - else if (de == "MATE") - return "sh -c \"mate-screensaver-command --lock && systemctl suspend -i\""; - else - return "systemctl suspend -i"; - - case HIBERNATE: - if (de == "XFCE") - return "xfce4-session-logout --hibernate"; - else if (de == "MATE") - return "sh -c \"mate-screensaver-command --lock && systemctl hibernate -i\""; - else - return "systemctl hibernate -i"; - - case REBOOT: - if (de == "Unity" || de == "Pantheon" || de == "Gnome") - return "gnome-session-quit --reboot"; - else if (de == "kde-plasma") - return "qdbus org.kde.ksmserver /KSMServer logout 0 1 0"; - else if (de == "X-Cinnamon") - return "cinnamon-session-quit --reboot"; - else if (de == "XFCE") - return "xfce4-session-logout --reboot"; - else if (de == "MATE") - return "mate-session-save --shutdown-dialog"; - else - return "notify-send \"Error.\" \"Reboot command is not set.\" --icon=system-reboot"; - - case POWEROFF: - if (de == "Unity" || de == "Pantheon" || de == "Gnome") - return "gnome-session-quit --power-off"; - else if (de == "kde-plasma") - return "qdbus org.kde.ksmserver /KSMServer logout 0 2 0"; - else if (de == "X-Cinnamon") - return "cinnamon-session-quit --power-off"; - else if (de == "XFCE") - return "xfce4-session-logout --halt"; - else if (de == "MATE") - return "mate-session-save --shutdown-dialog"; - else - return "notify-send \"Error.\" \"Poweroff command is not set.\" --icon=system-shutdown"; - - case NUMCOMMANDS: - // NEVER REACHED; - return ""; - } - - // NEVER REACHED; - return ""; -} - -} - - - -class System::SystemPrivate -{ -public: - QPointer widget; - vector iconPaths; - vector commands; -}; - - - -/** ***************************************************************************/ -System::Extension::Extension() - : Core::Extension("org.albert.extension.system"), - Core::QueryHandler(Core::Extension::id), - d(new SystemPrivate) { - - // Load settings - QSettings s(qApp->applicationName()); - s.beginGroup(Core::Extension::id); - for (size_t i = 0; i < NUMCOMMANDS; ++i) { - d->iconPaths.push_back(XdgIconLookup::iconPath(iconNames[i])); - d->commands.push_back(s.value(configNames[i], defaultCommand(static_cast(i))).toString()); - } - s.endGroup(); -} - - - -/** ***************************************************************************/ -System::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *System::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) { - d->widget = new ConfigWidget(parent); - - // Initialize the content and connect the signals - - d->widget->ui.lineEdit_lock->setText(d->commands[LOCK]); - connect(d->widget->ui.lineEdit_lock, &QLineEdit::textEdited, [this](const QString &s){ - d->commands[LOCK]= s; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, configNames[LOCK]), s); - }); - - d->widget->ui.lineEdit_logout->setText(d->commands[LOGOUT]); - connect(d->widget->ui.lineEdit_logout, &QLineEdit::textEdited, [this](const QString &s){ - d->commands[LOGOUT]= s; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, configNames[LOGOUT]), s); - }); - - d->widget->ui.lineEdit_suspend->setText(d->commands[SUSPEND]); - connect(d->widget->ui.lineEdit_suspend, &QLineEdit::textEdited, [this](const QString &s){ - d->commands[SUSPEND]= s; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, configNames[SUSPEND]), s); - }); - - d->widget->ui.lineEdit_hibernate->setText(d->commands[HIBERNATE]); - connect(d->widget->ui.lineEdit_hibernate, &QLineEdit::textEdited, [this](const QString &s){ - d->commands[HIBERNATE]= s; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, configNames[HIBERNATE]), s); - }); - - d->widget->ui.lineEdit_reboot->setText(d->commands[REBOOT]); - connect(d->widget->ui.lineEdit_reboot, &QLineEdit::textEdited, [this](const QString &s){ - d->commands[REBOOT]= s; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, configNames[REBOOT]), s); - }); - - d->widget->ui.lineEdit_shutdown->setText(d->commands[POWEROFF]); - connect(d->widget->ui.lineEdit_shutdown, &QLineEdit::textEdited, [this](const QString &s){ - d->commands[POWEROFF]= s; - QSettings(qApp->applicationName()).setValue(QString("%1/%2").arg(Core::Extension::id, configNames[POWEROFF]), s); - }); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void System::Extension::handleQuery(Core::Query * query) { - for (int i = 0; i < NUMCOMMANDS; ++i) { - if (configNames[i].startsWith(query->searchTerm().toLower())) { - - std::shared_ptr item = std::make_shared(configNames[i]); - item->setText(itemTitles[i]); - item->setSubtext(itemDescriptions[i]); - item->setIconPath(d->iconPaths[i]); - - QString cmd = d->commands[i]; - std::shared_ptr action = std::make_shared(); - action->setText(itemDescriptions[i]); - action->setAction([=](){ - QProcess::startDetached(cmd); - }); - - item->setActions({action}); - - query->addMatch(item); - } - } -} - diff -Nru albert-0.12.0/src/plugins/system/src/main.h albert-0.13.1+plugins1/src/plugins/system/src/main.h --- albert-0.12.0/src/plugins/system/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace System { - -class SystemPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of interfaces - */ - - QString name() const override { return "System"; } - QWidget *widget(QWidget *parent = nullptr) override; - void handleQuery(Core::Query * query) override; - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/system/system.qrc albert-0.13.1+plugins1/src/plugins/system/system.qrc --- albert-0.12.0/src/plugins/system/system.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/system/system.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - - - resources/poweroff.svg - resources/reboot.svg - resources/suspend.svg - resources/hibernate.svg - resources/lock.svg - resources/logout.svg - - diff -Nru albert-0.12.0/src/plugins/templateExtension/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/templateExtension/CMakeLists.txt --- albert-0.12.0/src/plugins/templateExtension/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(projectid) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets -) - -set(LIB - ${Qt5Widgets_LIBRARIES} - albertcore -) - -qt5_wrap_ui(UI - configwidget.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} ${LIB}) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/templateExtension/configwidget.ui albert-0.13.1+plugins1/src/plugins/templateExtension/configwidget.ui --- albert-0.12.0/src/plugins/templateExtension/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ - - - ProjectNamespace::ConfigWidget - - - - 0 - 0 - 480 - 320 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p align="center"><span style=" color:#808080;">This is a simple template extension.</span></p></body></html> - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/templateExtension/metadata.json albert-0.13.1+plugins1/src/plugins/templateExtension/metadata.json --- albert-0.12.0/src/plugins/templateExtension/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.projectid", - "name" : "Template", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Author missing", - "dependencies" : [], - "enabledbydefault": false -} diff -Nru albert-0.12.0/src/plugins/templateExtension/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/templateExtension/src/configwidget.cpp --- albert-0.12.0/src/plugins/templateExtension/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" - -/** ***************************************************************************/ -ProjectNamespace::ConfigWidget::ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); -} - - - -/** ***************************************************************************/ -ProjectNamespace::ConfigWidget::~ConfigWidget() { - -} diff -Nru albert-0.12.0/src/plugins/templateExtension/src/configwidget.h albert-0.13.1+plugins1/src/plugins/templateExtension/src/configwidget.h --- albert-0.12.0/src/plugins/templateExtension/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace ProjectNamespace { -class ConfigWidget final : public QWidget -{ - Q_OBJECT -public: - explicit ConfigWidget(QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; -}; -} diff -Nru albert-0.12.0/src/plugins/templateExtension/src/main.cpp albert-0.13.1+plugins1/src/plugins/templateExtension/src/main.cpp --- albert-0.12.0/src/plugins/templateExtension/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include "configwidget.h" -#include "item.h" -#include "main.h" -#include "query.h" - - - -class ProjectNamespace::ProjectNamespacePrivate -{ -public: - QPointer widget; -}; - - - -/** ***************************************************************************/ -ProjectNamespace::Extension::Extension() - : Core::Extension("org.albert.extension.projectid"), - Core::QueryHandler(Core::Extension::id), - d(new ProjectNamespacePrivate) { - - // You can throw in the constructor if something fatal happened - throw std::runtime_error( "Description of error." ); - throw std::string( "Description of error." ); - throw QString( "Description of error." ); - throw "Description of error."; - throw; // Whatever prints "unknown error" -} - - - -/** ***************************************************************************/ -ProjectNamespace::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *ProjectNamespace::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) { - d->widget = new ConfigWidget(parent); - } - return d->widget; -} - - - -/** ***************************************************************************/ -void ProjectNamespace::Extension::setupSession() { - -} - - - -/** ***************************************************************************/ -void ProjectNamespace::Extension::teardownSession() { - -} - - - -/** ***************************************************************************/ -void ProjectNamespace::Extension::handleQuery(Core::Query * query) { - - if ( query->isTriggered() ) { - - } else { - - } -} - diff -Nru albert-0.12.0/src/plugins/templateExtension/src/main.h albert-0.13.1+plugins1/src/plugins/templateExtension/src/main.h --- albert-0.12.0/src/plugins/templateExtension/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/templateExtension/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace ProjectNamespace { - -class ProjectNamespacePrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "Template"; } - QWidget *widget(QWidget *parent = nullptr) override; - void setupSession() override; - void teardownSession() override; - void handleQuery(Core::Query * query) override; - - /* - * Extension specific members - */ - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/terminal/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/terminal/CMakeLists.txt --- albert-0.12.0/src/plugins/terminal/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(terminal) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Concurrent - Widgets -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -qt5_wrap_ui(UI - configwidget.ui -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${QRC} ${UI}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - ${Qt5Concurrent_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/terminal/configwidget.ui albert-0.13.1+plugins1/src/plugins/terminal/configwidget.ui --- albert-0.12.0/src/plugins/terminal/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ - - - Terminal::ConfigWidget - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p><span style=" color:#808080;">There is nothing to configure here.</span></p><p><span style=" color:#808080;">Just run the extension using the trigger '>'.</span></p></body></html> - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/terminal/metadata.json albert-0.13.1+plugins1/src/plugins/terminal/metadata.json --- albert-0.12.0/src/plugins/terminal/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.terminal", - "name" : "Terminal", - "version" : "1.0", - "platform" : "Linux", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/terminal/resources/terminal.svg albert-0.13.1+plugins1/src/plugins/terminal/resources/terminal.svg --- albert-0.12.0/src/plugins/terminal/resources/terminal.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/resources/terminal.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/terminal/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/terminal/src/configwidget.cpp --- albert-0.12.0/src/plugins/terminal/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "configwidget.h" diff -Nru albert-0.12.0/src/plugins/terminal/src/configwidget.h albert-0.13.1+plugins1/src/plugins/terminal/src/configwidget.h --- albert-0.12.0/src/plugins/terminal/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace Terminal { - -class ConfigWidget final : public QWidget -{ - Q_OBJECT - -public: - - ConfigWidget(QWidget *parent) : QWidget(parent) { - ui.setupUi(this); - } - - Ui::ConfigWidget ui; - -}; - -} diff -Nru albert-0.12.0/src/plugins/terminal/src/main.cpp albert-0.13.1+plugins1/src/plugins/terminal/src/main.cpp --- albert-0.12.0/src/plugins/terminal/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include "main.h" -#include "xdgiconlookup.h" -#include "configwidget.h" -#include "query.h" -#include "standarditem.h" -#include "standardaction.h" -#include "shlex.h" -using std::shared_ptr; -using Core::Action; -using Core::StandardAction; -using Core::StandardItem; - -extern QString terminalCommand; - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -class Terminal::Internal -{ -public: - QPointer widget; - QString iconPath; -}; - - - -/** ***************************************************************************/ -Terminal::Extension::Extension() - : Core::Extension("org.albert.extension.terminal"), - Core::QueryHandler(Core::Extension::id), - d(new Internal) { - - QString iconPath = XdgIconLookup::iconPath("terminal"); - d->iconPath = iconPath.isNull() ? ":terminal" : iconPath; -} - - - -/** ***************************************************************************/ -Terminal::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *Terminal::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) - d->widget = new ConfigWidget(parent); - return d->widget; -} - - - -/** ***************************************************************************/ -void Terminal::Extension::handleQuery(Core::Query * query) { - - // This extension must run only triggered - if ( !query->isTriggered() ) - return; - - // passwd must not be freed - passwd *pwd = getpwuid(geteuid()); - if (pwd == NULL){ - qWarning() << "Could not retrieve user shell"; - return; - } - QString commandline = query->searchTerm().mid(1).trimmed(); - if (commandline.isEmpty()) - return; - - QString shell(pwd->pw_shell); - - // Build Item - std::shared_ptr item = std::make_shared(); - item->setText(commandline); - item->setSubtext(QString("Run '%1' in terminal").arg(commandline)); - item->setCompletionString(query->searchTerm()); - item->setIconPath(d->iconPath); - - std::vector> actions; - actions.push_back(std::make_shared("Execute in the shell", - [shell, commandline](){ - QProcess::startDetached(shell, {"-c", commandline}); - })); - actions.push_back(std::make_shared("Execute in the terminal", [=](){ - QStringList tokens = Util::ShellLexer::split(terminalCommand); - tokens << shell << "-ic" << QString("%1; exec %2").arg(commandline, shell); - QProcess::startDetached(tokens.takeFirst(), tokens); - })); - - item->setActions(std::move(actions)); - - // Add results to query - query->addMatch(item, 0); -} - diff -Nru albert-0.12.0/src/plugins/terminal/src/main.h albert-0.13.1+plugins1/src/plugins/terminal/src/main.h --- albert-0.12.0/src/plugins/terminal/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace Terminal { - -class Internal; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return "Terminal"; } - QWidget *widget(QWidget *parent = nullptr) override; - QStringList triggers() const override { return {">"}; } - void handleQuery(Core::Query * query) override; - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/terminal/terminal.qrc albert-0.13.1+plugins1/src/plugins/terminal/terminal.qrc --- albert-0.12.0/src/plugins/terminal/terminal.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/terminal/terminal.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/terminal.svg - - diff -Nru albert-0.12.0/src/plugins/virtualbox/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/virtualbox/CMakeLists.txt --- albert-0.12.0/src/plugins/virtualbox/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(virtualbox) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets - Xml -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - ${Qt5Xml_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/virtualbox/metadata.json albert-0.13.1+plugins1/src/plugins/virtualbox/metadata.json --- albert-0.12.0/src/plugins/virtualbox/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.virtualbox", - "name" : "VirtualBox", - "version" : "1.0", - "platform" : "Linux", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : ["virtualbox"], - "enabledbydefault": false -} diff -Nru albert-0.12.0/src/plugins/virtualbox/resources/virtualbox.svg albert-0.13.1+plugins1/src/plugins/virtualbox/resources/virtualbox.svg --- albert-0.12.0/src/plugins/virtualbox/resources/virtualbox.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/resources/virtualbox.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/virtualbox/src/main.cpp albert-0.13.1+plugins1/src/plugins/virtualbox/src/main.cpp --- albert-0.12.0/src/plugins/virtualbox/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// Contributed to by 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "main.h" -#include "vm.h" -#include "query.h" -#include "xdgiconlookup.h" -#include "standarditem.h" -#include "standardaction.h" -using Core::Action; -using Core::StandardAction; -using Core::StandardItem; - - - -class VirtualBox::VirtualBoxPrivate -{ -public: - VirtualBoxPrivate(Extension *q) : q(q) { } - Extension *q; - - QPointer widget; - QList vms; - QFileSystemWatcher vboxWatcher; - - void rescanVBoxConfig(QString path); - -}; - - - -/** ***************************************************************************/ -void VirtualBox::VirtualBoxPrivate::rescanVBoxConfig(QString path) { - - qDebug() << "Start indexing VirtualBox images."; - - QFile vboxConfigFile(path); - if (!vboxConfigFile.exists()) - return; - if (!vboxConfigFile.open(QFile::ReadOnly)) { - qCritical() << "Could not open VirtualBox config file for read operation!"; - return; - } - - QDomDocument vboxConfig; - QString errMsg = ""; - int errLine = 0, errCol = 0; - if (!vboxConfig.setContent(&vboxConfigFile, &errMsg, &errLine, &errCol)) { - qWarning() << qPrintable(QString("Parsing VBox config failed because %s in line %d col %d").arg(errMsg).arg(errLine, errCol)); - vboxConfigFile.close(); - return; - } - vboxConfigFile.close(); - - QDomElement root = vboxConfig.documentElement(); - if (root.isNull()) { - qCritical() << "In VBox config file: Root element is null."; - return; - } - - QDomElement global = root.firstChildElement("Global"); - if (global.isNull()) { - qCritical() << "In VBox config file: Global element is null."; - return; - } - - QDomElement machines = global.firstChildElement("MachineRegistry"); // List of MachineEntry - if (machines.isNull()) { - qCritical() << "In VBox config file: Machine registry element is null."; - return; - } - - // With this we iterate over the machine entries - QDomElement machine = machines.firstChildElement(); - - // And we count how many entries we find for information reasons - int found = 0; - - qDeleteAll(vms); - vms.clear(); - - while (!machine.isNull()) { - - vms.append(new VM(machine.attribute("src"))); - - machine = machine.nextSiblingElement(); - found++; - } - - qDebug() << qPrintable(QString("Indexed %2 VirtualBox images.").arg(found)); -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -VirtualBox::Extension::Extension() - : Core::Extension("org.albert.extension.virtualbox"), - Core::QueryHandler(Core::Extension::id), - d(new VirtualBoxPrivate(this)) { - - VMItem::iconPath_ = XdgIconLookup::iconPath("virtualbox"); - if ( VMItem::iconPath_.isNull() ) - VMItem::iconPath_ = ":vbox"; - - QString vboxConfigPath = QStandardPaths::locate(QStandardPaths::ConfigLocation, "VirtualBox/VirtualBox.xml"); - if (vboxConfigPath.isEmpty()) - throw "VirtualBox was not detected!"; - - d->rescanVBoxConfig(vboxConfigPath); - d->vboxWatcher.addPath(vboxConfigPath); - connect(&d->vboxWatcher, &QFileSystemWatcher::fileChanged, - std::bind(&VirtualBoxPrivate::rescanVBoxConfig, d.get(), std::placeholders::_1)); -} - - - -/** ***************************************************************************/ -VirtualBox::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *VirtualBox::Extension::widget(QWidget *parent) { - return new QWidget(parent); -} - - - -/** ***************************************************************************/ -void VirtualBox::Extension::setupSession() { - for (VM *vm : d->vms) - vm->probeState(); -} - - - -/** ***************************************************************************/ -void VirtualBox::Extension::handleQuery(Core::Query * query) { - for (VM* vm : d->vms) { - if (vm->startsWith(query->searchTerm())) - query->addMatch(std::shared_ptr(vm->produceItem())); - } -} diff -Nru albert-0.12.0/src/plugins/virtualbox/src/main.h albert-0.13.1+plugins1/src/plugins/virtualbox/src/main.h --- albert-0.12.0/src/plugins/virtualbox/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2015 Manuel Schneider -// Contributed to by 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include -#include "extension.h" -#include "queryhandler.h" - -namespace VirtualBox { - -class VirtualBoxPrivate; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - /* - * Implementation of extension interface - */ - - QString name() const override { return tr("VirtualBox"); } - QWidget *widget(QWidget *parent = nullptr) override; - void setupSession() override; - void handleQuery(Core::Query *) override; - -private: - - std::unique_ptr d; - -}; -} diff -Nru albert-0.12.0/src/plugins/virtualbox/src/vm.cpp albert-0.13.1+plugins1/src/plugins/virtualbox/src/vm.cpp --- albert-0.12.0/src/plugins/virtualbox/src/vm.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/src/vm.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "vm.h" - -#include -#include -#include -#include -#include -#include -#include "standardaction.h" -using Core::StandardAction; - - -/** ***************************************************************************/ -VirtualBox::VM::VM(const QString vboxFileName) { - - QFile vboxFile(vboxFileName); - if (!vboxFile.open(QFile::ReadOnly)) { - qWarning("Could not open VM config file for read operation: %s", vboxFileName.toStdString().c_str()); - return; - } - - QDomDocument machineConfig; - QString errMsg; - int errLine, errCol; - if (!machineConfig.setContent(&vboxFile, &errMsg, &errLine, &errCol)) { - qWarning("Could not parse VM config file %s because %s in line %d col %d", vboxFileName.toStdString().c_str(), errMsg.toStdString().c_str(), errLine, errCol); - state_ = ""; - vboxFile.close(); - return; - } - vboxFile.close(); - - QDomElement root = machineConfig.documentElement(); - QDomElement machine = root.firstChildElement("Machine"); - uuid_ = machine.attribute("uuid"); - name_ = machine.attribute("name"); - state_ = "poweroff"; - - probeState(); -} - - - -/* - - A state diagram of the VBox VMStates - - +---------[powerDown()] <- Stuck <--[failure]-+ - V | - +-> PoweredOff --+-->[powerUp()]--> Starting --+ | +-----[resume()]-----+ - | | | | V | - | Aborted -----+ +--> Running --[pause()]--> Paused - | | ^ | ^ | - | Saved -----------[powerUp()]--> Restoring -+ | | | | - | ^ | | | | - | | +-----------------------------------------+-|-------------------+ + - | | | | | - | | +- OnlineSnapshotting <--[takeSnapshot()]<--+---------------------+ - | | | | - | +-------- Saving <--------[saveState()]<----------+---------------------+ - | | | - +-------------- Stopping -------[powerDown()]<----------+---------------------+ - - */ -/** ***************************************************************************/ -VirtualBox::VMItem *VirtualBox::VM::produceItem() const { - if (state_.isEmpty()) - return nullptr; // This should not be empty... We just ignore this VM - - QString pauseCmd = "VBoxManage controlvm %1 pause"; - QString startCmd = "VBoxManage startvm %1"; - QString saveCmd = "VBoxManage controlvm %1 savestate"; - QString stopCmd = "VBoxManage controlvm %1 poweroff"; - QString resetCmd = "VBoxManage controlvm %1 reset"; - QString resumeCmd = "VBoxManage controlvm %1 resume"; - pauseCmd = pauseCmd.arg(uuid_); - startCmd = startCmd.arg(uuid_); - saveCmd = saveCmd.arg(uuid_); - stopCmd = stopCmd.arg(uuid_); - resetCmd = resetCmd.arg(uuid_); - resumeCmd = resumeCmd.arg(uuid_); - ActionSPtrVec actions; - int mainAction = 0; - if (state_ == "starting" || state_ == "restoring" || state_ == "saving" || state_ == "stopping") { - mainAction = VMItem::VM_STATE_CHANGING; - actions.push_back(std::shared_ptr( new StandardAction("Controls are disabled", [](){}) )); - } else if (state_ == "poweroff" || state_ == "aborted") { - mainAction = VMItem::VM_START; - actions.push_back(std::shared_ptr( new StandardAction("Start", [startCmd](){ QProcess::startDetached(startCmd); }) )); - } else if (state_ == "saved") { - mainAction = VMItem::VM_START; - actions.push_back(std::shared_ptr( new StandardAction("Start", [startCmd](){ QProcess::startDetached(startCmd); }) )); - } else if (state_ == "running") { - mainAction = VMItem::VM_PAUSE; - actions.push_back(std::shared_ptr( new StandardAction("Pause", [pauseCmd](){ QProcess::startDetached(pauseCmd); }) )); - actions.push_back(std::shared_ptr( new StandardAction("Save State", [saveCmd](){ QProcess::startDetached(saveCmd); }) )); - actions.push_back(std::shared_ptr( new StandardAction("Stop", [stopCmd](){ QProcess::startDetached(stopCmd); }) )); - } else if (state_ == "paused") { - mainAction = VMItem::VM_RESUME; - actions.push_back(std::shared_ptr( new StandardAction("Resume", [resumeCmd](){ QProcess::startDetached(resumeCmd); }) )); - actions.push_back(std::shared_ptr( new StandardAction("Save State", [saveCmd](){ QProcess::startDetached(saveCmd); }) )); - actions.push_back(std::shared_ptr( new StandardAction("Reset", [resetCmd](){ QProcess::startDetached(resetCmd); }) )); - } - - return new VMItem(name_, uuid_, mainAction, actions, state_); -} - - - -/** ***************************************************************************/ -bool VirtualBox::VM::startsWith(QString other) const { - return name_.startsWith(other, Qt::CaseInsensitive); -} - - - -/** ***************************************************************************/ -void VirtualBox::VM::probeState() const { - QProcess *process = new QProcess; - process->setReadChannel(QProcess::StandardOutput); - process->start("VBoxManage", {"showvminfo", uuid_, "--machinereadable"}); - QObject::connect(process, static_cast(&QProcess::finished), - [this, process](int exitCode, QProcess::ExitStatus exitStatus){ - if (exitStatus == QProcess::NormalExit && exitCode == 0){ - while (process->canReadLine()) { - QString line = QString::fromLocal8Bit(process->readLine()); - if (line.startsWith("VMState=")) { - QRegularExpression regex("VMState=\"(.*)\""); - QRegularExpressionMatch match = regex.match(line); - state_ = match.captured(1).toLower(); - break; - } - } - } - process->deleteLater(); - }); - QObject::connect(process, static_cast(&QProcess::error), [process](QProcess::ProcessError){ - process->deleteLater(); - }); -} - diff -Nru albert-0.12.0/src/plugins/virtualbox/src/vm.h albert-0.13.1+plugins1/src/plugins/virtualbox/src/vm.h --- albert-0.12.0/src/plugins/virtualbox/src/vm.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/src/vm.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#include -#include "vmitem.h" - -namespace VirtualBox { - -class VM -{ -public: - VM(const QString vboxFileName); - VMItem* produceItem() const; - bool startsWith(QString other) const; - const QString &uuid() const { return uuid_; } - void probeState() const; - -private: - QString name_; - QString uuid_; - mutable QString state_; -}; - -} // namespace VirtualBox - diff -Nru albert-0.12.0/src/plugins/virtualbox/src/vmitem.cpp albert-0.13.1+plugins1/src/plugins/virtualbox/src/vmitem.cpp --- albert-0.12.0/src/plugins/virtualbox/src/vmitem.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/src/vmitem.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "vmitem.h" - -#include - -/** ***************************************************************************/ -QString VirtualBox::VMItem::iconPath_; -const int VirtualBox::VMItem::VM_START = 1; -const int VirtualBox::VMItem::VM_PAUSE = 2; -const int VirtualBox::VMItem::VM_RESUME = 3; -const int VirtualBox::VMItem::VM_STATE_CHANGING = -1; - -VirtualBox::VMItem::VMItem(const QString &name, const QString &uuid, int &mainAction, const ActionSPtrVec actions, const QString &state) : name_(name), uuid_(uuid), actions_(actions), mainAction_(mainAction) { - idstring_ = QString("extension.virtualbox.item:%1.%2").arg(uuid).arg(state); -} - -QString VirtualBox::VMItem::subtext() const { - QString toreturn; - switch (mainAction_) { - case VM_START: - toreturn = "Start %1"; - break; - case VM_PAUSE: - toreturn = "Pause %1"; - break; - case VM_RESUME: - toreturn = "Resume %1"; - break; - case VM_STATE_CHANGING: - toreturn = "The VM %1 is currently in action. Controls are disabled!"; - break; - default: - toreturn = "Start %1"; - break; - } - return toreturn.arg(name_); -} - -/* -void VirtualBox::VMItem::activate(Action::ExecutionFlags *) { - QString executionCommand; - switch (mainAction_) { - case VM_START: - executionCommand = "vboxmanage startvm %1"; - break; - case VM_PAUSE: - executionCommand = "vboxmanage controlvm %1 pause"; - break; - case VM_RESUME: - executionCommand = "vboxmanage controlvm %1 resume"; - break; - case VM_STATE_CHANGING: - break; - default: - executionCommand = "vboxmanage startvm %1"; - break; - } - if (!executionCommand.isEmpty()) - QProcess::startDetached(executionCommand.arg(uuid_)); -} -*/ diff -Nru albert-0.12.0/src/plugins/virtualbox/src/vmitem.h albert-0.13.1+plugins1/src/plugins/virtualbox/src/vmitem.h --- albert-0.12.0/src/plugins/virtualbox/src/vmitem.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/src/vmitem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2016-2017 Martin Buergmann -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once - -#include "item.h" -using std::vector; -using std::shared_ptr; -using Core::Action; -using Core::Item; - -namespace VirtualBox { - -typedef vector> ActionSPtrVec; - -class VMItem : public Item -{ -public: - VMItem(const QString &name, const QString &uuid, int &mainAction, const ActionSPtrVec actions, const QString &state); - - - /* - * Implementation of AlbertItem interface - */ - - QString id() const override { return idstring_; } - QString text() const override { return name_; } - QString subtext() const override; - QString iconPath() const override { return iconPath_; } - ActionSPtrVec actions() override { return actions_; } - - /* - * Item specific members - */ - - static QString iconPath_; - static const int VM_START; - static const int VM_PAUSE; - static const int VM_RESUME; - static const int VM_STATE_CHANGING; - -private: - QString name_; - QString uuid_; - QString idstring_; - ActionSPtrVec actions_; - int mainAction_; -}; - -} // namespace VirtualBox diff -Nru albert-0.12.0/src/plugins/virtualbox/virtualbox.qrc albert-0.13.1+plugins1/src/plugins/virtualbox/virtualbox.qrc --- albert-0.12.0/src/plugins/virtualbox/virtualbox.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/virtualbox/virtualbox.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ - - - resources/virtualbox.svg - - diff -Nru albert-0.12.0/src/plugins/websearch/CMakeLists.txt albert-0.13.1+plugins1/src/plugins/websearch/CMakeLists.txt --- albert-0.12.0/src/plugins/websearch/CMakeLists.txt 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) - -PROJECT(websearch) - -FILE(GLOB_RECURSE SRC src/* metadata.json) - -find_package(Qt5 5.2.0 REQUIRED COMPONENTS - Widgets -) - -qt5_wrap_ui(UI - forms/configwidget.ui - forms/searchengineeditor.ui -) - -qt5_add_resources(QRC - ${PROJECT_NAME}.qrc -) - -# Define the target -add_library(${PROJECT_NAME} SHARED ${SRC} ${UI} ${QRC}) - -# Set INCLUDE_DIRS and INTERFACE_INCLUDE_DIRS -target_include_directories(${PROJECT_NAME} PRIVATE src/ forms/) - -# Link target to libraries -target_link_libraries(${PROJECT_NAME} - ${Qt5Widgets_LIBRARIES} - albertcore - xdg -) - -# Install target -install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION lib/albert/plugins) diff -Nru albert-0.12.0/src/plugins/websearch/forms/configwidget.ui albert-0.13.1+plugins1/src/plugins/websearch/forms/configwidget.ui --- albert-0.12.0/src/plugins/websearch/forms/configwidget.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/forms/configwidget.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ - - - Websearch::ConfigWidget - - - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAlwaysOff - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::InternalMove - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - false - - - false - - - false - - - true - - - false - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - .. - - - - - - - - .. - - - - - - - Restore - - - - - - - - - - diff -Nru albert-0.12.0/src/plugins/websearch/forms/searchengineeditor.ui albert-0.13.1+plugins1/src/plugins/websearch/forms/searchengineeditor.ui --- albert-0.12.0/src/plugins/websearch/forms/searchengineeditor.ui 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/forms/searchengineeditor.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,194 +0,0 @@ - - - Websearch::SearchEngineEditor - - - - 0 - 0 - 420 - 320 - - - - Edit search engine - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Click to set an icon for the search engine. - - - - 96 - 96 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Name: - - - - - - - Name of the search engine. - - - Name of the search engine - - - - - - - Trigger: - - - - - - - The query prefix that triggers this engine. Note that it may make sense to append a space to the trigger prefix. - - - The query prefix that triggers this engine - - - - - - - URL: - - - - - - - The URL containing a %s that will be replaced by the query. - - - The URL containing a %s that will be replaced by the query - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - lineEdit_name - lineEdit_trigger - lineEdit_url - toolButton_icon - - - - - buttonBox - accepted() - Websearch::SearchEngineEditor - accept() - - - 275 - 310 - - - 157 - 274 - - - - - buttonBox - rejected() - Websearch::SearchEngineEditor - reject() - - - 343 - 310 - - - 286 - 274 - - - - - diff -Nru albert-0.12.0/src/plugins/websearch/metadata.json albert-0.13.1+plugins1/src/plugins/websearch/metadata.json --- albert-0.12.0/src/plugins/websearch/metadata.json 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/metadata.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -{ - "id" : "org.albert.extension.websearch", - "name" : "WebSearch", - "version" : "1.0", - "platform" : "All", - "group" : "Extensions", - "author" : "Manuel Schneider", - "dependencies" : [], - "enabledbydefault": true -} diff -Nru albert-0.12.0/src/plugins/websearch/resources/amazon.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/amazon.svg --- albert-0.12.0/src/plugins/websearch/resources/amazon.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/amazon.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/resources/default.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/default.svg --- albert-0.12.0/src/plugins/websearch/resources/default.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/default.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/resources/ebay.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/ebay.svg --- albert-0.12.0/src/plugins/websearch/resources/ebay.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/ebay.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/resources/google.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/google.svg --- albert-0.12.0/src/plugins/websearch/resources/google.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/google.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/resources/octocat.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/octocat.svg --- albert-0.12.0/src/plugins/websearch/resources/octocat.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/octocat.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/resources/wikipedia.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/wikipedia.svg --- albert-0.12.0/src/plugins/websearch/resources/wikipedia.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/wikipedia.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ - - - - \ No newline at end of file Binary files /tmp/tmpCzni3Z/txVeZGSvC2/albert-0.12.0/src/plugins/websearch/resources/wolfram.png and /tmp/tmpCzni3Z/FiZEfB5P5R/albert-0.13.1+plugins1/src/plugins/websearch/resources/wolfram.png differ diff -Nru albert-0.12.0/src/plugins/websearch/resources/wolfram.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/wolfram.svg --- albert-0.12.0/src/plugins/websearch/resources/wolfram.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/wolfram.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/resources/youtube.svg albert-0.13.1+plugins1/src/plugins/websearch/resources/youtube.svg --- albert-0.12.0/src/plugins/websearch/resources/youtube.svg 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/resources/youtube.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file diff -Nru albert-0.12.0/src/plugins/websearch/src/configwidget.cpp albert-0.13.1+plugins1/src/plugins/websearch/src/configwidget.cpp --- albert-0.12.0/src/plugins/websearch/src/configwidget.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/configwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include "configwidget.h" -#include "enginesmodel.h" -#include "searchengineeditor.h" -#include "main.h" - -/** ***************************************************************************/ -Websearch::ConfigWidget::ConfigWidget(Extension *extension, QWidget *parent) - : QWidget(parent), extension_(extension) { - - ui.setupUi(this); - - enginesModel_ = new EnginesModel(extension, ui.tableView_searches); - ui.tableView_searches->setModel(enginesModel_); - - ui.tableView_searches->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - ui.tableView_searches->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - - // Initialize connections - connect(ui.pushButton_new, &QPushButton::clicked, - this, &ConfigWidget::onButton_new); - - connect(ui.pushButton_remove, &QPushButton::clicked, - this, &ConfigWidget::onButton_remove); - - connect(ui.pushButton_restoreDefaults, &QPushButton::clicked, - this, &ConfigWidget::onButton_restoreDefaults); - - connect(ui.tableView_searches, &QTableView::activated, - this, &ConfigWidget::onActivated); -} - - - -/** ***************************************************************************/ -Websearch::ConfigWidget::~ConfigWidget() { -} - - - -/** ***************************************************************************/ -void Websearch::ConfigWidget::onActivated(QModelIndex index) { - int row = index.row(); - SearchEngineEditor searchEngineEditor(extension_->engines()[static_cast(row)], this); - - if (searchEngineEditor.exec()){ - // Set the new engine - const SearchEngine & searchEngine = searchEngineEditor.searchEngine(); - enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.name, Qt::DisplayRole); - enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.iconPath, Qt::DecorationRole); - enginesModel_->setData(enginesModel_->index(row, 1), searchEngine.trigger, Qt::DisplayRole); - enginesModel_->setData(enginesModel_->index(row, 2), searchEngine.url, Qt::DisplayRole); - } - ui.tableView_searches->reset(); -} - - - -/** ***************************************************************************/ -void Websearch::ConfigWidget::onButton_new() { - - // Open search engine editor - SearchEngine searchEngine; - searchEngine.iconPath = ":default"; - SearchEngineEditor searchEngineEditor(searchEngine, this); - - if (searchEngineEditor.exec()){ - - // Insert new row in model - int row = (ui.tableView_searches->currentIndex().isValid()) - ? ui.tableView_searches->currentIndex().row() - : ui.tableView_searches->model()->rowCount(); - enginesModel_->insertRow(row); - - // Set the new engine - searchEngine = searchEngineEditor.searchEngine(); - enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.name, Qt::DisplayRole); - enginesModel_->setData(enginesModel_->index(row, 0), searchEngine.iconPath, Qt::DecorationRole); - enginesModel_->setData(enginesModel_->index(row, 1), searchEngine.trigger, Qt::DisplayRole); - enginesModel_->setData(enginesModel_->index(row, 2), searchEngine.url, Qt::DisplayRole); - - // Set current - QModelIndex index = ui.tableView_searches->model()->index(row, 0, QModelIndex()); - ui.tableView_searches->setCurrentIndex(index); - } -} - - - -/** ***************************************************************************/ -void Websearch::ConfigWidget::onButton_remove() { - // Ask if sure - int row = ui.tableView_searches->currentIndex().row(); - QString engineName = ui.tableView_searches->model() - ->data(ui.tableView_searches->model()->index(row, 1)).toString(); - QMessageBox::StandardButton reply = - QMessageBox::question(this, "Sure?", - QString("Do you really want to remove '%1' from the search engines?") - .arg(engineName), - QMessageBox::Yes|QMessageBox::No); - // Remove if sure - if (reply == QMessageBox::Yes) - ui.tableView_searches->model()->removeRow(ui.tableView_searches->currentIndex().row()); -} - - - -/** ***************************************************************************/ -void Websearch::ConfigWidget::onButton_restoreDefaults() { - QMessageBox::StandardButton reply = - QMessageBox::question(this, "Sure?", - QString("Do you really want to restore the default search engines?"), - QMessageBox::Yes|QMessageBox::No); - // Remove if sure - if (reply == QMessageBox::Yes) - enginesModel_->restoreDefaults(); -} diff -Nru albert-0.12.0/src/plugins/websearch/src/configwidget.h albert-0.13.1+plugins1/src/plugins/websearch/src/configwidget.h --- albert-0.12.0/src/plugins/websearch/src/configwidget.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/configwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_configwidget.h" - -namespace Websearch { - -class Extension; -class EnginesModel; - -class ConfigWidget final : public QWidget -{ - Q_OBJECT - -public: - - explicit ConfigWidget(Extension *extension, QWidget *parent = 0); - ~ConfigWidget(); - Ui::ConfigWidget ui; - -private: - - void onActivated(QModelIndex index); - void onButton_new(); - void onButton_remove(); - void onButton_restoreDefaults(); - - Extension *extension_; - EnginesModel *enginesModel_; -}; - -} diff -Nru albert-0.12.0/src/plugins/websearch/src/enginesmodel.cpp albert-0.13.1+plugins1/src/plugins/websearch/src/enginesmodel.cpp --- albert-0.12.0/src/plugins/websearch/src/enginesmodel.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/enginesmodel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,332 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -#include -#include -#include -#include -#include -#include -#include -#include "enginesmodel.h" -#include "main.h" -#include "searchengine.h" - -namespace { - -enum class Section{ Name, Trigger, URL} ; -const int sectionCount = 3; - -std::map iconCache; - -} - - -/** ***************************************************************************/ -Websearch::EnginesModel::EnginesModel(Extension *extension, QObject *parent) - : QAbstractTableModel(parent), extension_(extension) { -} - - -/** ***************************************************************************/ -int Websearch::EnginesModel::rowCount(const QModelIndex &) const { - return static_cast(extension_->engines().size()); -} - - - -/** ***************************************************************************/ -int Websearch::EnginesModel::columnCount(const QModelIndex &) const { - return sectionCount; -} - - - -/** ***************************************************************************/ -QVariant Websearch::EnginesModel::headerData(int section, Qt::Orientation orientation, int role) const { - // No sanity check necessary since - if ( section < 0 || sectionCount <= section ) - return QVariant(); - - - if (orientation == Qt::Horizontal){ - switch (static_cast
(section)) { - case Section::Name:{ - switch (role) { - case Qt::DisplayRole: return "Name"; - case Qt::ToolTipRole: return "The name of the searchengine."; - default: return QVariant(); - } - - } - case Section::Trigger:{ - switch (role) { - case Qt::DisplayRole: return "Trigger"; - case Qt::ToolTipRole: return "The term that triggers this searchengine."; - default: return QVariant(); - } - - } - case Section::URL:{ - switch (role) { - case Qt::DisplayRole: return "URL"; - case Qt::ToolTipRole: return "The URL of this searchengine. %s will be replaced by your searchterm."; - default: return QVariant(); - } - - } - } - } - return QVariant(); -} - - - -/** ***************************************************************************/ -QVariant Websearch::EnginesModel::data(const QModelIndex &index, int role) const { - if ( !index.isValid() || - index.row() >= static_cast(extension_->engines().size()) || - index.column() >= sectionCount ) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - switch (static_cast
(index.column())) { - case Section::Name: - return extension_->engines()[static_cast(index.row())].name; - case Section::Trigger: - return extension_->engines()[static_cast(index.row())].trigger; - case Section::URL: - return extension_->engines()[static_cast(index.row())].url; - } - } - case Qt::DecorationRole: { - switch (static_cast
(index.column())) { - case Section::Name:{ - // Resizing request thounsands of repaints. Creating an icon for - // ever paint event is to expensive. Therefor maintain an icon cache - const QString &iconPath = extension_->engines()[static_cast(index.row())].iconPath; - std::map::iterator it = iconCache.find(iconPath); - if ( it != iconCache.end() ) - return it->second; - return iconCache.insert(std::make_pair(iconPath, QIcon(iconPath))).second; - } - case Section::URL: - case Section::Trigger: - return QVariant(); - } - } - case Qt::ToolTipRole: { - return "Double click to edit"; - } - default: - return QVariant(); - } -} - - - -/** ***************************************************************************/ -bool Websearch::EnginesModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if ( !index.isValid() || - index.row() >= static_cast(extension_->engines().size()) || - index.column() >= sectionCount) - return false; - - switch (role) { - case Qt::DisplayRole: { - if ( !value.canConvert(QMetaType::QString) ) - return false; - QString s = value.toString(); - switch (static_cast
(index.column())) { - case Section::Name: { - std::vector newEngines = extension_->engines(); - newEngines[static_cast(index.row())].name = s; - extension_->setEngines(newEngines); - dataChanged(index, index, QVector({Qt::DisplayRole})); - return true; - } - case Section::Trigger: { - std::vector newEngines = extension_->engines(); - newEngines[static_cast(index.row())].trigger = s; - extension_->setEngines(newEngines); - dataChanged(index, index, QVector({Qt::DisplayRole})); - return true; - } - case Section::URL: { - std::vector newEngines = extension_->engines(); - newEngines[static_cast(index.row())].url = s; - extension_->setEngines(newEngines); - dataChanged(index, index, QVector({Qt::DisplayRole})); - return true; - } - } - } - case Qt::DecorationRole: { - QFileInfo fileInfo(value.toString()); - - if ( !fileInfo.exists() ) - return false; - - // Remove icon from cache - iconCache.erase(extension_->engines()[static_cast(index.row())].iconPath); - - // Create extension dir if necessary - QDir dataDir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - if ( !dataDir.exists(extension_->Core::Extension::id) ) { - if ( !dataDir.mkdir(extension_->Core::Extension::id) ) { - qWarning() << "Could not create extension data dir."; - return false; - } - } - - dataDir.cd(extension_->Core::Extension::id); - - // Build the new random path - QString newFilePath = dataDir.filePath(QString("%1.%2") - .arg(QUuid::createUuid().toString()) - .arg(fileInfo.suffix())); - - // Copy the file into data dir - if ( !QFile::copy(fileInfo.filePath(), newFilePath) ) { - qWarning() << "Could not copy icon to cache."; - return false; - } - - // Remove old icon and set the copied file as icon - std::vector newEngines = extension_->engines(); - QFile::remove(newEngines[static_cast(index.row())].iconPath); - newEngines[static_cast(index.row())].iconPath = newFilePath; - extension_->setEngines(newEngines); - - // Update the icon in the first section of the row - QModelIndex firstSectionIndex = index.model()->index(index.row(), 0); - dataChanged(firstSectionIndex, firstSectionIndex, QVector({Qt::DecorationRole})); - - return true; - } - default: - return false; - } -} - - - -/** ***************************************************************************/ -Qt::ItemFlags Websearch::EnginesModel::flags(const QModelIndex &index) const { - if (index.isValid()) - return QAbstractTableModel::flags(index) | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; - else - return QAbstractTableModel::flags(index) | Qt::ItemIsDropEnabled; -} - - - -/** ***************************************************************************/ -bool Websearch::EnginesModel::insertRows(int position, int rows, const QModelIndex &) { - if ( position < 0 || rows < 1 || - static_cast(extension_->engines().size()) < position) - return false; - - beginInsertRows(QModelIndex(), position, position + rows - 1); - std::vector newEngines = extension_->engines(); - for ( int row = position; row < position + rows; ++row ) - newEngines.insert(newEngines.begin() + row, - SearchEngine({"", "", ":default", - ""})); - extension_->setEngines(newEngines); - endInsertRows(); - return true; -} - - - -/** ***************************************************************************/ -bool Websearch::EnginesModel::removeRows(int position, int rows, const QModelIndex &) { - if ( position < 0 || rows < 1 || - static_cast(extension_->engines().size()) < position + rows) - return false; - - beginRemoveRows(QModelIndex(), position, position + rows - 1); - std::vector newEngines = extension_->engines(); - newEngines.erase(newEngines.begin() + position, - newEngines.begin() + position + rows); - extension_->setEngines(newEngines); - endRemoveRows(); - return true; -} - - - -/** ***************************************************************************/ -bool Websearch::EnginesModel::moveRows(const QModelIndex &srcParent, int srcRow, int cnt, - const QModelIndex &dstParent, int dstRow) { - if ( srcRow < 0 || cnt < 1 || dstRow < 0 || - static_cast(extension_->engines().size()) < srcRow + cnt - 1 || - static_cast(extension_->engines().size()) < dstRow || - ( srcRow <= dstRow && dstRow < srcRow + cnt) ) // If its inside the source do nothing - return false; - - std::vector newEngines = extension_->engines(); - beginMoveRows(srcParent, srcRow, srcRow + cnt - 1, dstParent, dstRow); - newEngines.insert(newEngines.begin() + dstRow, - extension_->engines().begin() + srcRow, - extension_->engines().begin() + srcRow + cnt); - if ( srcRow < dstRow ) - newEngines.erase(newEngines.begin() + srcRow, - newEngines.begin() + srcRow + cnt); - else - newEngines.erase(newEngines.begin() + srcRow + cnt, - newEngines.begin() + srcRow + cnt * 2); - extension_->setEngines(newEngines); - endMoveRows(); - return true; -} - - - -/** ***************************************************************************/ -void Websearch::EnginesModel::restoreDefaults() { - beginResetModel(); - extension_->restoreDefaultEngines(); - endResetModel(); -} - - - -/** ***************************************************************************/ -Qt::DropActions Websearch::EnginesModel::supportedDropActions() const { - return Qt::MoveAction; -} - - - -/** ***************************************************************************/ -bool Websearch::EnginesModel::dropMimeData(const QMimeData *data, - Qt::DropAction /*action*/, - int dstRow, - int /*column*/, - const QModelIndex &/*parent*/) { - QByteArray encoded = data->data("application/x-qabstractitemmodeldatalist"); - QDataStream stream(&encoded, QIODevice::ReadOnly); - int srcRow = 0; - if (!stream.atEnd()) - stream >> srcRow; - moveRows(QModelIndex(), srcRow, 1, QModelIndex(), dstRow); - return false; -} diff -Nru albert-0.12.0/src/plugins/websearch/src/enginesmodel.h albert-0.13.1+plugins1/src/plugins/websearch/src/enginesmodel.h --- albert-0.12.0/src/plugins/websearch/src/enginesmodel.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/enginesmodel.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include - -namespace Websearch { - -class Extension; - -class EnginesModel final : public QAbstractTableModel -{ - Q_OBJECT - -public: - - EnginesModel(Extension *extension, QObject *parent = Q_NULLPTR); - - int rowCount(const QModelIndex & parent = QModelIndex()) const override; - int columnCount(const QModelIndex & parent = QModelIndex()) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; - Qt::ItemFlags flags(const QModelIndex & index) const override; - bool insertRows (int position, int rows, const QModelIndex & parent = QModelIndex()) override; - bool removeRows (int position, int rows, const QModelIndex & parent = QModelIndex()) override; - bool moveRows(const QModelIndex &sourceRow, int srcRow, int cnt, const QModelIndex & dst, int destinationChild) override; - Qt::DropActions supportedDropActions() const override; - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - - void restoreDefaults(); - -private: - - Extension *extension_; - -}; - -} diff -Nru albert-0.12.0/src/plugins/websearch/src/main.cpp albert-0.13.1+plugins1/src/plugins/websearch/src/main.cpp --- albert-0.12.0/src/plugins/websearch/src/main.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,455 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "configwidget.h" -#include "enginesmodel.h" -#include "item.h" -#include "main.h" -#include "standardaction.h" -#include "standarditem.h" -#include "query.h" -#include "xdgiconlookup.h" -using std::shared_ptr; -using std::vector; -using namespace Core; - - -namespace { - -// http://data.iana.org/TLD/tlds-alpha-by-domain.txt -// Version 2017032500, Last Updated Sat Mar 25 07:07:02 2017 UTC -std::array validTlds = { {"AAA", "AARP", "ABARTH", "ABB", -"ABBOTT", "ABBVIE", "ABC", "ABLE", "ABOGADO", "ABUDHABI", "AC", "ACADEMY", -"ACCENTURE", "ACCOUNTANT", "ACCOUNTANTS", "ACO", "ACTIVE", "ACTOR", "AD", -"ADAC", "ADS", "ADULT", "AE", "AEG", "AERO", "AETNA", "AF", "AFAMILYCOMPANY", -"AFL", "AFRICA", "AG", "AGAKHAN", "AGENCY", "AI", "AIG", "AIGO", "AIRBUS", -"AIRFORCE", "AIRTEL", "AKDN", "AL", "ALFAROMEO", "ALIBABA", "ALIPAY", -"ALLFINANZ", "ALLSTATE", "ALLY", "ALSACE", "ALSTOM", "AM", "AMERICANEXPRESS", -"AMERICANFAMILY", "AMEX", "AMFAM", "AMICA", "AMSTERDAM", "ANALYTICS", -"ANDROID", "ANQUAN", "ANZ", "AO", "AOL", "APARTMENTS", "APP", "APPLE", "AQ", -"AQUARELLE", "AR", "ARAMCO", "ARCHI", "ARMY", "ARPA", "ART", "ARTE", "AS", -"ASDA", "ASIA", "ASSOCIATES", "AT", "ATHLETA", "ATTORNEY", "AU", "AUCTION", -"AUDI", "AUDIBLE", "AUDIO", "AUSPOST", "AUTHOR", "AUTO", "AUTOS", "AVIANCA", -"AW", "AWS", "AX", "AXA", "AZ", "AZURE", "BA", "BABY", "BAIDU", "BANAMEX", -"BANANAREPUBLIC", "BAND", "BANK", "BAR", "BARCELONA", "BARCLAYCARD", -"BARCLAYS", "BAREFOOT", "BARGAINS", "BASEBALL", "BASKETBALL", "BAUHAUS", -"BAYERN", "BB", "BBC", "BBT", "BBVA", "BCG", "BCN", "BD", "BE", "BEATS", -"BEAUTY", "BEER", "BENTLEY", "BERLIN", "BEST", "BESTBUY", "BET", "BF", "BG", -"BH", "BHARTI", "BI", "BIBLE", "BID", "BIKE", "BING", "BINGO", "BIO", "BIZ", -"BJ", "BLACK", "BLACKFRIDAY", "BLANCO", "BLOCKBUSTER", "BLOG", "BLOOMBERG", -"BLUE", "BM", "BMS", "BMW", "BN", "BNL", "BNPPARIBAS", "BO", "BOATS", -"BOEHRINGER", "BOFA", "BOM", "BOND", "BOO", "BOOK", "BOOKING", "BOOTS", -"BOSCH", "BOSTIK", "BOSTON", "BOT", "BOUTIQUE", "BOX", "BR", "BRADESCO", -"BRIDGESTONE", "BROADWAY", "BROKER", "BROTHER", "BRUSSELS", "BS", "BT", -"BUDAPEST", "BUGATTI", "BUILD", "BUILDERS", "BUSINESS", "BUY", "BUZZ", "BV", -"BW", "BY", "BZ", "BZH", "CA", "CAB", "CAFE", "CAL", "CALL", "CALVINKLEIN", -"CAM", "CAMERA", "CAMP", "CANCERRESEARCH", "CANON", "CAPETOWN", "CAPITAL", -"CAPITALONE", "CAR", "CARAVAN", "CARDS", "CARE", "CAREER", "CAREERS", "CARS", -"CARTIER", "CASA", "CASE", "CASEIH", "CASH", "CASINO", "CAT", "CATERING", -"CATHOLIC", "CBA", "CBN", "CBRE", "CBS", "CC", "CD", "CEB", "CENTER", "CEO", -"CERN", "CF", "CFA", "CFD", "CG", "CH", "CHANEL", "CHANNEL", "CHASE", "CHAT", -"CHEAP", "CHINTAI", "CHLOE", "CHRISTMAS", "CHROME", "CHRYSLER", "CHURCH", "CI", -"CIPRIANI", "CIRCLE", "CISCO", "CITADEL", "CITI", "CITIC", "CITY", "CITYEATS", -"CK", "CL", "CLAIMS", "CLEANING", "CLICK", "CLINIC", "CLINIQUE", "CLOTHING", -"CLOUD", "CLUB", "CLUBMED", "CM", "CN", "CO", "COACH", "CODES", "COFFEE", -"COLLEGE", "COLOGNE", "COM", "COMCAST", "COMMBANK", "COMMUNITY", "COMPANY", -"COMPARE", "COMPUTER", "COMSEC", "CONDOS", "CONSTRUCTION", "CONSULTING", -"CONTACT", "CONTRACTORS", "COOKING", "COOKINGCHANNEL", "COOL", "COOP", -"CORSICA", "COUNTRY", "COUPON", "COUPONS", "COURSES", "CR", "CREDIT", -"CREDITCARD", "CREDITUNION", "CRICKET", "CROWN", "CRS", "CRUISE", "CRUISES", -"CSC", "CU", "CUISINELLA", "CV", "CW", "CX", "CY", "CYMRU", "CYOU", "CZ", -"DABUR", "DAD", "DANCE", "DATA", "DATE", "DATING", "DATSUN", "DAY", "DCLK", -"DDS", "DE", "DEAL", "DEALER", "DEALS", "DEGREE", "DELIVERY", "DELL", -"DELOITTE", "DELTA", "DEMOCRAT", "DENTAL", "DENTIST", "DESI", "DESIGN", "DEV", -"DHL", "DIAMONDS", "DIET", "DIGITAL", "DIRECT", "DIRECTORY", "DISCOUNT", -"DISCOVER", "DISH", "DIY", "DJ", "DK", "DM", "DNP", "DO", "DOCS", "DOCTOR", -"DODGE", "DOG", "DOHA", "DOMAINS", "DOT", "DOWNLOAD", "DRIVE", "DTV", "DUBAI", -"DUCK", "DUNLOP", "DUNS", "DUPONT", "DURBAN", "DVAG", "DVR", "DZ", "EARTH", -"EAT", "EC", "ECO", "EDEKA", "EDU", "EDUCATION", "EE", "EG", "EMAIL", "EMERCK", -"ENERGY", "ENGINEER", "ENGINEERING", "ENTERPRISES", "EPOST", "EPSON", -"EQUIPMENT", "ER", "ERICSSON", "ERNI", "ES", "ESQ", "ESTATE", "ESURANCE", "ET", -"EU", "EUROVISION", "EUS", "EVENTS", "EVERBANK", "EXCHANGE", "EXPERT", -"EXPOSED", "EXPRESS", "EXTRASPACE", "FAGE", "FAIL", "FAIRWINDS", "FAITH", -"FAMILY", "FAN", "FANS", "FARM", "FARMERS", "FASHION", "FAST", "FEDEX", -"FEEDBACK", "FERRARI", "FERRERO", "FI", "FIAT", "FIDELITY", "FIDO", "FILM", -"FINAL", "FINANCE", "FINANCIAL", "FIRE", "FIRESTONE", "FIRMDALE", "FISH", -"FISHING", "FIT", "FITNESS", "FJ", "FK", "FLICKR", "FLIGHTS", "FLIR", -"FLORIST", "FLOWERS", "FLY", "FM", "FO", "FOO", "FOOD", "FOODNETWORK", -"FOOTBALL", "FORD", "FOREX", "FORSALE", "FORUM", "FOUNDATION", "FOX", "FR", -"FREE", "FRESENIUS", "FRL", "FROGANS", "FRONTDOOR", "FRONTIER", "FTR", -"FUJITSU", "FUJIXEROX", "FUN", "FUND", "FURNITURE", "FUTBOL", "FYI", "GA", -"GAL", "GALLERY", "GALLO", "GALLUP", "GAME", "GAMES", "GAP", "GARDEN", "GB", -"GBIZ", "GD", "GDN", "GE", "GEA", "GENT", "GENTING", "GEORGE", "GF", "GG", -"GGEE", "GH", "GI", "GIFT", "GIFTS", "GIVES", "GIVING", "GL", "GLADE", "GLASS", -"GLE", "GLOBAL", "GLOBO", "GM", "GMAIL", "GMBH", "GMO", "GMX", "GN", "GODADDY", -"GOLD", "GOLDPOINT", "GOLF", "GOO", "GOODHANDS", "GOODYEAR", "GOOG", "GOOGLE", -"GOP", "GOT", "GOV", "GP", "GQ", "GR", "GRAINGER", "GRAPHICS", "GRATIS", -"GREEN", "GRIPE", "GROUP", "GS", "GT", "GU", "GUARDIAN", "GUCCI", "GUGE", -"GUIDE", "GUITARS", "GURU", "GW", "GY", "HAIR", "HAMBURG", "HANGOUT", "HAUS", -"HBO", "HDFC", "HDFCBANK", "HEALTH", "HEALTHCARE", "HELP", "HELSINKI", "HERE", -"HERMES", "HGTV", "HIPHOP", "HISAMITSU", "HITACHI", "HIV", "HK", "HKT", "HM", -"HN", "HOCKEY", "HOLDINGS", "HOLIDAY", "HOMEDEPOT", "HOMEGOODS", "HOMES", -"HOMESENSE", "HONDA", "HONEYWELL", "HORSE", "HOSPITAL", "HOST", "HOSTING", -"HOT", "HOTELES", "HOTMAIL", "HOUSE", "HOW", "HR", "HSBC", "HT", "HTC", "HU", -"HUGHES", "HYATT", "HYUNDAI", "IBM", "ICBC", "ICE", "ICU", "ID", "IE", "IEEE", -"IFM", "IKANO", "IL", "IM", "IMAMAT", "IMDB", "IMMO", "IMMOBILIEN", "IN", -"INDUSTRIES", "INFINITI", "INFO", "ING", "INK", "INSTITUTE", "INSURANCE", -"INSURE", "INT", "INTEL", "INTERNATIONAL", "INTUIT", "INVESTMENTS", "IO", -"IPIRANGA", "IQ", "IR", "IRISH", "IS", "ISELECT", "ISMAILI", "IST", "ISTANBUL", -"IT", "ITAU", "ITV", "IVECO", "IWC", "JAGUAR", "JAVA", "JCB", "JCP", "JE", -"JEEP", "JETZT", "JEWELRY", "JIO", "JLC", "JLL", "JM", "JMP", "JNJ", "JO", -"JOBS", "JOBURG", "JOT", "JOY", "JP", "JPMORGAN", "JPRS", "JUEGOS", "JUNIPER", -"KAUFEN", "KDDI", "KE", "KERRYHOTELS", "KERRYLOGISTICS", "KERRYPROPERTIES", -"KFH", "KG", "KH", "KI", "KIA", "KIM", "KINDER", "KINDLE", "KITCHEN", "KIWI", -"KM", "KN", "KOELN", "KOMATSU", "KOSHER", "KP", "KPMG", "KPN", "KR", "KRD", -"KRED", "KUOKGROUP", "KW", "KY", "KYOTO", "KZ", "LA", "LACAIXA", "LADBROKES", -"LAMBORGHINI", "LAMER", "LANCASTER", "LANCIA", "LANCOME", "LAND", "LANDROVER", -"LANXESS", "LASALLE", "LAT", "LATINO", "LATROBE", "LAW", "LAWYER", "LB", "LC", -"LDS", "LEASE", "LECLERC", "LEFRAK", "LEGAL", "LEGO", "LEXUS", "LGBT", "LI", -"LIAISON", "LIDL", "LIFE", "LIFEINSURANCE", "LIFESTYLE", "LIGHTING", "LIKE", -"LILLY", "LIMITED", "LIMO", "LINCOLN", "LINDE", "LINK", "LIPSY", "LIVE", -"LIVING", "LIXIL", "LK", "LOAN", "LOANS", "LOCKER", "LOCUS", "LOFT", "LOL", -"LONDON", "LOTTE", "LOTTO", "LOVE", "LPL", "LPLFINANCIAL", "LR", "LS", "LT", -"LTD", "LTDA", "LU", "LUNDBECK", "LUPIN", "LUXE", "LUXURY", "LV", "LY", "MA", -"MACYS", "MADRID", "MAIF", "MAISON", "MAKEUP", "MAN", "MANAGEMENT", "MANGO", -"MARKET", "MARKETING", "MARKETS", "MARRIOTT", "MARSHALLS", "MASERATI", -"MATTEL", "MBA", "MC", "MCD", "MCDONALDS", "MCKINSEY", "MD", "ME", "MED", -"MEDIA", "MEET", "MELBOURNE", "MEME", "MEMORIAL", "MEN", "MENU", "MEO", -"METLIFE", "MG", "MH", "MIAMI", "MICROSOFT", "MIL", "MINI", "MINT", "MIT", -"MITSUBISHI", "MK", "ML", "MLB", "MLS", "MM", "MMA", "MN", "MO", "MOBI", -"MOBILE", "MOBILY", "MODA", "MOE", "MOI", "MOM", "MONASH", "MONEY", "MONSTER", -"MONTBLANC", "MOPAR", "MORMON", "MORTGAGE", "MOSCOW", "MOTO", "MOTORCYCLES", -"MOV", "MOVIE", "MOVISTAR", "MP", "MQ", "MR", "MS", "MSD", "MT", "MTN", "MTPC", -"MTR", "MU", "MUSEUM", "MUTUAL", "MV", "MW", "MX", "MY", "MZ", "NA", "NAB", -"NADEX", "NAGOYA", "NAME", "NATIONWIDE", "NATURA", "NAVY", "NBA", "NC", "NE", -"NEC", "NET", "NETBANK", "NETFLIX", "NETWORK", "NEUSTAR", "NEW", "NEWHOLLAND", -"NEWS", "NEXT", "NEXTDIRECT", "NEXUS", "NF", "NFL", "NG", "NGO", "NHK", "NI", -"NICO", "NIKE", "NIKON", "NINJA", "NISSAN", "NISSAY", "NL", "NO", "NOKIA", -"NORTHWESTERNMUTUAL", "NORTON", "NOW", "NOWRUZ", "NOWTV", "NP", "NR", "NRA", -"NRW", "NTT", "NU", "NYC", "NZ", "OBI", "OBSERVER", "OFF", "OFFICE", "OKINAWA", -"OLAYAN", "OLAYANGROUP", "OLDNAVY", "OLLO", "OM", "OMEGA", "ONE", "ONG", "ONL", -"ONLINE", "ONYOURSIDE", "OOO", "OPEN", "ORACLE", "ORANGE", "ORG", "ORGANIC", -"ORIENTEXPRESS", "ORIGINS", "OSAKA", "OTSUKA", "OTT", "OVH", "PA", "PAGE", -"PAMPEREDCHEF", "PANASONIC", "PANERAI", "PARIS", "PARS", "PARTNERS", "PARTS", -"PARTY", "PASSAGENS", "PAY", "PCCW", "PE", "PET", "PF", "PFIZER", "PG", "PH", -"PHARMACY", "PHILIPS", "PHONE", "PHOTO", "PHOTOGRAPHY", "PHOTOS", "PHYSIO", -"PIAGET", "PICS", "PICTET", "PICTURES", "PID", "PIN", "PING", "PINK", -"PIONEER", "PIZZA", "PK", "PL", "PLACE", "PLAY", "PLAYSTATION", "PLUMBING", -"PLUS", "PM", "PN", "PNC", "POHL", "POKER", "POLITIE", "PORN", "POST", "PR", -"PRAMERICA", "PRAXI", "PRESS", "PRIME", "PRO", "PROD", "PRODUCTIONS", "PROF", -"PROGRESSIVE", "PROMO", "PROPERTIES", "PROPERTY", "PROTECTION", "PRU", -"PRUDENTIAL", "PS", "PT", "PUB", "PW", "PWC", "PY", "QA", "QPON", "QUEBEC", -"QUEST", "QVC", "RACING", "RADIO", "RAID", "RE", "READ", "REALESTATE", -"REALTOR", "REALTY", "RECIPES", "RED", "REDSTONE", "REDUMBRELLA", "REHAB", -"REISE", "REISEN", "REIT", "RELIANCE", "REN", "RENT", "RENTALS", "REPAIR", -"REPORT", "REPUBLICAN", "REST", "RESTAURANT", "REVIEW", "REVIEWS", "REXROTH", -"RICH", "RICHARDLI", "RICOH", "RIGHTATHOME", "RIL", "RIO", "RIP", "RMIT", "RO", -"ROCHER", "ROCKS", "RODEO", "ROGERS", "ROOM", "RS", "RSVP", "RU", "RUHR", -"RUN", "RW", "RWE", "RYUKYU", "SA", "SAARLAND", "SAFE", "SAFETY", "SAKURA", -"SALE", "SALON", "SAMSCLUB", "SAMSUNG", "SANDVIK", "SANDVIKCOROMANT", "SANOFI", -"SAP", "SAPO", "SARL", "SAS", "SAVE", "SAXO", "SB", "SBI", "SBS", "SC", "SCA", -"SCB", "SCHAEFFLER", "SCHMIDT", "SCHOLARSHIPS", "SCHOOL", "SCHULE", "SCHWARZ", -"SCIENCE", "SCJOHNSON", "SCOR", "SCOT", "SD", "SE", "SEAT", "SECURE", -"SECURITY", "SEEK", "SELECT", "SENER", "SERVICES", "SES", "SEVEN", "SEW", -"SEX", "SEXY", "SFR", "SG", "SH", "SHANGRILA", "SHARP", "SHAW", "SHELL", -"SHIA", "SHIKSHA", "SHOES", "SHOP", "SHOPPING", "SHOUJI", "SHOW", "SHOWTIME", -"SHRIRAM", "SI", "SILK", "SINA", "SINGLES", "SITE", "SJ", "SK", "SKI", "SKIN", -"SKY", "SKYPE", "SL", "SLING", "SM", "SMART", "SMILE", "SN", "SNCF", "SO", -"SOCCER", "SOCIAL", "SOFTBANK", "SOFTWARE", "SOHU", "SOLAR", "SOLUTIONS", -"SONG", "SONY", "SOY", "SPACE", "SPIEGEL", "SPOT", "SPREADBETTING", "SR", -"SRL", "SRT", "ST", "STADA", "STAPLES", "STAR", "STARHUB", "STATEBANK", -"STATEFARM", "STATOIL", "STC", "STCGROUP", "STOCKHOLM", "STORAGE", "STORE", -"STREAM", "STUDIO", "STUDY", "STYLE", "SU", "SUCKS", "SUPPLIES", "SUPPLY", -"SUPPORT", "SURF", "SURGERY", "SUZUKI", "SV", "SWATCH", "SWIFTCOVER", "SWISS", -"SX", "SY", "SYDNEY", "SYMANTEC", "SYSTEMS", "SZ", "TAB", "TAIPEI", "TALK", -"TAOBAO", "TARGET", "TATAMOTORS", "TATAR", "TATTOO", "TAX", "TAXI", "TC", -"TCI", "TD", "TDK", "TEAM", "TECH", "TECHNOLOGY", "TEL", "TELECITY", -"TELEFONICA", "TEMASEK", "TENNIS", "TEVA", "TF", "TG", "TH", "THD", "THEATER", -"THEATRE", "TIAA", "TICKETS", "TIENDA", "TIFFANY", "TIPS", "TIRES", "TIROL", -"TJ", "TJMAXX", "TJX", "TK", "TKMAXX", "TL", "TM", "TMALL", "TN", "TO", -"TODAY", "TOKYO", "TOOLS", "TOP", "TORAY", "TOSHIBA", "TOTAL", "TOURS", "TOWN", -"TOYOTA", "TOYS", "TR", "TRADE", "TRADING", "TRAINING", "TRAVEL", -"TRAVELCHANNEL", "TRAVELERS", "TRAVELERSINSURANCE", "TRUST", "TRV", "TT", -"TUBE", "TUI", "TUNES", "TUSHU", "TV", "TVS", "TW", "TZ", "UA", "UBANK", "UBS", -"UCONNECT", "UG", "UK", "UNICOM", "UNIVERSITY", "UNO", "UOL", "UPS", "US", -"UY", "UZ", "VA", "VACATIONS", "VANA", "VANGUARD", "VC", "VE", "VEGAS", -"VENTURES", "VERISIGN", "VERSICHERUNG", "VET", "VG", "VI", "VIAJES", "VIDEO", -"VIG", "VIKING", "VILLAS", "VIN", "VIP", "VIRGIN", "VISA", "VISION", "VISTA", -"VISTAPRINT", "VIVA", "VIVO", "VLAANDEREN", "VN", "VODKA", "VOLKSWAGEN", -"VOLVO", "VOTE", "VOTING", "VOTO", "VOYAGE", "VU", "VUELOS", "WALES", -"WALMART", "WALTER", "WANG", "WANGGOU", "WARMAN", "WATCH", "WATCHES", -"WEATHER", "WEATHERCHANNEL", "WEBCAM", "WEBER", "WEBSITE", "WED", "WEDDING", -"WEIBO", "WEIR", "WF", "WHOSWHO", "WIEN", "WIKI", "WILLIAMHILL", "WIN", -"WINDOWS", "WINE", "WINNERS", "WME", "WOLTERSKLUWER", "WOODSIDE", "WORK", -"WORKS", "WORLD", "WOW", "WS", "WTC", "WTF", "XBOX", "XEROX", "XFINITY", -"XIHUAN", "XIN", "XN--11B4C3D", "XN--1CK2E1B", "XN--1QQW23A", "XN--30RR7Y", -"XN--3BST00M", "XN--3DS443G", "XN--3E0B707E", "XN--3OQ18VL8PN36A", -"XN--3PXU8K", "XN--42C2D9A", "XN--45BRJ9C", "XN--45Q11C", "XN--4GBRIM", -"XN--54B7FTA0CC", "XN--55QW42G", "XN--55QX5D", "XN--5SU34J936BGSG", -"XN--5TZM5G", "XN--6FRZ82G", "XN--6QQ986B3XL", "XN--80ADXHKS", "XN--80AO21A", -"XN--80AQECDR1A", "XN--80ASEHDB", "XN--80ASWG", "XN--8Y0A063A", "XN--90A3AC", -"XN--90AE", "XN--90AIS", "XN--9DBQ2A", "XN--9ET52U", "XN--9KRT00A", -"XN--B4W605FERD", "XN--BCK1B9A5DRE4C", "XN--C1AVG", "XN--C2BR7G", -"XN--CCK2B3B", "XN--CG4BKI", "XN--CLCHC0EA0B2G2A9GCD", "XN--CZR694B", -"XN--CZRS0T", "XN--CZRU2D", "XN--D1ACJ3B", "XN--D1ALF", "XN--E1A4C", -"XN--ECKVDTC9D", "XN--EFVY88H", "XN--ESTV75G", "XN--FCT429K", "XN--FHBEI", -"XN--FIQ228C5HS", "XN--FIQ64B", "XN--FIQS8S", "XN--FIQZ9S", "XN--FJQ720A", -"XN--FLW351E", "XN--FPCRJ9C3D", "XN--FZC2C9E2C", "XN--FZYS8D69UVGM", -"XN--G2XX48C", "XN--GCKR3F0F", "XN--GECRJ9C", "XN--GK3AT1E", "XN--H2BRJ9C", -"XN--HXT814E", "XN--I1B6B1A6A2E", "XN--IMR513N", "XN--IO0A7I", "XN--J1AEF", -"XN--J1AMH", "XN--J6W193G", "XN--JLQ61U9W7B", "XN--JVR189M", "XN--KCRX77D1X4A", -"XN--KPRW13D", "XN--KPRY57D", "XN--KPU716F", "XN--KPUT3I", "XN--L1ACC", -"XN--LGBBAT1AD8J", "XN--MGB9AWBF", "XN--MGBA3A3EJT", "XN--MGBA3A4F16A", -"XN--MGBA7C0BBN0A", "XN--MGBAAM7A8H", "XN--MGBAB2BD", "XN--MGBAI9AZGQP6J", -"XN--MGBAYH7GPA", "XN--MGBB9FBPOB", "XN--MGBBH1A71E", "XN--MGBC0A9AZCG", -"XN--MGBCA7DZDO", "XN--MGBERP4A5D4AR", "XN--MGBI4ECEXP", "XN--MGBPL2FH", -"XN--MGBT3DHD", "XN--MGBTX2B", "XN--MGBX4CD0AB", "XN--MIX891F", "XN--MK1BU44C", -"XN--MXTQ1M", "XN--NGBC5AZD", "XN--NGBE9E0A", "XN--NODE", "XN--NQV7F", -"XN--NQV7FS00EMA", "XN--NYQY26A", "XN--O3CW4H", "XN--OGBPF8FL", "XN--P1ACF", -"XN--P1AI", "XN--PBT977C", "XN--PGBS0DH", "XN--PSSY2U", "XN--Q9JYB4C", -"XN--QCKA1PMC", "XN--QXAM", "XN--RHQV96G", "XN--ROVU88B", "XN--S9BRJ9C", -"XN--SES554G", "XN--T60B56A", "XN--TCKWE", "XN--TIQ49XQYJ", "XN--UNUP4Y", -"XN--VERMGENSBERATER-CTB", "XN--VERMGENSBERATUNG-PWB", "XN--VHQUV", -"XN--VUQ861B", "XN--W4R85EL8FHU5DNRA", "XN--W4RS40L", "XN--WGBH1C", -"XN--WGBL6A", "XN--XHQ521B", "XN--XKC2AL3HYE2A", "XN--XKC2DL3A5EE0H", -"XN--Y9A3AQ", "XN--YFRO4I67O", "XN--YGBI2AMMX", "XN--ZFR164B", "XPERIA", "XXX", -"XYZ", "YACHTS", "YAHOO", "YAMAXUN", "YANDEX", "YE", "YODOBASHI", "YOGA", -"YOKOHAMA", "YOU", "YOUTUBE", "YT", "YUN", "ZA", "ZAPPOS", "ZARA", "ZERO", -"ZIP", "ZIPPO", "ZM", "ZONE", "ZUERICH", "ZW"} -}; - -std::vector defaultSearchEngines = { - {"Google", "gg ", ":google", "https://www.google.com/search?q=%s"}, - {"Youtube", "yt ", ":youtube", "https://www.youtube.com/results?search_query=%s"}, - {"Amazon", "ama ", ":amazon", "http://www.amazon.com/s/?field-keywords=%s"}, - {"Ebay", "eb ", ":ebay", "http://www.ebay.com/sch/i.html?_nkw=%s"}, - {"GitHub", "gh ", ":github", "https://github.com/search?utf8=✓&q=%s"}, - {"Wikipedia", "wiki ",":wikipedia", "https://en.wikipedia.org/w/index.php?search=%s"}, - {"Wolfram Alpha", "=", ":wolfram", "https://www.wolframalpha.com/input/?i=%s"} -}; - -shared_ptr buildWebsearchItem(const Websearch::SearchEngine &se, const QString &searchterm) { - - QString urlString = QString(se.url).replace("%s", QUrl::toPercentEncoding(searchterm)); - QUrl url = QUrl(urlString); - QString desc = QString("Start %1 search in your browser").arg(se.name); - - std::shared_ptr action = std::make_shared(); - action->setText(desc); - action->setAction([=](){ QDesktopServices::openUrl(url); }); - - std::shared_ptr item = std::make_shared(se.name); - item->setText(se.name); - item->setSubtext(desc); - item->setIconPath(se.iconPath); - item->setCompletionString(QString("%1%2").arg(se.trigger, searchterm)); - - item->setActions({action}); - - return item; -} -} - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -struct Websearch::Internal -{ - QPointer widget; - std::vector searchEngines; -}; - - - -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -/** ***************************************************************************/ -Websearch::Extension::Extension() - : Core::Extension("org.albert.extension.websearch"), - Core::QueryHandler(Core::Extension::id), - d(new Internal) { - - std::sort(validTlds.begin(), validTlds.end()); - - // Move config file from old location to new. (data -> config) TODO: REMOVE in 1.0 - QString dataLocFilePath = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)) - .filePath(QString("%1.json").arg(Core::Extension::id)); - QString confLocFilePath = QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)) - .filePath(QString("%1.json").arg(Core::Extension::id)); - - if ( QFile::exists(dataLocFilePath) ) - QFile::rename(dataLocFilePath, confLocFilePath); - - // Deserialize engines - QFile file(confLocFilePath); - if (file.open(QIODevice::ReadOnly)) { - QJsonArray array = QJsonDocument::fromJson(file.readAll()).array(); - SearchEngine searchEngine; - for ( const QJsonValue& value : array) { - QJsonObject object = value.toObject(); - searchEngine.name = object["name"].toString(); - searchEngine.trigger = object["trigger"].toString(); - searchEngine.iconPath = object["iconPath"].toString(); - searchEngine.url = object["url"].toString(); - d->searchEngines.push_back(searchEngine); - } - } else { - qWarning() << qPrintable(QString("Could not load from file: '%1'.").arg(confLocFilePath)); - setEngines(defaultSearchEngines); - } -} - - - -/** ***************************************************************************/ -Websearch::Extension::~Extension() { - -} - - - -/** ***************************************************************************/ -QWidget *Websearch::Extension::widget(QWidget *parent) { - if (d->widget.isNull()) - d->widget = new ConfigWidget(this, parent); - return d->widget; -} - - - -/** ***************************************************************************/ -QStringList Websearch::Extension::triggers() const { - QStringList triggers; - for ( const SearchEngine& se : d->searchEngines ) - triggers.push_back(se.trigger); - return triggers; -} - - - -/** ***************************************************************************/ -void Websearch::Extension::handleQuery(Core::Query * query) { - - if ( query->isTriggered() ) { - for (const SearchEngine &se : d->searchEngines) - if (query->searchTerm().startsWith(se.trigger)) - query->addMatch(buildWebsearchItem(se, query->searchTerm().mid(se.trigger.size())), SHRT_MAX); - } - else - { - QUrl url = QUrl::fromUserInput(query->searchTerm()); - - // Check syntax and TLD validity - if ( url.isValid() && ( // Check syntax - query->searchTerm().trimmed().startsWith("http://") || - query->searchTerm().trimmed().startsWith("https://") || - (QRegularExpression(R"R(\S+\.\S+$)R").match(url.host()).hasMatch() && // Check if not an emty tld - std::binary_search(validTlds.begin(), validTlds.end(), // Check tld validiy - url.topLevelDomain().mid(1).toUpper().toLocal8Bit().constData()) ))) { - - shared_ptr action = std::make_shared(); - action->setText("Open URL"); - action->setAction([url](){ - QDesktopServices::openUrl(url); - }); - - std::shared_ptr item = std::make_shared("valid_url"); - item->setText(QString("Open url in browser")); - item->setSubtext(QString("Visit %1").arg(url.authority())); - item->setCompletionString(query->searchTerm()); - QString icon = XdgIconLookup::iconPath("www"); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("web-browser"); - if (icon.isEmpty()) - icon = XdgIconLookup::iconPath("emblem-web"); - if (icon.isEmpty()) - icon = ":favicon"; - item->setIconPath(icon); - item->setActions({action}); - - query->addMatch(item, SHRT_MAX); - } - } -} - - - -/** ***************************************************************************/ -vector> Websearch::Extension::fallbacks(const QString & searchterm) { - vector> res; - for (const SearchEngine &se : d->searchEngines) - res.push_back(buildWebsearchItem(se, searchterm)); - return res; -} - - - -/** ***************************************************************************/ -const std::vector &Websearch::Extension::engines() const { - return d->searchEngines; -} - - - -/** ***************************************************************************/ -void Websearch::Extension::setEngines(const std::vector &engines) { - d->searchEngines = engines; - emit enginesChanged(d->searchEngines); - - // Serialize the engines - QFile file(QDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)) - .filePath(QString("%1.json").arg(Core::Extension::id))); - - if (file.open(QIODevice::WriteOnly)) { - QJsonArray array; - for ( const SearchEngine& searchEngine : d->searchEngines ) { - QJsonObject object; - object["name"] = searchEngine.name; - object["url"] = searchEngine.url; - object["trigger"] = searchEngine.trigger; - object["iconPath"] = searchEngine.iconPath; - array.append(object); - } - file.write(QJsonDocument(array).toJson()); - } else - qCritical() << qPrintable(QString("Could not write to file: '%1'.").arg(file.fileName())); -} - - - -/** ***************************************************************************/ -void Websearch::Extension::restoreDefaultEngines() { - setEngines(defaultSearchEngines); -} diff -Nru albert-0.12.0/src/plugins/websearch/src/main.h albert-0.13.1+plugins1/src/plugins/websearch/src/main.h --- albert-0.12.0/src/plugins/websearch/src/main.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/main.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "extension.h" -#include "queryhandler.h" -#include "fallbackprovider.h" -#include "searchengine.h" - -namespace Websearch { - -struct Internal; -class ConfigWidget; - -class Extension final : - public QObject, - public Core::Extension, - public Core::QueryHandler, - public Core::FallbackProvider -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID ALBERT_EXTENSION_IID FILE "metadata.json") - -public: - - Extension(); - ~Extension(); - - QString name() const override { return "Websearch"; } - QWidget *widget(QWidget *parent = nullptr) override; - QStringList triggers() const override; - void handleQuery(Core::Query * query) override; - std::vector> fallbacks(const QString &) override; - - const std::vector& engines() const; - void setEngines(const std::vector &engines); - - void restoreDefaultEngines(); - -private: - - std::unique_ptr d; - -signals: - - void enginesChanged(const std::vector &engines); - -}; - -} diff -Nru albert-0.12.0/src/plugins/websearch/src/searchengineeditor.cpp albert-0.13.1+plugins1/src/plugins/websearch/src/searchengineeditor.cpp --- albert-0.12.0/src/plugins/websearch/src/searchengineeditor.cpp 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/searchengineeditor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include -#include -#include "searchengineeditor.h" - - - -/** ***************************************************************************/ -Websearch::SearchEngineEditor::SearchEngineEditor(const SearchEngine &searchEngine, QWidget *parent) - : QDialog(parent), searchEngine_(searchEngine) { - - ui.setupUi(this); - setWindowModality(Qt::WindowModal); - - ui.lineEdit_name->setText(searchEngine.name); - ui.lineEdit_trigger->setText(searchEngine.trigger); - ui.lineEdit_url->setText(searchEngine.url); - ui.toolButton_icon->setIcon(QIcon(searchEngine.iconPath)); - - connect(ui.lineEdit_name, &QLineEdit::textChanged, - [this](const QString & text){ searchEngine_.name = text; }); - - connect(ui.lineEdit_trigger, &QLineEdit::textChanged, - [this](const QString & text){ searchEngine_.trigger = text; }); - - connect(ui.lineEdit_url, &QLineEdit::textChanged, - [this](const QString & text){ searchEngine_.url = text; }); - - connect(ui.toolButton_icon, &QToolButton::clicked, - [this](){ - - QString fileName = - QFileDialog::getOpenFileName( - this, - tr("Choose icon"), - QStandardPaths::writableLocation(QStandardPaths::HomeLocation), - tr("Images (*.png *.svg)")); - - if(fileName.isEmpty()) - return; - - searchEngine_.iconPath = fileName; - ui.toolButton_icon->setIcon(QIcon(fileName)); - }); - -} diff -Nru albert-0.12.0/src/plugins/websearch/src/searchengineeditor.h albert-0.13.1+plugins1/src/plugins/websearch/src/searchengineeditor.h --- albert-0.12.0/src/plugins/websearch/src/searchengineeditor.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/searchengineeditor.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include -#include "ui_searchengineeditor.h" -#include "searchengine.h" - -namespace Websearch { - -class SearchEngineEditor : public QDialog -{ - Q_OBJECT - -public: - - explicit SearchEngineEditor(const SearchEngine &searchEngine, QWidget *parent = 0); - const SearchEngine &searchEngine() { return searchEngine_; } - -private: - - SearchEngine searchEngine_; - Ui::SearchEngineEditor ui; - -}; - -} diff -Nru albert-0.12.0/src/plugins/websearch/src/searchengine.h albert-0.13.1+plugins1/src/plugins/websearch/src/searchengine.h --- albert-0.12.0/src/plugins/websearch/src/searchengine.h 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/src/searchengine.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -// albert - a simple application launcher for linux -// Copyright (C) 2014-2017 Manuel Schneider -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#pragma once -#include - -namespace Websearch { - -class SearchEngine { -public: - QString name; - QString trigger; - QString iconPath; - QString url; -}; - -} diff -Nru albert-0.12.0/src/plugins/websearch/websearch.qrc albert-0.13.1+plugins1/src/plugins/websearch/websearch.qrc --- albert-0.12.0/src/plugins/websearch/websearch.qrc 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/src/plugins/websearch/websearch.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ - - - resources/amazon.svg - resources/default.svg - resources/ebay.svg - resources/google.svg - resources/youtube.svg - resources/octocat.svg - resources/wikipedia.svg - resources/wolfram.png - - diff -Nru albert-0.12.0/.travis.yml albert-0.13.1+plugins1/.travis.yml --- albert-0.12.0/.travis.yml 2017-06-09 16:29:43.000000000 +0000 +++ albert-0.13.1+plugins1/.travis.yml 2017-09-30 09:43:39.000000000 +0000 @@ -1,14 +1,44 @@ language: cpp sudo: required dist: trusty -compiler: - - clang - - gcc + +matrix: + include: + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-5 + env: + - MATRIX_EVAL="CC=gcc-5 && CXX=g++-5" + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.6 + packages: + - clang-3.6 + env: + - MATRIX_EVAL="CC=clang-3.6 && CXX=clang++-3.6" + +git: + submodules: false + +before_install: + - eval "${MATRIX_EVAL}" + - sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules + - git submodule update --init --recursive install: - sudo add-apt-repository ppa:beineri/opt-qt551-trusty -y # Qt-5.5 - sudo apt-get update -qq - - sudo apt-get install -qq cmake qt55base qt55x11extras qt55svg libmuparser-dev + - sudo apt-get install -qq cmake qt55base qt55x11extras qt55svg qt55quickcontrols libmuparser-dev virtualbox + - wget http://download.virtualbox.org/virtualbox/5.0.40/VirtualBoxSDK-5.0.40-115130.zip + - unzip VirtualBoxSDK-5.0.40-115130.zip + - sudo mv sdk/bindings/xpcom/include /usr/lib/virtualbox/sdk/bindings/xpcom script: - source /opt/qt55/bin/qt55-env.sh