diff --git a/CMakeLists.txt b/CMakeLists.txt index 414df9f8..4cf8857a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,10 +113,10 @@ ENDIF() IF(Qt5Widgets_FOUND) MESSAGE(STATUS "Found Qt ${Qt5Widgets_VERSION_STRING}") - if(UNIX AND NOT APPLE AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") - # FIX: Qt was built with -reduce-relocations - add_definitions(-fPIC) - endif() + # FIX: Qt was built with -reduce-relocations + if (Qt5_POSITION_INDEPENDENT_CODE) + SET(CMAKE_POSITION_INDEPENDENT_CODE ON) + endif() FIND_PACKAGE(Qt5LinguistTools) IF(UPDATE_TRANSLATIONS) @@ -158,6 +158,11 @@ set(CMAKE_AUTOMOC TRUE) # Find other needed libraries FIND_PACKAGE(Protobuf REQUIRED) +#Find OpenSSL +IF(WIN32) + FIND_PACKAGE(Win32SslRuntime) +ENDIF() + # Package builder set(CPACK_PACKAGE_CONTACT "Daenyth+github@gmail.com") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME}) diff --git a/README.md b/README.md index f67c6fcc..9b88f18d 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ a network interface as well. Both client and server are written in Qt, supportin Chat with the Cockatrice developers on Gitter. Come here to talk about the application, features, or just to hang out. For support regarding specific servers, please contact that server's admin or forum for support rather than asking here. -[![Gitter chat](https://badges.gitter.im/Daenyth/Cockatrice.png)](https://gitter.im/Daenyth/Cockatrice) +[![Gitter chat](https://badges.gitter.im/Cockatrice/Cockatrice.png)](https://gitter.im/Cockatrice/Cockatrice) # Building -[![Build Status](https://travis-ci.org/Daenyth/Cockatrice.svg?branch=master)](https://travis-ci.org/Daenyth/Cockatrice) +[![Build Status](https://travis-ci.org/Cockatrice/Cockatrice.svg?branch=master)](https://travis-ci.org/Cockatrice/Cockatrice) Dependencies: diff --git a/cmake/FindWin32SslRuntime.cmake b/cmake/FindWin32SslRuntime.cmake new file mode 100644 index 00000000..4b0fafa5 --- /dev/null +++ b/cmake/FindWin32SslRuntime.cmake @@ -0,0 +1,52 @@ +# Find the OpenSSL runtime libraries (.dll) for Windows that +# will be needed by Qt in order to access https urls. + +if (WIN32) + # Get standard installation paths for OpenSSL under Windows + + # http://www.slproweb.com/products/Win32OpenSSL.html + set(_OPENSSL_ROOT_HINTS + ${OPENSSL_ROOT_DIR} + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]" + ENV OPENSSL_ROOT_DIR + ) + file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles) + set(_OPENSSL_ROOT_PATHS + "${_programfiles}/OpenSSL" + "${_programfiles}/OpenSSL-Win32" + "${_programfiles}/OpenSSL-Win64" + "C:/OpenSSL/" + "C:/OpenSSL-Win32/" + "C:/OpenSSL-Win64/" + ) + unset(_programfiles) +else () + set(_OPENSSL_ROOT_HINTS + ${OPENSSL_ROOT_DIR} + ENV OPENSSL_ROOT_DIR + ) +endif () + +set(_OPENSSL_ROOT_HINTS_AND_PATHS + HINTS ${_OPENSSL_ROOT_HINTS} + PATHS ${_OPENSSL_ROOT_PATHS} + ) + +FIND_FILE(WIN32SSLRUNTIME_LIBEAY NAMES libeay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS}) +FIND_FILE(WIN32SSLRUNTIME_SSLEAY NAMES ssleay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS}) + + +IF(WIN32SSLRUNTIME_LIBEAY AND WIN32SSLRUNTIME_SSLEAY) + SET(WIN32SSLRUNTIME_LIBRARIES "${WIN32SSLRUNTIME_LIBEAY}" "${WIN32SSLRUNTIME_SSLEAY}") + SET(WIN32SSLRUNTIME_FOUND "YES") + message(STATUS "Found OpenSSL ${WIN32SSLRUNTIME_LIBRARIES}") +ELSE() + SET(WIN32SSLRUNTIME_FOUND "NO") + message(WARNING "Could not find OpenSSL runtime libraries. They are not required for compiling, but needs to be available at runtime.") +ENDIF() + +MARK_AS_ADVANCED( + WIN32SSLRUNTIME_LIBEAY + WIN32SSLRUNTIME_SSLEAY + ) diff --git a/cmake/NSIS.template.in b/cmake/NSIS.template.in index 093d6caa..2e1910f5 100644 --- a/cmake/NSIS.template.in +++ b/cmake/NSIS.template.in @@ -63,6 +63,7 @@ Section "Start menu item" SecStartMenu createDirectory "$SMPROGRAMS\Cockatrice" createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" '--debug-output' createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe" + createShortCut "$SMPROGRAMS\Cockatrice\Servatrice.lnk" "$INSTDIR\servatrice.exe" createShortCut "$SMPROGRAMS\Cockatrice\Usermanual.lnk" "$INSTDIR\Usermanual.pdf" SectionEnd @@ -80,6 +81,8 @@ Section Uninstall Delete "$INSTDIR\libprotobuf.lib" Delete "$INSTDIR\Qt*.dll" Delete "$INSTDIR\icu*.dll" + Delete "$INSTDIR\libeay32.dll" + Delete "$INSTDIR\ssleay32.dll" Delete "$INSTDIR\qt.conf" Delete "$INSTDIR\qdebug.txt" Delete "$INSTDIR\servatrice.sql" diff --git a/cmake/headerimage.bmp b/cmake/headerimage.bmp index 73c88d6d..625680c3 100644 Binary files a/cmake/headerimage.bmp and b/cmake/headerimage.bmp differ diff --git a/cmake/leftimage.bmp b/cmake/leftimage.bmp index e89fdd95..aea76267 100644 Binary files a/cmake/leftimage.bmp and b/cmake/leftimage.bmp differ diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 454f1a1f..b127e414 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -242,6 +242,13 @@ endif() if(UNIX) if(APPLE) + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) + set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) + set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) + INSTALL(TARGETS cockatrice BUNDLE DESTINATION ./) INSTALL(FILES ${cockatrice_QM} DESTINATION ./cockatrice.app/Contents/Resources/translations) else() @@ -263,15 +270,16 @@ if(APPLE) set(qtconf_dest_dir cockatrice.app/Contents/Resources) # note: no codecs in qt5 - # note: phonon_backend => mediaservice + # note: phonon_backend => audio | mediaservice # note: needs platform on osx if (CMAKE_BUILD_TYPE STREQUAL "Debug") install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime - FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*_debug\\.dylib") + FILES_MATCHING REGEX "(audio|codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*_debug\\.dylib") else() install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime - FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/[^_]*\\.dylib") + FILES_MATCHING REGEX "(audio|codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*\\.dylib" + REGEX ".*_debug\\.dylib" EXCLUDE) endif() install(CODE " @@ -296,15 +304,15 @@ if(WIN32) set(qtconf_dest_dir .) # note: no codecs in qt5 - # note: phonon_backend => mediaservice + # note: phonon_backend => audio | mediaservice # note: needs platform on osx if (CMAKE_BUILD_TYPE STREQUAL "Debug") install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime - FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*d\\.dll") + FILES_MATCHING REGEX "(audio|codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*d\\.dll") else() install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime - FILES_MATCHING REGEX "(codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*[^d]\\.dll") + FILES_MATCHING REGEX "(audio|codecs|iconengines|imageformats|mediaservice|phonon_backend|platforms)/.*[^d]\\.dll") endif() install(CODE " @@ -321,4 +329,8 @@ Data = Resources\") include(BundleUtilities) fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\") " COMPONENT Runtime) + + if(WIN32SSLRUNTIME_FOUND) + install(FILES ${WIN32SSLRUNTIME_LIBRARIES} DESTINATION ./) + endif() endif() \ No newline at end of file diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc index 451f9c1b..34aacb68 100644 --- a/cockatrice/cockatrice.qrc +++ b/cockatrice/cockatrice.qrc @@ -1,131 +1,130 @@ - - resources/back.svg - resources/lock.svg - resources/icon_delete.svg - resources/icon_tab_changed.svg - resources/icon_config_general.svg - resources/icon_config_appearance.svg - resources/icon_config_interface.svg - resources/icon_config_messages.svg - resources/icon_config_deckeditor.svg - resources/phases/icon_phase_untap.svg - resources/phases/icon_phase_upkeep.svg - resources/phases/icon_phase_draw.svg - resources/phases/icon_phase_main1.svg - resources/phases/icon_phase_combat_start.svg - resources/phases/icon_phase_combat_attackers.svg - resources/phases/icon_phase_combat_blockers.svg - resources/phases/icon_phase_combat_damage.svg - resources/phases/icon_phase_combat_end.svg - resources/phases/icon_phase_main2.svg - resources/phases/icon_phase_cleanup.svg - resources/phases/icon_phase_nextturn.svg - resources/icon_settings.svg - resources/hand.svg - resources/pencil.svg - resources/icon_search.svg - resources/icon_clearsearch.svg - resources/icon_update.png - resources/icon_view.svg - resources/hr.jpg - resources/cockatrice.svg - resources/add_to_sideboard.svg - resources/decrement.svg - resources/increment.svg - resources/remove_row.svg - resources/arrow_left_green.svg - resources/arrow_right_green.svg - resources/icon_ready_start.svg - resources/icon_not_ready_start.svg - resources/icon_conceded.svg - resources/icon_player.svg - resources/icon_spectator.svg - - resources/replay_start.svg - resources/replay_stop.svg - resources/replay_fastforward.svg - resources/replay_rewind.svg - resources/replay_toend.svg - resources/replay_tostart.svg - resources/replay_pause.svg + + resources/back.svg + resources/lock.svg + resources/icon_delete.svg + resources/icon_tab_changed.svg + resources/icon_config_general.svg + resources/icon_config_appearance.svg + resources/icon_config_interface.svg + resources/icon_config_messages.svg + resources/icon_config_deckeditor.svg + resources/phases/icon_phase_untap.svg + resources/phases/icon_phase_upkeep.svg + resources/phases/icon_phase_draw.svg + resources/phases/icon_phase_main1.svg + resources/phases/icon_phase_combat_start.svg + resources/phases/icon_phase_combat_attackers.svg + resources/phases/icon_phase_combat_blockers.svg + resources/phases/icon_phase_combat_damage.svg + resources/phases/icon_phase_combat_end.svg + resources/phases/icon_phase_main2.svg + resources/phases/icon_phase_cleanup.svg + resources/phases/icon_phase_nextturn.svg + resources/icon_settings.svg + resources/hand.svg + resources/pencil.svg + resources/icon_search.svg + resources/icon_search_black.svg + resources/icon_clearsearch.svg + resources/icon_update.png + resources/icon_view.svg + resources/hr.jpg + resources/cockatrice.svg + resources/add_to_sideboard.svg + resources/decrement.svg + resources/increment.svg + resources/remove_row.svg + resources/arrow_left_green.svg + resources/arrow_right_green.svg + resources/icon_ready_start.svg + resources/icon_not_ready_start.svg + resources/icon_conceded.svg + resources/icon_player.svg + resources/icon_spectator.svg - resources/genders/male.svg - resources/genders/female.svg - resources/genders/unknown.svg + resources/replay_start.svg + resources/replay_stop.svg + resources/replay_fastforward.svg + resources/replay_rewind.svg + resources/replay_toend.svg + resources/replay_tostart.svg + resources/replay_pause.svg - resources/countries/ar.svg - resources/countries/at.svg - resources/countries/au.svg - resources/countries/be.svg - resources/countries/br.svg - resources/countries/by.svg - resources/countries/ca.svg - resources/countries/cl.svg - resources/countries/cz.svg - resources/countries/ch.svg - resources/countries/cn.svg - resources/countries/de.svg - resources/countries/dk.svg - resources/countries/do.svg - resources/countries/es.svg - resources/countries/fi.svg - resources/countries/fr.svg - resources/countries/ge.svg - resources/countries/gr.svg - resources/countries/gt.svg - resources/countries/hr.svg - resources/countries/hu.svg - resources/countries/ie.svg - resources/countries/il.svg - resources/countries/it.svg - resources/countries/jp.svg - resources/countries/lt.svg - resources/countries/lu.svg - resources/countries/lv.svg - resources/countries/mx.svg - resources/countries/my.svg - resources/countries/nl.svg - resources/countries/no.svg - resources/countries/nz.svg - resources/countries/pe.svg - resources/countries/ph.svg - resources/countries/pl.svg - resources/countries/pt.svg - resources/countries/ro.svg - resources/countries/ru.svg - resources/countries/se.svg - resources/countries/sg.svg - resources/countries/si.svg - resources/countries/sk.svg - resources/countries/tr.svg - resources/countries/ua.svg - resources/countries/uk.svg - resources/countries/us.svg - resources/countries/ve.svg - resources/countries/za.svg + resources/genders/male.svg + resources/genders/female.svg + resources/genders/unknown.svg - resources/counters/w.svg - resources/counters/w_highlight.svg - resources/counters/u.svg - resources/counters/u_highlight.svg - resources/counters/b.svg - resources/counters/b_highlight.svg - resources/counters/r.svg - resources/counters/r_highlight.svg - resources/counters/g.svg - resources/counters/g_highlight.svg - resources/counters/general.svg - resources/counters/general_highlight.svg + resources/countries/ar.svg + resources/countries/at.svg + resources/countries/au.svg + resources/countries/be.svg + resources/countries/br.svg + resources/countries/by.svg + resources/countries/ca.svg + resources/countries/cl.svg + resources/countries/cz.svg + resources/countries/ch.svg + resources/countries/cn.svg + resources/countries/de.svg + resources/countries/dk.svg + resources/countries/do.svg + resources/countries/es.svg + resources/countries/fi.svg + resources/countries/fr.svg + resources/countries/ge.svg + resources/countries/gr.svg + resources/countries/gt.svg + resources/countries/hr.svg + resources/countries/hu.svg + resources/countries/ie.svg + resources/countries/il.svg + resources/countries/it.svg + resources/countries/jp.svg + resources/countries/lt.svg + resources/countries/lu.svg + resources/countries/lv.svg + resources/countries/mx.svg + resources/countries/my.svg + resources/countries/nl.svg + resources/countries/no.svg + resources/countries/nz.svg + resources/countries/pe.svg + resources/countries/ph.svg + resources/countries/pl.svg + resources/countries/pt.svg + resources/countries/ro.svg + resources/countries/ru.svg + resources/countries/se.svg + resources/countries/sg.svg + resources/countries/si.svg + resources/countries/sk.svg + resources/countries/tr.svg + resources/countries/ua.svg + resources/countries/uk.svg + resources/countries/us.svg + resources/countries/ve.svg + resources/countries/za.svg - resources/userlevels/normal.svg - resources/userlevels/registered.svg - resources/userlevels/moderator.svg - resources/userlevels/admin.svg + resources/counters/w.svg + resources/counters/w_highlight.svg + resources/counters/u.svg + resources/counters/u_highlight.svg + resources/counters/b.svg + resources/counters/b_highlight.svg + resources/counters/r.svg + resources/counters/r_highlight.svg + resources/counters/g.svg + resources/counters/g_highlight.svg + resources/counters/general.svg + resources/counters/general_highlight.svg - resources/news/exclamation_mark.svg - resources/news/question_mark.svg + resources/userlevels/normal.svg + resources/userlevels/registered.svg + resources/userlevels/moderator.svg + resources/userlevels/admin.svg - resources/mtgforum.png - + resources/news/exclamation_mark.svg + resources/news/question_mark.svg + diff --git a/cockatrice/resources/appicon.icns b/cockatrice/resources/appicon.icns index 4bd00ffc..f521035e 100644 Binary files a/cockatrice/resources/appicon.icns and b/cockatrice/resources/appicon.icns differ diff --git a/cockatrice/resources/appicon.ico b/cockatrice/resources/appicon.ico index 9a4885f4..4cf839bc 100644 Binary files a/cockatrice/resources/appicon.ico and b/cockatrice/resources/appicon.ico differ diff --git a/cockatrice/resources/back.svg b/cockatrice/resources/back.svg index 0377ecb2..3dd1c69c 100644 --- a/cockatrice/resources/back.svg +++ b/cockatrice/resources/back.svg @@ -1,5 +1,6 @@ + + version="1.0" + inkscape:export-filename="C:\Users\Matt\Documents\GitHub\Cockatrice\cockatrice\resources\back_new.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + + + + + + + + + xlink:href="#linearGradient3009" + id="linearGradient3015" + x1="10.096291" + y1="329.42294" + x2="229.81081" + y2="12.591727" + gradientUnits="userSpaceOnUse" /> - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape:window-width="1920" + inkscape:window-height="1028" + inkscape:window-x="-8" + inkscape:window-y="-8" + inkscape:window-maximized="1" /> @@ -149,40 +658,377 @@ image/svg+xml + + id="layer1" + style="display:inline" + sodipodi:insensitive="true"> + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-opacity:0" + id="rect3004" + width="240" + height="340" + x="0" + y="0.57232106" + rx="10" + ry="10" /> + style="fill:url(#linearGradient3015);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00535154;stroke-opacity:0;display:inline" + id="rect3007" + width="220.67607" + height="318.77353" + x="10.096291" + y="11.610939" /> + + + + + + + style="fill:#ff5555;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-opacity:0;display:inline" + id="path5297-7" + sodipodi:cx="-96.635925" + sodipodi:cy="76.534889" + sodipodi:rx="2.8846545" + sodipodi:ry="2.8846545" + d="m -93.751271,76.534889 a 2.8846545,2.8846545 0 1 1 -5.769309,0 2.8846545,2.8846545 0 1 1 5.769309,0 z" + transform="translate(118.51147,240.79097)" /> + sodipodi:type="arc" + style="fill:url(#linearGradient5324-8);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-opacity:0;display:inline" + id="path5299-6-1" + sodipodi:cx="-24.925219" + sodipodi:cy="38.493507" + sodipodi:rx="1.4573514" + sodipodi:ry="1.1418424" + d="m -23.467867,38.493507 a 1.4573514,1.1418424 0 1 1 -2.914703,0 1.4573514,1.1418424 0 1 1 2.914703,0 z" + transform="matrix(-1.3207348,0.77962891,-1.166227,-1.9837166,33.337282,413.41782)" /> + + + + + + + + + + + + + + diff --git a/cockatrice/resources/cockatrice.png b/cockatrice/resources/cockatrice.png index ed79b88a..200d2480 100644 Binary files a/cockatrice/resources/cockatrice.png and b/cockatrice/resources/cockatrice.png differ diff --git a/cockatrice/resources/cockatrice.svg b/cockatrice/resources/cockatrice.svg index 991a53c6..1cd1f217 100644 --- a/cockatrice/resources/cockatrice.svg +++ b/cockatrice/resources/cockatrice.svg @@ -1,5 +1,6 @@ + + inkscape:version="0.48.5 r10040" + sodipodi:docname="cockatrice.svg"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2621" /> + + + + + + + + id="linearGradient3779"> + style="stop-color:#99ff00;stop-opacity:1;" /> + style="stop-color:#0f620f;stop-opacity:1;" /> + id="stop3815" /> + style="stop-color:#007400;stop-opacity:0.40000001;" /> + id="stop4579" /> + id="stop3817" /> + id="linearGradient3841"> + style="stop-color:white;stop-opacity:1;" /> + style="stop-color:#fefce9;stop-opacity:0;" /> + + + + + - + id="linearGradient3999-4"> + + + + id="linearGradient4009-4"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2621-2" /> + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2571-9" /> + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2519-8" /> + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2467-1" /> + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2650-6" /> + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2578-7" /> + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2511-5" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -180,95 +635,142 @@ image/svg+xml + - - - - - - - + id="g3026"> + transform="matrix(0.99103064,0,0,0.98943856,1.2668213,1.9022887)" + id="layer4" + style="display:inline" + clip-path="none"> + + + - - - + id="g3342" + transform="matrix(1.0090505,0,0,1.0106742,411.46737,-30.548174)" + style="fill:#ffffff;fill-opacity:1"> + + + + + + + + + - + id="layer1" + style="display:none"> + d="m 300,149.64285 a 149.64285,149.64285 0 1 1 -299.28570557,0 149.64285,149.64285 0 1 1 299.28570557,0 z" + transform="matrix(1.0015936,0,0,1.0000039,-0.00173336,0.71369073)" + id="path3221" + style="fill:url(#linearGradient4005);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0;filter:url(#filter4089)" /> + + + diff --git a/cockatrice/resources/hand.svg b/cockatrice/resources/hand.svg index 8c28fd59..11113d0f 100644 --- a/cockatrice/resources/hand.svg +++ b/cockatrice/resources/hand.svg @@ -14,10 +14,13 @@ height="500" id="svg2" sodipodi:version="0.32" - inkscape:version="0.47pre4 r22446" - sodipodi:docname="back.svg" + inkscape:version="0.48.5 r10040" + sodipodi:docname="hand.svg" inkscape:output_extension="org.inkscape.output.svg.inkscape" - version="1.0"> + version="1.0" + inkscape:export-filename="C:\Users\Matt\Documents\GitHub\Cockatrice\cockatrice\resources\hand_new.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> - - - - - - - - - + id="linearGradient4766-8-0-3-31"> + + + + x1="-20.65873" + y1="37.909077" + x2="-25.41811" + y2="38.523342" /> + + + + + x1="-20.65873" + y1="37.909077" + x2="-25.41811" + y2="38.523342" /> + + + + + x1="-20.65873" + y1="37.909077" + x2="-25.41811" + y2="38.523342" /> + + + + + x1="-20.65873" + y1="37.909077" + x2="-25.41811" + y2="38.523342" /> + + + + + + + + + x1="-20.65873" + y1="37.909077" + x2="-25.41811" + y2="38.523342" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -377,7 +3435,7 @@ image/svg+xml - + @@ -387,100 +3445,774 @@ id="layer1" transform="translate(0,160)"> + id="g4178-7" + transform="matrix(0.89531447,-0.44543462,0.44543462,0.89531447,-0.7217683,-5.4209005)"> - - - - - + style="display:inline" + id="layer1-1-4" + inkscape:label="boarder"> + + - - - - - + style="display:inline" + inkscape:label="inlay" + id="layer3-0"> + + - - - - - + inkscape:label="dots" + id="layer4-0"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cockatrice/resources/icon_search_black.svg b/cockatrice/resources/icon_search_black.svg new file mode 100644 index 00000000..05439a12 --- /dev/null +++ b/cockatrice/resources/icon_search_black.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + \ No newline at end of file diff --git a/cockatrice/resources/mtgforum.png b/cockatrice/resources/mtgforum.png deleted file mode 100644 index a91bb854..00000000 Binary files a/cockatrice/resources/mtgforum.png and /dev/null differ diff --git a/cockatrice/resources/phases_old/icon_phase_cleanup.svg b/cockatrice/resources/phases_old/icon_phase_cleanup.svg deleted file mode 100644 index a675d66f..00000000 --- a/cockatrice/resources/phases_old/icon_phase_cleanup.svg +++ /dev/null @@ -1,749 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg b/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg deleted file mode 100644 index 540107ac..00000000 --- a/cockatrice/resources/phases_old/icon_phase_combat_attackers.svg +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg b/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg deleted file mode 100644 index 6344ef6b..00000000 --- a/cockatrice/resources/phases_old/icon_phase_combat_blockers.svg +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_combat_damage.svg b/cockatrice/resources/phases_old/icon_phase_combat_damage.svg deleted file mode 100644 index 8536764e..00000000 --- a/cockatrice/resources/phases_old/icon_phase_combat_damage.svg +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_combat_end.svg b/cockatrice/resources/phases_old/icon_phase_combat_end.svg deleted file mode 100644 index 9e7b8950..00000000 --- a/cockatrice/resources/phases_old/icon_phase_combat_end.svg +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_combat_start.svg b/cockatrice/resources/phases_old/icon_phase_combat_start.svg deleted file mode 100644 index 996571d7..00000000 --- a/cockatrice/resources/phases_old/icon_phase_combat_start.svg +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_draw.svg b/cockatrice/resources/phases_old/icon_phase_draw.svg deleted file mode 100644 index 51918274..00000000 --- a/cockatrice/resources/phases_old/icon_phase_draw.svg +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_main1.svg b/cockatrice/resources/phases_old/icon_phase_main1.svg deleted file mode 100644 index 264cef39..00000000 --- a/cockatrice/resources/phases_old/icon_phase_main1.svg +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_main2.svg b/cockatrice/resources/phases_old/icon_phase_main2.svg deleted file mode 100644 index 50f77fa7..00000000 --- a/cockatrice/resources/phases_old/icon_phase_main2.svg +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_nextturn.svg b/cockatrice/resources/phases_old/icon_phase_nextturn.svg deleted file mode 100644 index 3cfd19ab..00000000 --- a/cockatrice/resources/phases_old/icon_phase_nextturn.svg +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_untap.svg b/cockatrice/resources/phases_old/icon_phase_untap.svg deleted file mode 100644 index 2f4d8173..00000000 --- a/cockatrice/resources/phases_old/icon_phase_untap.svg +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/cockatrice/resources/phases_old/icon_phase_upkeep.svg b/cockatrice/resources/phases_old/icon_phase_upkeep.svg deleted file mode 100644 index 5a06aae9..00000000 --- a/cockatrice/resources/phases_old/icon_phase_upkeep.svg +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/cockatrice/src/abstractcarddragitem.cpp b/cockatrice/src/abstractcarddragitem.cpp index 14724db3..acc73532 100644 --- a/cockatrice/src/abstractcarddragitem.cpp +++ b/cockatrice/src/abstractcarddragitem.cpp @@ -4,6 +4,9 @@ #include #include +static const float CARD_WIDTH_HALF = CARD_WIDTH / 2; +static const float CARD_HEIGHT_HALF = CARD_HEIGHT / 2; + AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag) : QGraphicsItem(), item(_item), hotSpot(_hotSpot) { @@ -22,7 +25,7 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item, const QPoint setZValue(2000000007); } if (item->getTapped()) - setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(90).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); + setTransform(QTransform().translate(CARD_WIDTH_HALF, CARD_HEIGHT_HALF).rotate(90).translate(-CARD_WIDTH_HALF, -CARD_HEIGHT_HALF)); setCacheMode(DeviceCoordinateCache); } diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index cdacf008..f34a0725 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -101,6 +101,14 @@ QString PictureToLoad::getSetName() const return QString(""); } +CardSet *PictureToLoad::getCurrentSet() const +{ + if (setIndex < sortedSets.size()) + return sortedSets[setIndex]; + else + return 0; +} + PictureLoader::PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent) : QObject(parent), _picsPath(__picsPath), picDownload(_picDownload), picDownloadHq(_picDownloadHq), @@ -134,15 +142,17 @@ void PictureLoader::processLoadQueue() PictureToLoad ptl = loadQueue.takeFirst(); mutex.unlock(); + QString setName = ptl.getSetName(); + QString correctedCardname = ptl.getCard()->getCorrectedName(); + qDebug() << "Trying to load picture (set: " << setName << " card: " << correctedCardname << ")"; + //The list of paths to the folders in which to search for images - QList picsPaths = QList() << _picsPath + "/CUSTOM/" + ptl.getCard()->getCorrectedName(); + QList picsPaths = QList() << _picsPath + "/CUSTOM/" + correctedCardname; - - QString setName=ptl.getSetName(); if(!setName.isEmpty()) { - picsPaths << _picsPath + "/" + setName + "/" + ptl.getCard()->getCorrectedName() - << _picsPath + "/downloadedPics/" + setName + "/" + ptl.getCard()->getCorrectedName(); + picsPaths << _picsPath + "/" + setName + "/" + correctedCardname + << _picsPath + "/downloadedPics/" + setName + "/" + correctedCardname; } QImage image; @@ -154,12 +164,14 @@ void PictureLoader::processLoadQueue() for (int i = 0; i < picsPaths.length() && !found; i ++) { imgReader.setFileName(picsPaths.at(i)); if (imgReader.read(&image)) { + qDebug() << "Picture found on disk (set: " << setName << " card: " << correctedCardname << ")"; emit imageLoaded(ptl.getCard(), image); found = true; break; } imgReader.setFileName(picsPaths.at(i) + ".full"); if (imgReader.read(&image)) { + qDebug() << "Picture.full found on disk (set: " << setName << " card: " << correctedCardname << ")"; emit imageLoaded(ptl.getCard(), image); found = true; } @@ -167,24 +179,32 @@ void PictureLoader::processLoadQueue() if (!found) { if (picDownload) { + qDebug() << "Picture NOT found, trying to download (set: " << setName << " card: " << correctedCardname << ")"; cardsToDownload.append(ptl); if (!downloadRunning) startNextPicDownload(); } else { if (ptl.nextSet()) + { + qDebug() << "Picture NOT found and download disabled, moving to next set (newset: " << setName << " card: " << correctedCardname << ")"; + mutex.lock(); loadQueue.prepend(ptl); - else + mutex.unlock(); + } else { + qDebug() << "Picture NOT found, download disabled, no more sets to try: BAILING OUT (oldset: " << setName << " card: " << correctedCardname << ")"; emit imageLoaded(ptl.getCard(), QImage()); + } } } } } -QString PictureLoader::getPicUrl(CardInfo *card) +QString PictureLoader::getPicUrl() { if (!picDownload) return QString(""); - CardSet *set = card->getPreferredSet(); + CardInfo *card = cardBeingDownloaded.getCard(); + CardSet *set=cardBeingDownloaded.getCurrentSet(); QString picUrl = QString(""); // if sets have been defined for the card, they can contain custom picUrls @@ -204,17 +224,19 @@ QString PictureLoader::getPicUrl(CardInfo *card) return picUrl; } - // otherwise, fallback to the default url - picUrl = picDownloadHq ? settingsCache->getPicUrlHq() : settingsCache->getPicUrl(); - picUrl.replace("!name!", QUrl::toPercentEncoding(card->getCorrectedName())); + // if a card has a muid, use the default url; if not, use the fallback + int muid = set ? muid = card->getMuId(set->getShortName()) : 0; + if(muid) + picUrl = picDownloadHq ? settingsCache->getPicUrlHq() : settingsCache->getPicUrl(); + else + picUrl = picDownloadHq ? settingsCache->getPicUrlHqFallback() : settingsCache->getPicUrlFallback(); + picUrl.replace("!name!", QUrl::toPercentEncoding(card->getCorrectedName())); + picUrl.replace("!cardid!", QUrl::toPercentEncoding(QString::number(muid))); if (set) { picUrl.replace("!setcode!", QUrl::toPercentEncoding(set->getShortName())); picUrl.replace("!setname!", QUrl::toPercentEncoding(set->getLongName())); } - int muid = card->getPreferredMuId(); - if (muid) - picUrl.replace("!cardid!", QUrl::toPercentEncoding(QString::number(muid))); if (picUrl.contains("!name!") || picUrl.contains("!setcode!") || @@ -239,19 +261,33 @@ void PictureLoader::startNextPicDownload() cardBeingDownloaded = cardsToDownload.takeFirst(); - QString picUrl = getPicUrl(cardBeingDownloaded.getCard()); + QString picUrl = getPicUrl(); if (picUrl.isEmpty()) { - qDebug() << "No url for" << cardBeingDownloaded.getCard()->getName(); - cardBeingDownloaded = 0; downloadRunning = false; - return; + picDownloadFailed(); + } else { + QUrl url(picUrl); + + QNetworkRequest req(url); + qDebug() << "starting picture download:" << cardBeingDownloaded.getCard()->getName() << "Url:" << req.url(); + networkManager->get(req); } +} - QUrl url(picUrl); - - QNetworkRequest req(url); - qDebug() << "starting picture download:" << cardBeingDownloaded.getCard()->getName() << "Url:" << req.url(); - networkManager->get(req); +void PictureLoader::picDownloadFailed() +{ + if (cardBeingDownloaded.nextSet()) + { + qDebug() << "Picture NOT found, download failed, moving to next set (newset: " << cardBeingDownloaded.getSetName() << " card: " << cardBeingDownloaded.getCard()->getCorrectedName() << ")"; + mutex.lock(); + loadQueue.prepend(cardBeingDownloaded); + mutex.unlock(); + emit startLoadQueue(); + } else { + qDebug() << "Picture NOT found, download failed, no more sets to try: BAILING OUT (oldset: " << cardBeingDownloaded.getSetName() << " card: " << cardBeingDownloaded.getCard()->getCorrectedName() << ")"; + cardBeingDownloaded = 0; + emit imageLoaded(cardBeingDownloaded.getCard(), QImage()); + } } void PictureLoader::picDownloadFinished(QNetworkReply *reply) @@ -288,21 +324,9 @@ void PictureLoader::picDownloadFinished(QNetworkReply *reply) } emit imageLoaded(cardBeingDownloaded.getCard(), testImage); - } else if (cardBeingDownloaded.getHq()) { - qDebug() << "HQ: received invalid picture. URL:" << reply->request().url(); - cardBeingDownloaded.setHq(false); - cardsToDownload.prepend(cardBeingDownloaded); } else { - qDebug() << "LQ: received invalid picture. URL:" << reply->request().url(); - if (cardBeingDownloaded.nextSet()) { - cardBeingDownloaded.setHq(true); - mutex.lock(); - loadQueue.prepend(cardBeingDownloaded); - mutex.unlock(); - emit startLoadQueue(); - } else - emit imageLoaded(cardBeingDownloaded.getCard(), QImage()); - } + picDownloadFailed(); + } reply->deleteLater(); startNextPicDownload(); @@ -497,21 +521,6 @@ void CardInfo::updatePixmapCache() emit pixmapUpdated(); } -CardSet* CardInfo::getPreferredSet() -{ - if(sets.isEmpty()) - return 0; - SetList sortedSets = sets; - sortedSets.sortByKey(); - return sortedSets.first(); -} - -int CardInfo::getPreferredMuId() -{ - CardSet *set = getPreferredSet(); - return set ? muIds[set->getShortName()] : 0; -} - QString CardInfo::simplifyName(const QString &name) { QString simpleName(name); diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index cbb25f3e..af5a16f1 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -53,6 +53,7 @@ private: public: PictureToLoad(CardInfo *_card = 0, bool _hq = true); CardInfo *getCard() const { return card; } + CardSet *getCurrentSet() const; QString getSetName() const; bool nextSet(); bool getHq() const { return hq; } @@ -70,7 +71,7 @@ private: PictureToLoad cardBeingDownloaded; bool picDownload, picDownloadHq, downloadRunning, loadQueueRunning; void startNextPicDownload(); - QString getPicUrl(CardInfo* card); + QString getPicUrl(); public: PictureLoader(const QString &__picsPath, bool _picDownload, bool _picDownloadHq, QObject *parent = 0); ~PictureLoader(); @@ -80,6 +81,7 @@ public: void loadImage(CardInfo *card); private slots: void picDownloadFinished(QNetworkReply *reply); + void picDownloadFailed(); public slots: void processLoadQueue(); signals: @@ -163,8 +165,6 @@ public: void clearPixmapCache(); void clearPixmapCacheMiss(); void imageLoaded(const QImage &image); - CardSet *getPreferredSet(); - int getPreferredMuId(); /** * Simplify a name to have no punctuation and lowercase all letters, for diff --git a/cockatrice/src/carditem.cpp b/cockatrice/src/carditem.cpp index e7ce6482..be449fb9 100644 --- a/cockatrice/src/carditem.cpp +++ b/cockatrice/src/carditem.cpp @@ -17,6 +17,7 @@ #include "tab_game.h" #include "pb/serverinfo_card.pb.h" + CardItem::CardItem(Player *_owner, const QString &_name, int _cardid, bool _revealedCard, QGraphicsItem *parent) : AbstractCardItem(_name, _owner, _cardid, parent), zone(0), revealedCard(_revealedCard), attacking(false), destroyOnZoneChange(false), doesntUntap(false), dragItem(0), attachedTo(0) { @@ -360,15 +361,16 @@ void CardItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) event->accept(); } + bool CardItem::animationEvent() { - int delta = 18; + int rotation = ROTATION_DEGREES_PER_FRAME; if (!tapped) - delta *= -1; - - tapAngle += delta; - - setTransform(QTransform().translate((float) CARD_WIDTH / 2, (float) CARD_HEIGHT / 2).rotate(tapAngle).translate((float) -CARD_WIDTH / 2, (float) -CARD_HEIGHT / 2)); + rotation *= -1; + + tapAngle += rotation; + + setTransform(QTransform().translate(CARD_WIDTH_HALF, CARD_HEIGHT_HALF).rotate(tapAngle).translate(-CARD_WIDTH_HALF, -CARD_HEIGHT_HALF)); setHovered(false); update(); diff --git a/cockatrice/src/carditem.h b/cockatrice/src/carditem.h index 9952550d..524c1695 100644 --- a/cockatrice/src/carditem.h +++ b/cockatrice/src/carditem.h @@ -12,6 +12,9 @@ class QAction; class QColor; const int MAX_COUNTERS_ON_CARD = 999; +const float CARD_WIDTH_HALF = CARD_WIDTH / 2; +const float CARD_HEIGHT_HALF = CARD_HEIGHT / 2; +const int ROTATION_DEGREES_PER_FRAME = 10; class CardItem : public AbstractCardItem { Q_OBJECT diff --git a/cockatrice/src/deckview.cpp b/cockatrice/src/deckview.cpp index 5a14ec3f..101a2a11 100644 --- a/cockatrice/src/deckview.cpp +++ b/cockatrice/src/deckview.cpp @@ -146,8 +146,15 @@ void DeckViewCardContainer::paint(QPainter *painter, const QStyleOptionGraphicsI { qreal totalTextWidth = getCardTypeTextWidth(); - if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), QColor(0, 0, 100)); + if (bgPixmap.isNull()) { + QLinearGradient grad1(0, 0, 1, 0); + grad1.setCoordinateMode(QGradient::ObjectBoundingMode); + grad1.setColorAt(0, QColor(48, 34, 69)); + grad1.setColorAt(1, QColor(110, 90, 140)); + painter->fillRect(QRectF(0, 0, width, height), QBrush(grad1)); + + painter->fillRect(boundingRect(), QColor(0, 0, 0, 80)); + } else painter->fillRect(boundingRect(), QBrush(bgPixmap)); painter->setPen(QColor(255, 255, 255, 100)); diff --git a/cockatrice/src/dlg_creategame.cpp b/cockatrice/src/dlg_creategame.cpp index fc62df7d..65b340bb 100644 --- a/cockatrice/src/dlg_creategame.cpp +++ b/cockatrice/src/dlg_creategame.cpp @@ -56,7 +56,12 @@ void DlgCreateGame::sharedCtor() onlyBuddiesCheckBox = new QCheckBox(tr("Only &buddies can join")); onlyRegisteredCheckBox = new QCheckBox(tr("Only ®istered users can join")); if (room && room->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) + { onlyRegisteredCheckBox->setChecked(true); + } else { + onlyBuddiesCheckBox->setEnabled(false); + onlyRegisteredCheckBox->setEnabled(false); + } QGridLayout *joinRestrictionsLayout = new QGridLayout; joinRestrictionsLayout->addWidget(passwordLabel, 0, 0); diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index 414550a9..ae7e4cc2 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -25,6 +25,7 @@ #include "main.h" #include "settingscache.h" #include "priceupdater.h" +#include "soundengine.h" GeneralSettingsPage::GeneralSettingsPage() { @@ -503,6 +504,8 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage() connect(soundPathClearButton, SIGNAL(clicked()), this, SLOT(soundPathClearButtonClicked())); QPushButton *soundPathButton = new QPushButton("..."); connect(soundPathButton, SIGNAL(clicked()), this, SLOT(soundPathButtonClicked())); + soundTestButton = new QPushButton(); + connect(soundTestButton, SIGNAL(clicked()), soundEngine, SLOT(cuckoo())); QGridLayout *soundGrid = new QGridLayout; soundGrid->addWidget(soundEnabledCheckBox, 0, 0, 1, 4); @@ -510,6 +513,7 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage() soundGrid->addWidget(soundPathEdit, 1, 1); soundGrid->addWidget(soundPathClearButton, 1, 2); soundGrid->addWidget(soundPathButton, 1, 3); + soundGrid->addWidget(soundTestButton, 2, 1); soundGroupBox = new QGroupBox; soundGroupBox->setLayout(soundGrid); @@ -538,6 +542,7 @@ void UserInterfaceSettingsPage::retranslateUi() tapAnimationCheckBox->setText(tr("&Tap/untap animation")); soundEnabledCheckBox->setText(tr("Enable &sounds")); soundPathLabel->setText(tr("Path to sounds directory:")); + soundTestButton->setText(tr("Test system sound engine")); } void UserInterfaceSettingsPage::soundPathClearButtonClicked() diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h index 0303ceef..de46f1b1 100644 --- a/cockatrice/src/dlg_settings.h +++ b/cockatrice/src/dlg_settings.h @@ -92,6 +92,7 @@ private: QLabel *soundPathLabel; QLineEdit *soundPathEdit; QGroupBox *generalGroupBox, *animationGroupBox, *soundGroupBox; + QPushButton *soundTestButton; public: UserInterfaceSettingsPage(); void retranslateUi(); diff --git a/cockatrice/src/gamescene.cpp b/cockatrice/src/gamescene.cpp index 8e777168..f5f11cef 100644 --- a/cockatrice/src/gamescene.cpp +++ b/cockatrice/src/gamescene.cpp @@ -262,7 +262,7 @@ void GameScene::registerAnimationItem(AbstractCardItem *card) { cardsToAnimate.insert(static_cast(card)); if (!animationTimer->isActive()) - animationTimer->start(50, this); + animationTimer->start(15, this); } void GameScene::unregisterAnimationItem(AbstractCardItem *card) diff --git a/cockatrice/src/handzone.cpp b/cockatrice/src/handzone.cpp index cd9ba959..3a4e6f1d 100644 --- a/cockatrice/src/handzone.cpp +++ b/cockatrice/src/handzone.cpp @@ -78,7 +78,7 @@ QRectF HandZone::boundingRect() const void HandZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), Qt::darkGreen); + painter->fillRect(boundingRect(), QColor(80, 100, 50)); else painter->fillRect(boundingRect(), QBrush(bgPixmap)); } diff --git a/cockatrice/src/phasestoolbar.cpp b/cockatrice/src/phasestoolbar.cpp index 9b22f611..35265ba8 100644 --- a/cockatrice/src/phasestoolbar.cpp +++ b/cockatrice/src/phasestoolbar.cpp @@ -65,7 +65,7 @@ void PhaseButton::setActive(bool _active) return; active = _active; - activeAnimationTimer->start(50); + activeAnimationTimer->start(25); } void PhaseButton::updateAnimation() diff --git a/cockatrice/src/settingscache.cpp b/cockatrice/src/settingscache.cpp index 5821d352..8374bdb5 100644 --- a/cockatrice/src/settingscache.cpp +++ b/cockatrice/src/settingscache.cpp @@ -25,6 +25,8 @@ SettingsCache::SettingsCache() picDownloadHq = settings->value("personal/picturedownloadhq", false).toBool(); picUrl = settings->value("personal/picUrl", PIC_URL_DEFAULT).toString(); picUrlHq = settings->value("personal/picUrlHq", PIC_URL_HQ_DEFAULT).toString(); + picUrlFallback = settings->value("personal/picUrlFallback", PIC_URL_FALLBACK).toString(); + picUrlHqFallback = settings->value("personal/picUrlHqFallback", PIC_URL_HQ_FALLBACK).toString(); mainWindowGeometry = settings->value("interface/main_window_geometry").toByteArray(); notificationsEnabled = settings->value("interface/notificationsenabled", true).toBool(); @@ -153,6 +155,18 @@ void SettingsCache::setPicUrlHq(const QString &_picUrlHq) settings->setValue("personal/picUrlHq", picUrlHq); } +void SettingsCache::setPicUrlFallback(const QString &_picUrlFallback) +{ + picUrlFallback = _picUrlFallback; + settings->setValue("personal/picUrlFallback", picUrlFallback); +} + +void SettingsCache::setPicUrlHqFallback(const QString &_picUrlHqFallback) +{ + picUrlHqFallback = _picUrlHqFallback; + settings->setValue("personal/picUrlHqFallback", picUrlHqFallback); +} + void SettingsCache::setNotificationsEnabled(int _notificationsEnabled) { notificationsEnabled = _notificationsEnabled; diff --git a/cockatrice/src/settingscache.h b/cockatrice/src/settingscache.h index b222a58b..3b1908a9 100644 --- a/cockatrice/src/settingscache.h +++ b/cockatrice/src/settingscache.h @@ -4,7 +4,9 @@ #include #define PIC_URL_DEFAULT "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card" +#define PIC_URL_FALLBACK "http://mtgimage.com/set/!setcode!/!name!.jpg" #define PIC_URL_HQ_DEFAULT "http://mtgimage.com/multiverseid/!cardid!.jpg" +#define PIC_URL_HQ_FALLBACK "http://mtgimage.com/set/!setcode!/!name!.jpg" class QSettings; @@ -57,6 +59,8 @@ private: bool ignoreUnregisteredUsers; QString picUrl; QString picUrlHq; + QString picUrlFallback; + QString picUrlHqFallback; bool attemptAutoConnect; public: SettingsCache(); @@ -93,6 +97,8 @@ public: bool getIgnoreUnregisteredUsers() const { return ignoreUnregisteredUsers; } QString getPicUrl() const { return picUrl; } QString getPicUrlHq() const { return picUrlHq; } + QString getPicUrlFallback() const { return picUrlFallback; } + QString getPicUrlHqFallback() const { return picUrlHqFallback; } void copyPath(const QString &src, const QString &dst); bool getAutoConnect() const { return attemptAutoConnect; } public slots: @@ -129,6 +135,8 @@ public slots: void setIgnoreUnregisteredUsers(bool _ignoreUnregisteredUsers); void setPicUrl(const QString &_picUrl); void setPicUrlHq(const QString &_picUrlHq); + void setPicUrlFallback(const QString &_picUrlFallback); + void setPicUrlHqFallback(const QString &_picUrlHqFallback); void setAutoConnect(const bool &_autoConnect); }; diff --git a/cockatrice/src/tab_deck_editor.cpp b/cockatrice/src/tab_deck_editor.cpp index 82a356d1..687e36c8 100644 --- a/cockatrice/src/tab_deck_editor.cpp +++ b/cockatrice/src/tab_deck_editor.cpp @@ -50,10 +50,12 @@ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor, QWidget *parent) aClearSearch = new QAction(QString(), this); aClearSearch->setIcon(QIcon(":/resources/icon_clearsearch.svg")); connect(aClearSearch, SIGNAL(triggered()), this, SLOT(actClearSearch())); - - searchLabel = new QLabel(); searchEdit = new SearchLineEdit; - searchLabel->setBuddy(searchEdit); +#if QT_VERSION >= 0x050000 + searchEdit->addAction(QIcon(":/resources/icon_search_black.svg"), QLineEdit::LeadingPosition); +#endif + searchEdit->setObjectName("searchEdit"); + setFocusProxy(searchEdit); setFocusPolicy(Qt::ClickFocus); @@ -73,7 +75,6 @@ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor, QWidget *parent) QHBoxLayout *searchLayout = new QHBoxLayout; searchLayout->addWidget(deckEditToolBar); - searchLayout->addWidget(searchLabel); searchLayout->addWidget(searchEdit); databaseModel = new CardDatabaseModel(db, this); @@ -293,7 +294,6 @@ void TabDeckEditor::retranslateUi() { aCardTextOnly->setText(tr("Show card text only")); aClearSearch->setText(tr("&Clear search")); - searchLabel->setText(tr("&Search for:")); nameLabel->setText(tr("Deck &name:")); commentsLabel->setText(tr("&Comments:")); @@ -365,7 +365,7 @@ void TabDeckEditor::updateCardInfoRight(const QModelIndex ¤t, const QModel void TabDeckEditor::updateSearch(const QString &search) { - databaseDisplayModel->setCardNameBeginning(search); + databaseDisplayModel->setCardName(search); QModelIndexList sel = databaseView->selectionModel()->selectedRows(); if (sel.isEmpty() && databaseDisplayModel->rowCount()) databaseView->selectionModel()->setCurrentIndex(databaseDisplayModel->index(0, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); diff --git a/cockatrice/src/tab_deck_editor.h b/cockatrice/src/tab_deck_editor.h index dd3b56ac..8db00e73 100644 --- a/cockatrice/src/tab_deck_editor.h +++ b/cockatrice/src/tab_deck_editor.h @@ -85,7 +85,6 @@ private: QTreeView *deckView; KeySignals deckViewKeySignals; CardFrame *cardInfo; - QLabel *searchLabel; SearchLineEdit *searchEdit; KeySignals searchKeySignals; diff --git a/cockatrice/src/tablezone.cpp b/cockatrice/src/tablezone.cpp index f716cfbc..68d22c47 100644 --- a/cockatrice/src/tablezone.cpp +++ b/cockatrice/src/tablezone.cpp @@ -16,16 +16,24 @@ #include "pb/command_move_card.pb.h" #include "pb/command_set_card_attr.pb.h" + +const QColor TableZone::BACKGROUND_COLOR = QColor(70, 50, 100); +const QColor TableZone::FADE_MASK = QColor(0, 0, 0, 80); +const QColor TableZone::GRADIENT_COLOR = QColor(255, 255, 255, 150); +const QColor TableZone::GRADIENT_COLORLESS = QColor(255, 255, 255, 0); + + TableZone::TableZone(Player *_p, QGraphicsItem *parent) : SelectZone(_p, "table", true, false, true, parent), active(false) { connect(settingsCache, SIGNAL(tableBgPathChanged()), this, SLOT(updateBgPixmap())); connect(settingsCache, SIGNAL(invertVerticalCoordinateChanged()), this, SLOT(reorganizeCards())); + updateBgPixmap(); - height = 2 * boxLineWidth + 3 * (CARD_HEIGHT + 20) + 2 * paddingY; - width = minWidth + 2 * marginX + 2 * boxLineWidth; - currentMinimumWidth = minWidth; + height = 2 * BOX_LINE_WIDTH + 3 * (CARD_HEIGHT + 20) + 2 * PADDING_Y; + width = MIN_WIDTH + 2 * MARGIN_X + 2 * BOX_LINE_WIDTH; + currentMinimumWidth = MIN_WIDTH; setCacheMode(DeviceCoordinateCache); #if QT_VERSION < 0x050000 @@ -35,57 +43,86 @@ TableZone::TableZone(Player *_p, QGraphicsItem *parent) #endif } + void TableZone::updateBgPixmap() { QString bgPath = settingsCache->getTableBgPath(); if (!bgPath.isEmpty()) - bgPixmap.load(bgPath); + backgroundPixelMap.load(bgPath); update(); } + QRectF TableZone::boundingRect() const { return QRectF(0, 0, width, height); } + bool TableZone::isInverted() const { return ((player->getMirrored() && !settingsCache->getInvertVerticalCoordinate()) || (!player->getMirrored() && settingsCache->getInvertVerticalCoordinate())); } + void TableZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { - if (bgPixmap.isNull()) - painter->fillRect(boundingRect(), QColor(0, 0, 100)); + // if no custom background is provided then use the default color + if (backgroundPixelMap.isNull()) + painter->fillRect(boundingRect(), BACKGROUND_COLOR); else - painter->fillRect(boundingRect(), QBrush(bgPixmap)); + painter->fillRect(boundingRect(), QBrush(backgroundPixelMap)); + + if (active) { + paintZoneOutline(painter); + } else { + // inactive player gets a darker table zone with a semi transparent black mask + // this means if the user provides a custom background it will fade + painter->fillRect(boundingRect(), FADE_MASK); + } + + paintLandDivider(painter); +} + + +/** + Render a soft outline around the edge of the TableZone. + + @param painter QPainter object + */ +void TableZone::paintZoneOutline(QPainter *painter) { + QLinearGradient grad1(0, 0, 0, 1); + grad1.setCoordinateMode(QGradient::ObjectBoundingMode); + grad1.setColorAt(0, GRADIENT_COLOR); + grad1.setColorAt(1, GRADIENT_COLORLESS); + painter->fillRect(QRectF(0, 0, width, BOX_LINE_WIDTH), QBrush(grad1)); + + grad1.setFinalStop(1, 0); + painter->fillRect(QRectF(0, 0, BOX_LINE_WIDTH, height), QBrush(grad1)); + + grad1.setStart(0, 1); + grad1.setFinalStop(0, 0); + painter->fillRect(QRectF(0, height - BOX_LINE_WIDTH, width, BOX_LINE_WIDTH), QBrush(grad1)); + + grad1.setStart(1, 0); + painter->fillRect(QRectF(width - BOX_LINE_WIDTH, 0, BOX_LINE_WIDTH, height), QBrush(grad1)); +} + + +/** + Render a division line for land placement + + @painter QPainter object + */ +void TableZone::paintLandDivider(QPainter *painter){ painter->setPen(QColor(255, 255, 255, 40)); - qreal separatorY = 2 * (CARD_HEIGHT + 20 + paddingY) + boxLineWidth - paddingY / 2; + qreal separatorY = 2 * (CARD_HEIGHT + 20 + PADDING_Y) + BOX_LINE_WIDTH - PADDING_Y / 2; if (isInverted()) separatorY = height - separatorY; painter->drawLine(QPointF(0, separatorY), QPointF(width, separatorY)); - - if (active) { - QColor color1(255, 255, 255, 150); - QColor color2(255, 255, 255, 0); - QLinearGradient grad1(0, 0, 0, 1); - grad1.setCoordinateMode(QGradient::ObjectBoundingMode); - grad1.setColorAt(0, color1); - grad1.setColorAt(1, color2); - painter->fillRect(QRectF(0, 0, width, boxLineWidth), QBrush(grad1)); - - grad1.setFinalStop(1, 0); - painter->fillRect(QRectF(0, 0, boxLineWidth, height), QBrush(grad1)); - - grad1.setStart(0, 1); - grad1.setFinalStop(0, 0); - painter->fillRect(QRectF(0, height - boxLineWidth, width, boxLineWidth), QBrush(grad1)); - - grad1.setStart(1, 0); - painter->fillRect(QRectF(width - boxLineWidth, 0, boxLineWidth, height), QBrush(grad1)); - } } + void TableZone::addCardImpl(CardItem *card, int _x, int _y) { cards.append(card); @@ -96,11 +133,13 @@ void TableZone::addCardImpl(CardItem *card, int _x, int _y) card->update(); } + void TableZone::handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint) { handleDropEventByGrid(dragItems, startZone, mapToGrid(dropPoint)); } + void TableZone::handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint) { Command_MoveCard cmd; @@ -121,6 +160,7 @@ void TableZone::handleDropEventByGrid(const QList &dragItems, Ca startZone->getPlayer()->sendGameCommand(cmd); } + void TableZone::reorganizeCards() { QList arrowsToUpdate; @@ -193,6 +233,7 @@ void TableZone::reorganizeCards() update(); } + void TableZone::toggleTapped() { QList selectedItems = scene()->selectedItems(); @@ -217,6 +258,7 @@ void TableZone::toggleTapped() player->sendGameCommand(player->prepareGameCommand(cmdList)); } + CardItem *TableZone::takeCard(int position, int cardId, bool canResize) { CardItem *result = CardZone::takeCard(position, cardId); @@ -225,6 +267,7 @@ CardItem *TableZone::takeCard(int position, int cardId, bool canResize) return result; } + void TableZone::resizeToContents() { int xMax = 0; @@ -232,9 +275,9 @@ void TableZone::resizeToContents() if (cards[i]->pos().x() > xMax) xMax = (int) cards[i]->pos().x(); xMax += 2 * CARD_WIDTH; - if (xMax < minWidth) - xMax = minWidth; - currentMinimumWidth = xMax + 2 * marginX + 2 * boxLineWidth; + if (xMax < MIN_WIDTH) + xMax = MIN_WIDTH; + currentMinimumWidth = xMax + 2 * MARGIN_X + 2 * BOX_LINE_WIDTH; if (currentMinimumWidth != width) { prepareGeometryChange(); width = currentMinimumWidth; @@ -242,6 +285,7 @@ void TableZone::resizeToContents() } } + CardItem *TableZone::getCardFromGrid(const QPoint &gridPoint) const { for (int i = 0; i < cards.size(); i++) @@ -256,17 +300,18 @@ CardItem *TableZone::getCardFromCoords(const QPointF &point) const return getCardFromGrid(gridPoint); } + QPointF TableZone::mapFromGrid(QPoint gridPoint) const { qreal x, y; - x = marginX + (gridPoint.x() % 3) * CARD_WIDTH / 3.0; + x = MARGIN_X + (gridPoint.x() % 3) * CARD_WIDTH / 3.0; for (int i = 0; i < gridPoint.x() / 3; ++i) - x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + paddingX; + x += gridPointWidth.value(gridPoint.y() * 1000 + i, CARD_WIDTH) + PADDING_X; if (isInverted()) gridPoint.setY(2 - gridPoint.y()); - y = boxLineWidth + gridPoint.y() * (CARD_HEIGHT + paddingY + 20) + (gridPoint.x() % 3) * 10; + y = BOX_LINE_WIDTH + gridPoint.y() * (CARD_HEIGHT + PADDING_Y + 20) + (gridPoint.x() % 3) * 10; /* if (isInverted()) y = height - CARD_HEIGHT - y; @@ -274,24 +319,25 @@ QPointF TableZone::mapFromGrid(QPoint gridPoint) const return QPointF(x, y); } + QPoint TableZone::mapToGrid(const QPointF &mapPoint) const { - qreal x = mapPoint.x() - marginX; + qreal x = mapPoint.x() - MARGIN_X; qreal y = mapPoint.y(); /* if (isInverted()) y = height - y; -*/ y -= boxLineWidth; +*/ y -= BOX_LINE_WIDTH; if (x < 0) x = 0; - else if (x > width - CARD_WIDTH - marginX) - x = width - CARD_WIDTH - marginX; + else if (x > width - CARD_WIDTH - MARGIN_X) + x = width - CARD_WIDTH - MARGIN_X; if (y < 0) y = 0; else if (y > height - CARD_HEIGHT) y = height - CARD_HEIGHT; - int resultY = round(y / (CARD_HEIGHT + paddingY + 20)); + int resultY = round(y / (CARD_HEIGHT + PADDING_Y + 20)); if (isInverted()) resultY = 2 - resultY; @@ -300,7 +346,7 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const do { ++baseX; oldTempX = tempX; - tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + paddingX; + tempX += gridPointWidth.value(resultY * 1000 + baseX, CARD_WIDTH) + PADDING_X; } while (tempX < x + 1); qreal xdiff = x - oldTempX; @@ -308,6 +354,7 @@ QPoint TableZone::mapToGrid(const QPointF &mapPoint) const return QPoint(resultX, resultY); } + QPointF TableZone::closestGridPoint(const QPointF &point) { QPoint gridPoint = mapToGrid(point + QPoint(1, 1)); @@ -318,9 +365,3 @@ QPointF TableZone::closestGridPoint(const QPointF &point) gridPoint.setX(gridPoint.x() + 1); return mapFromGrid(gridPoint); } - -void TableZone::setWidth(qreal _width) -{ - prepareGeometryChange(); - width = _width; -} diff --git a/cockatrice/src/tablezone.h b/cockatrice/src/tablezone.h index 297f097f..9b362efa 100644 --- a/cockatrice/src/tablezone.h +++ b/cockatrice/src/tablezone.h @@ -1,50 +1,149 @@ #ifndef TABLEZONE_H #define TABLEZONE_H + #include "selectzone.h" #include "abstractcarditem.h" + +/* +* TableZone is the grid based rect where CardItems may be placed. +* It is the main play zone and can be customized with background images. +* +* TODO: Refactor methods to make more readable, extract some logic to +* private methods (Im looking at you TableZone::reorganizeCards()) +*/ class TableZone : public SelectZone { Q_OBJECT + signals: void sizeChanged(); -private: - static const int boxLineWidth = 10; - static const int paddingX = 35; - static const int paddingY = 10; - static const int marginX = 20; - static const int minWidth = 15 * CARD_WIDTH / 2; +private: + static const int BOX_LINE_WIDTH = 10; + static const int PADDING_X = 35; + static const int PADDING_Y = 10; + static const int MARGIN_X = 20; + static const int MIN_WIDTH = 15 * CARD_WIDTH / 2; + + /* + Default background color, inactive mask and boarder gradient + */ + static const QColor BACKGROUND_COLOR; + static const QColor FADE_MASK; + static const QColor GRADIENT_COLOR; + static const QColor GRADIENT_COLORLESS; + + /* + Size and shape variables + */ QMap gridPointWidth; - int width, height; + int width; + int height; int currentMinimumWidth; - QPixmap bgPixmap; + + /* + Holds any custom background image for the TableZone + */ + QPixmap backgroundPixelMap; + + /* + If this TableZone is currently active + */ bool active; + bool isInverted() const; -private slots: + +private slots: + /** + Loads in any found custom background and updates + */ void updateBgPixmap(); + public slots: + /** + Reorganizes CardItems in the TableZone + */ void reorganizeCards(); + public: + /** + Constructs TableZone. + + @param _p the Player + @param parent defaults to null + */ TableZone(Player *_p, QGraphicsItem *parent = 0); + + /** + @return a QRectF of the TableZone bounding box. + */ QRectF boundingRect() const; + + /** + Render the TableZone + + @param painter + @param option + */ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + + /** + Toggles the selected items as tapped. + */ void toggleTapped(); + + /** + See HandleDropEventByGrid + */ void handleDropEvent(const QList &dragItems, CardZone *startZone, const QPoint &dropPoint); + + /** + Handles the placement of cards + */ void handleDropEventByGrid(const QList &dragItems, CardZone *startZone, const QPoint &gridPoint); + + /** + @return CardItem from grid location + */ CardItem *getCardFromGrid(const QPoint &gridPoint) const; + + /** + @return CardItem from coordinate location + */ CardItem *getCardFromCoords(const QPointF &point) const; + QPointF mapFromGrid(QPoint gridPoint) const; QPoint mapToGrid(const QPointF &mapPoint) const; QPointF closestGridPoint(const QPointF &point); + + /** + Removes a card from view. + + @param position card position + @param cardId id of card to take + @param canResize defaults to true + @return CardItem that has been removed + */ CardItem *takeCard(int position, int cardId, bool canResize = true); + + /** + Resizes the TableZone in case CardItems are within or + outside of the TableZone constraints. + */ void resizeToContents(); + int getMinimumWidth() const { return currentMinimumWidth; } - void setWidth(qreal _width); + void setWidth(qreal _width){ prepareGeometryChange(); width = _width;}; qreal getWidth() const { return width; } void setActive(bool _active) { active = _active; update(); } + protected: void addCardImpl(CardItem *card, int x, int y); + +private: + void paintZoneOutline(QPainter *painter); + void paintLandDivider(QPainter *painter); }; #endif diff --git a/cockatrice/translations/cockatrice_fr.ts b/cockatrice/translations/cockatrice_fr.ts index 8828b2b9..31aa65da 100644 --- a/cockatrice/translations/cockatrice_fr.ts +++ b/cockatrice/translations/cockatrice_fr.ts @@ -43,48 +43,48 @@ Path to hand background: - Chemin pour les images de fond de main: + Chemin vers l'image de fond de la zone de main: Path to stack background: - Chemin pour les images de fond de pile: + Chemin vers l'image de fond de la pile: Path to table background: - Chemin pour les images d'arrière-plan: + Chemin vers l'image de fond de la zone de jeu: Path to player info background: - Chemin pour les images de fond d'affichage d'informations: + Chemin vers l'image de fond d'informations joueur: Path to picture of card back: - Chemin pour les images de dos des cartes: - + Chemin vers l'image de dos des cartes: + Hand background: - + Image de fond de la zone de main: Stack background: - + Image de fond de la pile: Table background: - + Image de fond de la zone de jeu: Player info background: - + Image de fond de la zone d'informations joueur: Card back: - + Dos de carte: @@ -104,7 +104,7 @@ Display hand horizontally (wastes space) - Montrer la main horizontalement + Afficher la main horizontalement (perte d'espace) @@ -124,7 +124,7 @@ Zone view layout - Voir disposition de la zone + Disposition de la zone d'aperçu @@ -151,60 +151,60 @@ Please enter the duration of the ban (in minutes). Enter 0 for an indefinite ban. - Entrez la durée de temps du ban (en minutes). -Entrez 0 pour une durée illimitée du ban. + Entrez la durée de temps de blocage (en minutes). +Entrez 0 pour un blocage permanent. ban &user name - + bloquer &nom d'utilisateur ban &IP address - + bloquer &adresse IP Ban type - + Type du blocage &permanent ban - + &blocage permanent &temporary ban - + &blocage temporaire &Days: - + &Jours: &Hours: - + &Heures: &Minutes: - + &Minutes: Duration of the ban - + Durée du blocage Please enter the reason for the ban. This is only saved for moderators and cannot be seen by the banned person. - Veuillez expliquer la raison du ban. -Cette information ne sera consultable que par les modérateurs. + Veuillez expliquer la raison du blocage. +Cette information sera consultable uniquement par les modérateurs. @@ -229,12 +229,12 @@ Cette information ne sera consultable que par les modérateurs. Error - Erreur + Érreur You have to select a name-based or IP-based ban, or both. - + Vous devez choisir un blocage à partir du nom ou de l'IP, ou des deux. @@ -369,6 +369,12 @@ Cette information ne sera consultable que par les modérateurs. &Clone &Copier une carte + &Copier une carte + + + + Ctrl+H + Ctrl+H &Attach to card... @@ -384,16 +390,16 @@ Cette information ne sera consultable que par les modérateurs. Set &P/T... - Fixer &F/E... + Définir &F/E... &Draw arrow... &Tracer une flèche... - - &Power / toughness - F&orce / Endurance + + &Power / Toughness + &Force / Endurance &Increase power @@ -445,7 +451,7 @@ Cette information ne sera consultable que par les modérateurs. Set &power and toughness... - Fi&xer la force et l'endurance... + Dé&finir la force et l'endurance... Ctrl+P @@ -477,7 +483,7 @@ Cette information ne sera consultable que par les modérateurs. &Set counters (%1)... - &Fixer marqueurs (%1)... + &Définir marqueurs (%1)... &top of library @@ -497,7 +503,7 @@ Cette information ne sera consultable que par les modérateurs. &exile - &exiler + &exile @@ -2230,7 +2236,7 @@ Would you like to change your database location setting? Italian: - + Italien: @@ -5714,6 +5720,12 @@ Entrez 0 pour une durée illimitée du ban. &Commentaires: + + Hash: + Empreinte: + + + &Update prices Mettre à &jour les prix diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index c14b0cf6..344488b3 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -111,6 +111,13 @@ endif() if(UNIX) if(APPLE) + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) + set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) + set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) + INSTALL(TARGETS oracle BUNDLE DESTINATION ./) else() # Assume linux diff --git a/oracle/src/oraclewizard.cpp b/oracle/src/oraclewizard.cpp index 79ad5414..b9a13eee 100644 --- a/oracle/src/oraclewizard.cpp +++ b/oracle/src/oraclewizard.cpp @@ -103,17 +103,21 @@ LoadSetsPage::LoadSetsPage(QWidget *parent) urlRadioButton->setChecked(true); + urlButton = new QPushButton(tr("Restore default url"), this); + connect(urlButton, SIGNAL(clicked()), this, SLOT(actRestoreDefaultUrl())); + fileButton = new QPushButton(tr("Choose file..."), this); connect(fileButton, SIGNAL(clicked()), this, SLOT(actLoadSetsFile())); QGridLayout *layout = new QGridLayout(this); layout->addWidget(urlRadioButton, 0, 0); layout->addWidget(urlLineEdit, 0, 1); - layout->addWidget(fileRadioButton, 1, 0); - layout->addWidget(fileLineEdit, 1, 1); - layout->addWidget(fileButton, 2, 1, Qt::AlignRight); - layout->addWidget(progressLabel, 3, 0); - layout->addWidget(progressBar, 3, 1); + layout->addWidget(urlButton, 1, 1, Qt::AlignRight); + layout->addWidget(fileRadioButton, 2, 0); + layout->addWidget(fileLineEdit, 2, 1); + layout->addWidget(fileButton, 3, 1, Qt::AlignRight); + layout->addWidget(progressLabel, 4, 0); + layout->addWidget(progressBar, 4, 1); connect(&watcher, SIGNAL(finished()), this, SLOT(importFinished())); @@ -128,6 +132,11 @@ void LoadSetsPage::initializePage() progressBar->hide(); } +void LoadSetsPage::actRestoreDefaultUrl() +{ + urlLineEdit->setText(ALLSETS_URL); +} + void LoadSetsPage::actLoadSetsFile() { QFileDialog dialog(this, tr("Load sets file")); diff --git a/oracle/src/oraclewizard.h b/oracle/src/oraclewizard.h index 6e6a6ea8..f3255f8e 100644 --- a/oracle/src/oraclewizard.h +++ b/oracle/src/oraclewizard.h @@ -63,6 +63,7 @@ private: QRadioButton *fileRadioButton; QLineEdit *urlLineEdit; QLineEdit *fileLineEdit; + QPushButton *urlButton; QPushButton *fileButton; QLabel *progressLabel; QProgressBar * progressBar; @@ -72,6 +73,7 @@ private: QFuture future; private slots: void actLoadSetsFile(); + void actRestoreDefaultUrl(); void actDownloadProgressSetsFile(qint64 received, qint64 total); void actDownloadFinishedSetsFile(); void importFinished(); diff --git a/servatrice/CMakeLists.txt b/servatrice/CMakeLists.txt index 7bdf4721..4f407658 100644 --- a/servatrice/CMakeLists.txt +++ b/servatrice/CMakeLists.txt @@ -17,6 +17,19 @@ SET(servatrice_SOURCES ${VERSION_STRING_CPP} ) +set(servatrice_RESOURCES servatrice.qrc) + +if(WIN32) + set(servatrice_SOURCES ${servatrice_SOURCES} servatrice.rc) +endif(WIN32) + + +if(APPLE) + set(MACOSX_BUNDLE_ICON_FILE appicon.icns) + set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + set(servatrice_SOURCES ${servatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns) +ENDIF(APPLE) + set(SERVATRICE_LIBS) # Qt4 stuff @@ -32,6 +45,7 @@ if(Qt4_FOUND) # Libgcrypt is required only with Qt4 to support SHA512 hashing FIND_PACKAGE(Libgcrypt REQUIRED) INCLUDE_DIRECTORIES(${LIBGCRYPT_INCLUDE_DIR}) + QT4_ADD_RESOURCES(servatrice_RESOURCES_RCC ${servatrice_RESOURCES}) endif() # qt5 stuff @@ -53,6 +67,8 @@ if(Qt5Widgets_FOUND) list(APPEND SERVATRICE_LIBS Sql) endif() + QT5_ADD_RESOURCES(servatrice_RESOURCES_RCC ${servatrice_RESOURCES}) + # guess plugins and libraries directory set(QT_PLUGINS_DIR "${Qt5Widgets_DIR}/../../../plugins") get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION) @@ -61,6 +77,10 @@ endif() SET(QT_DONT_USE_QTGUI TRUE) +# Declare path variables +set(ICONDIR share/icons CACHE STRING "icon dir") +set(DESKTOPDIR share/applications CACHE STRING "desktop file destination") + # Include directories INCLUDE_DIRECTORIES(../common) INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) @@ -68,7 +88,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/../common) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # Build servatrice binary and link it -ADD_EXECUTABLE(servatrice MACOSX_BUNDLE ${servatrice_SOURCES} ${servatrice_MOC_SRCS}) +ADD_EXECUTABLE(servatrice MACOSX_BUNDLE ${servatrice_SOURCES} ${servatrice_RESOURCES_RCC} ${servatrice_MOC_SRCS}) if(Qt4_FOUND) if(MSVC) @@ -88,6 +108,13 @@ endif() # install rules if(UNIX) if(APPLE) + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) + set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) + set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) + INSTALL(TARGETS servatrice BUNDLE DESTINATION ./) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/servatrice.ini.example DESTINATION ./servatrice.app/Contents/Resources/) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/servatrice.sql DESTINATION ./servatrice.app/Contents/Resources/) @@ -96,6 +123,10 @@ if(UNIX) INSTALL(TARGETS servatrice RUNTIME DESTINATION bin/) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/servatrice.ini.example DESTINATION share/servatice/) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/servatrice.sql DESTINATION share/servatice/) + + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/servatrice.png DESTINATION ${ICONDIR}/hicolor/48x48/apps) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/servatrice.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/servatrice.desktop DESTINATION ${DESKTOPDIR}) endif() elseif(WIN32) INSTALL(TARGETS servatrice RUNTIME DESTINATION ./) diff --git a/servatrice/resources/appicon.icns b/servatrice/resources/appicon.icns new file mode 100644 index 00000000..2dece9b0 Binary files /dev/null and b/servatrice/resources/appicon.icns differ diff --git a/servatrice/resources/appicon.ico b/servatrice/resources/appicon.ico new file mode 100644 index 00000000..35663487 Binary files /dev/null and b/servatrice/resources/appicon.ico differ diff --git a/servatrice/resources/servatrice.png b/servatrice/resources/servatrice.png new file mode 100644 index 00000000..7d701ef0 Binary files /dev/null and b/servatrice/resources/servatrice.png differ diff --git a/servatrice/resources/servatrice.svg b/servatrice/resources/servatrice.svg new file mode 100644 index 00000000..580a04be --- /dev/null +++ b/servatrice/resources/servatrice.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/servatrice/servatrice.desktop b/servatrice/servatrice.desktop new file mode 100644 index 00000000..7149284b --- /dev/null +++ b/servatrice/servatrice.desktop @@ -0,0 +1,10 @@ +#!/usr/bin/env xdg-open +[Desktop Entry] +Version=1.0 +Type=Application +Name=Servatrice +Exec=servatrice +Icon=servatrice +Categories=Game;CardGame; +Terminal=true +Comment=Game server for Cockatrice diff --git a/servatrice/servatrice.qrc b/servatrice/servatrice.qrc new file mode 100644 index 00000000..f9cf3ef9 --- /dev/null +++ b/servatrice/servatrice.qrc @@ -0,0 +1,5 @@ + + + resources/servatrice.svg + + diff --git a/servatrice/servatrice.rc b/servatrice/servatrice.rc new file mode 100644 index 00000000..cf949f31 --- /dev/null +++ b/servatrice/servatrice.rc @@ -0,0 +1 @@ +ID1_ICON1 ICON DISCARDABLE "resources/appicon.ico" diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 70b96a02..22ba4cf5 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -220,6 +220,6 @@ PRIMARY KEY (`id`) CREATE TABLE IF NOT EXISTS `cockatrice_rooms_gametypes` ( `id_room` int(7) unsigned NOT NULL, `name` varchar(50) NOT NULL, -PRIMARY KEY (`id_room`) +PRIMARY KEY (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/servatrice/src/server_logger.cpp b/servatrice/src/server_logger.cpp index 1a1e4bed..4896852a 100644 --- a/servatrice/src/server_logger.cpp +++ b/servatrice/src/server_logger.cpp @@ -50,7 +50,7 @@ void ServerLogger::logMessage(QString message, void *caller) callerString = QString::number((qulonglong) caller, 16) + " "; //filter out all log entries based on values in configuration file - bool shouldWeWriteLog = settingsCache->value("server/writelog").toBool(); + bool shouldWeWriteLog = settingsCache->value("server/writelog",1).toBool(); QString logFilters = settingsCache->value("server/logfilters").toString(); QStringList listlogFilters = logFilters.split(",", QString::SkipEmptyParts); bool shouldWeSkipLine = false;