qcanvas 1.0.12.dev3__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qcanvas/app_start/__init__.py +6 -1
- qcanvas/icons/__init__.py +55 -6
- qcanvas/icons/_icon_type.py +42 -0
- qcanvas/icons/_update_icons.py +89 -0
- qcanvas/icons/dark/actions/exit.svg +3 -0
- qcanvas/icons/dark/actions/mark_all_read.svg +3 -0
- qcanvas/icons/dark/actions/open_downloads.svg +3 -0
- qcanvas/icons/dark/actions/quick_login.svg +3 -0
- qcanvas/icons/dark/actions/sync.svg +3 -0
- qcanvas/icons/dark/branding/logo_transparent.svg +303 -0
- qcanvas/icons/dark/options/auto_download.svg +3 -0
- qcanvas/icons/dark/options/theme.svg +3 -0
- qcanvas/icons/dark/tabs/assignments.svg +3 -0
- qcanvas/icons/dark/tabs/mail.svg +3 -0
- qcanvas/icons/dark/tabs/pages.svg +3 -0
- qcanvas/icons/dark/tree_items/assignment.svg +3 -0
- qcanvas/icons/dark/tree_items/mail.svg +3 -0
- qcanvas/icons/dark/tree_items/module.svg +3 -0
- qcanvas/icons/dark/tree_items/page.svg +3 -0
- qcanvas/icons/icons.qrc +44 -8
- qcanvas/icons/light/actions/exit.svg +3 -0
- qcanvas/icons/light/actions/mark_all_read.svg +3 -0
- qcanvas/icons/light/actions/open_downloads.svg +3 -0
- qcanvas/icons/light/actions/quick_login.svg +3 -0
- qcanvas/icons/light/actions/sync.svg +3 -0
- qcanvas/icons/light/branding/logo_transparent.svg +304 -0
- qcanvas/icons/light/options/auto_download.svg +3 -0
- qcanvas/icons/light/options/ignore_old.svg +3 -0
- qcanvas/icons/light/options/include_videos.svg +3 -0
- qcanvas/icons/light/options/theme.svg +3 -0
- qcanvas/icons/light/tabs/assignments.svg +3 -0
- qcanvas/icons/light/tabs/mail.svg +3 -0
- qcanvas/icons/light/tabs/pages.svg +3 -0
- qcanvas/icons/light/tree_items/assignment.svg +3 -0
- qcanvas/icons/light/tree_items/mail.svg +3 -0
- qcanvas/icons/light/tree_items/module.svg +3 -0
- qcanvas/icons/light/tree_items/page.svg +3 -0
- qcanvas/icons/rc_icons.py +2165 -355
- qcanvas/icons/universal/downloads/download_failed.svg +23 -0
- qcanvas/icons/universal/downloads/downloaded.svg +23 -0
- qcanvas/icons/universal/downloads/not_downloaded.svg +23 -0
- qcanvas/icons/universal/tabs/assignments_new_content.svg +3 -0
- qcanvas/icons/universal/tabs/mail_new_content.svg +3 -0
- qcanvas/icons/universal/tabs/pages_new_content.svg +3 -0
- qcanvas/icons/universal/tree_items/semester.svg +108 -0
- qcanvas/run.py +24 -0
- qcanvas/ui/course_viewer/content_tree.py +28 -7
- qcanvas/ui/course_viewer/course_tree/__init__.py +1 -0
- qcanvas/ui/course_viewer/course_tree/_course_icon_generator.py +86 -0
- qcanvas/ui/course_viewer/{course_tree.py → course_tree/course_tree.py} +20 -6
- qcanvas/ui/course_viewer/course_viewer.py +71 -24
- qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tree.py +15 -14
- qcanvas/ui/course_viewer/tabs/file_tab/__init__.py +1 -0
- qcanvas/ui/course_viewer/tabs/file_tab/file_tab.py +46 -0
- qcanvas/ui/course_viewer/tabs/file_tab/file_tree.py +99 -0
- qcanvas/ui/course_viewer/tabs/file_tab/pages_file_tree.py +56 -0
- qcanvas/ui/course_viewer/tabs/mail_tab/mail_tree.py +11 -11
- qcanvas/ui/course_viewer/tabs/page_tab/page_tree.py +13 -11
- qcanvas/ui/course_viewer/tabs/resource_rich_browser.py +57 -56
- qcanvas/ui/course_viewer/tabs/util.py +10 -0
- qcanvas/ui/course_viewer/tree_widget_data_item.py +22 -0
- qcanvas/ui/main_ui/course_viewer_container.py +46 -3
- qcanvas/ui/main_ui/options/auto_download_resources_option.py +3 -1
- qcanvas/ui/main_ui/options/theme_selection_menu.py +2 -0
- qcanvas/ui/main_ui/qcanvas_window.py +18 -5
- qcanvas/ui/main_ui/status_bar_progress_display.py +17 -8
- qcanvas/ui/memory_tree/_tree_memory.py +1 -0
- qcanvas/ui/memory_tree/memory_tree_widget.py +2 -2
- qcanvas/ui/setup/setup_checker.py +2 -2
- qcanvas/ui/setup/setup_dialog.py +145 -66
- qcanvas/util/__init__.py +0 -2
- qcanvas/util/auto_downloader.py +1 -2
- qcanvas/util/file_icons.py +54 -0
- qcanvas/util/html_cleaner.py +2 -0
- qcanvas/util/layouts.py +5 -2
- qcanvas/util/paths.py +15 -26
- qcanvas/util/runtime.py +20 -0
- qcanvas/util/settings/_client_settings.py +11 -2
- qcanvas/util/settings/_mapped_setting.py +6 -1
- qcanvas/util/themes/__init__.py +2 -0
- qcanvas/util/themes/_colour_scheme_helper.py +38 -0
- qcanvas/util/themes/_selected_theme.py +10 -0
- qcanvas/util/themes/_theme_changed_event.py +17 -0
- qcanvas/util/themes/_theme_changer.py +86 -0
- qcanvas/util/ui_tools.py +5 -1
- {qcanvas-1.0.12.dev3.dist-info → qcanvas-1.2.0.dist-info}/METADATA +16 -6
- qcanvas-1.2.0.dist-info/RECORD +118 -0
- qcanvas/icons/file-download-failed.svg +0 -6
- qcanvas/icons/file-downloaded.svg +0 -6
- qcanvas/icons/file-not-downloaded.svg +0 -6
- qcanvas/icons/sync.svg +0 -7
- qcanvas/util/themes.py +0 -24
- qcanvas-1.0.12.dev3.dist-info/RECORD +0 -68
- /qcanvas/icons/{main_icon.svg → universal/branding/main_icon.svg} +0 -0
- /qcanvas/icons/{file-unknown.svg → universal/downloads/unknown.svg} +0 -0
- {qcanvas-1.0.12.dev3.dist-info → qcanvas-1.2.0.dist-info}/WHEEL +0 -0
- {qcanvas-1.0.12.dev3.dist-info → qcanvas-1.2.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os.path
|
|
3
|
+
|
|
4
|
+
from qtpy.QtCore import QFileInfo, QMimeDatabase
|
|
5
|
+
from qtpy.QtGui import QIcon
|
|
6
|
+
from qtpy.QtWidgets import QApplication, QFileIconProvider, QStyle
|
|
7
|
+
|
|
8
|
+
import qcanvas.util.runtime as runtime
|
|
9
|
+
|
|
10
|
+
_logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
# Windows and linux have different ways of doing this
|
|
13
|
+
if runtime.is_running_on_windows:
|
|
14
|
+
_icon_provider = QFileIconProvider()
|
|
15
|
+
|
|
16
|
+
def icon_for_filename(file_name: str) -> QIcon:
|
|
17
|
+
return _icon_provider.icon(QFileInfo(file_name))
|
|
18
|
+
|
|
19
|
+
else:
|
|
20
|
+
_mime_database = QMimeDatabase()
|
|
21
|
+
# This must be initialised lazily because the QApplication might not be initialised at this time
|
|
22
|
+
_default_icon: QIcon | None = None
|
|
23
|
+
_icon_for_suffix: dict[str, QIcon] = {}
|
|
24
|
+
|
|
25
|
+
def icon_for_filename(file_name: str) -> QIcon:
|
|
26
|
+
global _default_icon
|
|
27
|
+
|
|
28
|
+
file_suffix = os.path.splitext(file_name)[1]
|
|
29
|
+
|
|
30
|
+
# Check if we already know what icon this file type has
|
|
31
|
+
if file_suffix in _icon_for_suffix:
|
|
32
|
+
return _icon_for_suffix[file_suffix]
|
|
33
|
+
|
|
34
|
+
# Try to find an icon for this file type
|
|
35
|
+
for mime_type in _mime_database.mimeTypesForFileName(file_name):
|
|
36
|
+
icon = QIcon.fromTheme(mime_type.iconName())
|
|
37
|
+
|
|
38
|
+
if not icon.isNull():
|
|
39
|
+
_icon_for_suffix[file_suffix] = icon
|
|
40
|
+
return icon
|
|
41
|
+
|
|
42
|
+
_lazy_init_default_icon()
|
|
43
|
+
|
|
44
|
+
# No icon for this type of file was found, return default icon
|
|
45
|
+
_icon_for_suffix[file_suffix] = _default_icon
|
|
46
|
+
return _default_icon
|
|
47
|
+
|
|
48
|
+
def _lazy_init_default_icon() -> None:
|
|
49
|
+
global _default_icon
|
|
50
|
+
|
|
51
|
+
if _default_icon is None:
|
|
52
|
+
_default_icon = QApplication.style().standardIcon(
|
|
53
|
+
QStyle.StandardPixmap.SP_FileIcon
|
|
54
|
+
)
|
qcanvas/util/html_cleaner.py
CHANGED
|
@@ -16,6 +16,8 @@ def clean_up_html(html: str) -> str:
|
|
|
16
16
|
_remove_tags(doc.find_all(["link", "script"]))
|
|
17
17
|
# Remove font awesome icons (which don't load anyway)
|
|
18
18
|
_remove_tags(doc.find_all(["span"], class_=["dp-icon-content"]))
|
|
19
|
+
# Remove screen reader elements
|
|
20
|
+
_remove_tags(doc.find_all(class_="screenreader-only"))
|
|
19
21
|
|
|
20
22
|
return str(doc)
|
|
21
23
|
|
qcanvas/util/layouts.py
CHANGED
|
@@ -22,11 +22,14 @@ def layout_widget(layout_type: Type[T], *items: QWidget, **kwargs) -> QWidget:
|
|
|
22
22
|
return widget
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def layout(layout_type: Type[T], *items: QWidget, **kwargs) -> T:
|
|
25
|
+
def layout(layout_type: Type[T], *items: QWidget | QLayout, **kwargs) -> T:
|
|
26
26
|
result_layout: QLayout = layout_type(**kwargs)
|
|
27
27
|
|
|
28
28
|
for item in items:
|
|
29
|
-
|
|
29
|
+
if isinstance(item, QLayout):
|
|
30
|
+
result_layout.addItem(item)
|
|
31
|
+
else:
|
|
32
|
+
result_layout.addWidget(item)
|
|
30
33
|
|
|
31
34
|
return result_layout
|
|
32
35
|
|
qcanvas/util/paths.py
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
-
import platform
|
|
4
|
-
import sys
|
|
5
3
|
from pathlib import Path
|
|
6
4
|
|
|
7
5
|
import cachetools
|
|
8
6
|
import platformdirs
|
|
9
7
|
from qtpy.QtCore import QSettings
|
|
10
8
|
|
|
9
|
+
from qcanvas.util.runtime import *
|
|
10
|
+
|
|
11
11
|
_logger = logging.getLogger(__name__)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
|
|
14
|
+
def ui_storage() -> Path:
|
|
15
|
+
return root() / ".UI"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def data_storage() -> Path:
|
|
19
|
+
return root()
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
def client_settings() -> QSettings:
|
|
21
|
-
if
|
|
23
|
+
if is_running_portable:
|
|
22
24
|
return QSettings("QCanvas.ini", QSettings.Format.IniFormat)
|
|
23
|
-
elif _is_running_as_pyinstaller and _is_running_on_windows:
|
|
24
|
-
return QSettings(
|
|
25
|
-
str(platformdirs.user_documents_path() / "QCanvasTeam" / "QCanvas.ini"),
|
|
26
|
-
QSettings.Format.IniFormat,
|
|
27
|
-
)
|
|
28
25
|
else:
|
|
29
26
|
return QSettings("QCanvasTeam", "QCanvas")
|
|
30
27
|
|
|
@@ -33,20 +30,12 @@ def client_settings() -> QSettings:
|
|
|
33
30
|
def root() -> Path:
|
|
34
31
|
root_path = Path()
|
|
35
32
|
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
if is_running_as_flatpak:
|
|
34
|
+
# Flatpak does not support portable mode
|
|
35
|
+
root_path = Path(os.environ["XDG_DATA_HOME"])
|
|
36
|
+
elif not is_running_portable and is_running_as_compiled:
|
|
37
|
+
root_path = platformdirs.user_data_path("QCanvasReborn", "QCanvasTeam")
|
|
41
38
|
|
|
42
39
|
print("Root path", root_path.absolute())
|
|
43
40
|
_logger.debug("Root path %s", root_path.absolute())
|
|
44
41
|
return root_path
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def ui_storage() -> Path:
|
|
48
|
-
return root() / ".UI"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def data_storage() -> Path:
|
|
52
|
-
return root()
|
qcanvas/util/runtime.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import sys
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
is_running_portable = Path(".portable").exists()
|
|
7
|
+
is_running_on_windows = platform.system() == "Windows"
|
|
8
|
+
is_running_on_linux = platform.system() == "Linux"
|
|
9
|
+
_is_nuitka = "__compiled__" in globals()
|
|
10
|
+
_is_pyinstaller = getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS")
|
|
11
|
+
is_running_as_compiled = _is_nuitka or _is_pyinstaller
|
|
12
|
+
is_running_as_flatpak = os.environ.get("container", "") == "flatpak"
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"is_running_portable",
|
|
16
|
+
"is_running_as_flatpak",
|
|
17
|
+
"is_running_on_linux",
|
|
18
|
+
"is_running_as_compiled",
|
|
19
|
+
"is_running_on_windows",
|
|
20
|
+
]
|
|
@@ -15,6 +15,7 @@ class _ClientSettings:
|
|
|
15
15
|
canvas_url: MappedSetting[Optional[str]] = MappedSetting(default=None)
|
|
16
16
|
canvas_api_key: MappedSetting[Optional[str]] = MappedSetting(default=None)
|
|
17
17
|
panopto_url: MappedSetting[Optional[str]] = MappedSetting(default=None)
|
|
18
|
+
panopto_disabled = BoolSetting(default=False)
|
|
18
19
|
quick_sync_enabled = BoolSetting(default=False)
|
|
19
20
|
sync_on_start = BoolSetting(default=False)
|
|
20
21
|
download_new_resources = BoolSetting(default=False)
|
|
@@ -27,5 +28,13 @@ class _ClientSettings:
|
|
|
27
28
|
)
|
|
28
29
|
|
|
29
30
|
@property
|
|
30
|
-
def panopto_config(self) -> PanoptoClientConfig:
|
|
31
|
-
|
|
31
|
+
def panopto_config(self) -> Optional[PanoptoClientConfig]:
|
|
32
|
+
"""
|
|
33
|
+
Generates a panopto client config. If panopto is disabled, it returns None.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
if self.panopto_disabled:
|
|
37
|
+
_logger.debug("Panopto is disabled")
|
|
38
|
+
return None
|
|
39
|
+
else:
|
|
40
|
+
return PanoptoClientConfig(panopto_url=self.panopto_url)
|
|
@@ -53,8 +53,13 @@ class BoolSetting(MappedSetting[bool]):
|
|
|
53
53
|
try:
|
|
54
54
|
# noinspection PyTypeChecker
|
|
55
55
|
value: str = super()._read()
|
|
56
|
+
|
|
57
|
+
if isinstance(value, bool):
|
|
58
|
+
return value
|
|
59
|
+
|
|
56
60
|
return value.lower() == "true"
|
|
57
|
-
except:
|
|
61
|
+
except Exception as e:
|
|
62
|
+
_logger.error("Could not read setting", exc_info=e)
|
|
58
63
|
return self.default
|
|
59
64
|
|
|
60
65
|
# @override
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from qtpy.QtCore import QObject, Signal, Slot
|
|
4
|
+
from qtpy.QtGui import QGuiApplication, Qt
|
|
5
|
+
|
|
6
|
+
_logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def colour_scheme() -> Qt.ColorScheme:
|
|
10
|
+
return QGuiApplication.styleHints().colorScheme()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def is_dark_colour_scheme() -> bool:
|
|
14
|
+
return colour_scheme() == Qt.ColorScheme.Dark
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ColourSchemeChangeEvent(QObject):
|
|
18
|
+
theme_changed = Signal()
|
|
19
|
+
|
|
20
|
+
def __init__(self):
|
|
21
|
+
super().__init__(None)
|
|
22
|
+
self._last_theme = colour_scheme()
|
|
23
|
+
QGuiApplication.styleHints().colorSchemeChanged.connect(self._theme_changed)
|
|
24
|
+
|
|
25
|
+
@Slot(Qt.ColorScheme)
|
|
26
|
+
def _theme_changed(self, colour_scheme: Qt.ColorScheme) -> None:
|
|
27
|
+
# Ensure the signal isn't fired when there wasn't actually a change
|
|
28
|
+
if colour_scheme != self._last_theme:
|
|
29
|
+
self._last_theme = colour_scheme
|
|
30
|
+
self.theme_changed.emit()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
_theme_changed_listener = ColourSchemeChangeEvent()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def colour_scheme_changed() -> Signal:
|
|
37
|
+
global _theme_changed_listener
|
|
38
|
+
return _theme_changed_listener.theme_changed
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from qtpy.QtCore import QObject, Signal
|
|
4
|
+
|
|
5
|
+
_logger = logging.getLogger(__name__)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ThemeChangedEvent(QObject):
|
|
9
|
+
theme_changed = Signal()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
theme_changed_event = ThemeChangedEvent(None)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def theme_changed() -> Signal:
|
|
16
|
+
global theme_changed_event
|
|
17
|
+
return theme_changed_event.theme_changed
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import qdarktheme
|
|
4
|
+
from qtpy.QtCore import Slot
|
|
5
|
+
from qtpy.QtGui import QIcon
|
|
6
|
+
from qtpy.QtWidgets import QApplication, QStyleFactory
|
|
7
|
+
|
|
8
|
+
from qcanvas.util.themes._colour_scheme_helper import (
|
|
9
|
+
colour_scheme_changed,
|
|
10
|
+
is_dark_colour_scheme,
|
|
11
|
+
)
|
|
12
|
+
from qcanvas.util.themes._selected_theme import SelectedTheme
|
|
13
|
+
from qcanvas.util.themes._theme_changed_event import theme_changed
|
|
14
|
+
|
|
15
|
+
_logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
default_theme = "auto"
|
|
18
|
+
_is_dark_mode: bool | None = None
|
|
19
|
+
_selected_theme: SelectedTheme | None = None
|
|
20
|
+
|
|
21
|
+
_universal_path = ":icons/universal"
|
|
22
|
+
_dark_path = ":icons/dark"
|
|
23
|
+
_light_path = ":icons/light"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def apply(theme: str) -> None:
|
|
27
|
+
global _is_dark_mode, _selected_theme
|
|
28
|
+
|
|
29
|
+
theme = ensure_theme_is_valid(theme)
|
|
30
|
+
was_dark_mode = _is_dark_mode
|
|
31
|
+
|
|
32
|
+
if theme != "native":
|
|
33
|
+
if theme == "auto":
|
|
34
|
+
_is_dark_mode = is_dark_colour_scheme()
|
|
35
|
+
_selected_theme = SelectedTheme.AUTO
|
|
36
|
+
selected_colour_scheme = "dark" if _is_dark_mode else "light"
|
|
37
|
+
else:
|
|
38
|
+
_is_dark_mode = theme == "dark"
|
|
39
|
+
_selected_theme = SelectedTheme.OVERRIDE
|
|
40
|
+
selected_colour_scheme = theme
|
|
41
|
+
|
|
42
|
+
qdarktheme.setup_theme(
|
|
43
|
+
selected_colour_scheme,
|
|
44
|
+
custom_colors={"primary": "e02424"},
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
QApplication.setStyle(QStyleFactory.create("Fusion"))
|
|
48
|
+
else:
|
|
49
|
+
_is_dark_mode = is_dark_colour_scheme()
|
|
50
|
+
_selected_theme = SelectedTheme.NATIVE
|
|
51
|
+
|
|
52
|
+
if was_dark_mode != _is_dark_mode:
|
|
53
|
+
_set_fallback_paths()
|
|
54
|
+
theme_changed().emit()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def is_dark_mode() -> bool:
|
|
58
|
+
return _is_dark_mode
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def ensure_theme_is_valid(theme: str) -> str:
|
|
62
|
+
if theme not in ["auto", "light", "dark", "native"]:
|
|
63
|
+
return default_theme
|
|
64
|
+
else:
|
|
65
|
+
return theme
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@Slot()
|
|
69
|
+
def _scheme_changed():
|
|
70
|
+
global _selected_theme, _is_dark_mode
|
|
71
|
+
|
|
72
|
+
if _selected_theme == SelectedTheme.AUTO:
|
|
73
|
+
apply("auto")
|
|
74
|
+
elif _selected_theme == SelectedTheme.NATIVE:
|
|
75
|
+
_is_dark_mode = is_dark_colour_scheme()
|
|
76
|
+
_set_fallback_paths()
|
|
77
|
+
theme_changed().emit()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _set_fallback_paths():
|
|
81
|
+
QIcon.setFallbackSearchPaths(
|
|
82
|
+
[_dark_path if _is_dark_mode else _light_path, _universal_path]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
colour_scheme_changed().connect(_scheme_changed)
|
qcanvas/util/ui_tools.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
|
-
from qtpy.QtGui import QKeySequence
|
|
4
|
+
from qtpy.QtGui import QIcon, QKeySequence, QPixmap
|
|
5
5
|
from qtpy.QtWidgets import *
|
|
6
6
|
|
|
7
7
|
_logger = logging.getLogger(__name__)
|
|
@@ -19,6 +19,7 @@ def create_qaction(
|
|
|
19
19
|
triggered: Any = None,
|
|
20
20
|
checkable: bool | None = None,
|
|
21
21
|
checked: bool | None = None,
|
|
22
|
+
icon: QIcon | QPixmap | None = None
|
|
22
23
|
) -> QAction:
|
|
23
24
|
action = QAction(name)
|
|
24
25
|
|
|
@@ -38,4 +39,7 @@ def create_qaction(
|
|
|
38
39
|
if checked is not None:
|
|
39
40
|
action.setChecked(checked)
|
|
40
41
|
|
|
42
|
+
if icon is not None:
|
|
43
|
+
action.setIcon(icon)
|
|
44
|
+
|
|
41
45
|
return action
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: qcanvas
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: QCanvas is a desktop client for Canvas LMS.
|
|
5
5
|
Author: QCanvas
|
|
6
6
|
Author-email: QCanvas@noreply.codeberg.org
|
|
7
|
-
Requires-Python:
|
|
7
|
+
Requires-Python: >3.11.0,<3.13
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
10
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
10
|
Requires-Dist: aiosqlite (>=0.20.0,<0.21.0)
|
|
12
11
|
Requires-Dist: asynctaskpool (>=0.2.1,<0.3.0)
|
|
@@ -14,8 +13,8 @@ Requires-Dist: lightdb (>=2.0,<3.0)
|
|
|
14
13
|
Requires-Dist: platformdirs (>=4.2.2,<5.0.0)
|
|
15
14
|
Requires-Dist: pyqtdarktheme-fork (>=2.3.2,<3.0.0)
|
|
16
15
|
Requires-Dist: qasync (>=0.27.1,<0.28.0)
|
|
17
|
-
Requires-Dist: qcanvas-api-clients (>=0.
|
|
18
|
-
Requires-Dist: qcanvas-backend (
|
|
16
|
+
Requires-Dist: qcanvas-api-clients (>=0.3.0,<0.4.0)
|
|
17
|
+
Requires-Dist: qcanvas-backend (>=0.2.5,<0.3.0)
|
|
19
18
|
Requires-Dist: qtpy (>=2.4.1,<3.0.0)
|
|
20
19
|
Requires-Dist: sqlalchemy (>=2.0.31,<3.0.0)
|
|
21
20
|
Requires-Dist: validators (>=0.33.0,<0.34.0)
|
|
@@ -25,9 +24,20 @@ Description-Content-Type: text/markdown
|
|
|
25
24
|
|
|
26
25
|
QCanvas is an **unofficial** desktop client for Canvas LMS.
|
|
27
26
|
|
|
27
|
+
https://codeberg.org/QCanvas/QCanvas
|
|
28
|
+
|
|
29
|
+
https://github.com/QCanvas/QCanvasApp
|
|
30
|
+
|
|
28
31
|
# Downloads
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
<a href='https://flathub.org/apps/io.github.qcanvas.QCanvasApp'>
|
|
34
|
+
<img width='240' alt='Get it on Flathub' src='https://flathub.org/api/badge?svg&locale=en'/>
|
|
35
|
+
</a>
|
|
36
|
+
|
|
37
|
+
You can download a **windows** version from [releases](https://github.com/QCanvas/QCanvasApp/releases)
|
|
38
|
+
|
|
39
|
+
The appimage version is *not recommended* as it is not a proper portable appimage. It will only work on debian/ubuntu
|
|
40
|
+
based distros.
|
|
31
41
|
|
|
32
42
|
# Development/Run from source
|
|
33
43
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
qcanvas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
qcanvas/app_start/__init__.py,sha256=r16bg9Otw8Sy6MYLmIt5Nu-oSwyYP8Y2kzMtbmeF6m0,1437
|
|
3
|
+
qcanvas/backend_connectors/__init__.py,sha256=Wj8cmxQng3SSlmlXJyzHaPmvxbkauwsxINckPb7WuHc,108
|
|
4
|
+
qcanvas/backend_connectors/frontend_resource_manager.py,sha256=87oszxCle0Y9AUAHH3wn_7oilY45ddMET-4EnpTtjn0,1322
|
|
5
|
+
qcanvas/backend_connectors/qcanvas_task_master.py,sha256=CTPBvf_9w-livscKNspnd98mNvFLYTYHef0RQSUkfFc,742
|
|
6
|
+
qcanvas/icons/__init__.py,sha256=gczS3dUVDSgkfalmNhnynILAkk4099BE8jWDTmY7fyY,1902
|
|
7
|
+
qcanvas/icons/_icon_type.py,sha256=p5YpGAoJViOA2SB4o4Vw4jI_kDwrvzwCP8NIxUydCjo,901
|
|
8
|
+
qcanvas/icons/_update_icons.py,sha256=iZrmZaaq2rIt5ATL9qJ-x2RhvQ4dDp391RsAhwfirLU,2410
|
|
9
|
+
qcanvas/icons/dark/actions/exit.svg,sha256=FTw6JW0xq-xRh7oHQdhKrJpf2nkm4ot5kVjXXJRgszI,228
|
|
10
|
+
qcanvas/icons/dark/actions/mark_all_read.svg,sha256=V7OEY0hjNmSJtt9Ufu0vgd5BZRH0pLCo5h58Xi0VJhI,201
|
|
11
|
+
qcanvas/icons/dark/actions/open_downloads.svg,sha256=ft5TuP97ErGRq5RUVtEC5HaA28yqbebkZVfz3zfRA4w,359
|
|
12
|
+
qcanvas/icons/dark/actions/quick_login.svg,sha256=I3_raVdsNKuCBazs8wj6JByu2p3qXSZ8_K8eYOmb3hw,982
|
|
13
|
+
qcanvas/icons/dark/actions/sync.svg,sha256=qN8F5qg_TIirjDePfmQgiR0DO5FmSckOP5Wlo2KQhI0,413
|
|
14
|
+
qcanvas/icons/dark/branding/logo_transparent.svg,sha256=1bVg8AK9FepOvWTcu_zDLX2eZ1inYuAMBwZRi252-5o,18660
|
|
15
|
+
qcanvas/icons/dark/options/auto_download.svg,sha256=MYiffHrLsCkLJ55SaKfBkoC3WZTe8Fj8l-jYzON28Mc,284
|
|
16
|
+
qcanvas/icons/dark/options/theme.svg,sha256=9Clv7h2z0YuprG4CoPEJAvl_mUsAeGwepe2tGvYJZoc,383
|
|
17
|
+
qcanvas/icons/dark/tabs/assignments.svg,sha256=MlYp4ibpT5bb3V2nRBwrTfNYzfFkvEX7uf287uy4i5k,502
|
|
18
|
+
qcanvas/icons/dark/tabs/mail.svg,sha256=CoTukvsulJnVtPdTgIExdUdoPtB4W-lnIvs4m-s80vc,334
|
|
19
|
+
qcanvas/icons/dark/tabs/pages.svg,sha256=TCoeLrX-UOzESVJMVVP1XnA6YfGKO7C3BDtH683nJ1k,339
|
|
20
|
+
qcanvas/icons/dark/tree_items/assignment.svg,sha256=MlYp4ibpT5bb3V2nRBwrTfNYzfFkvEX7uf287uy4i5k,502
|
|
21
|
+
qcanvas/icons/dark/tree_items/mail.svg,sha256=CoTukvsulJnVtPdTgIExdUdoPtB4W-lnIvs4m-s80vc,334
|
|
22
|
+
qcanvas/icons/dark/tree_items/module.svg,sha256=mfb16D2rGcVudJd4uTc9sRdN8B7tgaAU5OaxhZ_0daY,902
|
|
23
|
+
qcanvas/icons/dark/tree_items/page.svg,sha256=mLyiil83ycWaCEdQ6KaKTt4h6-HK5os_XzTsIkPlR1w,356
|
|
24
|
+
qcanvas/icons/icons.qrc,sha256=SHWS7nxSwzEDyqu_Z9zIcKbsshY4aoYT6QNazzIY7v0,2251
|
|
25
|
+
qcanvas/icons/light/actions/exit.svg,sha256=hTF_ke8f91D0t5SkNat5mijOiFfwZqg-t7NMIrx8k2w,228
|
|
26
|
+
qcanvas/icons/light/actions/mark_all_read.svg,sha256=pa_VNoSnlwgzrn5UyiRYf1EH3N2Eu3Q96SoO_A59Sf4,201
|
|
27
|
+
qcanvas/icons/light/actions/open_downloads.svg,sha256=wZTOfN7XwVPxaOZ_lTmTSuZvrlHi7L840JlduzjJ3z4,359
|
|
28
|
+
qcanvas/icons/light/actions/quick_login.svg,sha256=0toC_4pROdJQWz6DcLM_UqnRknqckTIcS0ZaJL5o_es,982
|
|
29
|
+
qcanvas/icons/light/actions/sync.svg,sha256=KqQi5DbT7_4OmZ1dwidkC61Tel3thcUHJ-3u1zgEvLw,413
|
|
30
|
+
qcanvas/icons/light/branding/logo_transparent.svg,sha256=DsNOFWHGAVCZ-ue-pf1iatQ1t_IBmnyxs3FNw-UUukg,18647
|
|
31
|
+
qcanvas/icons/light/options/auto_download.svg,sha256=93efpzvsLYYZVze2CKTDhp2x8l-4UsF75DFGMHmCD3I,307
|
|
32
|
+
qcanvas/icons/light/options/ignore_old.svg,sha256=Zn3Dl6DD9omgoqqcM5xAbRYA8fqVGKwooTFYOQZJTVo,484
|
|
33
|
+
qcanvas/icons/light/options/include_videos.svg,sha256=3HmJvM95JFqvE2WXEAIjTc5sPp0aLuKKu7yb0tX5sM4,349
|
|
34
|
+
qcanvas/icons/light/options/theme.svg,sha256=9HCwt6AndJJjgjPgS9BO4mkKWtkigTpUUxct4sw6SI4,383
|
|
35
|
+
qcanvas/icons/light/tabs/assignments.svg,sha256=ci5z-t0MAhTHYoMVXvIyHlZcd3MEYgeGMISxMSX0zes,502
|
|
36
|
+
qcanvas/icons/light/tabs/mail.svg,sha256=l_ITAKZRkq7PbPw1-iY5fma9Zimr9w9-721rYNros6o,334
|
|
37
|
+
qcanvas/icons/light/tabs/pages.svg,sha256=Zgcsknpd4jiWuqRNYqFQvCAxgH4ThlSUl9rS-ZcrpL4,339
|
|
38
|
+
qcanvas/icons/light/tree_items/assignment.svg,sha256=ci5z-t0MAhTHYoMVXvIyHlZcd3MEYgeGMISxMSX0zes,502
|
|
39
|
+
qcanvas/icons/light/tree_items/mail.svg,sha256=l_ITAKZRkq7PbPw1-iY5fma9Zimr9w9-721rYNros6o,334
|
|
40
|
+
qcanvas/icons/light/tree_items/module.svg,sha256=P8N_7iH3tfHEyajMO2aQ-eKaB3mbNptREAzAic5P6Cg,902
|
|
41
|
+
qcanvas/icons/light/tree_items/page.svg,sha256=ui8UX_bPrOOnb9GlHujzopLO8yRRdpzp0nwmmELb214,356
|
|
42
|
+
qcanvas/icons/rc_icons.py,sha256=xJteGJsyG7o6XmRtFO4fItlzLy-PvQzwcn5MR-ZYLNA,72887
|
|
43
|
+
qcanvas/icons/universal/branding/main_icon.svg,sha256=st2sfA8HIETmoacJ2Oq84iJzfnNHH-T03ijB-J419_s,16104
|
|
44
|
+
qcanvas/icons/universal/downloads/download_failed.svg,sha256=lhDf8ul__T2ByRcd5KZicNtUVl4BdSqeZ3yOR6DvCLk,1091
|
|
45
|
+
qcanvas/icons/universal/downloads/downloaded.svg,sha256=WM5Kpi9IzLvDASOHQGQGtFb_m4u02mGHLLZNs19-4HA,1091
|
|
46
|
+
qcanvas/icons/universal/downloads/not_downloaded.svg,sha256=7zl_Gmx2IHZrugFYAUjBCSwmfXM0pvlshj8GhewxY5Q,1091
|
|
47
|
+
qcanvas/icons/universal/downloads/unknown.svg,sha256=9xlN244HJX3zM_MqdMTnNbKlqLjOFgCx3ZdM4Wc4zC0,1729
|
|
48
|
+
qcanvas/icons/universal/tabs/assignments_new_content.svg,sha256=IwnLpS31-eZS6ADEtpf1PFjr5Z6QoeGWElZEguaMmBM,502
|
|
49
|
+
qcanvas/icons/universal/tabs/mail_new_content.svg,sha256=q43Y6Xnq2BDFXPA88kJJl4KQbJw7jsm8q8A1NnVcRJ8,334
|
|
50
|
+
qcanvas/icons/universal/tabs/pages_new_content.svg,sha256=vUksdaa0bzEm6xvbp0sqQ_XJlqW87P-N-Btifstx7Tc,339
|
|
51
|
+
qcanvas/icons/universal/tree_items/semester.svg,sha256=9aWy2VH-PMhkMlhlq97Yh2pvW2xyYsdRh-5knUcgzfY,4088
|
|
52
|
+
qcanvas/run.py,sha256=tP5bplaPa_Z8DaKqP59bwYaIEccW5B18xoyXgKJsrf8,1681
|
|
53
|
+
qcanvas/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
|
+
qcanvas/ui/course_viewer/__init__.py,sha256=XkoFnh4ULw3_i-GDsOlueEWido0PkoDcN9_EX6-nkXY,76
|
|
55
|
+
qcanvas/ui/course_viewer/content_tree.py,sha256=Rjq7GNf-h9tb1gyUdRebh_VNxltLafjoy7oDhafAWDU,4631
|
|
56
|
+
qcanvas/ui/course_viewer/course_tree/__init__.py,sha256=N2XorJ4COFHzRYx53noANb4_qJYf6N8_YCjPdQuDCHs,36
|
|
57
|
+
qcanvas/ui/course_viewer/course_tree/_course_icon_generator.py,sha256=3r0pBRbb9LsD0VAXOj4VfD8IPyGmfXu-FJPnL3aHbRI,3071
|
|
58
|
+
qcanvas/ui/course_viewer/course_tree/course_tree.py,sha256=XR9IirTSQZsmmHeTojkZL29sSn6VBTut5e-01yLU_bo,3195
|
|
59
|
+
qcanvas/ui/course_viewer/course_viewer.py,sha256=P5GI4_xv8mFZ671hyY1zciMhRTE4HiWU2-1aLuLAik8,5339
|
|
60
|
+
qcanvas/ui/course_viewer/tabs/__init__.py,sha256=SlfWUzk6_E5uM9GIV-y9BVeKMwqn3pRx_xWhMyb1dfI,54
|
|
61
|
+
qcanvas/ui/course_viewer/tabs/assignment_tab/__init__.py,sha256=w936dW7za10Fh6rN0zVA-7Kyiup3kd6C-mPAFHtxmy0,42
|
|
62
|
+
qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tab.py,sha256=_de3IPBCe27Bt8MoabcX1ZchBbVb-_QHVeYMvL3wzr8,1986
|
|
63
|
+
qcanvas/ui/course_viewer/tabs/assignment_tab/assignment_tree.py,sha256=ipscHCgvDLL0kGnDelZ3UprPRIwHS3Ju9L4qR4UyyS0,2925
|
|
64
|
+
qcanvas/ui/course_viewer/tabs/content_tab.py,sha256=CAfzUYawDde0lhL7R7dFu07uS1XEG39VIleS2Cpu30g,3540
|
|
65
|
+
qcanvas/ui/course_viewer/tabs/file_tab/__init__.py,sha256=mMebnrNw_V-lQ-eBXS_kFinL-ZdUAXa459NmuyuCu6s,30
|
|
66
|
+
qcanvas/ui/course_viewer/tabs/file_tab/file_tab.py,sha256=DOpnSDg7vDRvLc4LFf94BHkx0cRy6InYLpKH7n_p4IU,1404
|
|
67
|
+
qcanvas/ui/course_viewer/tabs/file_tab/file_tree.py,sha256=HJ7KEk5QOI2B8orvPXL-d7oMI2ZSROO8v5Ccn4xNDJ8,3360
|
|
68
|
+
qcanvas/ui/course_viewer/tabs/file_tab/pages_file_tree.py,sha256=0XUydcBgeXmQp7cRjZ6YUS0k4HkekWRuxp8-VCRlNrc,1919
|
|
69
|
+
qcanvas/ui/course_viewer/tabs/mail_tab/__init__.py,sha256=68iRUUWEP7mudbaxa4ZBKMra4rvs2oZKaZkBWwmUrsI,30
|
|
70
|
+
qcanvas/ui/course_viewer/tabs/mail_tab/mail_tab.py,sha256=fw0FORJiH19rAGsjBFJHZlNrVCMbwG4n3AFV3wbhwGM,1840
|
|
71
|
+
qcanvas/ui/course_viewer/tabs/mail_tab/mail_tree.py,sha256=Z1eQSp1D_E78khGKf4qGlmo6AF_heWuz9zmgrv_VXik,1784
|
|
72
|
+
qcanvas/ui/course_viewer/tabs/page_tab/__init__.py,sha256=lcafxlSEVZ0wqZySxT6hTrvExX-GU2AfcZQbp6W8haU,30
|
|
73
|
+
qcanvas/ui/course_viewer/tabs/page_tab/page_tab.py,sha256=cv-pCDri7thRJZv-gWUZrL2FUQAHe7vZthRAhejsqWY,771
|
|
74
|
+
qcanvas/ui/course_viewer/tabs/page_tab/page_tree.py,sha256=AbN9U35PUSF0eO5SNexyzaLaCs2t_imkKOkwYsRtfyM,2179
|
|
75
|
+
qcanvas/ui/course_viewer/tabs/resource_rich_browser.py,sha256=_Q9xwUW0Mb8DqWUCAps2tHA5t4a22mEjuOOZNTdQSyM,7180
|
|
76
|
+
qcanvas/ui/course_viewer/tabs/util.py,sha256=Cg8FmPbkiTepV9IlTZQSWtcUaovv66iAD4_BUYJjIAY,344
|
|
77
|
+
qcanvas/ui/course_viewer/tree_widget_data_item.py,sha256=_j-j-jmi65-PucXhf3qqQp6jZ49q5PszuFwH1SndC18,566
|
|
78
|
+
qcanvas/ui/main_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
79
|
+
qcanvas/ui/main_ui/course_viewer_container.py,sha256=814pP-HoALQdNE8L6XJ7WEmPcfmdRluz5Y-LqMJEUZQ,3447
|
|
80
|
+
qcanvas/ui/main_ui/options/__init__.py,sha256=SlfWUzk6_E5uM9GIV-y9BVeKMwqn3pRx_xWhMyb1dfI,54
|
|
81
|
+
qcanvas/ui/main_ui/options/auto_download_resources_option.py,sha256=n6OecWqCmyk4szHYVUkqTb9ADb4yQ0BKx50Xr7p_x4E,1361
|
|
82
|
+
qcanvas/ui/main_ui/options/quick_sync_option.py,sha256=qEfmtLllO32ejc-bydCvFRjal5RUlk2HtC5Ld4mT7ss,753
|
|
83
|
+
qcanvas/ui/main_ui/options/sync_on_start_option.py,sha256=zFFAAyGZEa6qBchJJIm7bJpOwxcntnto9Ee-lzCiHX4,731
|
|
84
|
+
qcanvas/ui/main_ui/options/theme_selection_menu.py,sha256=5DCCDBUiQHD_tC8e37kN6V7DElfhVGYChl5DgJd7cp4,1331
|
|
85
|
+
qcanvas/ui/main_ui/qcanvas_window.py,sha256=eVM4Y0q-enXS4NIooBQh1woVV5fOAJW5lYC8L1cxq3k,9013
|
|
86
|
+
qcanvas/ui/main_ui/status_bar_progress_display.py,sha256=vbuZwMR4It1qH8EY4ZiBz7akSDfaYZ_V18eS-pBgYq4,5047
|
|
87
|
+
qcanvas/ui/memory_tree/__init__.py,sha256=-XLitM6teC0zmwPrGf-Q-A53-zgmIPASExdOtaLIvPU,107
|
|
88
|
+
qcanvas/ui/memory_tree/_tree_memory.py,sha256=6d_-CpUC8u3s_LO100Gb-3DhoxwUDckgB56suOCyTZg,1893
|
|
89
|
+
qcanvas/ui/memory_tree/memory_tree_widget.py,sha256=Mq-zBNEwU-Npch-I5mhl_0tYAN7NvMN9GStajus3YWg,4408
|
|
90
|
+
qcanvas/ui/memory_tree/memory_tree_widget_item.py,sha256=JXk07AzrKsBnYAqhayIFYAwMfF_D_EfkfJY4Qyez47U,425
|
|
91
|
+
qcanvas/ui/setup/__init__.py,sha256=QWt2lEyLqWG5QC-BmCBlYyi0LZsBfsQYbP0XkvqA2f8,77
|
|
92
|
+
qcanvas/ui/setup/setup_checker.py,sha256=pRLZJR6ySa09DhMEt8F0VQ2D_r7IzrDJAULIatuokJw,449
|
|
93
|
+
qcanvas/ui/setup/setup_dialog.py,sha256=AbKtzHzdQkCHLksYedMWbAN2-r6jWm2R-1Vez0BGkKU,10281
|
|
94
|
+
qcanvas/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
|
+
qcanvas/util/auto_downloader.py,sha256=WGawgc849qpPf7ufe_yxRYhwVf2Aj15wTAAQvToxmHg,1842
|
|
96
|
+
qcanvas/util/basic_fonts.py,sha256=1NK5_kejgH45mENwiTWvE5oOuAvGqWMX3hg9tTUCBi4,243
|
|
97
|
+
qcanvas/util/file_icons.py,sha256=mJySt-RnlCYSn8pKdJtenB_oqRPJRbSOdvwC2u70LqI,1738
|
|
98
|
+
qcanvas/util/html_cleaner.py,sha256=U-UbZVX9x85gatOvxLsQXe2hL6x4I86eUKwkm0p159E,710
|
|
99
|
+
qcanvas/util/layouts.py,sha256=FN1DxKuAmI4P_RRO4Qo1-J1Y61hT7859OAkO-EpgrFU,1457
|
|
100
|
+
qcanvas/util/logs.py,sha256=VZKFITiW2WR2POEFVv5GRpEXic23Pzjehry-vH3g3Gk,138
|
|
101
|
+
qcanvas/util/paths.py,sha256=TzG5iy7A6ndzUdeV00lJKXq_gmbtooahueBjgvN02s8,989
|
|
102
|
+
qcanvas/util/qurl_util.py,sha256=NkskYvrMQJuYWMNF4DFQ4J5-YM5CGl5gHQKxJaAhHBE,197
|
|
103
|
+
qcanvas/util/runtime.py,sha256=EO1HFCN7dZbQtKHQOILuvjZFXGT7SzhlmPvU8ma95Z8,617
|
|
104
|
+
qcanvas/util/settings/__init__.py,sha256=ivc8bczhQdEJsWse6fc81Xyz0i2YX57pL4UubM3NJfw,228
|
|
105
|
+
qcanvas/util/settings/_client_settings.py,sha256=HyUpXoc7TinOviEd-eCo8g8Fbw8TqGAH2KfCkgPr9N0,1413
|
|
106
|
+
qcanvas/util/settings/_mapped_setting.py,sha256=Lb9mut_l5AM6a6jwfO9aZq1KEYZKa0qgOdAWwAJzX6Q,1973
|
|
107
|
+
qcanvas/util/settings/_ui_settings.py,sha256=zlWMjpntuqm7ZN3aBEROGrXc4bhtKOfWijmiGkdt1UA,804
|
|
108
|
+
qcanvas/util/themes/__init__.py,sha256=Ng-Rii7cFKrhSoE03J5tSYeaMY4UebFubKCBsWxouYM,134
|
|
109
|
+
qcanvas/util/themes/_colour_scheme_helper.py,sha256=QTrQ5c9AduBJMUuXp8sG-WPmYU82cF1tXjGDKhpI10w,1063
|
|
110
|
+
qcanvas/util/themes/_selected_theme.py,sha256=w1CXvMuLM8wKDgANOhcvNnlEXDyjdgnWO0TtA3vGomY,150
|
|
111
|
+
qcanvas/util/themes/_theme_changed_event.py,sha256=dIu1857h2ytSqmcRb2CABro3Gc0s9bm5DHdT23jyuk8,317
|
|
112
|
+
qcanvas/util/themes/_theme_changer.py,sha256=RA0b5Fur0LTlO-s1ZE4j2SedtbnWajEMw7m2HBdaDv0,2272
|
|
113
|
+
qcanvas/util/ui_tools.py,sha256=ogIHWutN7Yw_AgR5BEXDVXoo_ylN91SCXBdKUyWv-r8,1027
|
|
114
|
+
qcanvas/util/url_checker.py,sha256=gaV_KZZsG5bfJaGBv9jbHJjq0rVxIH55HRtucT6Qkx8,144
|
|
115
|
+
qcanvas-1.2.0.dist-info/METADATA,sha256=MBwhQpLuWA0_Nv0UD_7FXIvIRIdXbY5SwUo3UwtK-to,2071
|
|
116
|
+
qcanvas-1.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
117
|
+
qcanvas-1.2.0.dist-info/entry_points.txt,sha256=46VbnhQ9w2CYdfhYcPfWgjXYHjsKshu0asQ1B_sAMac,44
|
|
118
|
+
qcanvas-1.2.0.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
-
<title>file-times</title>
|
|
5
|
-
<path d="M26.731 9.902c-0.005-0.035-0.011-0.066-0.019-0.095l0.001 0.005c-0.031-0.134-0.094-0.249-0.182-0.342l0 0-8-8c-0.092-0.087-0.207-0.15-0.335-0.181l-0.005-0.001c-0.027-0.008-0.059-0.014-0.092-0.019l-0.003-0c-0.026-0.007-0.059-0.014-0.092-0.019l-0.004-0h-12c-0.414 0-0.75 0.336-0.75 0.75v0 28c0 0.414 0.336 0.75 0.75 0.75h20c0.414-0 0.75-0.336 0.75-0.75v0-20c-0.005-0.038-0.012-0.071-0.020-0.103l0.001 0.005zM24.189 9.25h-5.439v-5.439zM6.75 29.25v-26.5h10.5v7.25c0 0.414 0.336 0.75 0.75 0.75h7.25v18.5zM20.066 15.935c-0.136-0.136-0.324-0.22-0.531-0.22s-0.395 0.084-0.531 0.22v0l-3.004 3.004-3.005-3.004c-0.136-0.141-0.327-0.228-0.538-0.228-0.414 0-0.75 0.336-0.75 0.75 0 0.211 0.087 0.402 0.228 0.538l3.004 3.005-3.004 3.004c-0.136 0.136-0.22 0.324-0.22 0.531 0 0.415 0.336 0.751 0.751 0.751 0.207 0 0.395-0.084 0.53-0.219v0l3.005-3.005 3.004 3.005c0.136 0.136 0.324 0.22 0.531 0.22 0.415 0 0.751-0.336 0.751-0.751 0-0.207-0.084-0.395-0.22-0.531l-3.005-3.004 3.005-3.005c0.135-0.136 0.218-0.323 0.218-0.53s-0.083-0.394-0.218-0.53l0 0z"></path>
|
|
6
|
-
</svg>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
-
<title>file</title>
|
|
5
|
-
<path d="M26.731 9.902c-0.005-0.035-0.011-0.066-0.019-0.095l0.001 0.005c-0.031-0.134-0.094-0.249-0.182-0.342l0 0-8-8c-0.092-0.087-0.207-0.15-0.335-0.181l-0.005-0.001c-0.027-0.008-0.059-0.014-0.092-0.019l-0.003-0c-0.026-0.007-0.059-0.014-0.092-0.019l-0.004-0h-12c-0.414 0-0.75 0.336-0.75 0.75v0 28c0 0.414 0.336 0.75 0.75 0.75h20c0.414-0 0.75-0.336 0.75-0.75v0-20c-0.005-0.038-0.012-0.071-0.020-0.103l0.001 0.005zM24.189 9.25h-5.439v-5.439zM6.75 29.25v-26.5h10.5v7.25c0 0.414 0.336 0.75 0.75 0.75h7.25v18.5z"></path>
|
|
6
|
-
</svg>
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
-
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
-
<title>file-arrow-down</title>
|
|
5
|
-
<path d="M26.731 9.902c-0.005-0.035-0.011-0.066-0.019-0.095l0.001 0.005c-0.031-0.134-0.094-0.249-0.182-0.342l0 0-8-8c-0.092-0.087-0.207-0.15-0.335-0.181l-0.005-0.001c-0.027-0.008-0.059-0.014-0.092-0.019l-0.003-0c-0.026-0.007-0.059-0.014-0.092-0.019l-0.004-0h-12c-0.414 0-0.75 0.336-0.75 0.75v0 28c0 0.414 0.336 0.75 0.75 0.75h20c0.414-0 0.75-0.336 0.75-0.75v0-20c-0.005-0.038-0.012-0.071-0.020-0.103l0.001 0.005zM24.189 9.25h-5.439v-5.439zM6.75 29.25v-26.5h10.5v7.25c0 0.414 0.336 0.75 0.75 0.75h7.25v18.5zM20.469 20.91l-3.719 3.721v-10.676c0-0.414-0.336-0.75-0.75-0.75s-0.75 0.336-0.75 0.75v0 10.675l-3.72-3.72c-0.136-0.134-0.322-0.218-0.528-0.218-0.415 0-0.751 0.336-0.751 0.751 0 0.207 0.083 0.394 0.219 0.529l5 5c0.026 0.026 0.065 0.017 0.093 0.038 0.052 0.040 0.088 0.098 0.15 0.124 0.085 0.035 0.184 0.056 0.287 0.057h0c0 0 0 0 0 0 0.207 0 0.394-0.084 0.53-0.219l5.001-5c0.136-0.136 0.22-0.324 0.22-0.531 0-0.415-0.336-0.751-0.751-0.751-0.207 0-0.395 0.084-0.531 0.22v0z"></path>
|
|
6
|
-
</svg>
|
qcanvas/icons/sync.svg
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
-
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
-
<path d="M18.43 4.25C18.2319 4.25259 18.0426 4.33244 17.9025 4.47253C17.7625 4.61263 17.6826 4.80189 17.68 5V7.43L16.84 6.59C15.971 5.71363 14.8924 5.07396 13.7067 4.73172C12.5209 4.38948 11.2673 4.35604 10.065 4.63458C8.86267 4.91312 7.7515 5.49439 6.83703 6.32318C5.92255 7.15198 5.23512 8.20078 4.84001 9.37C4.79887 9.46531 4.77824 9.56821 4.77947 9.67202C4.7807 9.77583 4.80375 9.87821 4.84714 9.97252C4.89052 10.0668 4.95326 10.151 5.03129 10.2194C5.10931 10.2879 5.20087 10.3392 5.30001 10.37C5.38273 10.3844 5.4673 10.3844 5.55001 10.37C5.70646 10.3684 5.85861 10.3186 5.98568 10.2273C6.11275 10.136 6.20856 10.0078 6.26001 9.86C6.53938 9.0301 7.00847 8.27681 7.63001 7.66C8.70957 6.58464 10.1713 5.98085 11.695 5.98085C13.2188 5.98085 14.6805 6.58464 15.76 7.66L16.6 8.5H14.19C13.9911 8.5 13.8003 8.57902 13.6597 8.71967C13.519 8.86032 13.44 9.05109 13.44 9.25C13.44 9.44891 13.519 9.63968 13.6597 9.78033C13.8003 9.92098 13.9911 10 14.19 10H18.43C18.5289 10.0013 18.627 9.98286 18.7186 9.94565C18.8102 9.90844 18.8934 9.85324 18.9633 9.78333C19.0333 9.71341 19.0885 9.6302 19.1257 9.5386C19.1629 9.44699 19.1814 9.34886 19.18 9.25V5C19.18 4.80109 19.101 4.61032 18.9603 4.46967C18.8197 4.32902 18.6289 4.25 18.43 4.25Z"
|
|
4
|
-
fill="#000000"/>
|
|
5
|
-
<path d="M18.68 13.68C18.5837 13.6422 18.4808 13.6244 18.3774 13.6277C18.274 13.6311 18.1724 13.6555 18.0787 13.6995C17.9851 13.7435 17.9015 13.8062 17.8329 13.8836C17.7643 13.9611 17.7123 14.0517 17.68 14.15C17.4006 14.9799 16.9316 15.7332 16.31 16.35C15.2305 17.4254 13.7688 18.0291 12.245 18.0291C10.7213 18.0291 9.25957 17.4254 8.18001 16.35L7.34001 15.51H9.81002C10.0089 15.51 10.1997 15.431 10.3403 15.2903C10.481 15.1497 10.56 14.9589 10.56 14.76C10.56 14.5611 10.481 14.3703 10.3403 14.2297C10.1997 14.089 10.0089 14.01 9.81002 14.01H5.57001C5.47115 14.0086 5.37302 14.0271 5.28142 14.0643C5.18982 14.1016 5.1066 14.1568 5.03669 14.2267C4.96677 14.2966 4.91158 14.3798 4.87436 14.4714C4.83715 14.563 4.81867 14.6611 4.82001 14.76V19C4.82001 19.1989 4.89903 19.3897 5.03968 19.5303C5.18034 19.671 5.3711 19.75 5.57001 19.75C5.76893 19.75 5.95969 19.671 6.10034 19.5303C6.241 19.3897 6.32001 19.1989 6.32001 19V16.57L7.16001 17.41C8.02901 18.2864 9.10761 18.926 10.2934 19.2683C11.4791 19.6105 12.7327 19.6439 13.935 19.3654C15.1374 19.0869 16.2485 18.5056 17.163 17.6768C18.0775 16.848 18.7649 15.7992 19.16 14.63C19.1926 14.5362 19.2061 14.4368 19.1995 14.3377C19.1929 14.2386 19.1664 14.1418 19.1216 14.0532C19.0768 13.9645 19.0146 13.8858 18.9387 13.8217C18.8629 13.7576 18.7749 13.7094 18.68 13.68Z"
|
|
6
|
-
fill="#000000"/>
|
|
7
|
-
</svg>
|
qcanvas/util/themes.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
import qdarktheme
|
|
4
|
-
|
|
5
|
-
_logger = logging.getLogger(__name__)
|
|
6
|
-
|
|
7
|
-
default_theme = "auto"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def ensure_theme_is_valid(theme: str) -> str:
|
|
11
|
-
if theme not in ["auto", "light", "dark", "native"]:
|
|
12
|
-
return default_theme
|
|
13
|
-
else:
|
|
14
|
-
return theme
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def apply(theme: str) -> None:
|
|
18
|
-
theme = ensure_theme_is_valid(theme)
|
|
19
|
-
|
|
20
|
-
if theme != "native":
|
|
21
|
-
qdarktheme.setup_theme(
|
|
22
|
-
theme,
|
|
23
|
-
custom_colors={"primary": "e02424"},
|
|
24
|
-
)
|