Compare commits
132 Commits
replays_fi
...
2025-03-01
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec452aabe2 | ||
|
|
2a9599eed8 | ||
|
|
58a2b7ff39 | ||
|
|
448903efe3 | ||
|
|
d76e8f9146 | ||
|
|
3620664a9f | ||
|
|
7ff43f15fc | ||
|
|
e271e6ecf8 | ||
|
|
93d28717e0 | ||
|
|
6df97a156f | ||
|
|
05d06f9016 | ||
|
|
e8574641b0 | ||
|
|
9ac13018c6 | ||
|
|
06b25f1cfc | ||
|
|
6f5d369416 | ||
|
|
4543038fd8 | ||
|
|
345f8b772c | ||
|
|
47311b1dfd | ||
|
|
21e22ed5fb | ||
|
|
0d6497fcdc | ||
|
|
bfaeeb5aea | ||
|
|
b46667f6db | ||
|
|
49932ee6f8 | ||
|
|
57e37e8f4d | ||
|
|
af68a95964 | ||
|
|
959a268f91 | ||
|
|
77a3515470 | ||
|
|
6a008acb2b | ||
|
|
247e1aff83 | ||
|
|
3df4efebaa | ||
|
|
5c8d1f3cff | ||
|
|
01d5e58a5f | ||
|
|
a28300ac42 | ||
|
|
0666483756 | ||
|
|
abca5514af | ||
|
|
2247c66ea6 | ||
|
|
3b638598ad | ||
|
|
63e3e3ceb1 | ||
|
|
23f4c9c4e4 | ||
|
|
356b00e8c7 | ||
|
|
8916e049bd | ||
|
|
287b4a5597 | ||
|
|
d77ee00e70 | ||
|
|
18ac4c2bd4 | ||
|
|
2dc614c6b7 | ||
|
|
7c9bf75393 | ||
|
|
d1102939a2 | ||
|
|
cb060f43b5 | ||
|
|
80bd783d54 | ||
|
|
82b147d235 | ||
|
|
6944f5f81c | ||
|
|
8cbfe85ed4 | ||
|
|
eb2c71d381 | ||
|
|
86161185d9 | ||
|
|
79bf3adb2a | ||
|
|
07ca243d48 | ||
|
|
edaca772c5 | ||
|
|
b30b72b7c3 | ||
|
|
57eab3d48a | ||
|
|
2c6e7d4d3a | ||
|
|
9ec621a1ae | ||
|
|
23223e10b5 | ||
|
|
94129607e5 | ||
|
|
d951b082c4 | ||
|
|
1ee0e87ba7 | ||
|
|
67091fff9c | ||
|
|
9b4f51d1e4 | ||
|
|
a6649d5401 | ||
|
|
b509eed3e0 | ||
|
|
12ae7a9eeb | ||
|
|
e6e3333673 | ||
|
|
218ed726b6 | ||
|
|
0503fe589c | ||
|
|
e599c6bdac | ||
|
|
c2292c11a6 | ||
|
|
ec9feb9f50 | ||
|
|
9680e47bbc | ||
|
|
f782bd709a | ||
|
|
c00b41f3bd | ||
|
|
94e2d64e55 | ||
|
|
4535a70b57 | ||
|
|
6c1b7c83ec | ||
|
|
f0adafb275 | ||
|
|
9dd60d74d1 | ||
|
|
1de09deb59 | ||
|
|
a0b52ce450 | ||
|
|
95cea0f191 | ||
|
|
0fc05e15cd | ||
|
|
26c0cdc072 | ||
|
|
b1b48d50f3 | ||
|
|
349c18aa6a | ||
|
|
b956fd4bac | ||
|
|
34e0130b90 | ||
|
|
33d8edeb9a | ||
|
|
5d1e905255 | ||
|
|
51c542aa04 | ||
|
|
4d791f4d7a | ||
|
|
aee68f8b00 | ||
|
|
b911ea6e28 | ||
|
|
a41e7c75c1 | ||
|
|
9f729bf636 | ||
|
|
42e4c14a82 | ||
|
|
37a0c00b3f | ||
|
|
f6c31bf901 | ||
|
|
b48fe8b99c | ||
|
|
19b758591b | ||
|
|
ec6a23de56 | ||
|
|
ce416df3fb | ||
|
|
4e96157091 | ||
|
|
f428148f64 | ||
|
|
e8b1e3ef0c | ||
|
|
085f0dd26c | ||
|
|
1d2ab8d3d3 | ||
|
|
66e2e7a473 | ||
|
|
af161f00b7 | ||
|
|
420cca2402 | ||
|
|
97fdf11c8f | ||
|
|
aeb1b9fb4f | ||
|
|
b004e91aa4 | ||
|
|
090cc8c144 | ||
|
|
0467fae51b | ||
|
|
aa24502129 | ||
|
|
e752578d15 | ||
|
|
724db755af | ||
|
|
ec0caaf421 | ||
|
|
55b490ade0 | ||
|
|
1392bdd258 | ||
|
|
648c96ac3d | ||
|
|
d3a1538af3 | ||
|
|
2bc71095dd | ||
|
|
92a903b035 | ||
|
|
cd373edf3d |
11
.github/workflows/desktop-build.yml
vendored
@@ -330,7 +330,7 @@ jobs:
|
||||
if: matrix.make_package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macOS${{matrix.target}}${{ matrix.soc == 'Intel' && '_Intel' || '' }}${{ matrix.type == 'Debug' && '_Debug' || '' }}-dmg
|
||||
name: macOS${{matrix.target}}${{ matrix.soc == 'Intel' && '_Intel' || '' }}${{ matrix.type == 'Debug' && '_Debug' || '' }}-package
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
@@ -414,6 +414,15 @@ jobs:
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload pdb database
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Windows${{matrix.target}}-debug-pdbs
|
||||
path: |
|
||||
build/cockatrice/Release/*.pdb
|
||||
build/servatrice/Release/*.pdb
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
|
||||
@@ -74,11 +74,11 @@ endif()
|
||||
|
||||
# A project name is needed for CPack
|
||||
# Version can be overriden by git tags, see cmake/getversion.cmake
|
||||
project("Cockatrice" VERSION 2.10.0)
|
||||
project("Cockatrice" VERSION 2.10.1)
|
||||
|
||||
# Set release name if not provided via env/cmake var
|
||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||
set(GIT_TAG_RELEASENAME "Rings of the Wild")
|
||||
set(GIT_TAG_RELEASENAME "Omenpath")
|
||||
endif()
|
||||
|
||||
# Use c++20 for all targets
|
||||
@@ -140,12 +140,15 @@ endif()
|
||||
|
||||
# Define proper compilation flags
|
||||
if(MSVC)
|
||||
# Visual Studio: Disable Warning C4251, C++20 compatibility, Multi-threaded Builds, Warn Detection, Unwind Semantics
|
||||
set(CMAKE_CXX_FLAGS "/wd4251 /Zc:__cplusplus /std:c++20 /permissive- /W4 /MP /EHsc")
|
||||
# Disable Warning C4251, C++20 compatibility, Multi-threaded Builds, Warn Detection, Unwind Semantics, Debug Symbols
|
||||
set(CMAKE_CXX_FLAGS "/wd4251 /Zc:__cplusplus /std:c++20 /permissive- /W4 /MP /EHsc /Zi")
|
||||
# Visual Studio: Maximum Optimization, Multi-threaded DLL
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD")
|
||||
# Visual Studio: No Optimization, Multi-threaded Debug DLL, Debug Symbols
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/Od /MDd /Zi")
|
||||
# Visual Studio: No Optimization, Multi-threaded Debug DLL
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/Od /MDd")
|
||||
|
||||
# Generate PDB, even when in release (So developers can better analyze crash logs)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
|
||||
|
||||
add_compile_definitions(_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING)
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
@@ -23,6 +23,7 @@ if(WITH_CLIENT)
|
||||
Svg
|
||||
WebSockets
|
||||
Widgets
|
||||
Xml
|
||||
)
|
||||
endif()
|
||||
if(WITH_ORACLE)
|
||||
|
||||
@@ -238,7 +238,7 @@ ${If} $PortableMode = 0
|
||||
|
||||
; Enable Windows User-Mode Dumps
|
||||
; https://learn.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\cockatrice.exe" "DumpFolder" "%LOCALAPPDATA%\CrashDumps\Cockatrice"
|
||||
WriteRegExpandStr HKLM "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\cockatrice.exe" "DumpFolder" "%LOCALAPPDATA%\CrashDumps\Cockatrice"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\cockatrice.exe" "DumpCount" "5"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\Windows Error Reporting\LocalDumps\cockatrice.exe" "DumpType" "2"
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ set(cockatrice_SOURCES
|
||||
src/game/board/abstract_graphics_item.cpp
|
||||
src/game/board/arrow_item.cpp
|
||||
src/game/board/arrow_target.cpp
|
||||
src/client/ui/widgets/general/display/banner_widget.cpp
|
||||
src/game/cards/card_database.cpp
|
||||
src/game/cards/card_database_manager.cpp
|
||||
src/game/cards/card_database_model.cpp
|
||||
@@ -35,6 +36,7 @@ set(cockatrice_SOURCES
|
||||
src/deck/deck_list_model.cpp
|
||||
src/deck/deck_stats_interface.cpp
|
||||
src/dialogs/dlg_connect.cpp
|
||||
src/dialogs/dlg_convert_deck_to_cod_format.cpp
|
||||
src/dialogs/dlg_create_token.cpp
|
||||
src/dialogs/dlg_create_game.cpp
|
||||
src/dialogs/dlg_edit_avatar.cpp
|
||||
@@ -63,8 +65,6 @@ set(cockatrice_SOURCES
|
||||
src/game/filters/filter_tree.cpp
|
||||
src/game/filters/filter_tree_model.cpp
|
||||
src/client/ui/layouts/flow_layout.cpp
|
||||
src/client/ui/layouts/horizontal_flow_layout.cpp
|
||||
src/client/ui/layouts/vertical_flow_layout.cpp
|
||||
src/client/ui/widgets/general/layout_containers/flow_widget.cpp
|
||||
src/game/game_scene.cpp
|
||||
src/game/game_selector.cpp
|
||||
@@ -82,6 +82,7 @@ set(cockatrice_SOURCES
|
||||
src/utility/logger.cpp
|
||||
src/client/ui/widgets/cards/card_info_picture_enlarged_widget.cpp
|
||||
src/client/ui/widgets/cards/card_info_picture_with_text_overlay_widget.cpp
|
||||
src/client/ui/widgets/general/display/banner_widget.cpp
|
||||
src/client/ui/widgets/general/display/labeled_input.cpp
|
||||
src/client/ui/widgets/general/display/dynamic_font_size_label.cpp
|
||||
src/client/ui/widgets/general/display/dynamic_font_size_push_button.cpp
|
||||
@@ -110,9 +111,9 @@ set(cockatrice_SOURCES
|
||||
src/client/ui/widgets/printing_selector/printing_selector_card_search_widget.cpp
|
||||
src/client/ui/widgets/printing_selector/printing_selector_card_selection_widget.cpp
|
||||
src/client/ui/widgets/printing_selector/printing_selector_card_sorting_widget.cpp
|
||||
src/client/ui/widgets/printing_selector/printing_selector_view_options_toolbar_widget.cpp
|
||||
src/client/ui/widgets/printing_selector/printing_selector_view_options_widget.cpp
|
||||
src/client/ui/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp
|
||||
src/client/ui/widgets/quick_settings/settings_button_widget.cpp
|
||||
src/client/ui/widgets/quick_settings/settings_popup_widget.cpp
|
||||
src/client/network/release_channel.cpp
|
||||
src/client/network/client_update_checker.cpp
|
||||
src/server/remote/remote_client.cpp
|
||||
@@ -141,6 +142,7 @@ set(cockatrice_SOURCES
|
||||
src/client/tabs/tab.cpp
|
||||
src/client/tabs/tab_account.cpp
|
||||
src/client/tabs/tab_admin.cpp
|
||||
src/client/tabs/abstract_tab_deck_editor.cpp
|
||||
src/client/tabs/tab_deck_editor.cpp
|
||||
src/client/tabs/tab_deck_storage.cpp
|
||||
src/client/tabs/tab_game.cpp
|
||||
@@ -150,6 +152,19 @@ set(cockatrice_SOURCES
|
||||
src/client/tabs/tab_room.cpp
|
||||
src/client/tabs/tab_server.cpp
|
||||
src/client/tabs/tab_supervisor.cpp
|
||||
src/client/tabs/api/edhrec/tab_edhrec.cpp
|
||||
src/client/tabs/api/edhrec/edhrec_commander_api_response_display_widget.cpp
|
||||
src/client/tabs/api/edhrec/edhrec_commander_api_response_card_details_display_widget.cpp
|
||||
src/client/tabs/api/edhrec/edhrec_commander_api_response_card_list_display_widget.cpp
|
||||
src/client/tabs/api/edhrec/edhrec_commander_api_response_commander_details_display_widget.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_archidekt_links.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_average_deck_statistics.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_card_details.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_card_list.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_card_container.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_card_prices.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response_commander_details.cpp
|
||||
src/client/tabs/api/edhrec/api_response/edhrec_commander_api_response.cpp
|
||||
src/game/zones/table_zone.cpp
|
||||
src/client/tapped_out_interface.cpp
|
||||
src/client/ui/theme_manager.cpp
|
||||
@@ -164,6 +179,7 @@ set(cockatrice_SOURCES
|
||||
src/client/ui/window_main.cpp
|
||||
src/game/zones/view_zone_widget.cpp
|
||||
src/game/zones/view_zone.cpp
|
||||
src/client/menus/deck_editor/deck_editor_menu.cpp
|
||||
src/client/tabs/visual_deck_storage/tab_deck_storage_visual.cpp
|
||||
src/client/ui/widgets/cards/deck_preview_card_picture_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_widget.cpp
|
||||
@@ -175,9 +191,15 @@ set(cockatrice_SOURCES
|
||||
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp
|
||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp
|
||||
src/client/ui/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp
|
||||
src/client/ui/widgets/deck_editor/deck_editor_database_display_widget.cpp
|
||||
src/client/ui/widgets/deck_editor/deck_editor_deck_dock_widget.cpp
|
||||
src/client/ui/widgets/deck_editor/deck_editor_filter_dock_widget.cpp
|
||||
src/client/ui/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
@@ -324,6 +346,13 @@ if(APPLE)
|
||||
PATTERN "tls/*.dylib"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_BINARY_DIR}/cockatrice/"
|
||||
DESTINATION ${qtconf_dest_dir}/
|
||||
FILES_MATCHING
|
||||
PATTERN "*.ini"
|
||||
)
|
||||
|
||||
install(
|
||||
CODE "
|
||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||
@@ -358,6 +387,13 @@ if(WIN32)
|
||||
PATTERN "*.dll"
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_BINARY_DIR}/cockatrice/"
|
||||
DESTINATION ./
|
||||
FILES_MATCHING
|
||||
PATTERN "*.ini"
|
||||
)
|
||||
|
||||
# Qt plugins: audio (Qt5), iconengines, imageformats, multimedia (Qt6) platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||
install(
|
||||
DIRECTORY "${QT_PLUGINS_DIR}/"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<qresource prefix="/">
|
||||
<file>resources/cardback.svg</file>
|
||||
<file>resources/cockatrice.svg</file>
|
||||
<file>resources/hand.svg</file>
|
||||
@@ -13,9 +13,12 @@
|
||||
<file>resources/icons/arrow_top_green.svg</file>
|
||||
<file>resources/icons/arrow_up_green.svg</file>
|
||||
<file>resources/icons/clearsearch.svg</file>
|
||||
<file>resources/icons/cogwheel.svg</file>
|
||||
<file>resources/icons/conceded.svg</file>
|
||||
<file>resources/icons/decrement.svg</file>
|
||||
<file>resources/icons/delete.svg</file>
|
||||
<file>resources/icons/dropdown_collapsed.svg</file>
|
||||
<file>resources/icons/dropdown_expanded.svg</file>
|
||||
<file>resources/icons/forgot_password.svg</file>
|
||||
<file>resources/icons/increment.svg</file>
|
||||
<file>resources/icons/info.svg</file>
|
||||
@@ -24,7 +27,9 @@
|
||||
<file>resources/icons/pencil.svg</file>
|
||||
<file>resources/icons/player.svg</file>
|
||||
<file>resources/icons/ready_start.svg</file>
|
||||
<file>resources/icons/reload.svg</file>
|
||||
<file>resources/icons/remove_row.svg</file>
|
||||
<file>resources/icons/rename.svg</file>
|
||||
<file>resources/icons/scales.svg</file>
|
||||
<file>resources/icons/search.svg</file>
|
||||
<file>resources/icons/settings.svg</file>
|
||||
@@ -329,39 +334,42 @@
|
||||
<file>resources/replay/fastforward.svg</file>
|
||||
<file>resources/replay/pause.svg</file>
|
||||
|
||||
<file>resources/userlevels/normal.svg</file>
|
||||
<file>resources/userlevels/registered.svg</file>
|
||||
<file>resources/userlevels/registered_buddy.svg</file>
|
||||
<file>resources/userlevels/registered_vip.svg</file>
|
||||
<file>resources/userlevels/registered_vip_buddy.svg</file>
|
||||
<file>resources/userlevels/registered_donator.svg</file>
|
||||
<file>resources/userlevels/registered_donator_buddy.svg</file>
|
||||
|
||||
<file>resources/userlevels/moderator.svg</file>
|
||||
<file>resources/userlevels/moderator_buddy.svg</file>
|
||||
<file>resources/userlevels/moderator_vip.svg</file>
|
||||
<file>resources/userlevels/moderator_vip_buddy.svg</file>
|
||||
|
||||
<file>resources/userlevels/admin.svg</file>
|
||||
<file>resources/userlevels/admin_buddy.svg</file>
|
||||
<file>resources/userlevels/admin_vip.svg</file>
|
||||
<file>resources/userlevels/admin_vip_buddy.svg</file>
|
||||
<file>resources/usericons/pawn_single.svg</file>
|
||||
<file>resources/usericons/pawn_double.svg</file>
|
||||
<file>resources/usericons/pawn_donator_single.svg</file>
|
||||
<file>resources/usericons/pawn_donator_double.svg</file>
|
||||
<file>resources/usericons/pawn_judge_single.svg</file>
|
||||
<file>resources/usericons/pawn_judge_double.svg</file>
|
||||
<file>resources/usericons/pawn_vip_single.svg</file>
|
||||
<file>resources/usericons/pawn_vip_double.svg</file>
|
||||
<file>resources/usericons/star_single.svg</file>
|
||||
<file>resources/usericons/star_double.svg</file>
|
||||
|
||||
<!-- ADD TIP OF THE DAY IMAGES HERE -->
|
||||
<file>resources/tips/images/accounts_tab.png</file>
|
||||
<file>resources/tips/images/add_card.png</file>
|
||||
<file>resources/tips/images/arrows.png</file>
|
||||
<file>resources/tips/images/card_select.png</file>
|
||||
<file>resources/tips/images/cockatrice_register.png</file>
|
||||
<file>resources/tips/images/cockatrice_wiki.png</file>
|
||||
<file>resources/tips/images/coin_flip.png</file>
|
||||
<file>resources/tips/images/counter_expression.png</file>
|
||||
<file>resources/tips/images/discord.png</file>
|
||||
<file>resources/tips/images/edhrec.png</file>
|
||||
<file>resources/tips/images/expand_card_view.png</file>
|
||||
<file>resources/tips/images/face_down.png</file>
|
||||
<file>resources/tips/images/filter_games.png</file>
|
||||
<file>resources/tips/images/github_logo.png</file>
|
||||
<file>resources/tips/images/highlight_cards.png</file>
|
||||
<file>resources/tips/images/pawns.png</file>
|
||||
<file>resources/tips/images/setpt.png</file>
|
||||
<file>resources/tips/images/shortcuts.png</file>
|
||||
<file>resources/tips/images/syntax_help.png</file>
|
||||
<file>resources/tips/images/themes.png</file>
|
||||
<file>resources/tips/images/tip_of_the_day.png</file>
|
||||
<file>resources/tips/images/token.png</file>
|
||||
<file>resources/tips/images/updates.png</file>
|
||||
<file>resources/tips/images/visual_deck_tags.png</file>
|
||||
<file>resources/tips/tips_of_the_day.xml</file>
|
||||
|
||||
<file>resources/help/search.md</file>
|
||||
|
||||
@@ -1,3 +1,57 @@
|
||||
[Rules]
|
||||
picture_loader.debug = true
|
||||
deck_loader.debug = true
|
||||
# Uncomment a rule to disable logging for that category
|
||||
|
||||
# main = false
|
||||
# qt_translator = false
|
||||
# window_main.* = false
|
||||
# release_channel = false
|
||||
# spoiler_background_updater = false
|
||||
# theme_manager = false
|
||||
# sound_engine = false
|
||||
# tapped_out_interface = false
|
||||
|
||||
# tab_game = false
|
||||
# tab_message = false
|
||||
# tab_supervisor = false
|
||||
|
||||
# dlg_edit_avatar = false
|
||||
# dlg_settings = false
|
||||
# dlg_tip_of_the_day = false
|
||||
# dlg_update = false
|
||||
|
||||
# settings_cache = false
|
||||
# servers_settings = false
|
||||
# shortcuts_settings = false
|
||||
|
||||
# remote_client = false
|
||||
|
||||
# player = false
|
||||
# game_scene = false
|
||||
# game_scene.player_addition_removal = false
|
||||
# card_zone = false
|
||||
# view_zone = false
|
||||
|
||||
# user_info_connection = false
|
||||
|
||||
# picture_loader = false
|
||||
# picture_loader.worker = false
|
||||
# picture_loader.card_back_cache_fail = false
|
||||
# picture_loader.picture_to_load = false
|
||||
# deck_loader = false
|
||||
# card_database = false
|
||||
# card_database.loading = false
|
||||
# card_database.loading.success_or_failure = false
|
||||
# cockatrice_xml.* = false
|
||||
# cockatrice_xml.xml_3_parser = false
|
||||
# cockatrice_xml.xml_4_parser = false
|
||||
# card_list = false
|
||||
|
||||
# stack_zone = false
|
||||
|
||||
flow_layout.debug = false
|
||||
flow_widget.debug = false
|
||||
flow_widget.size.debug = false
|
||||
|
||||
# pixel_map_generator = false
|
||||
|
||||
# filter_string = false
|
||||
29
cockatrice/resources/icons/cogwheel.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" width="102.5024mm" height="102.24421mm"
|
||||
viewBox="0 0 102.5024 102.24421" version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="cog_wheel.svg"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview id="namedview1" pagecolor="#ffffff" bordercolor="#000000" borderopacity="0.25"
|
||||
inkscape:showpageshadow="2" inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="0.66101291"
|
||||
inkscape:cx="146.74449" inkscape:cy="193.64221" inkscape:window-width="1829"
|
||||
inkscape:window-height="951" inkscape:window-x="0" inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" inkscape:current-layer="layer1"/>
|
||||
<defs id="defs1"/>
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-66.148059,-97.377896)">
|
||||
<g id="g1" transform="translate(-165.09777,-82.009607)">
|
||||
<g id="g2" transform="matrix(0.26458333,0,0,0.26458333,64.983323,161.37858)">
|
||||
<path style="fill:#333333;stroke-width:94.4882"
|
||||
d="m 721.34301,94.413051 40.00966,29.763289 29.51933,-9.27053 14.63768,-46.840589 36.83817,0.48792 13.41787,46.108699 28.29952,9.5145 40.74155,-28.299519 29.0314,21.468599 -15.85748,47.08454 16.58937,23.66426 48.30432,-2.68358 12.93,34.88648 -41.71741,27.07971 -0.48792,29.27536 40.49763,26.10387 -10.2464,34.15459 -48.54834,-0.97584 -18.78502,23.42029 15.85749,45.37681 -28.29952,21.71256 -41.22947,-29.27536 -28.54348,9.75846 -13.66184,47.57246 -38.30194,-0.73188 -14.63768,-48.30435 -27.07971,-9.27054 -40.00966,29.27537 -30.25121,-20.49276 17.32125,-46.35266 -17.80918,-24.64009 -49.76812,3.17149 -11.22222,-34.64251 40.74155,-27.07971 0.48792,-30.00725 -41.71739,-27.32367 12.19807,-32.93479 48.30435,2.68358 20.24879,-24.6401 -17.32126,-47.08455 z"
|
||||
id="path1"/>
|
||||
<circle style="fill:#f9f9f9;stroke-width:72.1317" id="path2" cx="822.09906" cy="261.28262"
|
||||
r="83.434792"/>
|
||||
<circle style="fill:#4d4d4d;stroke-width:40.5147" id="circle2" cx="822.09906" cy="261.28262"
|
||||
r="46.863361"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
10
cockatrice/resources/icons/dropdown_collapsed.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="460.5" height="531.74"
|
||||
viewBox="0 0 460.5 531.74" overflow="visible" enable-background="new 0 0 460.5 531.74" xml:space="preserve">
|
||||
<polygon fill="#918d8d" points="0.5,0.866 459.5,265.87 0.5,530.874 "/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 657 B |
10
cockatrice/resources/icons/dropdown_expanded.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.1" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="531.74" height="460.5"
|
||||
viewBox="0 0 531.74 460.5" overflow="visible" enable-background="new 0 0 531.74 460.5" xml:space="preserve">
|
||||
<polygon fill="#918d8d" points="530.874,0.5 265.87,459.5 0.866,0.5 "/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 657 B |
7
cockatrice/resources/icons/reload.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||
<g><path d="M586.9,373.6l95.6-84.4c-49.6-39.2-129.4-79.1-198.2-79.1c-134.9,0-248.2,90.5-280.2,212.8L10.6,374.5C64.4,168.3,255.2,15.8,482.5,15.8c126.7,0,258.8,63.7,345.4,141.4l90.8-80.1L990,479.6L586.9,373.6z M317.5,710.8c49.6,39.2,129.4,79.1,198.2,79.1c134.9,0,248.2-90.5,280.2-212.8l193.5,48.5c-53.7,206.2-244.6,358.7-471.9,358.7c-126.7,0-258.8-63.7-345.4-141.4l-90.8,80.1L10,520.4l403.1,106L317.5,710.8z"/></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 797 B |
10
cockatrice/resources/icons/rename.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="1200pt" height="1200pt" version="1.1" viewBox="0 0 1200 1200" xmlns="http://www.w3.org/2000/svg">
|
||||
<path transform="scale(50)" d="m17 16h4v-8h-4" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path transform="scale(50)" d="m12 8h-9v8h9" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path transform="scale(50)" d="m6 12h5" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path transform="scale(50)" d="m20 4h-2c-1.1 0-2 0.9-2 2v12c0 1.1 0.9 2 2 2h2" fill="none" stroke="#000"
|
||||
stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2"/>
|
||||
<path transform="scale(50)" d="m12 20h2c1.1 0 2-0.9 2-2v-12c0-1.1-0.9-2-2-2h-2" fill="none" stroke="#000"
|
||||
stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 875 B |
BIN
cockatrice/resources/tips/images/add_card.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
cockatrice/resources/tips/images/card_select.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
cockatrice/resources/tips/images/edhrec.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
cockatrice/resources/tips/images/expand_card_view.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 227 KiB After Width: | Height: | Size: 70 KiB |
BIN
cockatrice/resources/tips/images/highlight_cards.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
cockatrice/resources/tips/images/pawns.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 39 KiB |
BIN
cockatrice/resources/tips/images/syntax_help.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
cockatrice/resources/tips/images/token.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
cockatrice/resources/tips/images/updates.png
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
cockatrice/resources/tips/images/visual_deck_tags.png
Normal file
|
After Width: | Height: | Size: 136 KiB |
@@ -1,99 +1,222 @@
|
||||
<tips>
|
||||
<tip>
|
||||
<title>Tip of the Day</title>
|
||||
<text>Tip of the Day is a new feature to Cockatrice that allows users to get information about the newest features of the program and some of the most commonly asked questions!</text>
|
||||
<image>tip_of_the_day.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Suggesting New Tips</title>
|
||||
<text>You can suggest new Tips of the Day by reaching out to the development team on <a href="https://discord.gg/3Z9yzmA">Discord</a>!</text>
|
||||
<image>discord.png</image>
|
||||
<date>2023-10-18</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Reporting Bugs</title>
|
||||
<text>If you encounter a bug while using Cockatrice, you can report the bug to the development team via <a href="https://github.com/cockatrice/cockatrice/issues">GitHub<a></text>
|
||||
<image>github_logo.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>FAQ/Troubleshooting Wiki</title>
|
||||
<text>You can find answers to the most common questions and some helpful Cockatrice toubleshooting over on the <a href="https://github.com/cockatrice/cockatrice/wiki">GitHub wiki<a></text>
|
||||
<image>cockatrice_wiki.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Register for a Server</title>
|
||||
<text>Click on either Cockatrice (Windows) or Actions (Mac) and then Register to server... When the dialogue appears, fill out the desired server information.</text>
|
||||
<image>cockatrice_register.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Drawing Arrows</title>
|
||||
<text>You can draw arrows of different color by holding a combination of keys!
|
||||
Right Click: Red Arrow
|
||||
Shift + Right Click: Green Arrow
|
||||
Alt + Right Click: Blue Arrow
|
||||
Cmd + Right Click: Yellow Arrow
|
||||
</text>
|
||||
<image>arrows.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Filtering Games</title>
|
||||
<text>Don't see all the active games? Want to see a smaller selection? Use the Game Filters to change your horizon</text>
|
||||
<image>filter_games.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Upload Custom Avatar</title>
|
||||
<text>Want to show off your hippo avatar? Need to update your password? Check out the Accounts Tab for more info!</text>
|
||||
<image>accounts_tab.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Common Shortcuts</title>
|
||||
<text>You can find a full list of shortcuts <a href="https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts">on the wiki</a>, but a short list:
|
||||
<br>Roll a die: CTRL + I
|
||||
<br>Mulligan: CTRL + M
|
||||
<br>Draw a card: CTRL + D
|
||||
<br>Undo a draw: CTRL + SHIFT + D
|
||||
<br>View Sideboard: CTRL + F3
|
||||
<br>Change Life: CTRL + L
|
||||
<br>All shortcuts can be customized via Settings->Shortcuts!
|
||||
</text>
|
||||
<image>shortcuts.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Changing Themes</title>
|
||||
<text>Did you know Cockatrice has custom themes? You can either <a href="https://github.com/Cockatrice/Cockatrice/wiki/Themes">create one yourself</a> or use one of the several pre-loaded ones! Go to Settings->Appearance and try them out!</text>
|
||||
<image>themes.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Flip of the Coin</title>
|
||||
<text>You can flip a coin instead of rolling a die by rolling a 2 sided die instead!</text>
|
||||
<image>coin_flip.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Face Down Cards</title>
|
||||
<text>You can hold Shift while dragging or clicking on a card to have it enter play face down</text>
|
||||
<image>face_down.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Counter expressions</title>
|
||||
<text>When setting a counter value, you can type a math expression in the box and the counter will be set to the result.<br>The "x" variable contains the current counter value.</text>
|
||||
<image>counter_expression.png</image>
|
||||
<date>2019-02-02</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Power and Toughness</title>
|
||||
<text>You can add and subtract to a creature's stats.<br>With a card selected, set the power and toughness ( default: ctrl + p ) and enter +3/-1 to increase power by three while decreasing toughness by one.<br>You can also reset it to the original value ( default: ctrl + alt + 0 ).</text>
|
||||
<image>setpt.png</image>
|
||||
<date>2019-03-02</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Tip of the Day</title>
|
||||
<text>Tip of the Day is a feature to Cockatrice that allows users to get information about the newest features of the program and some of the most commonly asked questions!
|
||||
Check back in with major updates for new tips to be added or old tips to be updated as features are added or expanded upon!
|
||||
</text>
|
||||
<image>tip_of_the_day.png</image>
|
||||
<date>2025-02-10</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Join the Community</title>
|
||||
<text>You can join the community to find games, interact with other players, suggest new 'Tips of the Day' and provide user feedback to the development or support teams on <a href="https://discord.gg/3Z9yzmA">Discord</a>!</text>
|
||||
<image>discord.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Reporting Bugs and Requesting Features</title>
|
||||
<text>If you encounter a bug while using Cockatrice, you can report the bug to and request the feature from the development team via <a href="https://github.com/cockatrice/cockatrice/issues">GitHub<a></text>
|
||||
<image>github_logo.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>FAQ/Troubleshooting Wiki</title>
|
||||
<text>You can find answers to the most common questions and some helpful Cockatrice troubleshooting over on the <a href="https://github.com/cockatrice/cockatrice/wiki">GitHub wiki<a></text>
|
||||
<image>cockatrice_wiki.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Register for a Server</title>
|
||||
<text>Click on either Cockatrice (Windows) or Actions (Mac) and then Register to server... When the dialogue appears, fill out the desired server information.</text>
|
||||
<image>cockatrice_register.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Filtering Games</title>
|
||||
<text>Don't see an open game or want to see a smaller selection? Use the Game Filters to change your horizon!</text>
|
||||
<image>filter_games.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Common Shortcuts</title>
|
||||
<text>You can find a full list of default shortcuts <a href="https://github.com/Cockatrice/Cockatrice/wiki/Custom-Keyboard-Shortcuts">on the wiki</a> or in Settings -> Shortcuts, but a short list:
|
||||
<ul>
|
||||
<li>Roll a die: CMD/CTRL + I</li>
|
||||
<li>Mulligan: CMD/CTRL + M</li>
|
||||
<li>Draw 1 / X card(s): CMD/CTRL + D / E</li>
|
||||
<li>Undo a draw: CMD/CTRL + SHIFT + D</li>
|
||||
<li>View Library / Sideboard: F3 / CMD/CTRL + F3</li>
|
||||
<li>Change Life: CMD/CTRL + L</li>
|
||||
<li>Show Card Info: Middle Mouse Click</li>
|
||||
</ul>
|
||||
All shortcuts can be customized via Cockatrice -> Settings -> Shortcuts!
|
||||
</text>
|
||||
<image>shortcuts.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Power and Toughness</title>
|
||||
<text>You can add and subtract to a creature's stats.
|
||||
With a card selected, with the following keybindings:
|
||||
|
||||
<ul>
|
||||
<li>Set P/T to any value: CTRL + P</li>
|
||||
<li>+1 or -1 to both to P/T: CMD/CTRL + ALT + '+' or '-'</li>
|
||||
<li>+1 or -1 to Power Only: CMD/CTRL + '+' or '-'</li>
|
||||
<li>+1 or -1 to Toughness Only: ALT + '+' or '-'</li>
|
||||
<li>Set P/T to Default: CMD/CTRL + ALT + 0</li>
|
||||
</ul>
|
||||
All shortcuts can be customized via Cockatrice -> Settings -> Shortcuts!
|
||||
</text>
|
||||
<image>setpt.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Drawing Arrows</title>
|
||||
<text>You can draw arrows of different color by holding a combination of keys!
|
||||
|
||||
<ul>
|
||||
<li>Right Click: Red Arrow</li>
|
||||
<li>SHIFT + Right Click: Green Arrow</li>
|
||||
<li>ALT + Right Click: Blue Arrow</li>
|
||||
<li>CMD/CTRL + Right Click: Yellow Arrow</li>
|
||||
</ul>
|
||||
</text>
|
||||
<image>arrows.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>General Etiquette</title>
|
||||
<text>When playing on Cockatrice there are general "rules of engagement" for a better play experience for all players.
|
||||
The following are some of the expectations a player should reasonably expect for how to operate smooth and enjoyable games:
|
||||
<ul>
|
||||
<li>Have a "Rule 0" conversation pre-game with your fellow players on the expectations of the game including deck strength, house rules (e.g. no take backs and "may is not must"), etc.</li>
|
||||
<li>When rolling your die for turn order, it is often best to create a token with the text of your roll (using CTRL + T and typing the number into "Name") and then tap this token when created to show that you have resolved your mulligans and are ready to start the game.</li>
|
||||
<li>Use the phases and steps trackers on the left of the client to show others where in the turn you are and announce when moving between them. (Double Click for the action of this button)</li>
|
||||
<li>When your turn is over leave it on your end step and DO NOT HIT PASS. Allow other players to respond if they can, and then if not, let the next player pass to themselves.</li>
|
||||
<li>Please treat others kindly and respect as per <a href="https://cockatrice.us/terms.php">our Terms of Service</a>.</li>
|
||||
</ul>
|
||||
</text>
|
||||
<image>token.png</image>
|
||||
<date>2025-02-10</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Flip of the Coin</title>
|
||||
<text>You can flip a coin instead of rolling a die by rolling a 2 sided die instead!</text>
|
||||
<image>coin_flip.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Upload Custom Avatar</title>
|
||||
<text>Want to show off your hippo avatar? Need to update your password? Check out the Accounts Tab for more info!</text>
|
||||
<image>accounts_tab.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Player Icon Key</title>
|
||||
<text>Besides your name is a player icon, this is a key for what they mean:
|
||||
<ul>
|
||||
<li>Flag: Country of Origin Player Selected</li>
|
||||
<li>Purple Heart: Donator (<a href="https://cockatrice.us/donate">Help support us and donate here!</a>)</li>
|
||||
<li>Gold Star: VIP (Special Admin Given Role)</li>
|
||||
<li>Brown Gavel (Hammer): Judge / Rule's Lawyer</li>
|
||||
<li>Black/White Pawn: Moderator (Support for Client Issues)</li>
|
||||
<li>Red: Administrator (Sever Operators)</li>
|
||||
</ul>
|
||||
</text>
|
||||
<image>pawns.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Changing Themes</title>
|
||||
<text>Did you know Cockatrice has custom themes? You can either <a href="https://github.com/Cockatrice/Cockatrice/wiki/Themes">create one yourself</a> or use one of the several preloaded ones! Go to Settings->Appearance and try them out!</text>
|
||||
<image>themes.png</image>
|
||||
<date>2018-03-01</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Face Down Cards</title>
|
||||
<text>You can hold Shift while dragging or clicking on a card to have it enter play face down.
|
||||
You can also hold CTRL + SHIFT and click and drag from your library to move bottom card face down as well!
|
||||
</text>
|
||||
<image>face_down.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Counter expressions</title>
|
||||
<text>When setting a counter value, you can type a math expression in the box and the counter will be set to the result.<br>The "x" variable contains the current counter value.</text>
|
||||
<image>counter_expression.png</image>
|
||||
<date>2019-02-02</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Select Multiple Cards</title>
|
||||
<text>You can click and drag in any zone in order to highlight all cards within the created box.
|
||||
You can also hold CMD/CTRL and clik or click and drag to maintain other previously selected cards while adding others!
|
||||
You can move, alter and attach multiple highlighted cards at the same time!
|
||||
Other useful multi-select keybindings:
|
||||
<ul>
|
||||
<li>Select All Cards in Zone: CMD/CTRL + A</li>
|
||||
<li>Select All Cards in Column: CMD/CTRL + SHIFT + C</li>
|
||||
<li>Select All Cards in Row: CMD/CTRL + SHIFT + X</li>
|
||||
</ul>
|
||||
</text>
|
||||
<image>highlight_cards.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Auto Cascade and Search Parameters</title>
|
||||
<text>You can use the default keybind of CMD/CTRL + SHIFT + Y in order to perform auto cascade or similar effects from your library using Scryfall search syntax.
|
||||
If you are unfamiliar with the syntax you may find it by opening a deck in deck editor and clicking the "i" next to the search bar in order to pull up a list of syntax commands.
|
||||
This same syntax can be used in the deck editor search bar as well to help you find the best cards for your decks!
|
||||
</text>
|
||||
<image>syntax_help.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Visual Deck Storage and Tags</title>
|
||||
<text>You can now view your saved decks visually with integrated folder,tags and filter support!
|
||||
Pro Tip: If you want to use emoji's press WinKey + '.' or CTRL + CMD + SPACE on Windows or Mac respectively!
|
||||
</text>
|
||||
<image>visual_deck_tags.png</image>
|
||||
<date>2025-02-09</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Card Selector And Card Preferences</title>
|
||||
<text>Cockatrice's deck editor now has the ability for players to bling out their decks by selecting the arts for cards on a per-card basis!
|
||||
You can also have multiple printings of the same card in your deck if you so choose!
|
||||
Not only that, other players will see the arts you have chosen by default!
|
||||
If you want to disable this feature for other players: Settings -> Appearance -> Select "Override all card art with personal set preference"
|
||||
</text>
|
||||
<image>card_select.png</image>
|
||||
<date>2025-02-10</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>EDHREC Integration</title>
|
||||
<text>We now have in-client integration for EDHREC, which allows you to right-click on any card name in the deck editor in order to bring up the contextual menu for the card.</text>
|
||||
<image>edhrec.png</image>
|
||||
<date>2025-02-10</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Add Cards to Deck</title>
|
||||
<text>You can now right-click anywhere on a card in any card info view in order to add it to any decks you have open in your tabs.</text>
|
||||
<image>add_card.png</image>
|
||||
<date>2025-02-10</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Update Client and Card Database</title>
|
||||
<text>You can update your client by going to Help and selecting whichever you wish to update.
|
||||
Client Update: Updates the client (if available) for new features, fixes and changes.
|
||||
Card Update: Updates card sources for spoilers and new card printings.
|
||||
Updating your card sources can often fix issues of cards not working or displaying properly, if not, go to Cockatrice -> Settings -> Card Sources -> Update Spoilers
|
||||
</text>
|
||||
<image>updates.png</image>
|
||||
<date>2025-02-10</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Expand Card View Window</title>
|
||||
<text>Double click on the title bar of the card view window to expand it! Double click again to shrink it back down.
|
||||
You can configure the initial and expanded heights of the window in the settings, under "Appearance".
|
||||
</text>
|
||||
<image>expand_card_view.png</image>
|
||||
<date>2025-02-27</date>
|
||||
</tip>
|
||||
</tips>
|
||||
|
||||
@@ -2,20 +2,20 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="registered.svg">
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="pawn_donator_double.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
@@ -226,16 +226,6 @@
|
||||
offset="1"
|
||||
id="stop5193-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5181-9"
|
||||
id="linearGradient5436"
|
||||
x1="12.105612"
|
||||
y1="1021.5341"
|
||||
x2="87.549789"
|
||||
y2="1021.5341"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,-952.36218)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
@@ -288,6 +278,28 @@
|
||||
id="linearGradient5799"
|
||||
xlink:href="#linearGradient5181-9"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2"
|
||||
id="linearGradient3"
|
||||
x1="49.889599"
|
||||
y1="87.971054"
|
||||
x2="50.103622"
|
||||
y2="27.668242"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2878408,0,0,1.2878408,-14.204862,937.12313)" />
|
||||
<linearGradient
|
||||
id="linearGradient2"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#8c5fd3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2" />
|
||||
<stop
|
||||
style="stop-color:#b284e9;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
@@ -297,16 +309,26 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="-150.71429"
|
||||
inkscape:cy="59.570011"
|
||||
inkscape:zoom="6.0735294"
|
||||
inkscape:cx="53.675545"
|
||||
inkscape:cy="53.922518"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
inkscape:window-width="1147"
|
||||
inkscape:window-height="1211"
|
||||
inkscape:window-x="2678"
|
||||
inkscape:window-y="120"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showguides="true">
|
||||
<sodipodi:guide
|
||||
position="49.829627,61.114263"
|
||||
orientation="1,0"
|
||||
id="guide1"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
@@ -325,9 +347,20 @@
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:url(#linearGradient5436);fill-opacity:1;stroke:black;stroke-width:2.78220295999999980;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
style="fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
transform="translate(0,952.36218)"
|
||||
id="path3597-8" />
|
||||
id="right" />
|
||||
<path
|
||||
style="opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 51.28696,1001.834 0,-46.98372 1.434151,0.16768 c 5.155008,0.60274 9.462857,2.72154 12.938257,6.36366 4.74393,4.9715 6.87913,11.35611 6.16464,18.43328 -0.53702,5.31935 -3.09008,10.59498 -6.83833,14.13074 l -1.94072,1.83069 3.04083,2.20427 c 3.58084,2.5957 7.18975,6.4912 9.55296,10.3116 4.89572,7.9144 9.23593,21.4918 8.50487,26.6055 -0.81312,5.6877 -5.43872,9.6977 -13.62216,11.8093 -3.80822,0.9826 -7.68056,1.4713 -14.763321,1.8633 l -4.471177,0.2474 0,-46.9837 z"
|
||||
id="left"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;fill:url(#linearGradient3);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.77952756;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
d="m 32.758369,1023.3386 c -11.433625,-11.4486 -17.473759,-17.611 -17.925056,-18.2881 -5.1991493,-7.80033 -4.072462,-18.0055 2.698653,-24.44352 0.714467,-0.67932 1.7595,-1.54783 2.322296,-1.93001 1.523368,-1.0345 4.16292,-2.23825 5.970504,-2.72281 1.443337,-0.38692 1.89368,-0.43006 4.608041,-0.44142 3.235152,-0.0136 4.137158,0.12212 6.533598,0.9827 3.134814,1.12573 4.852536,2.32851 8.590659,6.01531 1.655211,1.63249 3.214977,3.04629 3.466142,3.14178 0.581823,0.22121 1.425484,0.22197 2.004581,0.002 0.248578,-0.0945 1.808341,-1.50526 3.466143,-3.135 3.106188,-3.05362 4.561863,-4.18308 6.729637,-5.22153 5.163233,-2.47341 10.985326,-2.50551 16.312741,-0.0899 2.006474,0.90978 3.995303,2.39379 5.679043,4.16678 1.393273,1.46713 2.577641,3.13214 3.390238,4.83339 1.300107,2.7219 1.79207,4.98307 1.79207,8.23671 0,4.67613 -1.161204,8.04312 -4.066015,11.78952 -0.567611,0.7321 -8.293484,8.5311 -17.668765,17.8362 l -16.660107,16.5352 z"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="sssssssssssssssssscs"
|
||||
inkscape:label="heart" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
229
cockatrice/resources/usericons/pawn_donator_single.svg
Normal file
@@ -0,0 +1,229 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="pawn_donator_single.svg"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
|
||||
id="defs3"><linearGradient
|
||||
id="linearGradient2"
|
||||
inkscape:collect="always"><stop
|
||||
style="stop-color:#8c5fd3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2" /><stop
|
||||
style="stop-color:#b284e9;stop-opacity:1;"
|
||||
offset="0.5"
|
||||
id="stop1" /></linearGradient><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective5328" /><inkscape:perspective
|
||||
id="perspective5305"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><linearGradient
|
||||
id="linearGradient5181"><stop
|
||||
style="stop-color:#0fbb00;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5183" /><stop
|
||||
style="stop-color:#064400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5185" /></linearGradient><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-2"
|
||||
id="radialGradient3606-7"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" /><linearGradient
|
||||
id="linearGradient3600-2"><stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-4" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-9" /></linearGradient><inkscape:perspective
|
||||
id="perspective5478"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><linearGradient
|
||||
id="linearGradient5189"><stop
|
||||
style="stop-color:#000ec9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191" /><stop
|
||||
style="stop-color:#000657;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193" /></linearGradient><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-4"
|
||||
id="radialGradient3606-1"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" /><linearGradient
|
||||
id="linearGradient3600-4"><stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-3" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-5" /></linearGradient><inkscape:perspective
|
||||
id="perspective5559"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173"
|
||||
id="linearGradient5179"
|
||||
x1="167.33386"
|
||||
y1="178.83276"
|
||||
x2="244.78181"
|
||||
y2="178.83276"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
id="linearGradient5173"><stop
|
||||
style="stop-color:#f50000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5175" /><stop
|
||||
style="stop-color:#950000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5177" /></linearGradient><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600"
|
||||
id="radialGradient5169"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276" /><linearGradient
|
||||
id="linearGradient3600"><stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604" /></linearGradient><radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5574"
|
||||
xlink:href="#linearGradient3600"
|
||||
inkscape:collect="always" /><inkscape:perspective
|
||||
id="perspective5663"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
id="radialGradient3606-8"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" /><linearGradient
|
||||
id="linearGradient3600-7"><stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-7" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-6" /></linearGradient><radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5676"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
inkscape:collect="always" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2"
|
||||
id="linearGradient3"
|
||||
x1="49.889599"
|
||||
y1="87.971054"
|
||||
x2="50.103622"
|
||||
y2="27.668242"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2878408,0,0,1.2878408,-14.204016,-15.239682)" /></defs><sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.9195959"
|
||||
inkscape:cx="55.179583"
|
||||
inkscape:cy="45.519999"
|
||||
inkscape:current-layer="layer2"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1147"
|
||||
inkscape:window-height="1211"
|
||||
inkscape:window-x="3260"
|
||||
inkscape:window-y="138"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showguides="true"><sodipodi:guide
|
||||
position="50.002551,111.99556"
|
||||
orientation="1,0"
|
||||
id="guide3"
|
||||
inkscape:locked="false" /></sodipodi:namedview><metadata
|
||||
id="metadata4"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)"
|
||||
style="display:inline"><path
|
||||
style="display:inline;opacity:1;fill-opacity:1;stroke:#000000;stroke-width:2.7822;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 49.84375,1.71875 C 36.719738,1.71875 26.0625,12.375988 26.0625,25.5 c 0,7.477454 3.475825,14.112734 8.875,18.46875 -10.497549,5.974948 -17.018351,18.227376 -20.625,31.6875 -5.2744126,19.6844 15.911513,22.5625 35.53125,22.5625 19.619736,0 40.705577,-3.2516 35.53125,-22.5625 C 81.693381,61.916246 75.224585,49.827177 64.8125,43.9375 70.181573,39.580662 73.59375,32.953205 73.59375,25.5 c 0,-13.124012 -10.625988,-23.78125 -23.75,-23.78125 z"
|
||||
id="left"
|
||||
transform="translate(0,952.36218)" /></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"><path
|
||||
style="display:inline;fill:url(#linearGradient3);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.77952756;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
d="M 32.759215,70.975878 C 21.325591,59.527249 15.285457,53.364742 14.83416,52.687661 9.63501,44.887358 10.761698,34.682189 17.532813,28.244167 c 0.714467,-0.67932 1.7595,-1.547825 2.322296,-1.930012 1.523368,-1.034499 4.16292,-2.238249 5.970504,-2.722807 1.443337,-0.386915 1.89368,-0.430056 4.60804,-0.441421 3.235152,-0.01355 4.137158,0.122126 6.533598,0.982701 3.134814,1.125736 4.852536,2.328512 8.590659,6.015311 1.655211,1.632489 3.214977,3.046293 3.466142,3.141784 0.581823,0.221209 1.425484,0.221963 2.004581,0.0018 0.248578,-0.09451 1.808341,-1.50526 3.466143,-3.135003 3.106188,-3.053615 4.561863,-4.183076 6.729637,-5.221531 5.163233,-2.473409 10.985326,-2.505514 16.312741,-0.08995 2.006474,0.909779 3.995303,2.393791 5.679043,4.166785 1.393273,1.467129 2.577641,3.132133 3.390238,4.833386 1.300107,2.721904 1.79207,4.98307 1.79207,8.23671 0,4.676126 -1.161204,8.043076 -4.066015,11.789548 -0.567611,0.732076 -8.293484,8.531153 -17.668765,17.836181 l -16.660107,16.53525 z"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="sssssssssssssssssscs"
|
||||
inkscape:label="heart" /></g></svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
@@ -2,20 +2,20 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="normal.svg">
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="pawn_double.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
@@ -195,66 +195,16 @@
|
||||
id="stop3604-6" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
id="radialGradient5254"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
r="25.501276" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5189-1"
|
||||
id="linearGradient5394"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="385.03503"
|
||||
y1="180.09546"
|
||||
x2="462.48297"
|
||||
y2="180.09546"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-360.365,847.52359)" />
|
||||
<linearGradient
|
||||
id="linearGradient5189-1">
|
||||
<stop
|
||||
style="stop-color:#32c8ed;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191-0" />
|
||||
<stop
|
||||
style="stop-color:#32c8ed;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="180.09546"
|
||||
x2="462.48297"
|
||||
y1="180.09546"
|
||||
x1="385.03503"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-318.22214,876.88769)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5411"
|
||||
xlink:href="#linearGradient5189-1"
|
||||
id="radialGradient5676"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5189-1"
|
||||
id="linearGradient5436"
|
||||
x1="12.105612"
|
||||
y1="1021.5341"
|
||||
x2="87.549789"
|
||||
y2="1021.5341"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5189-1"
|
||||
id="linearGradient3795"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="12.105612"
|
||||
y1="1021.5341"
|
||||
x2="87.549789"
|
||||
y2="1021.5341"
|
||||
gradientTransform="translate(0,-952.36218)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
@@ -264,16 +214,19 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="-150.71429"
|
||||
inkscape:cy="59.570011"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="63.214286"
|
||||
inkscape:cy="46.160714"
|
||||
inkscape:current-layer="g5249"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
inkscape:window-width="1147"
|
||||
inkscape:window-height="1211"
|
||||
inkscape:window-x="2842"
|
||||
inkscape:window-y="58"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
@@ -291,10 +244,25 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:url(#linearGradient3795);fill-opacity:1;stroke:black;stroke-width:2.78220295999999980;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;opacity:1"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
transform="translate(0,952.36218)"
|
||||
id="path3597-8" />
|
||||
<g
|
||||
id="g5249"
|
||||
transform="translate(0.53874115,0.90502985)">
|
||||
<path
|
||||
style="stroke:#000000;stroke-width:4.45809746000000030;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
|
||||
d="m 49.582319,954.34642 c -12.850034,0 -23.284789,10.43476 -23.284789,23.28479 0,7.32135 3.403263,13.81811 8.689724,18.08319 -10.278401,5.8502 -16.663073,17.8469 -20.19443,31.0259 -5.1178053,19.1 15.207096,22.0401 34.269334,22.0915 l 0,0.031 c 0.290839,0 0.566498,0.031 0.856734,0.031 19.210152,0 39.855802,-3.1837 34.789494,-22.0914 -3.636192,-13.5705 -10.027831,-25.4711 -20.378015,-31.17899 5.208701,-4.26694 8.506139,-10.73278 8.506139,-17.9914 0,-12.85003 -10.404159,-23.28479 -23.254191,-23.28479 z"
|
||||
id="left"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
fill="none"
|
||||
style="stroke:#000000;stroke-width:1.97203517px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 50.522358,952.70715 0,95.71425"
|
||||
id="center"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.71966;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 51.054254,1001.4773 v -45.77683 l 1.097241,0.005 c 3.642211,0.0172 9.170661,2.46935 12.395732,5.49816 4.897489,4.59945 7.421654,10.97001 6.981907,17.62114 -0.389167,5.88609 -2.631878,10.66609 -6.951818,14.81672 l -2.05562,1.97506 2.959813,2.0746 c 3.467097,2.43015 7.403677,6.55065 9.666109,10.11765 3.325898,5.2437 6.79289,13.8355 8.153827,20.2065 2.584451,12.0989 -5.997953,18.2384 -26.592174,19.0232 l -5.655017,0.2154 v -45.7768 z"
|
||||
id="right"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.2 KiB |
@@ -2,33 +2,22 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="registered_vip.svg">
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="pawn_judge_double.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs3">
|
||||
<linearGradient
|
||||
id="linearGradient5181-9-1">
|
||||
<stop
|
||||
id="stop4188"
|
||||
offset="0"
|
||||
style="stop-color:#ece400;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop4190"
|
||||
offset="1"
|
||||
style="stop-color:#ec8b00;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
@@ -237,16 +226,6 @@
|
||||
offset="1"
|
||||
id="stop5193-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5181-9-1"
|
||||
id="linearGradient5436"
|
||||
x1="47.268291"
|
||||
y1="933.14362"
|
||||
x2="48.665382"
|
||||
y2="1050.2666"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,-952.36218)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
@@ -309,15 +288,18 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.2946338"
|
||||
inkscape:cx="35.27742"
|
||||
inkscape:cy="65.175571"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:cx="34.112338"
|
||||
inkscape:cy="64.964794"
|
||||
inkscape:current-layer="svg5322"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1152"
|
||||
inkscape:window-height="811"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="792"
|
||||
inkscape:window-x="2921"
|
||||
inkscape:window-y="661"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
@@ -326,7 +308,7 @@
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
@@ -336,9 +318,20 @@
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:url(#linearGradient5436);fill-opacity:1;stroke:black;stroke-width:2.78149606;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
style="fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
transform="translate(0,952.36218)"
|
||||
id="path3597-8" />
|
||||
id="right" />
|
||||
<path
|
||||
style="opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 51.28696,1001.834 0,-46.98372 1.434151,0.16768 c 5.155008,0.60274 9.462857,2.72154 12.938257,6.36366 4.74393,4.9715 6.87913,11.35611 6.16464,18.43328 -0.53702,5.31935 -3.09008,10.59498 -6.83833,14.13074 l -1.94072,1.83069 3.04083,2.20427 c 3.58084,2.5957 7.18975,6.4912 9.55296,10.3116 4.89572,7.9144 9.23593,21.4918 8.50487,26.6055 -0.81312,5.6877 -5.43872,9.6977 -13.62216,11.8093 -3.80822,0.9826 -7.68056,1.4713 -14.763321,1.8633 l -4.471177,0.2474 0,-46.9837 z"
|
||||
id="left"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 46.656521,12.167234 18.055171,18.054184 a 6.6081919,6.6078288 0 0 1 -0.126303,9.352065 6.6804126,6.6800456 0 0 1 -8.233169,1.011048 l -7.944268,7.943843 6.463762,6.445343 a 6.9331851,6.9328042 0 0 1 5.741536,2.022073 l 28.057729,28.092294 a 6.9962797,6.9958953 0 0 1 -9.894222,9.893685 L 50.719018,66.907526 A 7.0595711,7.0591833 0 0 1 49.18433,59.270613 l -5.741527,-5.741238 -7.944298,7.943843 A 6.716523,6.7161541 0 0 1 25.134866,69.832263 L 7.079684,51.778091 a 6.716523,6.7161541 0 0 1 8.39566,-10.345064 L 36.31101,20.59853 a 6.716523,6.7161541 0 0 1 10.345612,-8.431329 z"
|
||||
id="path1-2"
|
||||
style="display:inline;fill:#e1964c;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3.7852;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:label="gavel"
|
||||
transform="translate(0,952.36218)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
212
cockatrice/resources/usericons/pawn_judge_single.svg
Normal file
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="pawn_judge_single.svg"
|
||||
xml:space="preserve"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"><defs
|
||||
id="defs3"><inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective5328" /><inkscape:perspective
|
||||
id="perspective5305"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><linearGradient
|
||||
id="linearGradient5181"><stop
|
||||
style="stop-color:#0fbb00;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5183" /><stop
|
||||
style="stop-color:#064400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5185" /></linearGradient><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-2"
|
||||
id="radialGradient3606-7"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" /><linearGradient
|
||||
id="linearGradient3600-2"><stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-4" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-9" /></linearGradient><inkscape:perspective
|
||||
id="perspective5478"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><linearGradient
|
||||
id="linearGradient5189"><stop
|
||||
style="stop-color:#000ec9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191" /><stop
|
||||
style="stop-color:#000657;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193" /></linearGradient><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-4"
|
||||
id="radialGradient3606-1"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" /><linearGradient
|
||||
id="linearGradient3600-4"><stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-3" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-5" /></linearGradient><inkscape:perspective
|
||||
id="perspective5559"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173"
|
||||
id="linearGradient5179"
|
||||
x1="167.33386"
|
||||
y1="178.83276"
|
||||
x2="244.78181"
|
||||
y2="178.83276"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
id="linearGradient5173"><stop
|
||||
style="stop-color:#f50000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5175" /><stop
|
||||
style="stop-color:#950000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5177" /></linearGradient><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600"
|
||||
id="radialGradient5169"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276" /><linearGradient
|
||||
id="linearGradient3600"><stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604" /></linearGradient><radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5574"
|
||||
xlink:href="#linearGradient3600"
|
||||
inkscape:collect="always" /><inkscape:perspective
|
||||
id="perspective5663"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" /><radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
id="radialGradient3606-8"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" /><linearGradient
|
||||
id="linearGradient3600-7"><stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-7" /><stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-6" /></linearGradient><radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5676"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
inkscape:collect="always" /></defs><sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="58.035715"
|
||||
inkscape:cy="30.982143"
|
||||
inkscape:current-layer="svg5322"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1369"
|
||||
inkscape:window-x="2552"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showguides="true"><sodipodi:guide
|
||||
position="50.002551,111.99556"
|
||||
orientation="1,0"
|
||||
id="guide3"
|
||||
inkscape:locked="false" /></sodipodi:namedview><metadata
|
||||
id="metadata4"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="display:inline;opacity:1;fill-opacity:1;stroke:#000000;stroke-width:2.7822;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 49.84375,1.71875 C 36.719738,1.71875 26.0625,12.375988 26.0625,25.5 c 0,7.477454 3.475825,14.112734 8.875,18.46875 -10.497549,5.974948 -17.018351,18.227376 -20.625,31.6875 -5.2744126,19.6844 15.911513,22.5625 35.53125,22.5625 19.619736,0 40.705577,-3.2516 35.53125,-22.5625 C 81.693381,61.916246 75.224585,49.827177 64.8125,43.9375 70.181573,39.580662 73.59375,32.953205 73.59375,25.5 c 0,-13.124012 -10.625988,-23.78125 -23.75,-23.78125 z"
|
||||
id="left"
|
||||
sodipodi:insensitive="true"
|
||||
transform="translate(0,952.36218)" />
|
||||
<path
|
||||
d="m 46.233565,28.34179 -1.622479,1.622479 a 0.59382712,0.59382712 0 0 1 -0.840444,-0.01135 0.60031703,0.60031703 0 0 1 -0.09086,-0.739851 l -0.713891,-0.71389 -0.579225,0.580848 a 0.62303175,0.62303175 0 0 1 -0.181718,0.515948 l -2.524576,2.521331 a 0.62870157,0.62870157 0 0 1 -0.889118,-0.889117 l 2.522954,-2.521332 a 0.63438908,0.63438908 0 0 1 0.686308,-0.137911 l 0.515949,-0.515947 -0.713891,-0.713892 a 0.603562,0.603562 0 0 1 -0.751204,-0.9313 l 1.622478,-1.62248 a 0.603562,0.603562 0 0 1 0.929682,0.754453 l 1.872338,1.87234 a 0.603562,0.603562 0 0 1 0.7577,0.92968 z"
|
||||
id="path1-2"
|
||||
style="display:inline;fill:#e1964c;fill-rule:nonzero;stroke:#000000;stroke-width:0.34015748;stroke-opacity:1;fill-opacity:1;stroke-dasharray:none"
|
||||
transform="matrix(0,-11.111111,11.111111,0,-268.32014,1478.2316)"
|
||||
inkscape:label="gavel" /></g></svg>
|
||||
|
After Width: | Height: | Size: 8.9 KiB |
@@ -2,20 +2,20 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="vip.svg">
|
||||
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
|
||||
sodipodi:docname="pawn_single.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
@@ -194,57 +194,16 @@
|
||||
offset="1"
|
||||
id="stop3604-6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5189-1"
|
||||
id="linearGradient5394"
|
||||
<radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="385.03503"
|
||||
y1="180.09546"
|
||||
x2="462.48297"
|
||||
y2="180.09546"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-360.365,847.52359)" />
|
||||
<linearGradient
|
||||
id="linearGradient5189-1">
|
||||
<stop
|
||||
style="stop-color:#000ec9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191-0" />
|
||||
<stop
|
||||
style="stop-color:#000657;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
id="linearGradient5581"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="167.33386"
|
||||
y1="178.83276"
|
||||
x2="244.78181"
|
||||
y2="178.83276"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-149.54484,848.74636)" />
|
||||
<linearGradient
|
||||
id="linearGradient5173-1">
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5175-5" />
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5177-3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="178.83276"
|
||||
x2="244.78181"
|
||||
y1="178.83276"
|
||||
x1="167.33386"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-52.401983,877.75333)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5598"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
id="radialGradient5676"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
inkscape:collect="always" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
@@ -255,16 +214,19 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="-59.166471"
|
||||
inkscape:cy="4.9508223"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="63.214286"
|
||||
inkscape:cy="46.160714"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="792"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
inkscape:window-width="1147"
|
||||
inkscape:window-height="1211"
|
||||
inkscape:window-x="3185"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
@@ -283,9 +245,9 @@
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:#8d5fd3;fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
style="fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;opacity:1"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
id="path3597-8"
|
||||
id="left"
|
||||
transform="translate(0,952.36218)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.1 KiB |
@@ -337,19 +337,19 @@
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
style="fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
transform="translate(0,952.36218)"
|
||||
id="path3597-8" />
|
||||
id="right" />
|
||||
<path
|
||||
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
style="opacity:1;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 51.28696,1001.834 0,-46.98372 1.434151,0.16768 c 5.155008,0.60274 9.462857,2.72154 12.938257,6.36366 4.74393,4.9715 6.87913,11.35611 6.16464,18.43328 -0.53702,5.31935 -3.09008,10.59498 -6.83833,14.13074 l -1.94072,1.83069 3.04083,2.20427 c 3.58084,2.5957 7.18975,6.4912 9.55296,10.3116 4.89572,7.9144 9.23593,21.4918 8.50487,26.6055 -0.81312,5.6877 -5.43872,9.6977 -13.62216,11.8093 -3.80822,0.9826 -7.68056,1.4713 -14.763321,1.8633 l -4.471177,0.2474 0,-46.9837 z"
|
||||
id="path5355"
|
||||
id="left"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:url(#linearGradient3425-5);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path3415-0"
|
||||
id="star"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="27.80283"
|
||||
sodipodi:cy="970.9433"
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -337,14 +337,14 @@
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
style="fill-opacity:1;stroke:black;stroke-width:2.78220296;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
transform="translate(0,952.36218)"
|
||||
id="path3597-8" />
|
||||
id="left" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:url(#linearGradient3425);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path3415"
|
||||
id="star"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="27.80283"
|
||||
sodipodi:cy="970.9433"
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -114,18 +114,18 @@
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
|
||||
id="path4-9"
|
||||
id="outline"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 55.041981,25.814432 36.921945,25.730432 31.404334,7.3935963 25.885923,25.730432 7.7650846,25.814434 22.476316,37.520057 15.0387,57.488097 31.404334,44.800071 47.777965,57.488097 40.331551,37.520057 z"
|
||||
id="path4"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero"
|
||||
id="left"
|
||||
style="fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 56.276895,25.211993 37.3433,24.856806 31.486705,5.7742084 c 0.04705,37.4359336 -0.01851,2.6744908 -0.0678,40.1841446 L 48.19932,58.580578 40.956295,37.527792 z"
|
||||
id="path4-1"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero"
|
||||
id="right"
|
||||
style="fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
@@ -109,7 +109,7 @@
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
|
||||
id="path4"
|
||||
style="fill:url(#linearGradient3756);fill-opacity:1"
|
||||
id="left"
|
||||
style="fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -1,301 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="admin.svg">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective5328" />
|
||||
<inkscape:perspective
|
||||
id="perspective5305"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
id="linearGradient5181">
|
||||
<stop
|
||||
style="stop-color:#0fbb00;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5183" />
|
||||
<stop
|
||||
style="stop-color:#064400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5185" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-2"
|
||||
id="radialGradient3606-7"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" />
|
||||
<linearGradient
|
||||
id="linearGradient3600-2">
|
||||
<stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-4" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-9" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
id="perspective5478"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
id="linearGradient5189">
|
||||
<stop
|
||||
style="stop-color:#000ec9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191" />
|
||||
<stop
|
||||
style="stop-color:#000657;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-4"
|
||||
id="radialGradient3606-1"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" />
|
||||
<linearGradient
|
||||
id="linearGradient3600-4">
|
||||
<stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-3" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-5" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
id="perspective5559"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173"
|
||||
id="linearGradient5179"
|
||||
x1="167.33386"
|
||||
y1="178.83276"
|
||||
x2="244.78181"
|
||||
y2="178.83276"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient5173">
|
||||
<stop
|
||||
style="stop-color:#f50000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5175" />
|
||||
<stop
|
||||
style="stop-color:#950000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5177" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600"
|
||||
id="radialGradient5169"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276" />
|
||||
<linearGradient
|
||||
id="linearGradient3600">
|
||||
<stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5574"
|
||||
xlink:href="#linearGradient3600"
|
||||
inkscape:collect="always" />
|
||||
<inkscape:perspective
|
||||
id="perspective5663"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
id="radialGradient3606-8"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" />
|
||||
<linearGradient
|
||||
id="linearGradient3600-7">
|
||||
<stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-7" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5189-1"
|
||||
id="linearGradient5394"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="385.03503"
|
||||
y1="180.09546"
|
||||
x2="462.48297"
|
||||
y2="180.09546"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-360.365,847.52359)" />
|
||||
<linearGradient
|
||||
id="linearGradient5189-1">
|
||||
<stop
|
||||
style="stop-color:#000ec9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191-0" />
|
||||
<stop
|
||||
style="stop-color:#000657;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
id="linearGradient5436"
|
||||
x1="12.105612"
|
||||
y1="1021.5341"
|
||||
x2="87.549789"
|
||||
y2="1021.5341"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(0,-952.36218)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
id="linearGradient5581"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="167.33386"
|
||||
y1="178.83276"
|
||||
x2="244.78181"
|
||||
y2="178.83276"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-149.54484,848.74636)" />
|
||||
<linearGradient
|
||||
id="linearGradient5173-1">
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5175-5" />
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5177-3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="178.83276"
|
||||
x2="244.78181"
|
||||
y1="178.83276"
|
||||
x1="167.33386"
|
||||
gradientTransform="matrix(0.96839241,0,0,0.96839241,-52.401983,877.75333)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient5598"
|
||||
xlink:href="#linearGradient5173-1"
|
||||
inkscape:collect="always" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.8"
|
||||
inkscape:cx="-32.045264"
|
||||
inkscape:cy="65.284297"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<path
|
||||
style="fill:url(#linearGradient5436);fill-opacity:1;stroke:black;stroke-width:2.78220295999999980;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 49.84375 1.71875 C 36.719738 1.71875 26.0625 12.375988 26.0625 25.5 C 26.0625 32.977454 29.538325 39.612734 34.9375 43.96875 C 24.439951 49.943698 17.919149 62.196126 14.3125 75.65625 C 9.0380874 95.34065 30.224013 98.21875 49.84375 98.21875 C 69.463486 98.21875 90.549327 94.96715 85.375 75.65625 C 81.693381 61.916246 75.224585 49.827177 64.8125 43.9375 C 70.181573 39.580662 73.59375 32.953205 73.59375 25.5 C 73.59375 12.375988 62.967762 1.71875 49.84375 1.71875 z "
|
||||
transform="translate(0,952.36218)"
|
||||
id="path3597-8" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.6 KiB |
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 64 64"
|
||||
enable-background="new 0 0 64 64"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
width="100%"
|
||||
height="100%"
|
||||
sodipodi:docname="admin_buddy.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient3766">
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3768" />
|
||||
<stop
|
||||
style="stop-color:#820000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3770" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5225">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5227" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop5229" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5219"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5221" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3758">
|
||||
<stop
|
||||
id="stop3760"
|
||||
offset="0"
|
||||
style="stop-color:#0fbb00;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762"
|
||||
offset="1"
|
||||
style="stop-color:#064400;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3750">
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3752" />
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3754" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3758-7"
|
||||
id="linearGradient3756-1"
|
||||
x1="1.960216"
|
||||
y1="31.261461"
|
||||
x2="60.456024"
|
||||
y2="31.261461"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3758-7">
|
||||
<stop
|
||||
id="stop3760-4"
|
||||
offset="0"
|
||||
style="stop-color:#ece400;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762-0"
|
||||
offset="1"
|
||||
style="stop-color:#ec8b00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="5.2149125"
|
||||
inkscape:cx="-37.840247"
|
||||
inkscape:cy="51.245759"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
|
||||
id="path4-9"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
|
||||
id="path4"
|
||||
style="fill:#ff2700;fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 64 64"
|
||||
enable-background="new 0 0 64 64"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
width="100%"
|
||||
height="100%"
|
||||
sodipodi:docname="admin_buddy.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient3766">
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3768" />
|
||||
<stop
|
||||
style="stop-color:#820000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3770" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5225">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5227" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop5229" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5219"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5221" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3758">
|
||||
<stop
|
||||
id="stop3760"
|
||||
offset="0"
|
||||
style="stop-color:#0fbb00;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762"
|
||||
offset="1"
|
||||
style="stop-color:#064400;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3750">
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3752" />
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3754" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3758-7"
|
||||
id="linearGradient3756-1"
|
||||
x1="1.960216"
|
||||
y1="31.261461"
|
||||
x2="60.456024"
|
||||
y2="31.261461"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3758-7">
|
||||
<stop
|
||||
id="stop3760-4"
|
||||
offset="0"
|
||||
style="stop-color:#ece400;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762-0"
|
||||
offset="1"
|
||||
style="stop-color:#ec8b00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="5.2149125"
|
||||
inkscape:cx="-37.840247"
|
||||
inkscape:cy="51.245759"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
|
||||
id="path4-9"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
|
||||
id="path4"
|
||||
style="fill:#ff2700;fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,294 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100"
|
||||
height="100"
|
||||
id="svg5322"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
sodipodi:docname="moderator.svg">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective5328" />
|
||||
<inkscape:perspective
|
||||
id="perspective5305"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
id="linearGradient5181">
|
||||
<stop
|
||||
style="stop-color:#0fbb00;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5183" />
|
||||
<stop
|
||||
style="stop-color:#064400;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5185" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-2"
|
||||
id="radialGradient3606-7"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" />
|
||||
<linearGradient
|
||||
id="linearGradient3600-2">
|
||||
<stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-4" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-9" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
id="perspective5478"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
id="linearGradient5189">
|
||||
<stop
|
||||
style="stop-color:#000ec9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5191" />
|
||||
<stop
|
||||
style="stop-color:#000657;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5193" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-4"
|
||||
id="radialGradient3606-1"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" />
|
||||
<linearGradient
|
||||
id="linearGradient3600-4">
|
||||
<stop
|
||||
style="stop-color:#ffc33d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-3" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-5" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
id="perspective5559"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient5173"
|
||||
id="linearGradient5179"
|
||||
x1="167.33386"
|
||||
y1="178.83276"
|
||||
x2="244.78181"
|
||||
y2="178.83276"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient5173">
|
||||
<stop
|
||||
style="stop-color:#f50000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5175" />
|
||||
<stop
|
||||
style="stop-color:#950000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop5177" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600"
|
||||
id="radialGradient5169"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276" />
|
||||
<linearGradient
|
||||
id="linearGradient3600">
|
||||
<stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5574"
|
||||
xlink:href="#linearGradient3600"
|
||||
inkscape:collect="always" />
|
||||
<inkscape:perspective
|
||||
id="perspective5663"
|
||||
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
|
||||
inkscape:vp_z="1 : 0.5 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_x="0 : 0.5 : 1"
|
||||
sodipodi:type="inkscape:persp3d" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
id="radialGradient3606-8"
|
||||
cx="324.32715"
|
||||
cy="131.40274"
|
||||
fx="324.32715"
|
||||
fy="131.40274"
|
||||
r="25.501276"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)" />
|
||||
<linearGradient
|
||||
id="linearGradient3600-7">
|
||||
<stop
|
||||
style="stop-color:#ffc13d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3602-7" />
|
||||
<stop
|
||||
style="stop-color:#e09900;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3604-6" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="25.501276"
|
||||
fy="131.40274"
|
||||
fx="324.32715"
|
||||
cy="131.40274"
|
||||
cx="324.32715"
|
||||
gradientTransform="matrix(0.92332021,0.38403097,-0.41592401,1.0000002,78.192026,-120.05314)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient5676"
|
||||
xlink:href="#linearGradient3600-7"
|
||||
inkscape:collect="always" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:document-units="mm"
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:cx="63.241533"
|
||||
inkscape:cy="46.246766"
|
||||
inkscape:current-layer="g5249"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata4">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-952.36218)">
|
||||
<g
|
||||
id="g5249"
|
||||
transform="translate(0.53874115,0.90502985)">
|
||||
<path
|
||||
style="fill:#ffffff;stroke:#000000;stroke-width:4.45809746000000030;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
|
||||
d="m 49.582319,954.34642 c -12.850034,0 -23.284789,10.43476 -23.284789,23.28479 0,7.32135 3.403263,13.81811 8.689724,18.08319 -10.278401,5.8502 -16.663073,17.8469 -20.19443,31.0259 -5.1178053,19.1 15.207096,22.0401 34.269334,22.0915 l 0,0.031 c 0.290839,0 0.566498,0.031 0.856734,0.031 19.210152,0 39.855802,-3.1837 34.789494,-22.0914 -3.636192,-13.5705 -10.027831,-25.4711 -20.378015,-31.17899 5.208701,-4.26694 8.506139,-10.73278 8.506139,-17.9914 0,-12.85003 -10.404159,-23.28479 -23.254191,-23.28479 z"
|
||||
id="path3597-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.97203517px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 50.522358,952.70715 0,95.71425"
|
||||
id="path5303"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.5844 0,-46.66155 1.096703,0.005 c 3.640423,0.0175 9.166159,2.51708 12.389647,5.60443 4.895085,4.68835 7.418012,11.18204 6.97848,17.96172 -0.388976,5.99986 -2.630586,10.87224 -6.948405,15.1031 l -2.054611,2.01323 2.95836,2.1147 c 3.465395,2.47714 7.400043,6.67727 9.661364,10.31317 3.324266,5.3451 6.789556,14.1029 8.149825,20.5971 2.583182,12.3327 -5.995009,18.5909 -26.579121,19.3908 l -5.652242,0.2196 0,-46.6616 z"
|
||||
id="path5343"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.5844 0,-46.66155 1.096703,0.005 c 3.711439,0.0179 9.230395,2.54932 12.52612,5.74551 2.710429,2.62858 4.363146,5.23853 5.699734,9.00096 0.930917,2.62048 1.042531,3.35671 1.066373,7.03397 0.02902,4.47725 -0.343832,6.4262 -1.860873,9.72679 -1.358173,2.95494 -2.652341,4.81714 -4.971275,7.15326 l -2.043484,2.05863 2.932618,2.09329 c 6.98445,4.98544 12.210204,12.81934 15.750058,23.61084 3.543721,10.8033 3.39602,15.1985 -0.654452,19.4747 -4.329667,4.571 -11.449354,6.7169 -23.88928,7.2003 l -5.652242,0.2196 0,-46.6616 z"
|
||||
id="path5345"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.5844 0,-46.66155 1.127086,0 c 1.963684,0 6.316627,1.3793 8.624731,2.73288 1.305624,0.76568 3.277555,2.429 4.764529,4.01888 4.347263,4.6481 6.318993,10.15893 5.954049,16.6411 -0.326518,5.79966 -2.122114,9.97998 -6.25177,14.55473 -1.44716,1.60313 -2.388203,2.91735 -2.210758,3.08744 0.169927,0.16289 1.447842,1.10199 2.839812,2.08691 6.268453,4.43531 11.362918,11.94641 14.960201,22.05661 2.740177,7.7013 3.480992,12.7857 2.399253,16.4664 -0.490882,1.6703 -1.040601,2.5538 -2.66191,4.2781 -4.29247,4.5651 -11.326737,6.6778 -23.892981,7.176 l -5.652242,0.2241 0,-46.6616 z"
|
||||
id="path5347"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.5855 0,-46.66265 1.127086,0 c 1.830826,0 6.182017,1.32383 8.427379,2.56398 3.074383,1.69804 7.222246,6.22736 8.789514,9.59784 4.043357,8.69543 2.602054,18.25614 -3.837601,25.45626 -1.482649,1.65774 -2.695724,3.09743 -2.695724,3.19932 0,0.10189 1.186029,0.99046 2.635621,1.97461 3.078254,2.08987 6.81705,5.92344 9.062839,9.29254 3.274171,4.9119 7.232757,14.564 8.731682,21.29 0.646579,2.9014 0.614978,6.1318 -0.08275,8.4594 -0.86467,2.8846 -4.147214,6.2392 -7.573604,7.74 -5.13932,2.251 -10.156844,3.194 -18.763476,3.5265 l -5.820965,0.2249 0,-46.6627 z"
|
||||
id="path5349"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.5853 0,-46.66245 1.164456,0 c 4.764705,0 11.112502,3.49049 14.697127,8.08157 5.260553,6.73756 6.190324,16.72129 2.284493,24.53056 -0.608066,1.21576 -2.304134,3.5367 -3.77148,5.16099 -1.466571,1.62342 -2.603753,3.01808 -2.527074,3.09924 0.07667,0.0811 1.300896,0.95003 2.720481,1.93083 6.904062,4.77006 12.487313,13.40446 16.085176,24.87536 1.733472,5.5268 2.208105,8.1847 2.003089,11.2173 -0.604468,8.9414 -9.318247,13.5855 -26.66658,14.2125 l -5.989688,0.2165 0,-46.6624 z"
|
||||
id="path5351"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.7111 0,-46.78825 1.265427,0.005 c 4.153532,0.0173 9.758512,2.75815 13.295303,6.50137 1.792452,1.89707 2.63621,3.17089 3.798098,5.73397 1.746736,3.85324 2.225454,6.0014 2.225454,9.98629 0,6.50755 -2.416561,12.11247 -7.223569,16.75421 -0.945331,0.91283 -1.642858,1.7317 -1.550059,1.81971 0.0928,0.088 1.155757,0.85585 2.362131,1.70631 3.35942,2.36829 4.992087,3.86859 7.229212,6.64329 3.924869,4.8681 7.249491,11.7229 9.87191,20.3544 1.173448,3.8623 1.289753,4.5994 1.289753,8.1737 0,3.6878 -0.0614,4.0459 -1.001592,5.8425 -1.309266,2.5017 -3.108338,4.122 -6.422247,5.7839 -4.375689,2.1945 -9.62921,3.3669 -16.70364,3.7278 -2.134354,0.1088 -4.905639,0.2757 -6.158413,0.3708 l -2.277768,0.1729 0,-46.7882 z"
|
||||
id="path5353"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.73577702;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 51.062274,1000.6174 0,-46.98372 1.434151,0.16768 c 5.155008,0.60274 9.462857,2.72154 12.938259,6.36366 4.743924,4.9715 6.879132,11.35611 6.164642,18.43328 -0.537028,5.31935 -3.090083,10.59498 -6.838339,14.13074 l -1.940717,1.83069 3.040832,2.20427 c 3.580837,2.59571 7.189745,6.4912 9.552957,10.3116 4.895721,7.9144 9.235933,21.4918 8.504868,26.6055 -0.813112,5.6877 -5.438715,9.6977 -13.622159,11.8093 -3.808212,0.9826 -7.680557,1.4713 -14.763317,1.8633 l -4.471177,0.2474 0,-46.9837 z"
|
||||
id="path5355"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 14 KiB |
@@ -1,131 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 64 64"
|
||||
enable-background="new 0 0 64 64"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.5 r10040"
|
||||
width="100%"
|
||||
height="100%"
|
||||
sodipodi:docname="moderator_buddy.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient5225">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5227" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop5229" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5219"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5221" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3758">
|
||||
<stop
|
||||
id="stop3760"
|
||||
offset="0"
|
||||
style="stop-color:#0fbb00;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762"
|
||||
offset="1"
|
||||
style="stop-color:#064400;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3750">
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3752" />
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3754" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3758-7"
|
||||
id="linearGradient3756-1"
|
||||
x1="1.960216"
|
||||
y1="31.261461"
|
||||
x2="60.456024"
|
||||
y2="31.261461"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3758-7">
|
||||
<stop
|
||||
id="stop3760-4"
|
||||
offset="0"
|
||||
style="stop-color:#ece400;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762-0"
|
||||
offset="1"
|
||||
style="stop-color:#ec8b00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1028"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="5.2149125"
|
||||
inkscape:cx="-26.445493"
|
||||
inkscape:cy="31.598459"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
|
||||
id="path4-9"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 55.041981,25.814432 36.921945,25.730432 31.404334,7.3935963 25.885923,25.730432 7.7650846,25.814434 22.476316,37.520057 15.0387,57.488097 31.404334,44.800071 47.777965,57.488097 40.331551,37.520057 z"
|
||||
id="path4"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 56.276895,25.211993 37.3433,24.856806 31.486705,5.7742084 c 0.04705,37.4359336 -0.01851,2.6744908 -0.0678,40.1841446 L 48.19932,58.580578 40.956295,37.527792 z"
|
||||
id="path4-1"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,137 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 64 64"
|
||||
enable-background="new 0 0 64 64"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
width="100%"
|
||||
height="100%"
|
||||
sodipodi:docname="vip_buddy.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient3766">
|
||||
<stop
|
||||
style="stop-color:#ff2700;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3768" />
|
||||
<stop
|
||||
style="stop-color:#820000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3770" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5225">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5227" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop5229" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient5219"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop5221" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3758">
|
||||
<stop
|
||||
id="stop3760"
|
||||
offset="0"
|
||||
style="stop-color:#0fbb00;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762"
|
||||
offset="1"
|
||||
style="stop-color:#064400;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3750">
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3752" />
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3754" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3758-7"
|
||||
id="linearGradient3756-1"
|
||||
x1="1.960216"
|
||||
y1="31.261461"
|
||||
x2="60.456024"
|
||||
y2="31.261461"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3758-7">
|
||||
<stop
|
||||
id="stop3760-4"
|
||||
offset="0"
|
||||
style="stop-color:#ece400;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762-0"
|
||||
offset="1"
|
||||
style="stop-color:#ec8b00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-height="792"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="5.2149125"
|
||||
inkscape:cx="14.509163"
|
||||
inkscape:cy="51.245759"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
|
||||
id="path4-9"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
|
||||
id="path4"
|
||||
style="fill:#8d5fd3;fill-opacity:1;fill-rule:nonzero"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,127 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 64 64"
|
||||
enable-background="new 0 0 64 64"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
width="100%"
|
||||
height="100%"
|
||||
sodipodi:docname="registered_vip_buddy.svg">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
id="linearGradient4153">
|
||||
<stop
|
||||
style="stop-color:#ffec79;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4155" />
|
||||
<stop
|
||||
style="stop-color:#f2c15b;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4157" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3758">
|
||||
<stop
|
||||
id="stop3760"
|
||||
offset="0"
|
||||
style="stop-color:#80d600;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762"
|
||||
offset="1"
|
||||
style="stop-color:#80d600;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3750">
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3752" />
|
||||
<stop
|
||||
style="stop-color:#ece400;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3754" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3758-7"
|
||||
id="linearGradient3756"
|
||||
x1="31.290251"
|
||||
y1="-19.003599"
|
||||
x2="31.135509"
|
||||
y2="67.496323"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.87626222,0,0,0.87626222,4.174756,4.8555263)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3758-7"
|
||||
id="linearGradient3756-1"
|
||||
x1="1.960216"
|
||||
y1="31.261461"
|
||||
x2="60.456024"
|
||||
y2="31.261461"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3758-7">
|
||||
<stop
|
||||
id="stop3760-4"
|
||||
offset="0"
|
||||
style="stop-color:#ece400;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3762-0"
|
||||
offset="1"
|
||||
style="stop-color:#ec8b00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1152"
|
||||
inkscape:window-height="811"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
inkscape:zoom="7.375"
|
||||
inkscape:cx="29.258475"
|
||||
inkscape:cy="35.341768"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
|
||||
id="path4-9"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
|
||||
id="path4"
|
||||
style="fill:url(#linearGradient3756);fill-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -98,8 +98,8 @@ protected:
|
||||
virtual void sendCommandContainer(const CommandContainer &cont) = 0;
|
||||
|
||||
public:
|
||||
AbstractClient(QObject *parent = nullptr);
|
||||
~AbstractClient();
|
||||
explicit AbstractClient(QObject *parent = nullptr);
|
||||
~AbstractClient() override;
|
||||
|
||||
ClientStatus getStatus() const
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ signals:
|
||||
void onCtrlC();
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *, QEvent *event);
|
||||
bool eventFilter(QObject *, QEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
171
cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include "deck_editor_menu.h"
|
||||
|
||||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../../settings/shortcuts_settings.h"
|
||||
|
||||
DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEditor)
|
||||
: QMenu(parent), deckEditor(_deckEditor)
|
||||
{
|
||||
aNewDeck = new QAction(QString(), this);
|
||||
connect(aNewDeck, SIGNAL(triggered()), deckEditor, SLOT(actNewDeck()));
|
||||
|
||||
aLoadDeck = new QAction(QString(), this);
|
||||
connect(aLoadDeck, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeck()));
|
||||
|
||||
loadRecentDeckMenu = new QMenu(this);
|
||||
connect(&SettingsCache::instance().recents(), &RecentsSettings::recentlyOpenedDeckPathsChanged, this,
|
||||
&DeckEditorMenu::updateRecentlyOpened);
|
||||
|
||||
aClearRecents = new QAction(QString(), this);
|
||||
connect(aClearRecents, &QAction::triggered, this, &DeckEditorMenu::actClearRecents);
|
||||
|
||||
updateRecentlyOpened();
|
||||
|
||||
aSaveDeck = new QAction(QString(), this);
|
||||
connect(aSaveDeck, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeck()));
|
||||
|
||||
aSaveDeckAs = new QAction(QString(), this);
|
||||
connect(aSaveDeckAs, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckAs()));
|
||||
|
||||
aLoadDeckFromClipboard = new QAction(QString(), this);
|
||||
connect(aLoadDeckFromClipboard, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeckFromClipboard()));
|
||||
|
||||
aSaveDeckToClipboard = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboard, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboard()));
|
||||
|
||||
aSaveDeckToClipboardNoSetNameAndNumber = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboardNoSetNameAndNumber, SIGNAL(triggered()), deckEditor,
|
||||
SLOT(actSaveDeckToClipboardNoSetNameAndNumber()));
|
||||
|
||||
aSaveDeckToClipboardRaw = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboardRaw, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboardRaw()));
|
||||
|
||||
aSaveDeckToClipboardRawNoSetNameAndNumber = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboardRawNoSetNameAndNumber, SIGNAL(triggered()), deckEditor,
|
||||
SLOT(actSaveDeckToClipboardRawNoSetNameAndNumber()));
|
||||
|
||||
aPrintDeck = new QAction(QString(), this);
|
||||
connect(aPrintDeck, SIGNAL(triggered()), deckEditor, SLOT(actPrintDeck()));
|
||||
|
||||
aExportDeckDecklist = new QAction(QString(), this);
|
||||
connect(aExportDeckDecklist, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklist()));
|
||||
|
||||
aAnalyzeDeckDeckstats = new QAction(QString(), this);
|
||||
connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckDeckstats()));
|
||||
|
||||
aAnalyzeDeckTappedout = new QAction(QString(), this);
|
||||
connect(aAnalyzeDeckTappedout, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckTappedout()));
|
||||
|
||||
analyzeDeckMenu = new QMenu(this);
|
||||
analyzeDeckMenu->addAction(aExportDeckDecklist);
|
||||
analyzeDeckMenu->addAction(aAnalyzeDeckDeckstats);
|
||||
analyzeDeckMenu->addAction(aAnalyzeDeckTappedout);
|
||||
|
||||
aClose = new QAction(QString(), this);
|
||||
connect(aClose, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::closeRequest);
|
||||
|
||||
saveDeckToClipboardMenu = new QMenu(this);
|
||||
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboard);
|
||||
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardNoSetNameAndNumber);
|
||||
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardRaw);
|
||||
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardRawNoSetNameAndNumber);
|
||||
|
||||
addAction(aNewDeck);
|
||||
addAction(aLoadDeck);
|
||||
addMenu(loadRecentDeckMenu);
|
||||
addAction(aSaveDeck);
|
||||
addAction(aSaveDeckAs);
|
||||
addSeparator();
|
||||
addAction(aLoadDeckFromClipboard);
|
||||
addMenu(saveDeckToClipboardMenu);
|
||||
addSeparator();
|
||||
addAction(aPrintDeck);
|
||||
addMenu(analyzeDeckMenu);
|
||||
addSeparator();
|
||||
addAction(deckEditor->filterDockWidget->aClearFilterOne);
|
||||
addAction(deckEditor->filterDockWidget->aClearFilterAll);
|
||||
addSeparator();
|
||||
addAction(aClose);
|
||||
|
||||
retranslateUi();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
||||
void DeckEditorMenu::setSaveStatus(bool newStatus)
|
||||
{
|
||||
aSaveDeck->setEnabled(newStatus);
|
||||
aSaveDeckAs->setEnabled(newStatus);
|
||||
aSaveDeckToClipboard->setEnabled(newStatus);
|
||||
aSaveDeckToClipboardNoSetNameAndNumber->setEnabled(newStatus);
|
||||
aSaveDeckToClipboardRaw->setEnabled(newStatus);
|
||||
aSaveDeckToClipboardRawNoSetNameAndNumber->setEnabled(newStatus);
|
||||
saveDeckToClipboardMenu->setEnabled(newStatus);
|
||||
aPrintDeck->setEnabled(newStatus);
|
||||
analyzeDeckMenu->setEnabled(newStatus);
|
||||
}
|
||||
|
||||
void DeckEditorMenu::updateRecentlyOpened()
|
||||
{
|
||||
loadRecentDeckMenu->clear();
|
||||
for (const auto &deckPath : SettingsCache::instance().recents().getRecentlyOpenedDeckPaths()) {
|
||||
QAction *aRecentlyOpenedDeck = new QAction(deckPath, this);
|
||||
loadRecentDeckMenu->addAction(aRecentlyOpenedDeck);
|
||||
connect(aRecentlyOpenedDeck, &QAction::triggered, deckEditor,
|
||||
[=, this] { deckEditor->actOpenRecent(aRecentlyOpenedDeck->text()); });
|
||||
}
|
||||
loadRecentDeckMenu->addSeparator();
|
||||
loadRecentDeckMenu->addAction(aClearRecents);
|
||||
aClearRecents->setEnabled(SettingsCache::instance().recents().getRecentlyOpenedDeckPaths().length() > 0);
|
||||
}
|
||||
|
||||
void DeckEditorMenu::actClearRecents()
|
||||
{
|
||||
SettingsCache::instance().recents().clearRecentlyOpenedDeckPaths();
|
||||
}
|
||||
|
||||
void DeckEditorMenu::retranslateUi()
|
||||
{
|
||||
setTitle(tr("&Deck Editor"));
|
||||
aNewDeck->setText(tr("&New deck"));
|
||||
aLoadDeck->setText(tr("&Load deck..."));
|
||||
loadRecentDeckMenu->setTitle(tr("Load recent deck..."));
|
||||
aClearRecents->setText(tr("Clear"));
|
||||
aSaveDeck->setText(tr("&Save deck"));
|
||||
aSaveDeckAs->setText(tr("Save deck &as..."));
|
||||
aLoadDeckFromClipboard->setText(tr("Load deck from cl&ipboard..."));
|
||||
|
||||
saveDeckToClipboardMenu->setTitle(tr("Save deck to clipboard"));
|
||||
aSaveDeckToClipboard->setText(tr("Annotated"));
|
||||
aSaveDeckToClipboardNoSetNameAndNumber->setText(tr("Annotated (No set name or number)"));
|
||||
aSaveDeckToClipboardRaw->setText(tr("Not Annotated"));
|
||||
aSaveDeckToClipboardRawNoSetNameAndNumber->setText(tr("Not Annotated (No set name or number)"));
|
||||
|
||||
aPrintDeck->setText(tr("&Print deck..."));
|
||||
|
||||
analyzeDeckMenu->setTitle(tr("&Send deck to online service"));
|
||||
aExportDeckDecklist->setText(tr("Create decklist (decklist.org)"));
|
||||
aAnalyzeDeckDeckstats->setText(tr("Analyze deck (deckstats.net)"));
|
||||
aAnalyzeDeckTappedout->setText(tr("Analyze deck (tappedout.net)"));
|
||||
|
||||
aClose->setText(tr("&Close"));
|
||||
}
|
||||
|
||||
void DeckEditorMenu::refreshShortcuts()
|
||||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
aNewDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aNewDeck"));
|
||||
aLoadDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aLoadDeck"));
|
||||
aSaveDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeck"));
|
||||
aExportDeckDecklist->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklist"));
|
||||
aSaveDeckAs->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckAs"));
|
||||
aLoadDeckFromClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aLoadDeckFromClipboard"));
|
||||
aPrintDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aPrintDeck"));
|
||||
aAnalyzeDeckDeckstats->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aAnalyzeDeck"));
|
||||
aClose->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClose"));
|
||||
|
||||
aSaveDeckToClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckToClipboard"));
|
||||
aSaveDeckToClipboardRaw->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckToClipboardRaw"));
|
||||
|
||||
aClose->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClose"));
|
||||
}
|
||||
32
cockatrice/src/client/menus/deck_editor/deck_editor_menu.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef DECK_EDITOR_MENU_H
|
||||
#define DECK_EDITOR_MENU_H
|
||||
|
||||
#include "../../tabs/abstract_tab_deck_editor.h"
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
class AbstractTabDeckEditor;
|
||||
class DeckEditorMenu : public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *deckEditor);
|
||||
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
|
||||
QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard,
|
||||
*aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetNameAndNumber, *aSaveDeckToClipboardRaw,
|
||||
*aSaveDeckToClipboardRawNoSetNameAndNumber, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats,
|
||||
*aAnalyzeDeckTappedout, *aClose;
|
||||
QMenu *loadRecentDeckMenu, *analyzeDeckMenu, *saveDeckToClipboardMenu;
|
||||
|
||||
void setSaveStatus(bool newStatus);
|
||||
|
||||
public slots:
|
||||
void updateRecentlyOpened();
|
||||
void actClearRecents();
|
||||
void retranslateUi();
|
||||
void refreshShortcuts();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,11 @@
|
||||
#include <QSysInfo>
|
||||
#include <QtGlobal>
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#define STABLERELEASE_URL "https://api.github.com/repos/Cockatrice/Cockatrice/releases/latest"
|
||||
#define STABLEMANUALDOWNLOAD_URL "https://github.com/Cockatrice/Cockatrice/releases/latest"
|
||||
#define STABLETAG_URL "https://api.github.com/repos/Cockatrice/Cockatrice/git/refs/tags/"
|
||||
@@ -33,31 +38,42 @@ ReleaseChannel::~ReleaseChannel()
|
||||
void ReleaseChannel::checkForUpdates()
|
||||
{
|
||||
QString releaseChannelUrl = getReleaseChannelUrl();
|
||||
qDebug() << "Searching for updates on the channel: " << releaseChannelUrl;
|
||||
qCDebug(ReleaseChannelLog) << "Searching for updates on the channel: " << releaseChannelUrl;
|
||||
response = netMan->get(QNetworkRequest(releaseChannelUrl));
|
||||
connect(response, &QNetworkReply::finished, this, &ReleaseChannel::releaseListFinished);
|
||||
}
|
||||
|
||||
// Different release channel checking functions for different operating systems
|
||||
#if defined(Q_OS_MACOS)
|
||||
bool ReleaseChannel::downloadMatchesCurrentOS(const QString &fileName)
|
||||
{
|
||||
static QRegularExpression version_regex("macOS-(\\d+)\\.(\\d+)");
|
||||
#if defined(Q_OS_MACOS)
|
||||
static QRegularExpression version_regex("macOS(\\d+)");
|
||||
auto match = version_regex.match(fileName);
|
||||
if (!match.hasMatch()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto getSystemVersion = [] {
|
||||
// QSysInfo does not go through translation layers
|
||||
// We need to use sysctl to reliably detect the underlying architecture
|
||||
char arch[255];
|
||||
size_t len = sizeof(arch);
|
||||
if (sysctlbyname("machdep.cpu.brand_string", arch, &len, nullptr, 0) == 0) {
|
||||
// Intel mac is only supported on macOS 13 versions
|
||||
if (QString::fromUtf8(arch).contains("Intel")) {
|
||||
return 13;
|
||||
}
|
||||
}
|
||||
|
||||
return QSysInfo::productVersion().split(".")[0].toInt();
|
||||
};
|
||||
|
||||
// older(smaller) releases are compatible with a newer or the same system version
|
||||
int sys_maj = QSysInfo::productVersion().split(".")[0].toInt();
|
||||
int sys_min = QSysInfo::productVersion().split(".")[1].toInt();
|
||||
int sys_maj = getSystemVersion();
|
||||
int rel_maj = match.captured(1).toInt();
|
||||
int rel_min = match.captured(2).toInt();
|
||||
return rel_maj < sys_maj || (rel_maj == sys_maj && rel_min <= sys_min);
|
||||
}
|
||||
return rel_maj == sys_maj;
|
||||
|
||||
#elif defined(Q_OS_WIN)
|
||||
bool ReleaseChannel::downloadMatchesCurrentOS(const QString &fileName)
|
||||
{
|
||||
#if Q_PROCESSOR_WORDSIZE == 4
|
||||
return fileName.contains("32bit");
|
||||
#elif Q_PROCESSOR_WORDSIZE == 8
|
||||
@@ -68,16 +84,15 @@ bool ReleaseChannel::downloadMatchesCurrentOS(const QString &fileName)
|
||||
return fileName.contains("Win10");
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(fileName);
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#else // If the OS doesn't fit one of the above #defines, then it will never match
|
||||
Q_UNUSED(fileName);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
bool ReleaseChannel::downloadMatchesCurrentOS(const QString &)
|
||||
{
|
||||
// If the OS doesn't fit one of the above #defines, then it will never match
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString StableReleaseChannel::getManualDownloadUrl() const
|
||||
{
|
||||
@@ -101,7 +116,7 @@ void StableReleaseChannel::releaseListFinished()
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
reply->deleteLater();
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "No reply received from the release update server.";
|
||||
qCWarning(ReleaseChannelLog) << "No reply received from the release update server.";
|
||||
emit error(tr("No reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
@@ -109,7 +124,7 @@ void StableReleaseChannel::releaseListFinished()
|
||||
QVariantMap resultMap = jsonResponse.toVariant().toMap();
|
||||
if (!(resultMap.contains("name") && resultMap.contains("html_url") && resultMap.contains("tag_name") &&
|
||||
resultMap.contains("published_at"))) {
|
||||
qWarning() << "Invalid received from the release update server:" << resultMap;
|
||||
qCWarning(ReleaseChannelLog) << "Invalid received from the release update server:" << resultMap;
|
||||
emit error(tr("Invalid reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
@@ -123,37 +138,29 @@ void StableReleaseChannel::releaseListFinished()
|
||||
|
||||
if (resultMap.contains("assets")) {
|
||||
auto rawAssets = resultMap["assets"].toList();
|
||||
// [(name, url)]
|
||||
QVector<std::pair<QString, QString>> assets;
|
||||
std::transform(rawAssets.begin(), rawAssets.end(), std::back_inserter(assets), [](QVariant _asset) {
|
||||
QVariantMap asset = _asset.toMap();
|
||||
for (const auto &rawAsset : rawAssets) {
|
||||
QVariantMap asset = rawAsset.toMap();
|
||||
QString name = asset["name"].toString();
|
||||
QString url = asset["browser_download_url"].toString();
|
||||
return std::make_pair(name, url);
|
||||
});
|
||||
|
||||
auto _releaseAsset = std::find_if(assets.begin(), assets.end(), [](std::pair<QString, QString> nameAndUrl) {
|
||||
return downloadMatchesCurrentOS(nameAndUrl.first);
|
||||
});
|
||||
|
||||
if (_releaseAsset != assets.end()) {
|
||||
std::pair<QString, QString> releaseAsset = *_releaseAsset;
|
||||
auto releaseUrl = releaseAsset.second;
|
||||
lastRelease->setDownloadUrl(releaseUrl);
|
||||
if (downloadMatchesCurrentOS(name)) {
|
||||
lastRelease->setDownloadUrl(url);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
qCDebug(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
qDebug() << "Got reply from release server, name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl() << "date=" << lastRelease->getPublishDate()
|
||||
<< "url=" << lastRelease->getDownloadUrl();
|
||||
qCDebug(ReleaseChannelLog) << "Got reply from release server, name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "date=" << lastRelease->getPublishDate() << "url=" << lastRelease->getDownloadUrl();
|
||||
|
||||
const QString &tagName = resultMap["tag_name"].toString();
|
||||
QString url = QString(STABLETAG_URL) + tagName;
|
||||
qDebug() << "Searching for commit hash corresponding to stable channel tag: " << tagName;
|
||||
qCDebug(ReleaseChannelLog) << "Searching for commit hash corresponding to stable channel tag: " << tagName;
|
||||
response = netMan->get(QNetworkRequest(url));
|
||||
connect(response, &QNetworkReply::finished, this, &StableReleaseChannel::tagListFinished);
|
||||
}
|
||||
@@ -165,24 +172,24 @@ void StableReleaseChannel::tagListFinished()
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
reply->deleteLater();
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "No reply received from the tag update server.";
|
||||
qCWarning(ReleaseChannelLog) << "No reply received from the tag update server.";
|
||||
emit error(tr("No reply received from the tag update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap resultMap = jsonResponse.toVariant().toMap();
|
||||
if (!(resultMap.contains("object") && resultMap["object"].toMap().contains("sha"))) {
|
||||
qWarning() << "Invalid received from the tag update server.";
|
||||
qCWarning(ReleaseChannelLog) << "Invalid received from the tag update server.";
|
||||
emit error(tr("Invalid reply received from the tag update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
lastRelease->setCommitHash(resultMap["object"].toMap()["sha"].toString());
|
||||
qDebug() << "Got reply from tag server, commit=" << lastRelease->getCommitHash();
|
||||
qCDebug(ReleaseChannelLog) << "Got reply from tag server, commit=" << lastRelease->getCommitHash();
|
||||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
qCDebug(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
const bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||
|
||||
emit finishedCheck(needToUpdate, lastRelease->isCompatibleVersionFound(), lastRelease);
|
||||
@@ -225,7 +232,7 @@ void BetaReleaseChannel::releaseListFinished()
|
||||
QVariantMap resultMap = array.at(0).toObject().toVariantMap();
|
||||
|
||||
if (array.empty() || resultMap.empty()) {
|
||||
qWarning() << "No reply received from the release update server:" << QString(jsonData);
|
||||
qCWarning(ReleaseChannelLog) << "No reply received from the release update server:" << QString(jsonData);
|
||||
emit error(tr("No reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
@@ -234,7 +241,7 @@ void BetaReleaseChannel::releaseListFinished()
|
||||
if (!resultMap.contains("assets") || !resultMap.contains("author") || !resultMap.contains("tag_name") ||
|
||||
!resultMap.contains("target_commitish") || !resultMap.contains("assets_url") ||
|
||||
!resultMap.contains("published_at")) {
|
||||
qWarning() << "Invalid received from the release update server:" << resultMap;
|
||||
qCWarning(ReleaseChannelLog) << "Invalid received from the release update server:" << resultMap;
|
||||
emit error(tr("Invalid reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
@@ -249,13 +256,13 @@ void BetaReleaseChannel::releaseListFinished()
|
||||
lastRelease->setName(QString("%1 (%2)").arg(resultMap["tag_name"].toString()).arg(shortHash));
|
||||
lastRelease->setDescriptionUrl(QString(BETARELEASE_CHANGESURL).arg(VERSION_COMMIT, shortHash));
|
||||
|
||||
qDebug() << "Got reply from release server, size=" << resultMap.size() << "name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl() << "commit=" << lastRelease->getCommitHash()
|
||||
<< "date=" << lastRelease->getPublishDate();
|
||||
qCDebug(ReleaseChannelLog) << "Got reply from release server, size=" << resultMap.size()
|
||||
<< "name=" << lastRelease->getName() << "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "commit=" << lastRelease->getCommitHash() << "date=" << lastRelease->getPublishDate();
|
||||
|
||||
QString betaBuildDownloadUrl = resultMap["assets_url"].toString();
|
||||
|
||||
qDebug() << "Searching for a corresponding file on the beta channel: " << betaBuildDownloadUrl;
|
||||
qCDebug(ReleaseChannelLog) << "Searching for a corresponding file on the beta channel: " << betaBuildDownloadUrl;
|
||||
response = netMan->get(QNetworkRequest(betaBuildDownloadUrl));
|
||||
connect(response, &QNetworkReply::finished, this, &BetaReleaseChannel::fileListFinished);
|
||||
}
|
||||
@@ -267,7 +274,7 @@ void BetaReleaseChannel::fileListFinished()
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||
reply->deleteLater();
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qWarning() << "No reply received from the file update server.";
|
||||
qCWarning(ReleaseChannelLog) << "No reply received from the file update server.";
|
||||
emit error(tr("No reply received from the file update server."));
|
||||
return;
|
||||
}
|
||||
@@ -275,7 +282,7 @@ void BetaReleaseChannel::fileListFinished()
|
||||
QVariantList resultList = jsonResponse.toVariant().toList();
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
qCDebug(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||
bool compatibleVersion = false;
|
||||
@@ -292,7 +299,7 @@ void BetaReleaseChannel::fileListFinished()
|
||||
if (downloadMatchesCurrentOS(*url)) {
|
||||
compatibleVersion = true;
|
||||
lastRelease->setDownloadUrl(*url);
|
||||
qDebug() << "Found compatible version url=" << *url;
|
||||
qCDebug(ReleaseChannelLog) << "Found compatible version url=" << *url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
#define RELEASECHANNEL_H
|
||||
|
||||
#include <QDate>
|
||||
#include <QLoggingCategory>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVariantMap>
|
||||
#include <utility>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(ReleaseChannelLog, "release_channel");
|
||||
|
||||
class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
|
||||
|
||||
@@ -57,28 +57,29 @@ public:
|
||||
SortRole = Qt::UserRole
|
||||
};
|
||||
|
||||
SetsModel(CardDatabase *_db, QObject *parent = nullptr);
|
||||
~SetsModel();
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const
|
||||
explicit SetsModel(CardDatabase *_db, QObject *parent = nullptr);
|
||||
~SetsModel() override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return NUM_COLS;
|
||||
}
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
Qt::DropActions supportedDropActions() const;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
|
||||
QStringList mimeTypes() const;
|
||||
QMimeData *mimeData(const QModelIndexList &indexes) const override;
|
||||
bool
|
||||
dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
QStringList mimeTypes() const override;
|
||||
void swapRows(int oldRow, int newRow);
|
||||
void toggleRow(int row, bool enable);
|
||||
void toggleRow(int row);
|
||||
void toggleAll(bool);
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
|
||||
void save(CardDatabase *db);
|
||||
void restore(CardDatabase *db);
|
||||
void restoreOriginalOrder();
|
||||
@@ -88,7 +89,7 @@ class SetsDisplayModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SetsDisplayModel(QObject *parent = NULL);
|
||||
explicit SetsDisplayModel(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
@@ -28,7 +28,7 @@ SpoilerBackgroundUpdater::SpoilerBackgroundUpdater(QObject *apParent) : QObject(
|
||||
// File exists means we're in spoiler season
|
||||
startSpoilerDownloadProcess(SPOILERS_STATUS_URL, false);
|
||||
} else {
|
||||
qDebug() << "Spoilers Disabled";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoilers Disabled";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ void SpoilerBackgroundUpdater::actDownloadFinishedSpoilersFile()
|
||||
reply->deleteLater();
|
||||
emit spoilerCheckerDone();
|
||||
} else {
|
||||
qDebug() << "Error downloading spoilers file" << errorCode;
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Error downloading spoilers file" << errorCode;
|
||||
emit spoilerCheckerDone();
|
||||
}
|
||||
}
|
||||
@@ -81,11 +81,11 @@ bool SpoilerBackgroundUpdater::deleteSpoilerFile()
|
||||
|
||||
// Delete the spoiler.xml file
|
||||
if (file.exists() && file.remove()) {
|
||||
qDebug() << "Deleting spoiler.xml";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Deleting spoiler.xml";
|
||||
return true;
|
||||
}
|
||||
|
||||
qDebug() << "Error: Spoiler.xml not found or not deleted";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Error: Spoiler.xml not found or not deleted";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -101,24 +101,24 @@ void SpoilerBackgroundUpdater::actCheckIfSpoilerSeasonEnabled()
|
||||
trayIcon->showMessage(tr("Spoilers season has ended"), tr("Deleting spoiler.xml. Please run Oracle"));
|
||||
}
|
||||
|
||||
qDebug() << "Spoiler Season Offline";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Season Offline";
|
||||
emit spoilerCheckerDone();
|
||||
} else if (errorCode == QNetworkReply::NoError) {
|
||||
qDebug() << "Spoiler Service Online";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Online";
|
||||
startSpoilerDownloadProcess(SPOILERS_URL, true);
|
||||
} else if (errorCode == QNetworkReply::HostNotFoundError) {
|
||||
if (trayIcon) {
|
||||
trayIcon->showMessage(tr("Spoilers download failed"), tr("No internet connection"));
|
||||
}
|
||||
|
||||
qDebug() << "Spoiler download failed due to no internet connection";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler download failed due to no internet connection";
|
||||
emit spoilerCheckerDone();
|
||||
} else {
|
||||
if (trayIcon) {
|
||||
trayIcon->showMessage(tr("Spoilers download failed"), tr("Error") + " " + (short)errorCode);
|
||||
}
|
||||
|
||||
qDebug() << "Spoiler download failed with reason" << errorCode;
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler download failed with reason" << errorCode;
|
||||
emit spoilerCheckerDone();
|
||||
}
|
||||
}
|
||||
@@ -139,19 +139,19 @@ bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
|
||||
trayIcon->showMessage(tr("Spoilers already up to date"), tr("No new spoilers added"));
|
||||
}
|
||||
|
||||
qDebug() << "Spoilers Up to Date";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoilers Up to Date";
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qDebug() << "Spoiler Service Error: File open (w) failed for" << fileName;
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Error: File open (w) failed for" << fileName;
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.write(data) == -1) {
|
||||
qDebug() << "Spoiler Service Error: File write (w) failed for" << fileName;
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Error: File write (w) failed for" << fileName;
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
@@ -159,7 +159,7 @@ bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
|
||||
file.close();
|
||||
|
||||
// Data written, so reload the card database
|
||||
qDebug() << "Spoiler Service Data Written";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Data Written";
|
||||
const auto reloadOk = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); });
|
||||
|
||||
// If the user has notifications enabled, let them know
|
||||
@@ -202,12 +202,12 @@ QByteArray SpoilerBackgroundUpdater::getHash(const QString fileName)
|
||||
QCryptographicHash hash(QCryptographicHash::Algorithm::Md5);
|
||||
hash.addData(bytes);
|
||||
|
||||
qDebug() << "File Hash =" << hash.result();
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "File Hash =" << hash.result();
|
||||
|
||||
file.close();
|
||||
return hash.result();
|
||||
} else {
|
||||
qDebug() << "getHash ReadOnly failed!";
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "getHash ReadOnly failed!";
|
||||
file.close();
|
||||
return QByteArray();
|
||||
}
|
||||
@@ -221,7 +221,7 @@ QByteArray SpoilerBackgroundUpdater::getHash(QByteArray data)
|
||||
QCryptographicHash hash(QCryptographicHash::Algorithm::Md5);
|
||||
hash.addData(bytes);
|
||||
|
||||
qDebug() << "Data Hash =" << hash.result();
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Data Hash =" << hash.result();
|
||||
|
||||
return hash.result();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
#define COCKATRICE_SPOILER_DOWNLOADER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QLoggingCategory>
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(SpoilerBackgroundUpdaterLog, "spoiler_background_updater");
|
||||
|
||||
class SpoilerBackgroundUpdater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -37,7 +37,7 @@ SoundEngine::~SoundEngine()
|
||||
void SoundEngine::soundEnabledChanged()
|
||||
{
|
||||
if (SettingsCache::instance().getSoundEnabled()) {
|
||||
qDebug() << "SoundEngine: enabling sound with" << audioData.size() << "sounds";
|
||||
qCDebug(SoundEngineLog) << "SoundEngine: enabling sound with" << audioData.size() << "sounds";
|
||||
if (!player) {
|
||||
player = new QMediaPlayer;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
@@ -46,7 +46,7 @@ void SoundEngine::soundEnabledChanged()
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
qDebug() << "SoundEngine: disabling sound";
|
||||
qCDebug(SoundEngineLog) << "SoundEngine: disabling sound";
|
||||
if (player) {
|
||||
player->stop();
|
||||
player->deleteLater();
|
||||
@@ -90,7 +90,7 @@ void SoundEngine::ensureThemeDirectoryExists()
|
||||
{
|
||||
if (SettingsCache::instance().getSoundThemeName().isEmpty() ||
|
||||
!getAvailableThemes().contains(SettingsCache::instance().getSoundThemeName())) {
|
||||
qDebug() << "Sounds theme name not set, setting default value";
|
||||
qCDebug(SoundEngineLog) << "Sounds theme name not set, setting default value";
|
||||
SettingsCache::instance().setSoundThemeName(DEFAULT_THEME_NAME);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ QStringMap &SoundEngine::getAvailableThemes()
|
||||
void SoundEngine::themeChangedSlot()
|
||||
{
|
||||
QString themeName = SettingsCache::instance().getSoundThemeName();
|
||||
qDebug() << "Sound theme changed:" << themeName;
|
||||
qCDebug(SoundEngineLog) << "Sound theme changed:" << themeName;
|
||||
|
||||
QDir dir = getAvailableThemes().value(themeName);
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
#define SOUNDENGINE_H
|
||||
|
||||
#include <QAudioOutput>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMap>
|
||||
#include <QMediaPlayer>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(SoundEngineLog, "sound_engine");
|
||||
|
||||
class QBuffer;
|
||||
|
||||
typedef QMap<QString, QString> QStringMap;
|
||||
|
||||
519
cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
|
||||
#include "../../client/game_logic/abstract_client.h"
|
||||
#include "../../client/tapped_out_interface.h"
|
||||
#include "../../client/ui/widgets/cards/card_info_frame_widget.h"
|
||||
#include "../../deck/deck_stats_interface.h"
|
||||
#include "../../dialogs/dlg_load_deck.h"
|
||||
#include "../../dialogs/dlg_load_deck_from_clipboard.h"
|
||||
#include "../../game/cards/card_database_manager.h"
|
||||
#include "../../game/cards/card_database_model.h"
|
||||
#include "../../server/pending_command.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../ui/picture_loader/picture_loader.h"
|
||||
#include "../ui/pixel_map_generator.h"
|
||||
#include "pb/command_deck_upload.pb.h"
|
||||
#include "pb/response.pb.h"
|
||||
#include "tab_supervisor.h"
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QCloseEvent>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QHeaderView>
|
||||
#include <QLineEdit>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QPrintPreviewDialog>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QSplitter>
|
||||
#include <QTextStream>
|
||||
#include <QTreeView>
|
||||
#include <QUrl>
|
||||
|
||||
AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||
{
|
||||
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||
|
||||
databaseDisplayDockWidget = new DeckEditorDatabaseDisplayWidget(this);
|
||||
deckDockWidget = new DeckEditorDeckDockWidget(this);
|
||||
cardInfoDockWidget = new DeckEditorCardInfoDockWidget(this);
|
||||
filterDockWidget = new DeckEditorFilterDockWidget(this);
|
||||
printingSelectorDockWidget = new DeckEditorPrintingSelectorDockWidget(this);
|
||||
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckChanged, this, &AbstractTabDeckEditor::onDeckChanged);
|
||||
connect(deckDockWidget, &DeckEditorDeckDockWidget::cardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||
connect(this, &AbstractTabDeckEditor::decrementCard, deckDockWidget, &DeckEditorDeckDockWidget::actDecrementCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
||||
&AbstractTabDeckEditor::updateCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, this,
|
||||
&AbstractTabDeckEditor::actAddCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToSideboard, this,
|
||||
&AbstractTabDeckEditor::actAddCardToSideboard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromMainDeck, this,
|
||||
&AbstractTabDeckEditor::actDecrementCard);
|
||||
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, this,
|
||||
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
||||
|
||||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::updateCard(CardInfoPtr _card)
|
||||
{
|
||||
cardInfoDockWidget->updateCard(_card);
|
||||
printingSelectorDockWidget->printingSelector->setCard(_card, DECK_ZONE_MAIN);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::onDeckChanged()
|
||||
{
|
||||
setModified(true);
|
||||
deckMenu->setSaveStatus(!getDeckList()->isEmpty());
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::addCardHelper(const CardInfoPtr info, QString zoneName)
|
||||
{
|
||||
if (!info)
|
||||
return;
|
||||
if (info->getIsToken())
|
||||
zoneName = DECK_ZONE_TOKENS;
|
||||
|
||||
QModelIndex newCardIndex = deckDockWidget->deckModel->addPreferredPrintingCard(info->getName(), zoneName, false);
|
||||
// recursiveExpand(newCardIndex);
|
||||
deckDockWidget->deckView->clearSelection();
|
||||
deckDockWidget->deckView->setCurrentIndex(newCardIndex);
|
||||
setModified(true);
|
||||
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actAddCard(CardInfoPtr info)
|
||||
{
|
||||
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
||||
actAddCardToSideboard(info);
|
||||
else
|
||||
addCardHelper(info, DECK_ZONE_MAIN);
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actAddCardToSideboard(CardInfoPtr info)
|
||||
{
|
||||
addCardHelper(info, DECK_ZONE_SIDE);
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actDecrementCard(CardInfoPtr info)
|
||||
{
|
||||
emit decrementCard(info, DECK_ZONE_MAIN);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actDecrementCardFromSideboard(CardInfoPtr info)
|
||||
{
|
||||
emit decrementCard(info, DECK_ZONE_SIDE);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actSwapCard(CardInfoPtr info, QString zoneName)
|
||||
{
|
||||
QString providerId = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("uuid");
|
||||
QString collectorNumber = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("num");
|
||||
deckDockWidget->swapCard(
|
||||
deckDockWidget->deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber));
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
||||
{
|
||||
deckDockWidget->setDeck(_deck);
|
||||
PictureLoader::cacheCardPixmaps(
|
||||
CardDatabaseManager::getInstance()->getCardsByNameAndProviderId(getDeckList()->getCardListWithProviderId()));
|
||||
setModified(false);
|
||||
|
||||
// If they load a deck, make the deck list appear
|
||||
aDeckDockVisible->setChecked(true);
|
||||
deckDockWidget->setVisible(aDeckDockVisible->isChecked());
|
||||
}
|
||||
|
||||
DeckLoader *AbstractTabDeckEditor::getDeckList() const
|
||||
{
|
||||
return deckDockWidget->getDeckList();
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::setModified(bool _modified)
|
||||
{
|
||||
modified = _modified;
|
||||
emit tabTextChanged(this, getTabText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if this tab is a blank newly opened tab, as if it was just created with the `New Deck` action.
|
||||
*/
|
||||
bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||
{
|
||||
DeckLoader *deck = getDeckList();
|
||||
return !modified && deck->hasNotBeenLoaded();
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actNewDeck()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen(false);
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (deckOpenLocation == NEW_TAB) {
|
||||
emit openDeckEditor(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
cleanDeckAndResetModified();
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
||||
{
|
||||
deckMenu->setSaveStatus(false);
|
||||
deckDockWidget->cleanDeck();
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Displays the save confirmation dialogue that is shown before loading a deck, if required. Takes into
|
||||
* account the `openDeckInNewTab` settting.
|
||||
*
|
||||
* @param openInSameTabIfBlank Open the deck in the same tab instead of a new tab if the current tab is completely
|
||||
* blank. Only relevant when the `openDeckInNewTab` setting is enabled.
|
||||
*
|
||||
* @returns An enum that indicates if and where to load the deck
|
||||
*/
|
||||
AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const bool openInSameTabIfBlank)
|
||||
{
|
||||
// handle `openDeckInNewTab` setting
|
||||
if (SettingsCache::instance().getOpenDeckInNewTab()) {
|
||||
if (openInSameTabIfBlank && isBlankNewDeck()) {
|
||||
return SAME_TAB;
|
||||
} else {
|
||||
return NEW_TAB;
|
||||
}
|
||||
}
|
||||
|
||||
// early return if deck is unmodified
|
||||
if (!modified) {
|
||||
return SAME_TAB;
|
||||
}
|
||||
|
||||
// do the save confirmation dialogue
|
||||
tabSupervisor->setCurrentWidget(this);
|
||||
|
||||
QMessageBox *msgBox = createSaveConfirmationWindow();
|
||||
QPushButton *newTabButton = msgBox->addButton(tr("Open in new tab"), QMessageBox::ApplyRole);
|
||||
|
||||
int ret = msgBox->exec();
|
||||
|
||||
// `exec()` returns an opaque value if a non-standard button was clicked.
|
||||
// Directly check if newTabButton was clicked before switching over the standard buttons.
|
||||
if (msgBox->clickedButton() == newTabButton) {
|
||||
return NEW_TAB;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case QMessageBox::Save:
|
||||
return actSaveDeck() ? SAME_TAB : CANCELLED;
|
||||
case QMessageBox::Discard:
|
||||
return SAME_TAB;
|
||||
default:
|
||||
return CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates the base save confirmation dialogue box.
|
||||
*
|
||||
* @returns A QMessageBox that can be further modified
|
||||
*/
|
||||
QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
||||
{
|
||||
QMessageBox *msgBox = new QMessageBox(this);
|
||||
msgBox->setIcon(QMessageBox::Warning);
|
||||
msgBox->setWindowTitle(tr("Are you sure?"));
|
||||
msgBox->setText(tr("The decklist has been modified.\nDo you want to save the changes?"));
|
||||
msgBox->setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
return msgBox;
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actLoadDeck()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
DlgLoadDeck dialog(this);
|
||||
if (!dialog.exec())
|
||||
return;
|
||||
|
||||
QString fileName = dialog.selectedFiles().at(0);
|
||||
openDeckFromFile(fileName, deckOpenLocation);
|
||||
deckDockWidget->updateBannerCardComboBox();
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actOpenRecent(const QString &fileName)
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
openDeckFromFile(fileName, deckOpenLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually opens the deck from file
|
||||
* @param fileName The path of the deck to open
|
||||
* @param deckOpenLocation Which tab to open the deck
|
||||
*/
|
||||
void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation)
|
||||
{
|
||||
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
|
||||
|
||||
auto *l = new DeckLoader;
|
||||
if (l->loadFromFile(fileName, fmt, true)) {
|
||||
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||
if (deckOpenLocation == NEW_TAB) {
|
||||
emit openDeckEditor(l);
|
||||
} else {
|
||||
deckMenu->setSaveStatus(false);
|
||||
setDeck(l);
|
||||
}
|
||||
} else {
|
||||
delete l;
|
||||
QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(fileName));
|
||||
}
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
bool AbstractTabDeckEditor::actSaveDeck()
|
||||
{
|
||||
DeckLoader *const deck = getDeckList();
|
||||
if (deck->getLastRemoteDeckId() != -1) {
|
||||
QString deckString = deck->writeToString_Native();
|
||||
if (deckString.length() > MAX_FILE_LENGTH) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Could not save remote deck"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Command_DeckUpload cmd;
|
||||
cmd.set_deck_id(static_cast<google::protobuf::uint32>(deck->getLastRemoteDeckId()));
|
||||
cmd.set_deck_list(deckString.toStdString());
|
||||
|
||||
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(saveDeckRemoteFinished(Response)));
|
||||
tabSupervisor->getClient()->sendCommand(pend);
|
||||
|
||||
return true;
|
||||
} else if (deck->getLastFileName().isEmpty())
|
||||
return actSaveDeckAs();
|
||||
else if (deck->saveToFile(deck->getLastFileName(), deck->getLastFileFormat())) {
|
||||
setModified(false);
|
||||
return true;
|
||||
}
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractTabDeckEditor::actSaveDeckAs()
|
||||
{
|
||||
QFileDialog dialog(this, tr("Save deck"));
|
||||
dialog.setDirectory(SettingsCache::instance().getDeckPath());
|
||||
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
dialog.setDefaultSuffix("cod");
|
||||
dialog.setNameFilters(DeckLoader::fileNameFilters);
|
||||
dialog.selectFile(getDeckList()->getName().trimmed() + ".cod");
|
||||
if (!dialog.exec())
|
||||
return false;
|
||||
|
||||
QString fileName = dialog.selectedFiles().at(0);
|
||||
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
|
||||
|
||||
if (!getDeckList()->saveToFile(fileName, fmt)) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||
return false;
|
||||
}
|
||||
setModified(false);
|
||||
|
||||
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
||||
{
|
||||
if (response.response_code() != Response::RespOk)
|
||||
QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved."));
|
||||
else
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
||||
{
|
||||
auto deckOpenLocation = confirmOpen();
|
||||
|
||||
if (deckOpenLocation == CANCELLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
DlgLoadDeckFromClipboard dlg(this);
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
if (deckOpenLocation == NEW_TAB) {
|
||||
emit openDeckEditor(dlg.getDeckList());
|
||||
} else {
|
||||
setDeck(dlg.getDeckList());
|
||||
setModified(true);
|
||||
}
|
||||
|
||||
deckMenu->setSaveStatus(true);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
||||
{
|
||||
getDeckList()->saveToClipboard(true, true);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetNameAndNumber()
|
||||
{
|
||||
getDeckList()->saveToClipboard(true, false);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
||||
{
|
||||
getDeckList()->saveToClipboard(false, true);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetNameAndNumber()
|
||||
{
|
||||
getDeckList()->saveToClipboard(false, false);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actPrintDeck()
|
||||
{
|
||||
auto *dlg = new QPrintPreviewDialog(this);
|
||||
connect(dlg, SIGNAL(paintRequested(QPrinter *)), deckDockWidget->deckModel, SLOT(printDeckList(QPrinter *)));
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
// Action called when export deck to decklist menu item is pressed.
|
||||
void AbstractTabDeckEditor::actExportDeckDecklist()
|
||||
{
|
||||
// Get the decklist class for the deck.
|
||||
DeckLoader *const deck = getDeckList();
|
||||
// create a string to load the decklist url into.
|
||||
QString decklistUrlString;
|
||||
// check if deck is not null
|
||||
if (deck) {
|
||||
// Get the decklist url string from the deck loader class.
|
||||
decklistUrlString = deck->exportDeckToDecklist();
|
||||
// Check to make sure the string isn't empty.
|
||||
if (QString::compare(decklistUrlString, "", Qt::CaseInsensitive) == 0) {
|
||||
// Show an error if the deck is empty, and return.
|
||||
QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported"));
|
||||
return;
|
||||
}
|
||||
// Encode the string recieved from the model to make sure all characters are encoded.
|
||||
// first we put it into a qurl object
|
||||
QUrl decklistUrl = QUrl(decklistUrlString);
|
||||
// we get the correctly encoded url.
|
||||
decklistUrlString = decklistUrl.toEncoded();
|
||||
// We open the url in the user's default browser
|
||||
QDesktopServices::openUrl(decklistUrlString);
|
||||
} else {
|
||||
// if there's no deck loader object, return an error
|
||||
QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be saved."));
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||
{
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||
this); // it deletes itself when done
|
||||
interface->analyzeDeck(getDeckList());
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||
{
|
||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||
this); // it deletes itself when done
|
||||
interface->analyzeDeck(getDeckList());
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::filterTreeChanged(FilterTree *filterTree)
|
||||
{
|
||||
databaseDisplayDockWidget->setFilterTree(filterTree);
|
||||
}
|
||||
|
||||
// Method uses to sync docks state with menu items state
|
||||
bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::Close) {
|
||||
if (o == cardInfoDockWidget) {
|
||||
aCardInfoDockVisible->setChecked(false);
|
||||
aCardInfoDockFloating->setEnabled(false);
|
||||
} else if (o == deckDockWidget) {
|
||||
aDeckDockVisible->setChecked(false);
|
||||
aDeckDockFloating->setEnabled(false);
|
||||
} else if (o == filterDockWidget) {
|
||||
aFilterDockVisible->setChecked(false);
|
||||
aFilterDockFloating->setEnabled(false);
|
||||
} else if (o == printingSelectorDockWidget) {
|
||||
aPrintingSelectorDockVisible->setChecked(false);
|
||||
aPrintingSelectorDockFloating->setEnabled(false);
|
||||
}
|
||||
}
|
||||
if (o == this && e->type() == QEvent::Hide) {
|
||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||
layouts.setDeckEditorLayoutState(saveState());
|
||||
layouts.setDeckEditorGeometry(saveGeometry());
|
||||
layouts.setDeckEditorCardSize(cardInfoDockWidget->size());
|
||||
layouts.setDeckEditorFilterSize(filterDockWidget->size());
|
||||
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractTabDeckEditor::confirmClose()
|
||||
{
|
||||
if (modified) {
|
||||
tabSupervisor->setCurrentWidget(this);
|
||||
int ret = createSaveConfirmationWindow()->exec();
|
||||
if (ret == QMessageBox::Save)
|
||||
return actSaveDeck();
|
||||
else if (ret == QMessageBox::Cancel)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::closeRequest(bool forced)
|
||||
{
|
||||
if (!forced && !confirmClose()) {
|
||||
return;
|
||||
}
|
||||
|
||||
emit deckEditorClosing(this);
|
||||
close();
|
||||
}
|
||||
147
cockatrice/src/client/tabs/abstract_tab_deck_editor.h
Normal file
@@ -0,0 +1,147 @@
|
||||
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||
#define TAB_GENERIC_DECK_EDITOR_H
|
||||
|
||||
#include "../../game/cards/card_database.h"
|
||||
#include "../menus/deck_editor/deck_editor_menu.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_card_info_dock_widget.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_database_display_widget.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_deck_dock_widget.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_filter_dock_widget.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h"
|
||||
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||
#include "tab.h"
|
||||
|
||||
class CardDatabaseModel;
|
||||
class CardDatabaseDisplayModel;
|
||||
|
||||
class CardInfoFrameWidget;
|
||||
class DeckLoader;
|
||||
class DeckEditorMenu;
|
||||
class DeckEditorCardInfoDockWidget;
|
||||
class DeckEditorDatabaseDisplayWidget;
|
||||
class DeckEditorDeckDockWidget;
|
||||
class DeckEditorFilterDockWidget;
|
||||
class DeckEditorPrintingSelectorDockWidget;
|
||||
class DeckPreviewDeckTagsDisplayWidget;
|
||||
class Response;
|
||||
class FilterTreeModel;
|
||||
class FilterBuilder;
|
||||
|
||||
class QTreeView;
|
||||
class QTextEdit;
|
||||
class QLabel;
|
||||
class QComboBox;
|
||||
class QGroupBox;
|
||||
class QMessageBox;
|
||||
class QHBoxLayout;
|
||||
class QVBoxLayout;
|
||||
class QPushButton;
|
||||
class QDockWidget;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
class AbstractTabDeckEditor : public Tab
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||
|
||||
// UI and Navigation
|
||||
virtual void createMenus() = 0;
|
||||
[[nodiscard]] virtual QString getTabText() const override = 0;
|
||||
bool confirmClose();
|
||||
virtual void retranslateUi() override = 0;
|
||||
|
||||
// Deck Management
|
||||
virtual void setDeck(DeckLoader *_deckLoader);
|
||||
DeckLoader *getDeckList() const;
|
||||
void setModified(bool _windowModified);
|
||||
|
||||
// UI Elements
|
||||
DeckEditorMenu *deckMenu;
|
||||
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget;
|
||||
DeckEditorCardInfoDockWidget *cardInfoDockWidget;
|
||||
DeckEditorDeckDockWidget *deckDockWidget;
|
||||
DeckEditorFilterDockWidget *filterDockWidget;
|
||||
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
||||
|
||||
public slots:
|
||||
void onDeckChanged();
|
||||
void updateCard(CardInfoPtr _card);
|
||||
void actAddCard(CardInfoPtr info);
|
||||
void actAddCardToSideboard(CardInfoPtr info);
|
||||
void actDecrementCard(CardInfoPtr info);
|
||||
void actDecrementCardFromSideboard(CardInfoPtr info);
|
||||
void actOpenRecent(const QString &fileName);
|
||||
void filterTreeChanged(FilterTree *filterTree);
|
||||
void closeRequest(bool forced = false) override;
|
||||
virtual void showPrintingSelector() = 0;
|
||||
virtual void dockTopLevelChanged(bool topLevel) = 0;
|
||||
|
||||
signals:
|
||||
void openDeckEditor(const DeckLoader *deckLoader);
|
||||
void deckEditorClosing(AbstractTabDeckEditor *tab);
|
||||
void decrementCard(CardInfoPtr card, QString zoneName);
|
||||
|
||||
protected slots:
|
||||
// Deck Operations
|
||||
virtual void actNewDeck();
|
||||
void cleanDeckAndResetModified();
|
||||
virtual void actLoadDeck();
|
||||
bool actSaveDeck();
|
||||
bool actSaveDeckAs();
|
||||
virtual void actLoadDeckFromClipboard();
|
||||
void actSaveDeckToClipboard();
|
||||
void actSaveDeckToClipboardNoSetNameAndNumber();
|
||||
void actSaveDeckToClipboardRaw();
|
||||
void actSaveDeckToClipboardRawNoSetNameAndNumber();
|
||||
void actPrintDeck();
|
||||
void actExportDeckDecklist();
|
||||
void actAnalyzeDeckDeckstats();
|
||||
void actAnalyzeDeckTappedout();
|
||||
|
||||
// Remote Save
|
||||
void saveDeckRemoteFinished(const Response &r);
|
||||
|
||||
// UI Layout Management
|
||||
virtual void loadLayout() = 0;
|
||||
virtual void restartLayout() = 0;
|
||||
virtual void freeDocksSize() = 0;
|
||||
virtual void refreshShortcuts() = 0;
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
virtual void dockVisibleTriggered() = 0;
|
||||
virtual void dockFloatingTriggered() = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Enum for selecting deck open location
|
||||
*/
|
||||
enum DeckOpenLocation
|
||||
{
|
||||
CANCELLED,
|
||||
SAME_TAB,
|
||||
NEW_TAB
|
||||
};
|
||||
|
||||
DeckOpenLocation confirmOpen(bool openInSameTabIfBlank = true);
|
||||
QMessageBox *createSaveConfirmationWindow();
|
||||
bool isBlankNewDeck() const;
|
||||
|
||||
// Helper functions for card actions
|
||||
void addCardHelper(CardInfoPtr info, QString zoneName);
|
||||
void actSwapCard(CardInfoPtr info, QString zoneName);
|
||||
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
||||
|
||||
// UI Menu Elements
|
||||
QMenu *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *printingSelectorDockMenu;
|
||||
|
||||
QAction *aResetLayout;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
||||
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||
|
||||
bool modified;
|
||||
};
|
||||
|
||||
#endif // TAB_GENERIC_DECK_EDITOR_H
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "edhrec_commander_api_response.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
|
||||
void EdhrecCommanderApiResponse::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse the collapsed DeckStatistics
|
||||
deckStats.fromJson(json);
|
||||
|
||||
// Parse Archidekt section
|
||||
QJsonArray archidektJson = json.value("archidekt").toArray();
|
||||
archidekt.fromJson(archidektJson);
|
||||
|
||||
// Parse other fields
|
||||
similar = json.value("similar").toObject();
|
||||
header = json.value("header").toString();
|
||||
panels = json.value("panels").toObject();
|
||||
description = json.value("description").toString();
|
||||
QJsonObject containerJson = json.value("container").toObject();
|
||||
container.fromJson(containerJson);
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponse::debugPrint() const
|
||||
{
|
||||
qDebug() << "Deck Statistics:";
|
||||
qDebug() << " Creature:" << deckStats.creature;
|
||||
qDebug() << " Instant:" << deckStats.instant;
|
||||
qDebug() << " Sorcery:" << deckStats.sorcery;
|
||||
qDebug() << " Artifact:" << deckStats.artifact;
|
||||
qDebug() << " Enchantment:" << deckStats.enchantment;
|
||||
qDebug() << " Battle:" << deckStats.battle;
|
||||
qDebug() << " Planeswalker:" << deckStats.planeswalker;
|
||||
qDebug() << " Land:" << deckStats.land;
|
||||
qDebug() << " Basic:" << deckStats.basic;
|
||||
qDebug() << " Nonbasic:" << deckStats.nonbasic;
|
||||
|
||||
archidekt.debugPrint();
|
||||
|
||||
qDebug() << "Similar:" << similar;
|
||||
qDebug() << "Header:" << header;
|
||||
qDebug() << "Panels:" << panels;
|
||||
qDebug() << "Description:" << description;
|
||||
container.debugPrint();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef DECKDATA_H
|
||||
#define DECKDATA_H
|
||||
|
||||
#include "edhrec_commander_api_response_archidekt_links.h"
|
||||
#include "edhrec_commander_api_response_average_deck_statistics.h"
|
||||
#include "edhrec_commander_api_response_card_container.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
// Represents the main structure of the JSON
|
||||
class EdhrecCommanderApiResponse
|
||||
{
|
||||
public:
|
||||
EdhrecCommanderApiResponseAverageDeckStatistics deckStats;
|
||||
EdhrecCommanderApiResponseArchidektLinks archidekt;
|
||||
QJsonObject similar;
|
||||
QString header;
|
||||
QJsonObject panels;
|
||||
QString description;
|
||||
EdhrecCommanderApiResponseCardContainer container;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // DECKDATA_H
|
||||
@@ -0,0 +1,43 @@
|
||||
#include "edhrec_commander_api_response_archidekt_links.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
void EdhrecCommanderApiResponseArchidektLink::fromJson(const QJsonObject &json)
|
||||
{
|
||||
c = json.value("c").toString();
|
||||
f = json.value("f").toInt(0);
|
||||
q = json.value("q").toInt(0);
|
||||
u = json.value("u").toString();
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseArchidektLink::debugPrint() const
|
||||
{
|
||||
qDebug() << " C:" << c;
|
||||
qDebug() << " F:" << f;
|
||||
qDebug() << " Q:" << q;
|
||||
qDebug() << " U:" << u;
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseArchidektLinks::fromJson(const QJsonArray &json)
|
||||
{
|
||||
entries.clear();
|
||||
for (const QJsonValue &value : json) {
|
||||
if (value.isObject()) {
|
||||
QJsonObject entryJson = value.toObject();
|
||||
EdhrecCommanderApiResponseArchidektLink entry;
|
||||
entry.fromJson(entryJson);
|
||||
entries.append(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseArchidektLinks::debugPrint() const
|
||||
{
|
||||
qDebug() << "Archidekt Entries:";
|
||||
for (const auto &entry : entries) {
|
||||
entry.debugPrint();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef ARCHIDEKTENTRY_H
|
||||
#define ARCHIDEKTENTRY_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
// Represents a single Archidekt entry
|
||||
class EdhrecCommanderApiResponseArchidektLink
|
||||
{
|
||||
public:
|
||||
QString c;
|
||||
int f = 0;
|
||||
int q = 0;
|
||||
QString u;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
// Represents the Archidekt section as a list of entries
|
||||
class EdhrecCommanderApiResponseArchidektLinks
|
||||
{
|
||||
public:
|
||||
QVector<EdhrecCommanderApiResponseArchidektLink> entries;
|
||||
|
||||
void fromJson(const QJsonArray &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // ARCHIDEKTENTRY_H
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "edhrec_commander_api_response_average_deck_statistics.h"
|
||||
|
||||
void EdhrecCommanderApiResponseAverageDeckStatistics::fromJson(const QJsonObject &json)
|
||||
{
|
||||
creature = json.value("creature").toInt(0);
|
||||
instant = json.value("instant").toInt(0);
|
||||
sorcery = json.value("sorcery").toInt(0);
|
||||
artifact = json.value("artifact").toInt(0);
|
||||
enchantment = json.value("enchantment").toInt(0);
|
||||
battle = json.value("battle").toInt(0);
|
||||
planeswalker = json.value("planeswalker").toInt(0);
|
||||
land = json.value("land").toInt(0);
|
||||
basic = json.value("basic").toInt(0);
|
||||
nonbasic = json.value("nonbasic").toInt(0);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef AVERAGE_DECK_STATISTICS_H
|
||||
#define AVERAGE_DECK_STATISTICS_H
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
// Represents the typical deck statistics (collapsed section)
|
||||
struct EdhrecCommanderApiResponseAverageDeckStatistics
|
||||
{
|
||||
int creature = 0;
|
||||
int instant = 0;
|
||||
int sorcery = 0;
|
||||
int artifact = 0;
|
||||
int enchantment = 0;
|
||||
int battle = 0;
|
||||
int planeswalker = 0;
|
||||
int land = 0;
|
||||
int basic = 0;
|
||||
int nonbasic = 0;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
};
|
||||
#endif // AVERAGE_DECK_STATISTICS_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "edhrec_commander_api_response_card_container.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
void EdhrecCommanderApiResponseCardContainer::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse breadcrumb
|
||||
QJsonArray breadcrumbArray = json.value("breadcrumb").toArray();
|
||||
for (const QJsonValue &breadcrumbValue : breadcrumbArray) {
|
||||
breadcrumb.push_back(breadcrumbValue.toObject());
|
||||
}
|
||||
|
||||
description = json.value("description").toString();
|
||||
QJsonObject jsonDict = json.value("json_dict").toObject();
|
||||
card.fromJson(jsonDict.value("card").toObject());
|
||||
QJsonArray cardlistsArray = jsonDict.value("cardlists").toArray();
|
||||
|
||||
for (const QJsonValue &cardlistValue : cardlistsArray) {
|
||||
QJsonObject cardlistObj = cardlistValue.toObject();
|
||||
QJsonArray cardviewsArray = cardlistObj.value("cardviews").toArray();
|
||||
EdhrecCommanderApiResponseCardList cardView;
|
||||
cardView.fromJson(cardlistValue.toObject());
|
||||
cardlists.push_back(cardView);
|
||||
}
|
||||
|
||||
keywords = json.value("keywords").toString();
|
||||
title = json.value("title").toString();
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardContainer::debugPrint() const
|
||||
{
|
||||
qDebug() << "Breadcrumb:";
|
||||
for (const auto &breadcrumbEntry : breadcrumb) {
|
||||
qDebug() << breadcrumbEntry;
|
||||
}
|
||||
|
||||
qDebug() << "Description:" << description;
|
||||
card.debugPrint();
|
||||
|
||||
qDebug() << "Cardlists:";
|
||||
for (const auto &cardlist : cardlists) {
|
||||
cardlist.debugPrint();
|
||||
}
|
||||
|
||||
qDebug() << "Keywords:" << keywords;
|
||||
qDebug() << "Title:" << title;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef CONTAINER_ENTRY_H
|
||||
#define CONTAINER_ENTRY_H
|
||||
|
||||
#include "edhrec_commander_api_response_card_list.h"
|
||||
#include "edhrec_commander_api_response_commander_details.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
class EdhrecCommanderApiResponseCardContainer
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
EdhrecCommanderApiResponseCardContainer() = default;
|
||||
|
||||
// Parse deck-related data from JSON
|
||||
void fromJson(const QJsonObject &json);
|
||||
|
||||
// Debug method for logging
|
||||
void debugPrint() const;
|
||||
|
||||
// Getter methods for deck container
|
||||
const QString &getDescription() const
|
||||
{
|
||||
return description;
|
||||
}
|
||||
const QVector<QJsonObject> &getBreadcrumb() const
|
||||
{
|
||||
return breadcrumb;
|
||||
}
|
||||
const EdhrecCommanderApiResponseCommanderDetails &getCommanderDetails() const
|
||||
{
|
||||
return card;
|
||||
}
|
||||
const QVector<EdhrecCommanderApiResponseCardList> &getCardlists() const
|
||||
{
|
||||
return cardlists;
|
||||
}
|
||||
const QString &getKeywords() const
|
||||
{
|
||||
return keywords;
|
||||
}
|
||||
const QString &getTitle() const
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
private:
|
||||
QString description;
|
||||
QVector<QJsonObject> breadcrumb;
|
||||
EdhrecCommanderApiResponseCommanderDetails card;
|
||||
QVector<EdhrecCommanderApiResponseCardList> cardlists;
|
||||
QString keywords;
|
||||
QString title;
|
||||
};
|
||||
|
||||
#endif // CONTAINER_ENTRY_H
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "edhrec_commander_api_response_card_details.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
EdhrecCommanderApiResponseCardDetails::EdhrecCommanderApiResponseCardDetails()
|
||||
: synergy(0.0), inclusion(0), numDecks(0), potentialDecks(0)
|
||||
{
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardDetails::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse the fields from the JSON object
|
||||
name = json.value("name").toString();
|
||||
sanitized = json.value("sanitized").toString();
|
||||
sanitizedWo = json.value("sanitized_wo").toString();
|
||||
url = json.value("url").toString();
|
||||
synergy = json.value("synergy").toDouble(0.0);
|
||||
inclusion = json.value("inclusion").toInt(0);
|
||||
label = json.value("label").toString();
|
||||
numDecks = json.value("num_decks").toInt(0);
|
||||
potentialDecks = json.value("potential_decks").toInt(0);
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardDetails::debugPrint() const
|
||||
{
|
||||
// Print out all the fields for debugging
|
||||
qDebug() << "Name:" << name;
|
||||
qDebug() << "Sanitized:" << sanitized;
|
||||
qDebug() << "Sanitized Wo:" << sanitizedWo;
|
||||
qDebug() << "URL:" << url;
|
||||
qDebug() << "Synergy:" << synergy;
|
||||
qDebug() << "Inclusion:" << inclusion;
|
||||
qDebug() << "Label:" << label;
|
||||
qDebug() << "Num Decks:" << numDecks;
|
||||
qDebug() << "Potential Decks:" << potentialDecks;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef CARD_VIEW_H
|
||||
#define CARD_VIEW_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
class EdhrecCommanderApiResponseCardDetails
|
||||
{
|
||||
public:
|
||||
QString name;
|
||||
QString sanitized;
|
||||
QString sanitizedWo;
|
||||
QString url;
|
||||
double synergy;
|
||||
int inclusion;
|
||||
QString label;
|
||||
int numDecks;
|
||||
int potentialDecks;
|
||||
|
||||
EdhrecCommanderApiResponseCardDetails();
|
||||
|
||||
// Method to populate the object from a JSON object
|
||||
void fromJson(const QJsonObject &json);
|
||||
|
||||
// Debug method to print out the data
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // CARD_VIEW_H
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "edhrec_commander_api_response_card_list.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
EdhrecCommanderApiResponseCardList::EdhrecCommanderApiResponseCardList()
|
||||
{
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardList::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse the header from the JSON object
|
||||
header = json.value("header").toString();
|
||||
|
||||
// Parse the cardviews array and populate cardViews
|
||||
QJsonArray cardviewsArray = json.value("cardviews").toArray();
|
||||
for (const QJsonValue &value : cardviewsArray) {
|
||||
QJsonObject cardviewObj = value.toObject();
|
||||
EdhrecCommanderApiResponseCardDetails cardView;
|
||||
cardView.fromJson(cardviewObj);
|
||||
cardViews.append(cardView);
|
||||
}
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardList::debugPrint() const
|
||||
{
|
||||
// Print out the header
|
||||
qDebug() << "Header:" << header;
|
||||
|
||||
// Print out all the CardView objects
|
||||
for (const EdhrecCommanderApiResponseCardDetails &cardView : cardViews) {
|
||||
cardView.debugPrint();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef CARD_LIST_H
|
||||
#define CARD_LIST_H
|
||||
|
||||
#include "edhrec_commander_api_response_card_details.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
class EdhrecCommanderApiResponseCardList
|
||||
{
|
||||
public:
|
||||
QString header;
|
||||
QList<EdhrecCommanderApiResponseCardDetails> cardViews;
|
||||
|
||||
// Default constructor
|
||||
EdhrecCommanderApiResponseCardList();
|
||||
|
||||
// Method to populate the object from a JSON object
|
||||
void fromJson(const QJsonObject &json);
|
||||
|
||||
// Debug method to print out the data
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // CARD_LIST_H
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "edhrec_commander_api_response_card_prices.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
void CardPrices::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse prices from various sources
|
||||
cardhoarder = json.value("cardhoarder").toObject();
|
||||
cardkingdom = json.value("cardkingdom").toObject();
|
||||
cardmarket = json.value("cardmarket").toObject();
|
||||
face2face = json.value("face2face").toObject();
|
||||
manapool = json.value("manapool").toObject();
|
||||
mtgstocks = json.value("mtgstocks").toObject();
|
||||
scg = json.value("scg").toObject();
|
||||
tcgl = json.value("tcgl").toObject();
|
||||
tcgplayer = json.value("tcgplayer").toObject();
|
||||
}
|
||||
|
||||
void CardPrices::debugPrint() const
|
||||
{
|
||||
qDebug() << "Card Prices:";
|
||||
qDebug() << "Cardhoarder:" << cardhoarder;
|
||||
qDebug() << "Cardkingdom:" << cardkingdom;
|
||||
qDebug() << "Cardmarket:" << cardmarket;
|
||||
qDebug() << "Face2Face:" << face2face;
|
||||
qDebug() << "Manapool:" << manapool;
|
||||
qDebug() << "Mtgstocks:" << mtgstocks;
|
||||
qDebug() << "SCG:" << scg;
|
||||
qDebug() << "TCGL:" << tcgl;
|
||||
qDebug() << "Tcgplayer:" << tcgplayer;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_PRICES_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_PRICES_H
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
class CardPrices
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
CardPrices() = default;
|
||||
|
||||
// Parse prices from JSON
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
|
||||
// Getter methods for card prices
|
||||
const QJsonObject &getCardhoarder() const
|
||||
{
|
||||
return cardhoarder;
|
||||
}
|
||||
const QJsonObject &getCardkingdom() const
|
||||
{
|
||||
return cardkingdom;
|
||||
}
|
||||
const QJsonObject &getCardmarket() const
|
||||
{
|
||||
return cardmarket;
|
||||
}
|
||||
const QJsonObject &getFace2face() const
|
||||
{
|
||||
return face2face;
|
||||
}
|
||||
const QJsonObject &getManapool() const
|
||||
{
|
||||
return manapool;
|
||||
}
|
||||
const QJsonObject &getMtgstocks() const
|
||||
{
|
||||
return mtgstocks;
|
||||
}
|
||||
const QJsonObject &getScg() const
|
||||
{
|
||||
return scg;
|
||||
}
|
||||
const QJsonObject &getTcgl() const
|
||||
{
|
||||
return tcgl;
|
||||
}
|
||||
const QJsonObject &getTcgplayer() const
|
||||
{
|
||||
return tcgplayer;
|
||||
}
|
||||
|
||||
private:
|
||||
QJsonObject cardhoarder;
|
||||
QJsonObject cardkingdom;
|
||||
QJsonObject cardmarket;
|
||||
QJsonObject face2face;
|
||||
QJsonObject manapool;
|
||||
QJsonObject mtgstocks;
|
||||
QJsonObject scg;
|
||||
QJsonObject tcgl;
|
||||
QJsonObject tcgplayer;
|
||||
};
|
||||
|
||||
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_PRICES_H
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "edhrec_commander_api_response_commander_details.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
void EdhrecCommanderApiResponseCommanderDetails::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse card-related data
|
||||
aetherhubUri = json.value("aetherhub_uri").toString();
|
||||
archidektUri = json.value("archidekt_uri").toString();
|
||||
cmc = json.value("cmc").toInt(0);
|
||||
colorIdentity = json.value("color_identity").toArray();
|
||||
combos = json.value("combos").toBool(false);
|
||||
deckstatsUri = json.value("deckstats_uri").toString();
|
||||
|
||||
// Parse image URIs
|
||||
QJsonArray imageUrisArray = json.value("image_uris").toArray();
|
||||
for (const QJsonValue &imageValue : imageUrisArray) {
|
||||
QJsonObject imageObject = imageValue.toObject();
|
||||
imageUris.push_back(imageObject.value("normal").toString());
|
||||
imageUris.push_back(imageObject.value("art_crop").toString());
|
||||
}
|
||||
|
||||
inclusion = json.value("inclusion").toInt(0);
|
||||
isCommander = json.value("is_commander").toBool(false);
|
||||
label = json.value("label").toString();
|
||||
layout = json.value("layout").toString();
|
||||
legalCommander = json.value("legal_commander").toBool(false);
|
||||
moxfieldUri = json.value("moxfield_uri").toString();
|
||||
mtggoldfishUri = json.value("mtggoldfish_uri").toString();
|
||||
name = json.value("name").toString();
|
||||
names = json.value("names").toArray();
|
||||
numDecks = json.value("num_decks").toInt(0);
|
||||
potentialDecks = json.value("potential_decks").toInt(0);
|
||||
precon = json.value("precon").toString();
|
||||
|
||||
// Parse prices
|
||||
prices.fromJson(json.value("prices").toObject());
|
||||
|
||||
primaryType = json.value("primary_type").toString();
|
||||
rarity = json.value("rarity").toString();
|
||||
salt = json.value("salt").toDouble(0.0);
|
||||
sanitized = json.value("sanitized").toString();
|
||||
sanitizedWo = json.value("sanitized_wo").toString();
|
||||
scryfallUri = json.value("scryfall_uri").toString();
|
||||
spellbookUri = json.value("spellbook_uri").toString();
|
||||
type = json.value("type").toString();
|
||||
url = json.value("url").toString();
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCommanderDetails::debugPrint() const
|
||||
{
|
||||
qDebug() << "Card Data:";
|
||||
qDebug() << "Aetherhub URI:" << aetherhubUri;
|
||||
qDebug() << "Archidekt URI:" << archidektUri;
|
||||
qDebug() << "CMC:" << cmc;
|
||||
qDebug() << "Color Identity:" << colorIdentity;
|
||||
qDebug() << "Combos:" << combos;
|
||||
qDebug() << "Deckstats URI:" << deckstatsUri;
|
||||
|
||||
qDebug() << "Image URIs:";
|
||||
for (const auto &uri : imageUris) {
|
||||
qDebug() << uri;
|
||||
}
|
||||
|
||||
qDebug() << "Inclusion:" << inclusion;
|
||||
qDebug() << "Is Commander:" << isCommander;
|
||||
qDebug() << "Label:" << label;
|
||||
qDebug() << "Layout:" << layout;
|
||||
qDebug() << "Legal Commander:" << legalCommander;
|
||||
qDebug() << "Moxfield URI:" << moxfieldUri;
|
||||
qDebug() << "MTGGoldfish URI:" << mtggoldfishUri;
|
||||
qDebug() << "Name:" << name;
|
||||
qDebug() << "Names:" << names;
|
||||
qDebug() << "Number of Decks:" << numDecks;
|
||||
qDebug() << "Potential Decks:" << potentialDecks;
|
||||
qDebug() << "Precon:" << precon;
|
||||
|
||||
// Print the prices using the debugPrint method from CardPrices
|
||||
prices.debugPrint();
|
||||
|
||||
qDebug() << "Primary Type:" << primaryType;
|
||||
qDebug() << "Rarity:" << rarity;
|
||||
qDebug() << "Salt:" << salt;
|
||||
qDebug() << "Sanitized:" << sanitized;
|
||||
qDebug() << "Sanitized WO:" << sanitizedWo;
|
||||
qDebug() << "Scryfall URI:" << scryfallUri;
|
||||
qDebug() << "Spellbook URI:" << spellbookUri;
|
||||
qDebug() << "Type:" << type;
|
||||
qDebug() << "URL:" << url;
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
||||
|
||||
#include "edhrec_commander_api_response_card_prices.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
class EdhrecCommanderApiResponseCommanderDetails
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
EdhrecCommanderApiResponseCommanderDetails() = default;
|
||||
|
||||
// Parse card-related data from JSON
|
||||
void fromJson(const QJsonObject &json);
|
||||
|
||||
// Debug method for logging
|
||||
void debugPrint() const;
|
||||
|
||||
// Getters for the card data
|
||||
const QString &getAetherhubUri() const
|
||||
{
|
||||
return aetherhubUri;
|
||||
}
|
||||
const QString &getArchidektUri() const
|
||||
{
|
||||
return archidektUri;
|
||||
}
|
||||
int getCmc() const
|
||||
{
|
||||
return cmc;
|
||||
}
|
||||
const QJsonArray &getColorIdentity() const
|
||||
{
|
||||
return colorIdentity;
|
||||
}
|
||||
bool isCombos() const
|
||||
{
|
||||
return combos;
|
||||
}
|
||||
const QString &getDeckstatsUri() const
|
||||
{
|
||||
return deckstatsUri;
|
||||
}
|
||||
const QVector<QString> &getImageUris() const
|
||||
{
|
||||
return imageUris;
|
||||
}
|
||||
int getInclusion() const
|
||||
{
|
||||
return inclusion;
|
||||
}
|
||||
bool getIsCommander() const
|
||||
{
|
||||
return isCommander;
|
||||
}
|
||||
const QString &getLabel() const
|
||||
{
|
||||
return label;
|
||||
}
|
||||
const QString &getLayout() const
|
||||
{
|
||||
return layout;
|
||||
}
|
||||
bool getLegalCommander() const
|
||||
{
|
||||
return legalCommander;
|
||||
}
|
||||
const QString &getMoxfieldUri() const
|
||||
{
|
||||
return moxfieldUri;
|
||||
}
|
||||
const QString &getMtggoldfishUri() const
|
||||
{
|
||||
return mtggoldfishUri;
|
||||
}
|
||||
const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
const QJsonArray &getNames() const
|
||||
{
|
||||
return names;
|
||||
}
|
||||
int getNumDecks() const
|
||||
{
|
||||
return numDecks;
|
||||
}
|
||||
int getPotentialDecks() const
|
||||
{
|
||||
return potentialDecks;
|
||||
}
|
||||
const QString &getPrecon() const
|
||||
{
|
||||
return precon;
|
||||
}
|
||||
const CardPrices &getPrices() const
|
||||
{
|
||||
return prices;
|
||||
}
|
||||
const QString &getPrimaryType() const
|
||||
{
|
||||
return primaryType;
|
||||
}
|
||||
const QString &getRarity() const
|
||||
{
|
||||
return rarity;
|
||||
}
|
||||
double getSalt() const
|
||||
{
|
||||
return salt;
|
||||
}
|
||||
const QString &getSanitized() const
|
||||
{
|
||||
return sanitized;
|
||||
}
|
||||
const QString &getSanitizedWo() const
|
||||
{
|
||||
return sanitizedWo;
|
||||
}
|
||||
const QString &getScryfallUri() const
|
||||
{
|
||||
return scryfallUri;
|
||||
}
|
||||
const QString &getSpellbookUri() const
|
||||
{
|
||||
return spellbookUri;
|
||||
}
|
||||
const QString &getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
const QString &getUrl() const
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
private:
|
||||
QString aetherhubUri;
|
||||
QString archidektUri;
|
||||
int cmc = 0;
|
||||
QJsonArray colorIdentity;
|
||||
bool combos = false;
|
||||
QString deckstatsUri;
|
||||
QVector<QString> imageUris;
|
||||
int inclusion = 0;
|
||||
bool isCommander = false;
|
||||
QString label;
|
||||
QString layout;
|
||||
bool legalCommander = false;
|
||||
QString moxfieldUri;
|
||||
QString mtggoldfishUri;
|
||||
QString name;
|
||||
QJsonArray names;
|
||||
int numDecks = 0;
|
||||
int potentialDecks = 0;
|
||||
QString precon;
|
||||
CardPrices prices;
|
||||
QString primaryType;
|
||||
QString rarity;
|
||||
double salt = 0.0;
|
||||
QString sanitized;
|
||||
QString sanitizedWo;
|
||||
QString scryfallUri;
|
||||
QString spellbookUri;
|
||||
QString type;
|
||||
QString url;
|
||||
};
|
||||
|
||||
#endif // EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "edhrec_commander_api_response_card_details_display_widget.h"
|
||||
|
||||
#include "../../../../game/cards/card_database_manager.h"
|
||||
|
||||
EdhrecCommanderApiResponseCardDetailsDisplayWidget::EdhrecCommanderApiResponseCardDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCardDetails &_toDisplay)
|
||||
: QWidget(parent), toDisplay(_toDisplay)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
cardPictureWidget = new CardInfoPictureWidget(this);
|
||||
cardPictureWidget->setCard(CardDatabaseManager::getInstance()->getCard(toDisplay.name));
|
||||
|
||||
label = new QLabel(this);
|
||||
label->setText(toDisplay.name + "\n" + toDisplay.label);
|
||||
label->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
// Set label color based on inclusion rate
|
||||
int inclusionRate = (toDisplay.numDecks * 100) / toDisplay.potentialDecks;
|
||||
|
||||
QColor labelColor;
|
||||
if (inclusionRate <= 30) {
|
||||
labelColor = QColor(255, 0, 0); // Red
|
||||
} else if (inclusionRate <= 60) {
|
||||
int red = 255 - ((inclusionRate - 30) * 2);
|
||||
int green = (inclusionRate - 30) * 4; // Adjust green to make the transition smoother
|
||||
labelColor = QColor(red, green, 0); // purple-ish
|
||||
} else if (inclusionRate <= 90) {
|
||||
int green = (inclusionRate - 60) * 5; // Increase green
|
||||
labelColor = QColor(100, green, 100); // Green shades
|
||||
} else {
|
||||
labelColor = QColor(100, 200, 100); // Dark Green
|
||||
}
|
||||
|
||||
label->setStyleSheet(QString("color: %1").arg(labelColor.name()));
|
||||
|
||||
layout->addWidget(cardPictureWidget);
|
||||
layout->addWidget(label);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response_card_details.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecCommanderApiResponseCardDetailsDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EdhrecCommanderApiResponseCardDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCardDetails &_toDisplay);
|
||||
|
||||
private:
|
||||
EdhrecCommanderApiResponseCardDetails toDisplay;
|
||||
QVBoxLayout *layout;
|
||||
CardInfoPictureWidget *cardPictureWidget;
|
||||
QLabel *label;
|
||||
};
|
||||
|
||||
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "edhrec_commander_api_response_card_list_display_widget.h"
|
||||
|
||||
#include "../../../ui/widgets/general/display/banner_widget.h"
|
||||
#include "edhrec_commander_api_response_card_details_display_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
EdhrecCommanderApiResponseCardListDisplayWidget::EdhrecCommanderApiResponseCardListDisplayWidget(
|
||||
QWidget *parent,
|
||||
EdhrecCommanderApiResponseCardList toDisplay)
|
||||
: QWidget(parent)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
header = new BannerWidget(this, toDisplay.header);
|
||||
|
||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
||||
header->setBuddy(flowWidget);
|
||||
|
||||
foreach (EdhrecCommanderApiResponseCardDetails card_detail, toDisplay.cardViews) {
|
||||
auto widget = new EdhrecCommanderApiResponseCardDetailsDisplayWidget(flowWidget, card_detail);
|
||||
flowWidget->addWidget(widget);
|
||||
}
|
||||
|
||||
layout->addWidget(header);
|
||||
layout->addWidget(flowWidget);
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardListDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
qDebug() << event->size();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../ui/widgets/general/display/banner_widget.h"
|
||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response_card_list.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecCommanderApiResponseCardListDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EdhrecCommanderApiResponseCardListDisplayWidget(QWidget *parent,
|
||||
EdhrecCommanderApiResponseCardList toDisplay);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
[[nodiscard]] QString getBannerText() const
|
||||
{
|
||||
return header->getText();
|
||||
};
|
||||
|
||||
private:
|
||||
QVBoxLayout *layout;
|
||||
BannerWidget *header;
|
||||
FlowWidget *flowWidget;
|
||||
};
|
||||
|
||||
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
||||
|
||||
#include "../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails)
|
||||
: QWidget(parent), commanderDetails(_commanderDetails)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
commanderPicture = new CardInfoPictureWidget(this);
|
||||
commanderPicture->setCard(CardDatabaseManager::getInstance()->getCard(commanderDetails.getName()));
|
||||
|
||||
commanderDetails.debugPrint();
|
||||
|
||||
label = new QLabel(this);
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
salt = new QLabel(this);
|
||||
salt->setAlignment(Qt::AlignCenter);
|
||||
|
||||
layout->addWidget(commanderPicture);
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(salt);
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void EdhrecCommanderResponseCommanderDetailsDisplayWidget::retranslateUi()
|
||||
{
|
||||
label->setText(commanderDetails.getLabel());
|
||||
salt->setText(tr("Salt: ") + QString::number(commanderDetails.getSalt()));
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response_commander_details.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecCommanderResponseCommanderDetailsDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails);
|
||||
void retranslateUi();
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
QLabel *salt;
|
||||
QVBoxLayout *layout;
|
||||
CardInfoPictureWidget *commanderPicture;
|
||||
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
|
||||
};
|
||||
|
||||
#endif // EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||
@@ -0,0 +1,102 @@
|
||||
#include "edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response.h"
|
||||
#include "edhrec_commander_api_response_card_list_display_widget.h"
|
||||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
||||
|
||||
#include <QListView>
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollArea>
|
||||
#include <QSplitter>
|
||||
#include <QStringListModel>
|
||||
|
||||
EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
|
||||
EdhrecCommanderApiResponse response)
|
||||
: QWidget(parent)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
cardDisplayLayout = new QVBoxLayout(this);
|
||||
|
||||
// Create a QSplitter to hold the ListView and ScrollArea holding CardListdisplayWidgets side by side
|
||||
auto splitter = new QSplitter(this);
|
||||
splitter->setOrientation(Qt::Horizontal);
|
||||
|
||||
auto listView = new QListView(splitter);
|
||||
listView->setMinimumWidth(50);
|
||||
listView->setMaximumWidth(150);
|
||||
auto listModel = new QStringListModel(this);
|
||||
QStringList widgetNames;
|
||||
|
||||
// Add commander details
|
||||
auto commanderPicture =
|
||||
new EdhrecCommanderResponseCommanderDetailsDisplayWidget(this, response.container.getCommanderDetails());
|
||||
cardDisplayLayout->addWidget(commanderPicture);
|
||||
widgetNames.append("Commander Details");
|
||||
|
||||
// Add card list widgets
|
||||
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||
for (const EdhrecCommanderApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||
auto cardListDisplayWidget = new EdhrecCommanderApiResponseCardListDisplayWidget(this, card_list);
|
||||
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||
widgetNames.append(cardListDisplayWidget->getBannerText());
|
||||
}
|
||||
|
||||
// Create a QScrollArea to hold the card display widgets
|
||||
scrollArea = new QScrollArea(splitter);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
// Set the cardDisplayLayout inside the scroll area
|
||||
auto scrollWidget = new QWidget(scrollArea);
|
||||
scrollWidget->setLayout(cardDisplayLayout);
|
||||
connect(splitter, &QSplitter::splitterMoved, this, &EdhrecCommanderApiResponseDisplayWidget::onSplitterChange);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
|
||||
// Configure the list view
|
||||
listModel->setStringList(widgetNames);
|
||||
listView->setModel(listModel);
|
||||
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
||||
// Connect the list view to ensure the corresponding widget is visible
|
||||
connect(listView, &QListView::clicked, this, [this](const QModelIndex &index) {
|
||||
int widgetIndex = index.row();
|
||||
qDebug() << "clicked: " << widgetIndex;
|
||||
auto targetWidget = cardDisplayLayout->itemAt(widgetIndex)->widget();
|
||||
if (targetWidget) {
|
||||
qDebug() << "Found targetWidget" << targetWidget;
|
||||
// Attempt to cast the parent to QScrollArea
|
||||
auto scrollArea = qobject_cast<QScrollArea *>(this->scrollArea); // Use the scroll area instance
|
||||
if (scrollArea) {
|
||||
qDebug() << "ScrollArea" << scrollArea;
|
||||
scrollArea->ensureWidgetVisible(targetWidget);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add splitter to the main layout
|
||||
splitter->addWidget(listView);
|
||||
splitter->addWidget(scrollArea);
|
||||
|
||||
layout->addWidget(splitter);
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseDisplayWidget::onSplitterChange()
|
||||
{
|
||||
scrollArea->widget()->resize(scrollArea->size());
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
qDebug() << event->size();
|
||||
layout->invalidate();
|
||||
layout->activate();
|
||||
layout->update();
|
||||
if (scrollArea && scrollArea->widget()) {
|
||||
scrollArea->widget()->resize(event->size());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "api_response/edhrec_commander_api_response.h"
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecCommanderApiResponseDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EdhrecCommanderApiResponseDisplayWidget(QWidget *parent, EdhrecCommanderApiResponse response);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void onSplitterChange();
|
||||
|
||||
private:
|
||||
QHBoxLayout *layout;
|
||||
QVBoxLayout *cardDisplayLayout;
|
||||
QScrollArea *scrollArea;
|
||||
};
|
||||
|
||||
#endif // EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
112
cockatrice/src/client/tabs/api/edhrec/tab_edhrec.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "tab_edhrec.h"
|
||||
|
||||
#include "api_response/edhrec_commander_api_response.h"
|
||||
#include "edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QRegularExpression>
|
||||
#include <QResizeEvent>
|
||||
|
||||
TabEdhRec::TabEdhRec(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||
{
|
||||
networkManager = new QNetworkAccessManager(this);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
networkManager->setTransferTimeout(); // Use Qt's default timeout
|
||||
#endif
|
||||
|
||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(processApiJson(QNetworkReply *)));
|
||||
}
|
||||
|
||||
void TabEdhRec::retranslateUi()
|
||||
{
|
||||
}
|
||||
|
||||
void TabEdhRec::setCard(CardInfoPtr _cardToQuery, bool isCommander)
|
||||
{
|
||||
cardToQuery = _cardToQuery;
|
||||
|
||||
if (!cardToQuery) {
|
||||
qDebug() << "Invalid card information provided.";
|
||||
return;
|
||||
}
|
||||
|
||||
QString cardName = cardToQuery->getName();
|
||||
QString formattedName = cardName.toLower().replace(" ", "-").remove(QRegularExpression("[^a-z0-9\\-]"));
|
||||
|
||||
QString url;
|
||||
if (isCommander) {
|
||||
url = QString("https://json.edhrec.com/pages/commanders/%1.json").arg(formattedName);
|
||||
} else {
|
||||
url = QString("https://json.edhrec.com/pages/cards/%1.json").arg(formattedName);
|
||||
}
|
||||
|
||||
QNetworkRequest request{QUrl(url)};
|
||||
|
||||
networkManager->get(request);
|
||||
}
|
||||
|
||||
void TabEdhRec::processApiJson(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qDebug() << "Network error occurred:" << reply->errorString();
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray responseData = reply->readAll();
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
|
||||
|
||||
if (!jsonDoc.isObject()) {
|
||||
qDebug() << "Invalid JSON response received.";
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject jsonObj = jsonDoc.object();
|
||||
|
||||
// qDebug() << jsonObj;
|
||||
|
||||
EdhrecCommanderApiResponse deckData;
|
||||
deckData.fromJson(jsonObj);
|
||||
|
||||
displayWidget = new EdhrecCommanderApiResponseDisplayWidget(this, deckData);
|
||||
// flowWidget->addWidget(displayWidget);
|
||||
setCentralWidget(displayWidget);
|
||||
|
||||
reply->deleteLater();
|
||||
update();
|
||||
}
|
||||
|
||||
void TabEdhRec::prettyPrintJson(const QJsonValue &value, int indentLevel)
|
||||
{
|
||||
const QString indent(indentLevel * 2, ' '); // Adjust spacing as needed for pretty printing
|
||||
|
||||
if (value.isObject()) {
|
||||
QJsonObject obj = value.toObject();
|
||||
for (auto it = obj.begin(); it != obj.end(); ++it) {
|
||||
qDebug().noquote() << indent + it.key() + ":";
|
||||
prettyPrintJson(it.value(), indentLevel + 1);
|
||||
}
|
||||
} else if (value.isArray()) {
|
||||
QJsonArray array = value.toArray();
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
qDebug().noquote() << indent + QString("[%1]:").arg(i);
|
||||
prettyPrintJson(array[i], indentLevel + 1);
|
||||
}
|
||||
} else if (value.isString()) {
|
||||
qDebug().noquote() << indent + "\"" + value.toString() + "\"";
|
||||
} else if (value.isDouble()) {
|
||||
qDebug().noquote() << indent + QString::number(value.toDouble());
|
||||
} else if (value.isBool()) {
|
||||
qDebug().noquote() << indent + (value.toBool() ? "true" : "false");
|
||||
} else if (value.isNull()) {
|
||||
qDebug().noquote() << indent + "null";
|
||||
}
|
||||
}
|
||||
37
cockatrice/src/client/tabs/api/edhrec/tab_edhrec.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef TAB_EDHREC_H
|
||||
#define TAB_EDHREC_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "../../tab.h"
|
||||
#include "edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class TabEdhRec : public Tab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TabEdhRec(TabSupervisor *_tabSupervisor);
|
||||
|
||||
void retranslateUi() override;
|
||||
QString getTabText() const override
|
||||
{
|
||||
auto cardName = cardToQuery.isNull() ? QString() : cardToQuery->getName();
|
||||
return tr("EDHREC: ") + cardName;
|
||||
}
|
||||
|
||||
QNetworkAccessManager *networkManager;
|
||||
|
||||
public slots:
|
||||
void processApiJson(QNetworkReply *reply);
|
||||
void prettyPrintJson(const QJsonValue &value, int indentLevel);
|
||||
void setCard(CardInfoPtr _cardToQuery, bool isCommander = false);
|
||||
|
||||
private:
|
||||
CardInfoPtr cardToQuery;
|
||||
EdhrecCommanderApiResponseDisplayWidget *displayWidget;
|
||||
};
|
||||
|
||||
#endif // TAB_EDHREC_H
|
||||
@@ -87,18 +87,23 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool
|
||||
activateUserLayout->addWidget(userToActivate, 0, 0);
|
||||
activateUserLayout->addWidget(activateUserButton, 0, 1);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(updateServerMessageButton);
|
||||
vbox->addWidget(shutdownServerButton);
|
||||
vbox->addWidget(reloadConfigButton);
|
||||
vbox->addLayout(grandReplayAccessLayout);
|
||||
vbox->addLayout(activateUserLayout);
|
||||
vbox->addStretch();
|
||||
auto *adminVBox = new QVBoxLayout;
|
||||
adminVBox->addWidget(updateServerMessageButton);
|
||||
adminVBox->addWidget(shutdownServerButton);
|
||||
adminVBox->addWidget(reloadConfigButton);
|
||||
|
||||
adminGroupBox = new QGroupBox;
|
||||
adminGroupBox->setLayout(vbox);
|
||||
adminGroupBox->setLayout(adminVBox);
|
||||
adminGroupBox->setEnabled(false);
|
||||
|
||||
auto *moderatorVBox = new QVBoxLayout;
|
||||
moderatorVBox->addLayout(grandReplayAccessLayout);
|
||||
moderatorVBox->addLayout(activateUserLayout);
|
||||
|
||||
moderatorGroupBox = new QGroupBox;
|
||||
moderatorGroupBox->setLayout(moderatorVBox);
|
||||
moderatorGroupBox->setEnabled(false);
|
||||
|
||||
unlockButton = new QPushButton;
|
||||
connect(unlockButton, &QPushButton::clicked, this, &TabAdmin::actUnlock);
|
||||
lockButton = new QPushButton;
|
||||
@@ -107,6 +112,8 @@ TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, bool
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(adminGroupBox);
|
||||
mainLayout->addWidget(moderatorGroupBox);
|
||||
mainLayout->addStretch();
|
||||
mainLayout->addWidget(unlockButton);
|
||||
mainLayout->addWidget(lockButton);
|
||||
|
||||
@@ -125,6 +132,7 @@ void TabAdmin::retranslateUi()
|
||||
shutdownServerButton->setText(tr("&Shut down server"));
|
||||
reloadConfigButton->setText(tr("&Reload configuration"));
|
||||
adminGroupBox->setTitle(tr("Server administration functions"));
|
||||
moderatorGroupBox->setTitle(tr("Server moderator functions"));
|
||||
|
||||
replayIdToGrant->setPlaceholderText(tr("Replay ID"));
|
||||
grantReplayAccessButton->setText(tr("Grant Replay Access"));
|
||||
@@ -229,20 +237,28 @@ void TabAdmin::activateUserProcessResponse(const Response &response)
|
||||
|
||||
void TabAdmin::actUnlock()
|
||||
{
|
||||
if (fullAdmin)
|
||||
if (fullAdmin) {
|
||||
adminGroupBox->setEnabled(true);
|
||||
}
|
||||
|
||||
moderatorGroupBox->setEnabled(true);
|
||||
lockButton->setEnabled(true);
|
||||
unlockButton->setEnabled(false);
|
||||
locked = false;
|
||||
|
||||
emit adminLockChanged(false);
|
||||
}
|
||||
|
||||
void TabAdmin::actLock()
|
||||
{
|
||||
if (fullAdmin)
|
||||
if (fullAdmin) {
|
||||
adminGroupBox->setEnabled(false);
|
||||
}
|
||||
|
||||
moderatorGroupBox->setEnabled(false);
|
||||
lockButton->setEnabled(false);
|
||||
unlockButton->setEnabled(true);
|
||||
locked = true;
|
||||
|
||||
emit adminLockChanged(true);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ private:
|
||||
bool fullAdmin;
|
||||
QPushButton *updateServerMessageButton, *shutdownServerButton, *reloadConfigButton, *grantReplayAccessButton,
|
||||
*activateUserButton;
|
||||
QGroupBox *adminGroupBox;
|
||||
QGroupBox *adminGroupBox, *moderatorGroupBox;
|
||||
QPushButton *unlockButton, *lockButton;
|
||||
QLineEdit *replayIdToGrant, *userToActivate;
|
||||
signals:
|
||||
|
||||
@@ -1,191 +1,41 @@
|
||||
#ifndef WINDOW_DECKEDITOR_H
|
||||
#define WINDOW_DECKEDITOR_H
|
||||
|
||||
#include "../../deck/custom_line_edit.h"
|
||||
#include "../../game/cards/card_database.h"
|
||||
#include "../game_logic/key_signals.h"
|
||||
#include "../ui/widgets/printing_selector/printing_selector.h"
|
||||
#include "tab.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QDir>
|
||||
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
|
||||
class CardDatabaseModel;
|
||||
class CardDatabaseDisplayModel;
|
||||
class DeckListModel;
|
||||
class QTreeView;
|
||||
|
||||
class CardInfoFrameWidget;
|
||||
class QTextEdit;
|
||||
class QLabel;
|
||||
class DeckLoader;
|
||||
class Response;
|
||||
class FilterTreeModel;
|
||||
class FilterBuilder;
|
||||
class QComboBox;
|
||||
class QGroupBox;
|
||||
class QMessageBox;
|
||||
class QHBoxLayout;
|
||||
class QVBoxLayout;
|
||||
class QPushButton;
|
||||
class QDockWidget;
|
||||
|
||||
class TabDeckEditor : public Tab
|
||||
class TabDeckEditor : public AbstractTabDeckEditor
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void updateName(const QString &name);
|
||||
void updateComments();
|
||||
void updateBannerCardComboBox();
|
||||
void setBannerCard(int);
|
||||
void updateHash();
|
||||
void updateCardInfoLeft(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void updateCardInfoRight(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void updatePrintingSelectorDatabase(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void updatePrintingSelectorDeckView(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void updateSearch(const QString &search);
|
||||
void databaseCustomMenu(QPoint point);
|
||||
void decklistCustomMenu(QPoint point);
|
||||
void updateRecentlyOpened();
|
||||
|
||||
void actNewDeck();
|
||||
void actLoadDeck();
|
||||
void actOpenRecent(const QString &fileName);
|
||||
void actClearRecents();
|
||||
bool actSaveDeck();
|
||||
bool actSaveDeckAs();
|
||||
void actLoadDeckFromClipboard();
|
||||
void actSaveDeckToClipboard();
|
||||
void actSaveDeckToClipboardNoSetNameAndNumber();
|
||||
void actSaveDeckToClipboardRaw();
|
||||
void actSaveDeckToClipboardRawNoSetNameAndNumber();
|
||||
void actPrintDeck();
|
||||
void actExportDeckDecklist();
|
||||
void actAnalyzeDeckDeckstats();
|
||||
void actAnalyzeDeckTappedout();
|
||||
|
||||
void actClearFilterAll();
|
||||
void actClearFilterOne();
|
||||
|
||||
void actSwapCard();
|
||||
void actAddCard();
|
||||
void actAddCardToSideboard();
|
||||
void actRemoveCard();
|
||||
void actIncrement();
|
||||
void actDecrement();
|
||||
void actDecrementCard();
|
||||
void actDecrementCardFromSideboard();
|
||||
void copyDatabaseCellContents();
|
||||
|
||||
void saveDeckRemoteFinished(const Response &r);
|
||||
void filterViewCustomContextMenu(const QPoint &point);
|
||||
void filterRemove(QAction *action);
|
||||
|
||||
void loadLayout();
|
||||
void restartLayout();
|
||||
void freeDocksSize();
|
||||
void refreshShortcuts();
|
||||
protected slots:
|
||||
void loadLayout() override;
|
||||
void restartLayout() override;
|
||||
void freeDocksSize() override;
|
||||
void refreshShortcuts() override;
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
void dockVisibleTriggered();
|
||||
void dockFloatingTriggered();
|
||||
void dockTopLevelChanged(bool topLevel);
|
||||
void saveDbHeaderState();
|
||||
void setSaveStatus(bool newStatus);
|
||||
void showSearchSyntaxHelp();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Which tab to open the new deck in
|
||||
*/
|
||||
enum DeckOpenLocation
|
||||
{
|
||||
CANCELLED,
|
||||
SAME_TAB,
|
||||
NEW_TAB
|
||||
};
|
||||
|
||||
DeckOpenLocation confirmOpen(const bool openInSameTabIfBlank = true);
|
||||
QMessageBox *createSaveConfirmationWindow();
|
||||
|
||||
bool isBlankNewDeck() const;
|
||||
CardInfoPtr currentCardInfo() const;
|
||||
void addCardHelper(QString zoneName);
|
||||
void offsetCountAtIndex(const QModelIndex &idx, int offset);
|
||||
void decrementCardHelper(QString zoneName);
|
||||
bool swapCard(const QModelIndex &idx);
|
||||
void recursiveExpand(const QModelIndex &index);
|
||||
void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
||||
|
||||
QModelIndexList getSelectedCardNodes() const;
|
||||
|
||||
CardDatabaseModel *databaseModel;
|
||||
CardDatabaseDisplayModel *databaseDisplayModel;
|
||||
DeckListModel *deckModel;
|
||||
QTreeView *databaseView;
|
||||
|
||||
QTreeView *deckView;
|
||||
KeySignals deckViewKeySignals;
|
||||
CardInfoFrameWidget *cardInfo;
|
||||
PrintingSelector *printingSelector;
|
||||
SearchLineEdit *searchEdit;
|
||||
KeySignals searchKeySignals;
|
||||
|
||||
QLabel *nameLabel;
|
||||
LineEditUnfocusable *nameEdit;
|
||||
QLabel *commentsLabel;
|
||||
QTextEdit *commentsEdit;
|
||||
QLabel *bannerCardLabel;
|
||||
QComboBox *bannerCardComboBox;
|
||||
QLabel *hashLabel1;
|
||||
LineEditUnfocusable *hashLabel;
|
||||
FilterTreeModel *filterModel;
|
||||
QTreeView *filterView;
|
||||
KeySignals filterViewKeySignals;
|
||||
QWidget *filterBox;
|
||||
|
||||
QMenu *deckMenu, *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *printingSelectorDockMenu,
|
||||
*analyzeDeckMenu, *saveDeckToClipboardMenu, *loadRecentDeckMenu;
|
||||
QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard,
|
||||
*aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetNameAndNumber, *aSaveDeckToClipboardRaw,
|
||||
*aSaveDeckToClipboardRawNoSetNameAndNumber, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats,
|
||||
*aAnalyzeDeckTappedout, *aClose;
|
||||
QAction *aClearFilterAll, *aClearFilterOne;
|
||||
QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement, *aSwapCard;
|
||||
QAction *aResetLayout;
|
||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating, *aFilterDockVisible,
|
||||
*aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||
|
||||
bool modified;
|
||||
QVBoxLayout *centralFrame;
|
||||
QHBoxLayout *searchLayout;
|
||||
QDockWidget *cardInfoDock;
|
||||
QDockWidget *deckDock;
|
||||
QDockWidget *filterDock;
|
||||
QDockWidget *printingSelectorDock;
|
||||
QWidget *centralWidget;
|
||||
void dockVisibleTriggered() override;
|
||||
void dockFloatingTriggered() override;
|
||||
void dockTopLevelChanged(bool topLevel) override;
|
||||
|
||||
public:
|
||||
explicit TabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||
void retranslateUi() override;
|
||||
QString getTabText() const override;
|
||||
void setDeck(DeckLoader *_deckLoader);
|
||||
void setModified(bool _windowModified);
|
||||
bool confirmClose();
|
||||
void createDeckDock();
|
||||
void createCardInfoDock();
|
||||
void createFiltersDock();
|
||||
void createPrintingSelectorDock();
|
||||
void createMenus();
|
||||
void createCentralFrame();
|
||||
void updateCardInfo(CardInfoPtr _card);
|
||||
void createMenus() override;
|
||||
|
||||
public slots:
|
||||
void closeRequest(bool forced = false) override;
|
||||
void showPrintingSelector();
|
||||
signals:
|
||||
void openDeckEditor(const DeckLoader *deckLoader);
|
||||
void deckEditorClosing(TabDeckEditor *tab);
|
||||
void showPrintingSelector() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "../../server/pending_command.h"
|
||||
#include "../../server/remote/remote_decklist_tree_widget.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../game_logic/abstract_client.h"
|
||||
#include "../get_text_with_max.h"
|
||||
#include "decklist.h"
|
||||
#include "pb/command_deck_del.pb.h"
|
||||
@@ -31,7 +30,9 @@
|
||||
#include <QUrl>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client)
|
||||
TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
||||
AbstractClient *_client,
|
||||
const ServerInfo_User *currentUserInfo)
|
||||
: Tab(_tabSupervisor), client(_client)
|
||||
{
|
||||
localDirModel = new QFileSystemModel(this);
|
||||
@@ -105,6 +106,9 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_c
|
||||
aOpenLocalDeck = new QAction(this);
|
||||
aOpenLocalDeck->setIcon(QPixmap("theme:icons/pencil"));
|
||||
connect(aOpenLocalDeck, SIGNAL(triggered()), this, SLOT(actOpenLocalDeck()));
|
||||
aRenameLocal = new QAction(this);
|
||||
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
||||
connect(aRenameLocal, &QAction::triggered, this, &TabDeckStorage::actRenameLocal);
|
||||
aUpload = new QAction(this);
|
||||
aUpload->setIcon(QPixmap("theme:icons/arrow_right_green"));
|
||||
connect(aUpload, SIGNAL(triggered()), this, SLOT(actUpload()));
|
||||
@@ -135,6 +139,7 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_c
|
||||
|
||||
// Add actions to toolbars
|
||||
leftToolBar->addAction(aOpenLocalDeck);
|
||||
leftToolBar->addAction(aRenameLocal);
|
||||
leftToolBar->addAction(aUpload);
|
||||
leftToolBar->addAction(aNewLocalFolder);
|
||||
leftToolBar->addAction(aDeleteLocalDeck);
|
||||
@@ -151,6 +156,10 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_c
|
||||
QWidget *mainWidget = new QWidget(this);
|
||||
mainWidget->setLayout(hbox);
|
||||
setCentralWidget(mainWidget);
|
||||
|
||||
connect(client, &AbstractClient::userInfoChanged, this, &TabDeckStorage::handleConnected);
|
||||
connect(client, &AbstractClient::statusChanged, this, &TabDeckStorage::handleConnectionChanged);
|
||||
setRemoteEnabled(currentUserInfo && currentUserInfo->user_level() & ServerInfo_User::IsRegistered);
|
||||
}
|
||||
|
||||
void TabDeckStorage::retranslateUi()
|
||||
@@ -159,6 +168,7 @@ void TabDeckStorage::retranslateUi()
|
||||
rightGroupBox->setTitle(tr("Server deck storage"));
|
||||
|
||||
aOpenLocalDeck->setText(tr("Open in deck editor"));
|
||||
aRenameLocal->setText(tr("Rename deck or folder"));
|
||||
aUpload->setText(tr("Upload deck"));
|
||||
aOpenRemoteDeck->setText(tr("Open in deck editor"));
|
||||
aDownload->setText(tr("Download deck"));
|
||||
@@ -187,6 +197,36 @@ QString TabDeckStorage::getTargetPath() const
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::handleConnected(const ServerInfo_User &userInfo)
|
||||
{
|
||||
setRemoteEnabled(userInfo.user_level() & ServerInfo_User::IsRegistered);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only responsible for handling the disconnect. The connect is already handled elsewhere
|
||||
*/
|
||||
void TabDeckStorage::handleConnectionChanged(ClientStatus status)
|
||||
{
|
||||
if (status == StatusDisconnected) {
|
||||
setRemoteEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::setRemoteEnabled(bool enabled)
|
||||
{
|
||||
aUpload->setEnabled(enabled);
|
||||
aOpenRemoteDeck->setEnabled(enabled);
|
||||
aDownload->setEnabled(enabled);
|
||||
aNewFolder->setEnabled(enabled);
|
||||
aDeleteRemoteDeck->setEnabled(enabled);
|
||||
|
||||
if (enabled) {
|
||||
serverDirView->refreshTree();
|
||||
} else {
|
||||
serverDirView->clearTree();
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::actLocalDoubleClick(const QModelIndex &curLeft)
|
||||
{
|
||||
if (!localDirModel->isDir(curLeft)) {
|
||||
@@ -212,6 +252,36 @@ void TabDeckStorage::actOpenLocalDeck()
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::actRenameLocal()
|
||||
{
|
||||
QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||
for (const auto &curLeft : curLefts) {
|
||||
const QFileInfo info = localDirModel->fileInfo(curLeft);
|
||||
|
||||
const QString oldName = info.baseName();
|
||||
const QString title = info.isDir() ? tr("Rename local folder") : tr("Rename local file");
|
||||
|
||||
bool ok;
|
||||
QString newName = QInputDialog::getText(this, title, tr("New name:"), QLineEdit::Normal, oldName, &ok);
|
||||
if (!ok) { // terminate all remaining selections if user cancels
|
||||
return;
|
||||
}
|
||||
if (newName.isEmpty() || oldName == newName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString newFileName = newName;
|
||||
if (!info.suffix().isEmpty()) {
|
||||
newFileName += "." + info.suffix();
|
||||
}
|
||||
const QString newFilePath = QFileInfo(info.dir(), newFileName).filePath();
|
||||
|
||||
if (!QFile::rename(info.filePath(), newFilePath)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Rename failed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckStorage::actUpload()
|
||||
{
|
||||
QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#define TAB_DECK_STORAGE_H
|
||||
|
||||
#include "../../server/remote/remote_decklist_tree_widget.h"
|
||||
#include "../game_logic/abstract_client.h"
|
||||
#include "tab.h"
|
||||
|
||||
class ServerInfo_User;
|
||||
class AbstractClient;
|
||||
class QTreeView;
|
||||
class QFileSystemModel;
|
||||
@@ -26,20 +28,27 @@ private:
|
||||
RemoteDeckList_TreeWidget *serverDirView;
|
||||
QGroupBox *leftGroupBox, *rightGroupBox;
|
||||
|
||||
QAction *aOpenLocalDeck, *aUpload, *aNewLocalFolder, *aDeleteLocalDeck;
|
||||
QAction *aOpenLocalDeck, *aRenameLocal, *aUpload, *aNewLocalFolder, *aDeleteLocalDeck;
|
||||
QAction *aOpenDecksFolder;
|
||||
QAction *aOpenRemoteDeck, *aDownload, *aNewFolder, *aDeleteRemoteDeck;
|
||||
QString getTargetPath() const;
|
||||
|
||||
void setRemoteEnabled(bool enabled);
|
||||
|
||||
void uploadDeck(const QString &filePath, const QString &targetPath);
|
||||
void deleteRemoteDeck(const RemoteDeckList_TreeModel::Node *node);
|
||||
|
||||
void downloadNodeAtIndex(const QModelIndex &curLeft, const QModelIndex &curRight);
|
||||
|
||||
private slots:
|
||||
void handleConnected(const ServerInfo_User &userInfo);
|
||||
void handleConnectionChanged(ClientStatus status);
|
||||
|
||||
void actLocalDoubleClick(const QModelIndex &curLeft);
|
||||
void actOpenLocalDeck();
|
||||
|
||||
void actRenameLocal();
|
||||
|
||||
void actUpload();
|
||||
void uploadFinished(const Response &r, const CommandContainer &commandContainer);
|
||||
|
||||
@@ -63,11 +72,11 @@ private slots:
|
||||
void deleteDeckFinished(const Response &response, const CommandContainer &commandContainer);
|
||||
|
||||
public:
|
||||
TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client);
|
||||
TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User *currentUserInfo);
|
||||
void retranslateUi() override;
|
||||
QString getTabText() const override
|
||||
{
|
||||
return tr("Deck storage");
|
||||
return tr("Deck Storage");
|
||||
}
|
||||
signals:
|
||||
void openDeckEditor(const DeckLoader *deckLoader);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../../main.h"
|
||||
#include "../../server/message_log_widget.h"
|
||||
#include "../../server/pending_command.h"
|
||||
#include "../../server/user/user_list_manager.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../game_logic/abstract_client.h"
|
||||
#include "../network/replay_timeline_widget.h"
|
||||
@@ -65,8 +66,8 @@
|
||||
#include <QToolButton>
|
||||
#include <QWidget>
|
||||
|
||||
TabGame::TabGame(TabSupervisor *_tabSupervisor, UserListProxy *_userListProxy, GameReplay *_replay)
|
||||
: Tab(_tabSupervisor), userListProxy(_userListProxy), secondsElapsed(0), hostId(-1), localPlayerId(-1),
|
||||
TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
|
||||
: Tab(_tabSupervisor), secondsElapsed(0), hostId(-1), localPlayerId(-1),
|
||||
isLocalGame(_tabSupervisor->getIsLocalGame()), spectator(true), judge(false), gameStateKnown(false),
|
||||
resuming(false), currentPhase(-1), activeCard(nullptr), gameClosed(false), replay(_replay), currentReplayStep(0),
|
||||
sayLabel(nullptr), sayEdit(nullptr)
|
||||
@@ -123,16 +124,16 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, UserListProxy *_userListProxy, G
|
||||
}
|
||||
|
||||
TabGame::TabGame(TabSupervisor *_tabSupervisor,
|
||||
UserListProxy *_userListProxy,
|
||||
QList<AbstractClient *> &_clients,
|
||||
const Event_GameJoined &event,
|
||||
const QMap<int, QString> &_roomGameTypes)
|
||||
: Tab(_tabSupervisor), userListProxy(_userListProxy), clients(_clients), gameInfo(event.game_info()),
|
||||
roomGameTypes(_roomGameTypes), hostId(event.host_id()), localPlayerId(event.player_id()),
|
||||
isLocalGame(_tabSupervisor->getIsLocalGame()), spectator(event.spectator()), judge(event.judge()),
|
||||
gameStateKnown(false), resuming(event.resuming()), currentPhase(-1), activeCard(nullptr), gameClosed(false),
|
||||
replay(nullptr), replayPlayButton(nullptr), replayFastForwardButton(nullptr), aReplaySkipForward(nullptr),
|
||||
aReplaySkipBackward(nullptr), aReplaySkipForwardBig(nullptr), aReplaySkipBackwardBig(nullptr), replayDock(nullptr)
|
||||
: Tab(_tabSupervisor), userListProxy(_tabSupervisor->getUserListManager()), clients(_clients),
|
||||
gameInfo(event.game_info()), roomGameTypes(_roomGameTypes), hostId(event.host_id()),
|
||||
localPlayerId(event.player_id()), isLocalGame(_tabSupervisor->getIsLocalGame()), spectator(event.spectator()),
|
||||
judge(event.judge()), gameStateKnown(false), resuming(event.resuming()), currentPhase(-1), activeCard(nullptr),
|
||||
gameClosed(false), replay(nullptr), replayPlayButton(nullptr), replayFastForwardButton(nullptr),
|
||||
aReplaySkipForward(nullptr), aReplaySkipBackward(nullptr), aReplaySkipForwardBig(nullptr),
|
||||
aReplaySkipBackwardBig(nullptr), replayDock(nullptr)
|
||||
{
|
||||
// THIS CTOR IS USED ON GAMES
|
||||
gameInfo.set_started(false);
|
||||
@@ -188,14 +189,7 @@ void TabGame::emitUserEvent()
|
||||
|
||||
TabGame::~TabGame()
|
||||
{
|
||||
scene->clearViews();
|
||||
|
||||
delete replay;
|
||||
|
||||
QMapIterator<int, Player *> i(players);
|
||||
while (i.hasNext()) {
|
||||
delete i.next().value();
|
||||
}
|
||||
}
|
||||
|
||||
void TabGame::updatePlayerListDockTitle()
|
||||
@@ -759,7 +753,7 @@ void TabGame::processGameEventContainer(const GameEventContainer &cont,
|
||||
default: {
|
||||
Player *player = players.value(playerId, 0);
|
||||
if (!player) {
|
||||
qDebug() << "unhandled game event: invalid player id";
|
||||
qCDebug(TabGameLog) << "unhandled game event: invalid player id";
|
||||
break;
|
||||
}
|
||||
player->processGameEvent(eventType, event, context, options);
|
||||
@@ -842,6 +836,7 @@ void TabGame::startGame(bool _resuming)
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
i.value()->setReadyStart(false);
|
||||
i.value()->setVisualDeckStorageExists(false);
|
||||
i.value()->hide();
|
||||
}
|
||||
|
||||
@@ -888,8 +883,7 @@ void TabGame::closeGame()
|
||||
void TabGame::eventSpectatorSay(const Event_GameSay &event, int eventPlayerId, const GameEventContext & /*context*/)
|
||||
{
|
||||
const ServerInfo_User &userInfo = spectators.value(eventPlayerId);
|
||||
messageLog->logSpectatorSay(QString::fromStdString(userInfo.name()), UserLevelFlags(userInfo.user_level()),
|
||||
QString::fromStdString(userInfo.privlevel()), QString::fromStdString(event.message()));
|
||||
messageLog->logSpectatorSay(userInfo, QString::fromStdString(event.message()));
|
||||
}
|
||||
|
||||
void TabGame::eventSpectatorLeave(const Event_Leave &event, int eventPlayerId, const GameEventContext & /*context*/)
|
||||
@@ -935,8 +929,8 @@ void TabGame::eventGameStateChanged(const Event_GameStateChanged &event,
|
||||
DeckViewContainer *deckViewContainer = deckViewContainers.value(playerId);
|
||||
if (playerInfo.has_deck_list()) {
|
||||
DeckLoader newDeck(QString::fromStdString(playerInfo.deck_list()));
|
||||
PictureLoader::cacheCardPixmaps(
|
||||
CardDatabaseManager::getInstance()->getCards(newDeck.getCardList()));
|
||||
PictureLoader::cacheCardPixmaps(CardDatabaseManager::getInstance()->getCardsByNameAndProviderId(
|
||||
newDeck.getCardListWithProviderId()));
|
||||
deckViewContainer->setDeck(newDeck);
|
||||
player->setDeck(newDeck);
|
||||
}
|
||||
@@ -1096,6 +1090,7 @@ void TabGame::eventLeave(const Event_Leave &event, int eventPlayerId, const Game
|
||||
players.remove(eventPlayerId);
|
||||
emit playerRemoved(player);
|
||||
player->clear();
|
||||
scene->removePlayer(player);
|
||||
player->deleteLater();
|
||||
|
||||
// Rearrange all remaining zones so that attachment relationship updates take place
|
||||
@@ -1684,7 +1679,7 @@ void TabGame::createPlayerListDock(bool bReplay)
|
||||
|
||||
void TabGame::createMessageDock(bool bReplay)
|
||||
{
|
||||
messageLog = new MessageLogWidget(tabSupervisor, userListProxy, this);
|
||||
messageLog = new MessageLogWidget(tabSupervisor, this);
|
||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfoFrameWidget, SLOT(setCard(QString)));
|
||||
connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
#include "tab.h"
|
||||
|
||||
#include <QCompleter>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMap>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(TabGameLog, "tab_game");
|
||||
|
||||
class UserListProxy;
|
||||
class DeckViewContainer;
|
||||
class AbstractClient;
|
||||
@@ -67,7 +70,7 @@ class TabGame : public Tab
|
||||
private:
|
||||
QTimer *gameTimer;
|
||||
int secondsElapsed;
|
||||
UserListProxy *userListProxy;
|
||||
const UserListProxy *userListProxy;
|
||||
QList<AbstractClient *> clients;
|
||||
ServerInfo_Game gameInfo;
|
||||
QMap<int, QString> roomGameTypes;
|
||||
@@ -212,11 +215,10 @@ private slots:
|
||||
|
||||
public:
|
||||
TabGame(TabSupervisor *_tabSupervisor,
|
||||
UserListProxy *_userListProxy,
|
||||
QList<AbstractClient *> &_clients,
|
||||
const Event_GameJoined &event,
|
||||
const QMap<int, QString> &_roomGameTypes);
|
||||
TabGame(TabSupervisor *_tabSupervisor, UserListProxy *_userListProxy, GameReplay *replay);
|
||||
TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay);
|
||||
~TabGame() override;
|
||||
void retranslateUi() override;
|
||||
void updatePlayerListDockTitle();
|
||||
|
||||
@@ -26,7 +26,7 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor,
|
||||
: Tab(_tabSupervisor), client(_client), ownUserInfo(new ServerInfo_User(_ownUserInfo)),
|
||||
otherUserInfo(new ServerInfo_User(_otherUserInfo)), userOnline(true)
|
||||
{
|
||||
chatView = new ChatView(tabSupervisor, tabSupervisor->getUserListManager(), 0, true);
|
||||
chatView = new ChatView(tabSupervisor, 0, true);
|
||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup);
|
||||
connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||
@@ -118,11 +118,8 @@ void TabMessage::messageSent(const Response &response)
|
||||
void TabMessage::processUserMessageEvent(const Event_UserMessage &event)
|
||||
{
|
||||
auto userInfo = event.sender_name() == otherUserInfo->name() ? otherUserInfo : ownUserInfo;
|
||||
const UserLevelFlags userLevel(userInfo->user_level());
|
||||
const QString userPriv = QString::fromStdString(userInfo->privlevel());
|
||||
|
||||
chatView->appendMessage(QString::fromStdString(event.message()), {}, QString::fromStdString(event.sender_name()),
|
||||
userLevel, userPriv, true);
|
||||
chatView->appendMessage(QString::fromStdString(event.message()), {}, *userInfo, true);
|
||||
if (tabSupervisor->currentIndex() != tabSupervisor->indexOf(this))
|
||||
soundEngine->playSound("private_message");
|
||||
if (SettingsCache::instance().getShowMessagePopup() && shouldShowSystemPopup(event))
|
||||
@@ -148,7 +145,7 @@ void TabMessage::showSystemPopup(const Event_UserMessage &event)
|
||||
event.message().c_str());
|
||||
connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
|
||||
} else {
|
||||
qDebug() << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
|
||||
qCDebug(TabMessageLog) << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include "tab.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(TabMessageLog, "tab_message");
|
||||
|
||||
class AbstractClient;
|
||||
class ChatView;
|
||||
class LineEditUnfocusable;
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
#include <QUrl>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) : Tab(_tabSupervisor), client(_client)
|
||||
TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User *currentUserInfo)
|
||||
: Tab(_tabSupervisor), client(_client)
|
||||
{
|
||||
localDirModel = new QFileSystemModel(this);
|
||||
localDirModel->setRootPath(SettingsCache::instance().getReplaysPath());
|
||||
@@ -98,7 +99,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) :
|
||||
connect(aOpenLocalReplay, SIGNAL(triggered()), this, SLOT(actOpenLocalReplay()));
|
||||
connect(localDirView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(actOpenLocalReplay()));
|
||||
aRenameLocal = new QAction(this);
|
||||
aRenameLocal->setIcon(QPixmap("theme:icons/pencil"));
|
||||
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
||||
connect(aRenameLocal, &QAction::triggered, this, &TabReplays::actRenameLocal);
|
||||
aNewLocalFolder = new QAction(this);
|
||||
aNewLocalFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
||||
@@ -147,6 +148,10 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) :
|
||||
|
||||
connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this,
|
||||
SLOT(replayAddedEventReceived(const Event_ReplayAdded &)));
|
||||
|
||||
connect(client, &AbstractClient::userInfoChanged, this, &TabReplays::handleConnected);
|
||||
connect(client, &AbstractClient::statusChanged, this, &TabReplays::handleConnectionChanged);
|
||||
setRemoteEnabled(currentUserInfo && currentUserInfo->user_level() & ServerInfo_User::IsRegistered);
|
||||
}
|
||||
|
||||
void TabReplays::retranslateUi()
|
||||
@@ -165,6 +170,35 @@ void TabReplays::retranslateUi()
|
||||
aDeleteRemoteReplay->setText(tr("Delete"));
|
||||
}
|
||||
|
||||
void TabReplays::handleConnected(const ServerInfo_User &userInfo)
|
||||
{
|
||||
setRemoteEnabled(userInfo.user_level() & ServerInfo_User::IsRegistered);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only responsible for handling the disconnect. The connect is already handled elsewhere
|
||||
*/
|
||||
void TabReplays::handleConnectionChanged(ClientStatus status)
|
||||
{
|
||||
if (status == StatusDisconnected) {
|
||||
setRemoteEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TabReplays::setRemoteEnabled(bool enabled)
|
||||
{
|
||||
aOpenRemoteReplay->setEnabled(enabled);
|
||||
aDownload->setEnabled(enabled);
|
||||
aKeep->setEnabled(enabled);
|
||||
aDeleteRemoteReplay->setEnabled(enabled);
|
||||
|
||||
if (enabled) {
|
||||
serverDirView->refreshTree();
|
||||
} else {
|
||||
serverDirView->clearTree();
|
||||
}
|
||||
}
|
||||
|
||||
void TabReplays::actLocalDoubleClick(const QModelIndex &curLeft)
|
||||
{
|
||||
if (!localDirModel->isDir(curLeft)) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#ifndef TAB_REPLAYS_H
|
||||
#define TAB_REPLAYS_H
|
||||
|
||||
#include "../game_logic/abstract_client.h"
|
||||
#include "tab.h"
|
||||
|
||||
class ServerInfo_User;
|
||||
class Response;
|
||||
class AbstractClient;
|
||||
class QTreeView;
|
||||
@@ -29,9 +31,14 @@ private:
|
||||
QAction *aOpenReplaysFolder;
|
||||
QAction *aOpenRemoteReplay, *aDownload, *aKeep, *aDeleteRemoteReplay;
|
||||
|
||||
void setRemoteEnabled(bool enabled);
|
||||
|
||||
void downloadNodeAtIndex(const QModelIndex &curLeft, const QModelIndex &curRight);
|
||||
|
||||
private slots:
|
||||
void handleConnected(const ServerInfo_User &userInfo);
|
||||
void handleConnectionChanged(ClientStatus status);
|
||||
|
||||
void actLocalDoubleClick(const QModelIndex &curLeft);
|
||||
void actRenameLocal();
|
||||
void actOpenLocalReplay();
|
||||
@@ -58,11 +65,11 @@ signals:
|
||||
void openReplay(GameReplay *replay);
|
||||
|
||||
public:
|
||||
TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client);
|
||||
TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, const ServerInfo_User *currentUserInfo);
|
||||
void retranslateUi() override;
|
||||
QString getTabText() const override
|
||||
{
|
||||
return tr("Game replays");
|
||||
return tr("Game Replays");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -36,10 +36,9 @@
|
||||
TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
||||
AbstractClient *_client,
|
||||
ServerInfo_User *_ownUser,
|
||||
const UserListProxy *_userListProxy,
|
||||
const ServerInfo_Room &info)
|
||||
: Tab(_tabSupervisor), client(_client), roomId(info.room_id()), roomName(QString::fromStdString(info.name())),
|
||||
ownUser(_ownUser), userListProxy(_userListProxy)
|
||||
ownUser(_ownUser), userListProxy(_tabSupervisor->getUserListManager())
|
||||
{
|
||||
const int gameTypeListSize = info.gametype_list_size();
|
||||
for (int i = 0; i < gameTypeListSize; ++i)
|
||||
@@ -53,7 +52,7 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
||||
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this,
|
||||
SIGNAL(openMessageDialog(const QString &, bool)));
|
||||
|
||||
chatView = new ChatView(tabSupervisor, userListProxy, nullptr, true, this);
|
||||
chatView = new ChatView(tabSupervisor, nullptr, true, this);
|
||||
connect(chatView, SIGNAL(showMentionPopup(const QString &)), this, SLOT(actShowMentionPopup(const QString &)));
|
||||
connect(chatView, SIGNAL(messageClickedSignal()), this, SLOT(focusTab()));
|
||||
connect(chatView, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
@@ -284,17 +283,15 @@ void TabRoom::processRoomSayEvent(const Event_RoomSay &event)
|
||||
QString senderName = QString::fromStdString(event.name());
|
||||
QString message = QString::fromStdString(event.message());
|
||||
|
||||
if (userListProxy->getOnlineUser(senderName))
|
||||
if (userListProxy->isUserIgnored(senderName))
|
||||
return;
|
||||
|
||||
UserListTWI *twi = userList->getUsers().value(senderName);
|
||||
UserLevelFlags userLevel;
|
||||
QString userPrivLevel;
|
||||
ServerInfo_User userInfo = {};
|
||||
if (twi) {
|
||||
userLevel = UserLevelFlags(twi->getUserInfo().user_level());
|
||||
userPrivLevel = QString::fromStdString(twi->getUserInfo().privlevel());
|
||||
userInfo = twi->getUserInfo();
|
||||
if (SettingsCache::instance().getIgnoreUnregisteredUsers() &&
|
||||
!userLevel.testFlag(ServerInfo_User::IsRegistered))
|
||||
!UserLevelFlags(userInfo.user_level()).testFlag(ServerInfo_User::IsRegistered))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -307,7 +304,7 @@ void TabRoom::processRoomSayEvent(const Event_RoomSay &event)
|
||||
QString(QDateTime::fromMSecsSinceEpoch(event.time_of()).toLocalTime().toString("d MMM yyyy HH:mm:ss")) +
|
||||
"] " + message;
|
||||
|
||||
chatView->appendMessage(message, event.message_type(), senderName, userLevel, userPrivLevel, true);
|
||||
chatView->appendMessage(message, event.message_type(), userInfo, true);
|
||||
emit userEvent(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,6 @@ public:
|
||||
TabRoom(TabSupervisor *_tabSupervisor,
|
||||
AbstractClient *_client,
|
||||
ServerInfo_User *_ownUser,
|
||||
const UserListProxy *_userListProxy,
|
||||
const ServerInfo_Room &info);
|
||||
void retranslateUi() override;
|
||||
void closeRequest(bool forced = false) override;
|
||||
|
||||
@@ -176,11 +176,11 @@ void TabSupervisor::retranslateUi()
|
||||
{
|
||||
// tab menu actions
|
||||
aTabDeckEditor->setText(tr("Deck Editor"));
|
||||
aTabVisualDeckStorage->setText(tr("&Visual Deck storage"));
|
||||
aTabVisualDeckStorage->setText(tr("&Visual Deck Storage"));
|
||||
aTabServer->setText(tr("Server"));
|
||||
aTabAccount->setText(tr("Account"));
|
||||
aTabDeckStorage->setText(tr("Deck storage"));
|
||||
aTabReplays->setText(tr("Game replays"));
|
||||
aTabDeckStorage->setText(tr("Deck Storage"));
|
||||
aTabReplays->setText(tr("Game Replays"));
|
||||
aTabAdmin->setText(tr("Administration"));
|
||||
aTabLog->setText(tr("Logs"));
|
||||
|
||||
@@ -201,7 +201,7 @@ void TabSupervisor::retranslateUi()
|
||||
QListIterator<TabGame *> replayIterator(replayTabs);
|
||||
while (replayIterator.hasNext())
|
||||
tabs.append(replayIterator.next());
|
||||
QListIterator<TabDeckEditor *> deckEditorIterator(deckEditorTabs);
|
||||
QListIterator<AbstractTabDeckEditor *> deckEditorIterator(deckEditorTabs);
|
||||
while (deckEditorIterator.hasNext())
|
||||
tabs.append(deckEditorIterator.next());
|
||||
QMapIterator<QString, TabMessage *> messageIterator(messageTabs);
|
||||
@@ -222,7 +222,14 @@ void TabSupervisor::retranslateUi()
|
||||
void TabSupervisor::refreshShortcuts()
|
||||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
aTabDeckEditor->setShortcuts(shortcuts.getShortcut("MainWindow/aDeckEditor"));
|
||||
aTabDeckEditor->setShortcuts(shortcuts.getShortcut("Tabs/aTabDeckEditor"));
|
||||
aTabVisualDeckStorage->setShortcuts(shortcuts.getShortcut("Tabs/aTabVisualDeckStorage"));
|
||||
aTabServer->setShortcuts(shortcuts.getShortcut("Tabs/aTabServer"));
|
||||
aTabAccount->setShortcuts(shortcuts.getShortcut("Tabs/aTabAccount"));
|
||||
aTabDeckStorage->setShortcuts(shortcuts.getShortcut("Tabs/aTabDeckStorage"));
|
||||
aTabReplays->setShortcuts(shortcuts.getShortcut("Tabs/aTabReplays"));
|
||||
aTabAdmin->setShortcuts(shortcuts.getShortcut("Tabs/aTabAdmin"));
|
||||
aTabLog->setShortcuts(shortcuts.getShortcut("Tabs/aTabLog"));
|
||||
}
|
||||
|
||||
bool TabSupervisor::closeRequest()
|
||||
@@ -235,7 +242,7 @@ bool TabSupervisor::closeRequest()
|
||||
}
|
||||
}
|
||||
|
||||
for (TabDeckEditor *tab : deckEditorTabs) {
|
||||
for (AbstractTabDeckEditor *tab : deckEditorTabs) {
|
||||
if (!tab->confirmClose())
|
||||
return false;
|
||||
}
|
||||
@@ -279,6 +286,8 @@ void TabSupervisor::initStartupTabs()
|
||||
addDeckEditorTab(nullptr);
|
||||
|
||||
checkAndTrigger(aTabVisualDeckStorage, SettingsCache::instance().getTabVisualDeckStorageOpen());
|
||||
checkAndTrigger(aTabDeckStorage, SettingsCache::instance().getTabDeckStorageOpen());
|
||||
checkAndTrigger(aTabReplays, SettingsCache::instance().getTabReplaysOpen());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,6 +343,8 @@ void TabSupervisor::resetTabsMenu()
|
||||
tabsMenu->addAction(aTabDeckEditor);
|
||||
tabsMenu->addSeparator();
|
||||
tabsMenu->addAction(aTabVisualDeckStorage);
|
||||
tabsMenu->addAction(aTabDeckStorage);
|
||||
tabsMenu->addAction(aTabReplays);
|
||||
}
|
||||
|
||||
void TabSupervisor::start(const ServerInfo_User &_userInfo)
|
||||
@@ -354,14 +365,6 @@ void TabSupervisor::start(const ServerInfo_User &_userInfo)
|
||||
|
||||
updatePingTime(0, -1);
|
||||
|
||||
if (userInfo->user_level() & ServerInfo_User::IsRegistered) {
|
||||
tabsMenu->addAction(aTabDeckStorage);
|
||||
tabsMenu->addAction(aTabReplays);
|
||||
|
||||
checkAndTrigger(aTabDeckStorage, SettingsCache::instance().getTabDeckStorageOpen());
|
||||
checkAndTrigger(aTabReplays, SettingsCache::instance().getTabReplaysOpen());
|
||||
}
|
||||
|
||||
if (userInfo->user_level() & ServerInfo_User::IsModerator) {
|
||||
tabsMenu->addSeparator();
|
||||
tabsMenu->addAction(aTabAdmin);
|
||||
@@ -379,8 +382,6 @@ void TabSupervisor::startLocal(const QList<AbstractClient *> &_clients)
|
||||
resetTabsMenu();
|
||||
|
||||
tabAccount = nullptr;
|
||||
tabDeckStorage = nullptr;
|
||||
tabReplays = nullptr;
|
||||
tabAdmin = nullptr;
|
||||
tabLog = nullptr;
|
||||
isLocalGame = true;
|
||||
@@ -416,12 +417,6 @@ void TabSupervisor::stop()
|
||||
if (tabServer) {
|
||||
tabServer->closeRequest(true);
|
||||
}
|
||||
if (tabDeckStorage) {
|
||||
tabDeckStorage->closeRequest(true);
|
||||
}
|
||||
if (tabReplays) {
|
||||
tabReplays->closeRequest(true);
|
||||
}
|
||||
if (tabAdmin) {
|
||||
tabAdmin->closeRequest(true);
|
||||
}
|
||||
@@ -460,7 +455,6 @@ void TabSupervisor::actTabVisualDeckStorage(bool checked)
|
||||
if (checked && !tabVisualDeckStorage) {
|
||||
tabVisualDeckStorage = new TabDeckStorageVisual(this);
|
||||
myAddTab(tabVisualDeckStorage, aTabVisualDeckStorage);
|
||||
setCurrentWidget(tabVisualDeckStorage);
|
||||
connect(tabVisualDeckStorage, &Tab::closed, this, [this] {
|
||||
tabVisualDeckStorage = nullptr;
|
||||
aTabVisualDeckStorage->setChecked(false);
|
||||
@@ -508,7 +502,7 @@ void TabSupervisor::actTabDeckStorage(bool checked)
|
||||
{
|
||||
SettingsCache::instance().setTabDeckStorageOpen(checked);
|
||||
if (checked && !tabDeckStorage) {
|
||||
tabDeckStorage = new TabDeckStorage(this, client);
|
||||
tabDeckStorage = new TabDeckStorage(this, client, userInfo);
|
||||
connect(tabDeckStorage, &TabDeckStorage::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
||||
myAddTab(tabDeckStorage, aTabDeckStorage);
|
||||
connect(tabDeckStorage, &Tab::closed, this, [this] {
|
||||
@@ -524,7 +518,7 @@ void TabSupervisor::actTabReplays(bool checked)
|
||||
{
|
||||
SettingsCache::instance().setTabReplaysOpen(checked);
|
||||
if (checked && !tabReplays) {
|
||||
tabReplays = new TabReplays(this, client);
|
||||
tabReplays = new TabReplays(this, client, userInfo);
|
||||
connect(tabReplays, &TabReplays::openReplay, this, &TabSupervisor::openReplay);
|
||||
myAddTab(tabReplays, aTabReplays);
|
||||
connect(tabReplays, &Tab::closed, this, [this] {
|
||||
@@ -588,7 +582,7 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event)
|
||||
roomGameTypes.insert(event.game_types(i).game_type_id(),
|
||||
QString::fromStdString(event.game_types(i).description()));
|
||||
|
||||
auto *tab = new TabGame(this, userListManager, QList<AbstractClient *>() << client, event, roomGameTypes);
|
||||
auto *tab = new TabGame(this, QList<AbstractClient *>() << client, event, roomGameTypes);
|
||||
connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft);
|
||||
connect(tab, &TabGame::openMessageDialog, this, &TabSupervisor::addMessageTab);
|
||||
connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
||||
@@ -599,7 +593,7 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event)
|
||||
|
||||
void TabSupervisor::localGameJoined(const Event_GameJoined &event)
|
||||
{
|
||||
auto *tab = new TabGame(this, userListManager, localClients, event, QMap<int, QString>());
|
||||
auto *tab = new TabGame(this, localClients, event, QMap<int, QString>());
|
||||
connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft);
|
||||
connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
||||
myAddTab(tab);
|
||||
@@ -627,7 +621,7 @@ void TabSupervisor::gameLeft(TabGame *tab)
|
||||
|
||||
void TabSupervisor::addRoomTab(const ServerInfo_Room &info, bool setCurrent)
|
||||
{
|
||||
auto *tab = new TabRoom(this, client, userInfo, userListManager, info);
|
||||
auto *tab = new TabRoom(this, client, userInfo, info);
|
||||
connect(tab, &TabRoom::maximizeClient, this, &TabSupervisor::maximizeMainWindow);
|
||||
connect(tab, &TabRoom::roomClosing, this, &TabSupervisor::roomLeft);
|
||||
connect(tab, &TabRoom::openMessageDialog, this, &TabSupervisor::addMessageTab);
|
||||
@@ -648,7 +642,7 @@ void TabSupervisor::roomLeft(TabRoom *tab)
|
||||
|
||||
void TabSupervisor::openReplay(GameReplay *replay)
|
||||
{
|
||||
auto *replayTab = new TabGame(this, userListManager, replay);
|
||||
auto *replayTab = new TabGame(this, replay);
|
||||
connect(replayTab, &TabGame::gameClosing, this, &TabSupervisor::replayLeft);
|
||||
myAddTab(replayTab);
|
||||
replayTabs.append(replayTab);
|
||||
@@ -712,15 +706,27 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
|
||||
auto *tab = new TabDeckEditor(this);
|
||||
if (deckToOpen)
|
||||
tab->setDeck(new DeckLoader(*deckToOpen));
|
||||
connect(tab, &TabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
|
||||
connect(tab, &TabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
||||
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
|
||||
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
||||
myAddTab(tab);
|
||||
deckEditorTabs.append(tab);
|
||||
setCurrentWidget(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
void TabSupervisor::deckEditorClosed(TabDeckEditor *tab)
|
||||
TabEdhRec *TabSupervisor::addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander)
|
||||
{
|
||||
auto *tab = new TabEdhRec(this);
|
||||
if (cardToQuery) {
|
||||
tab->setCard(cardToQuery, isCommander);
|
||||
}
|
||||
|
||||
myAddTab(tab);
|
||||
setCurrentWidget(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
void TabSupervisor::deckEditorClosed(AbstractTabDeckEditor *tab)
|
||||
{
|
||||
if (tab == currentWidget())
|
||||
emit setMenu();
|
||||
@@ -760,7 +766,7 @@ void TabSupervisor::processGameEventContainer(const GameEventContainer &cont)
|
||||
if (tab)
|
||||
tab->processGameEventContainer(cont, qobject_cast<AbstractClient *>(sender()), {});
|
||||
else
|
||||
qDebug() << "gameEvent: invalid gameId";
|
||||
qCDebug(TabSupervisorLog) << "gameEvent: invalid gameId";
|
||||
}
|
||||
|
||||
void TabSupervisor::processUserMessageEvent(const Event_UserMessage &event)
|
||||
@@ -787,9 +793,9 @@ void TabSupervisor::processUserMessageEvent(const Event_UserMessage &event)
|
||||
|
||||
void TabSupervisor::actShowPopup(const QString &message)
|
||||
{
|
||||
qDebug() << "ACT SHOW POPUP";
|
||||
qCDebug(TabSupervisorLog) << "ACT SHOW POPUP";
|
||||
if (trayIcon && (QApplication::activeWindow() == nullptr || QApplication::focusWidget() == nullptr)) {
|
||||
qDebug() << "LAUNCHING POPUP";
|
||||
qCDebug(TabSupervisorLog) << "LAUNCHING POPUP";
|
||||
// disconnect(trayIcon, SIGNAL(messageClicked()), nullptr, nullptr);
|
||||
trayIcon->showMessage(message, tr("Click to view"));
|
||||
// connect(trayIcon, SIGNAL(messageClicked()), chatView, SLOT(actMessageClicked()));
|
||||
@@ -810,10 +816,10 @@ void TabSupervisor::processUserJoined(const ServerInfo_User &userInfoJoined)
|
||||
if (auto *tab = getTabAccount()) {
|
||||
if (tab != currentWidget()) {
|
||||
tab->setContentsChanged(true);
|
||||
QPixmap avatarPixmap =
|
||||
UserLevelPixmapGenerator::generatePixmap(13, (UserLevelFlags)userInfoJoined.user_level(), true,
|
||||
QString::fromStdString(userInfoJoined.privlevel()));
|
||||
setTabIcon(indexOf(tab), QPixmap(avatarPixmap));
|
||||
QIcon avatarIcon = UserLevelPixmapGenerator::generateIcon(
|
||||
13, (UserLevelFlags)userInfoJoined.user_level(), userInfoJoined.pawn_colors(), true,
|
||||
QString::fromStdString(userInfoJoined.privlevel()));
|
||||
setTabIcon(indexOf(tab), avatarIcon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,19 @@
|
||||
|
||||
#include "../../deck/deck_loader.h"
|
||||
#include "../../server/user/user_list_proxy.h"
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
#include "api/edhrec/tab_edhrec.h"
|
||||
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QCommonStyle>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMap>
|
||||
#include <QProxyStyle>
|
||||
#include <QTabWidget>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(TabSupervisorLog, "tab_supervisor");
|
||||
|
||||
class UserListManager;
|
||||
class QMenu;
|
||||
class AbstractClient;
|
||||
@@ -83,7 +88,7 @@ private:
|
||||
QMap<int, TabGame *> gameTabs;
|
||||
QList<TabGame *> replayTabs;
|
||||
QMap<QString, TabMessage *> messageTabs;
|
||||
QList<TabDeckEditor *> deckEditorTabs;
|
||||
QList<AbstractTabDeckEditor *> deckEditorTabs;
|
||||
bool isLocalGame;
|
||||
|
||||
QAction *aTabDeckEditor, *aTabVisualDeckStorage, *aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays,
|
||||
@@ -128,6 +133,10 @@ public:
|
||||
{
|
||||
return roomTabs;
|
||||
}
|
||||
QList<AbstractTabDeckEditor *> getDeckEditorTabs() const
|
||||
{
|
||||
return deckEditorTabs;
|
||||
}
|
||||
bool getAdminLocked() const;
|
||||
bool closeRequest();
|
||||
bool switchToGameTabIfAlreadyExists(const int gameId);
|
||||
@@ -140,6 +149,7 @@ signals:
|
||||
|
||||
public slots:
|
||||
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen);
|
||||
TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false);
|
||||
void openReplay(GameReplay *replay);
|
||||
void maximizeMainWindow();
|
||||
private slots:
|
||||
@@ -165,7 +175,7 @@ private slots:
|
||||
void processUserLeft(const QString &userName);
|
||||
void processUserJoined(const ServerInfo_User &userInfo);
|
||||
void talkLeft(TabMessage *tab);
|
||||
void deckEditorClosed(TabDeckEditor *tab);
|
||||
void deckEditorClosed(AbstractTabDeckEditor *tab);
|
||||
void tabUserEvent(bool globalEvent);
|
||||
void updateTabText(Tab *tab, const QString &newTabText);
|
||||
void processRoomEvent(const RoomEvent &event);
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
#include "../tab_supervisor.h"
|
||||
#include "pb/command_deck_del.pb.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
|
||||
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
||||
: Tab(_tabSupervisor), visualDeckStorageWidget(new VisualDeckStorageWidget(this))
|
||||
{
|
||||
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::addDeckEditorTab);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckPreviewDoubleClicked, this,
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckLoadRequested, this,
|
||||
&TabDeckStorageVisual::actOpenLocalDeck);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::openDeckEditor, this,
|
||||
&TabDeckStorageVisual::openDeckEditor);
|
||||
|
||||
auto *widget = new QWidget(this);
|
||||
auto *layout = new QVBoxLayout(widget);
|
||||
@@ -22,10 +25,11 @@ TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
||||
layout->addWidget(visualDeckStorageWidget);
|
||||
}
|
||||
|
||||
void TabDeckStorageVisual::actOpenLocalDeck(QMouseEvent * /*event*/, DeckPreviewWidget *instance)
|
||||
void TabDeckStorageVisual::actOpenLocalDeck(const QString &filePath)
|
||||
{
|
||||
DeckLoader deckLoader;
|
||||
if (!deckLoader.loadFromFile(instance->filePath, DeckLoader::CockatriceFormat, true)) {
|
||||
if (!deckLoader.loadFromFile(filePath, DeckLoader::getFormatFromName(filePath), true)) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||