diff --git a/cockatrice/cockatrice_en@source.ts b/cockatrice/cockatrice_en@source.ts index 82e0da237..8be7525f4 100644 --- a/cockatrice/cockatrice_en@source.ts +++ b/cockatrice/cockatrice_en@source.ts @@ -22,6 +22,86 @@ + + AbstractDlgDeckTextEdit + + + &Refresh + + + + + Parse Set Name and Number (if available) + + + + + AbstractTabDeckEditor + + + Open in new tab + + + + + Are you sure? + + + + + The decklist has been modified. +Do you want to save the changes? + + + + + + + + + + + Error + + + + + Could not open deck at %1 + + + + + Could not save remote deck + + + + + + The deck could not be saved. +Please check that the directory is writable and try again. + + + + + Save deck + + + + + The deck could not be saved. + + + + + There are no cards in your deck to be exported + + + + + No deck was selected to be saved. + + + AdminNotesDialog @@ -51,127 +131,123 @@ AppearanceSettingsPage - + Error - + Could not create themes directory at '%1'. - + Theme settings - + Current theme: - + Open themes folder - + Menu settings - + Show keyboard shortcuts in right-click menus - - Draw missing color identities in visual deck storage without color label - - - - - Missing color identity opacity - - - - + Card rendering - + Display card names on cards having a picture - + Auto-Rotate cards with sideways layout - + Override all card art with personal set preference (Pre-ProviderID change behavior) [Requires Client restart] - + Bump sets that the deck contains cards from to the top in the printing selector - + Scale cards on mouse over - + Minimum overlap percentage of cards on the stack and in vertical hand - + Maximum initial height for card view window: - + + rows - + + Maximum expanded height for card view window: + + + + Hand layout - + Display hand horizontally (wastes space) - + Enable left justification - + Table grid layout - + Invert vertical coordinate - + Minimum player count for multi-column layout: - + Maximum font size for information displayed on cards: @@ -291,22 +367,22 @@ This is only saved for moderators and cannot be seen by the banned person. BetaReleaseChannel - + Beta - + No reply received from the release update server. - + Invalid reply received from the release update server. - + No reply received from the file update server. @@ -457,22 +533,22 @@ This is only saved for moderators and cannot be seen by the banned person. CardInfoPictureWidget - + View related cards - + Add card to deck - + Mainboard - + Sideboard @@ -498,12 +574,12 @@ This is only saved for moderators and cannot be seen by the banned person. CardItem - + &Move to - + &Power / toughness @@ -639,169 +715,409 @@ This is only saved for moderators and cannot be seen by the banned person. + + DeckEditorCardInfoDockWidget + + + Card Info + + + + + DeckEditorDatabaseDisplayWidget + + + Search by card name (or search expressions) + + + + + Add to Deck + + + + + Add to Sideboard + + + + + Select Printing + + + + + Show on EDHREC (Commander) + + + + + Show on EDHREC (Card) + + + + + Show Related cards + + + + + Add card to &maindeck + + + + + Add card to &sideboard + + + + + DeckEditorDeckDockWidget + + + Banner Card + + + + + Select Printing + + + + + Deck + + + + + Deck &name: + + + + + &Comments: + + + + + Hash: + + + + + &Increment number + + + + + &Decrement number + + + + + &Remove row + + + + + Swap card to/from sideboard + + + + + DeckEditorFilterDockWidget + + + Filters + + + + + &Clear all filters + + + + + Delete selected + + + + + DeckEditorMenu + + + &Deck Editor + + + + + &New deck + + + + + &Load deck... + + + + + Load recent deck... + + + + + Clear + + + + + &Save deck + + + + + Save deck &as... + + + + + Load deck from cl&ipboard... + + + + + Edit deck in clipboard + + + + + + Annotated + + + + + + Not Annotated + + + + + Save deck to clipboard + + + + + Annotated (No set info) + + + + + Not Annotated (No set info) + + + + + &Print deck... + + + + + &Send deck to online service + + + + + Create decklist (decklist.org) + + + + + Analyze deck (deckstats.net) + + + + + Analyze deck (tappedout.net) + + + + + &Close + + + + + DeckEditorPrintingSelectorDockWidget + + + Printing Selector + + + DeckEditorSettingsPage - - + + Update Spoilers - - + + Success - + Download URLs have been reset. - + Downloaded card pictures have been reset. - + Error - + One or more downloaded card pictures could not be cleared. - + Add URL - + URL: - - + + Edit URL - + Network Cache Size: - + Redirect Cache TTL: - + How long cached redirects for urls are valid for. - + Picture Cache Size: - + Add New URL - + Remove URL - + Day(s) - + Updating... - + Choose path - + URL Download Priority - + Spoilers - + Download Spoilers Automatically - + Spoiler Location: - + Last Change - + Spoilers download automatically on launch - + Press the button to manually update without relaunching - + Do not close settings until manual update is complete - + Download card pictures on the fly - + How to add a custom URL - + Delete Downloaded Images - + Reset Download URLs - + On-disk cache for downloaded pictures - + In-memory cache for pictures not currently on screen @@ -834,15 +1150,28 @@ This is only saved for moderators and cannot be seen by the banned person. + + DeckLoader + + + Common deck formats (%1) + + + + + All files (*.*) + + + DeckPreviewColorIdentityFilterWidget - + Mode: Exact Match - + Mode: Includes @@ -850,8 +1179,8 @@ This is only saved for moderators and cannot be seen by the banned person. DeckPreviewDeckTagsDisplayWidget - - + + Edit tags ... @@ -914,6 +1243,101 @@ This is only saved for moderators and cannot be seen by the banned person. + + DeckPreviewWidget + + + Banner Card + + + + + Open in deck editor + + + + + Edit Tags + + + + + Rename Deck + + + + + Save Deck to Clipboard + + + + + Annotated + + + + + Annotated (No set info) + + + + + Not Annotated + + + + + Not Annotated (No set info) + + + + + Rename File + + + + + Delete File + + + + + Set Banner Card + + + + + + New name: + + + + + + Error + + + + + Rename failed + + + + + Delete file + + + + + Are you sure you want to delete the selected file? + + + + + Delete failed + + + DeckStatsInterface @@ -931,48 +1355,48 @@ This is only saved for moderators and cannot be seen by the banned person. DeckViewContainer - + Load deck... - + Load remote deck... - + Unload deck Unload deck... - + Ready to start - + Force start - + Sideboard unlocked - + Sideboard locked - + Error - + The selected file could not be loaded. @@ -1392,6 +1816,24 @@ To remove your current avatar, confirm without choosing a new image. + + DlgEditDeckInClipboard + + + Edit deck in clipboard + + + + + Error + + + + + Invalid deck list. + + + DlgEditPassword @@ -1876,29 +2318,17 @@ Make sure to enable the 'Token' set in the "Manage sets" dia DlgLoadDeckFromClipboard - - &Refresh - - - - - Parse Set Name and Number (if available) - - - - + Load deck from clipboard - - + Error - - + Invalid deck list. @@ -1906,7 +2336,7 @@ Make sure to enable the 'Token' set in the "Manage sets" dia DlgLoadRemoteDeck - + Load deck @@ -2062,12 +2492,12 @@ Your email will be used to verify your account. DlgSettings - + Unknown Error loading card database - + Your card database is invalid. Cockatrice may not function correctly with an invalid database @@ -2078,7 +2508,7 @@ Would you like to change your database location setting? - + Your card database version is too old. This can cause problems loading card information or images @@ -2089,7 +2519,7 @@ Would you like to change your database location setting? - + Your card database did not finish loading Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues with your cards.xml attached @@ -2098,21 +2528,21 @@ Would you like to change your database location setting? - + File Error loading your card database. Would you like to change your database location setting? - + Your card database was loaded but contains no cards. Would you like to change your database location setting? - + Unknown card database load status Please file a ticket at https://github.com/Cockatrice/Cockatrice/issues @@ -2121,59 +2551,59 @@ Would you like to change your database location setting? - - + + Error - + The path to your deck directory is invalid. Would you like to go back and set the correct path? - + The path to your card pictures directory is invalid. Would you like to go back and set the correct path? - + Settings - + General - + Appearance - + User Interface - + Card Sources - + Chat - + Sound - + Shortcuts @@ -2225,9 +2655,9 @@ Would you like to change your database location setting? - - - + + + Error @@ -2239,7 +2669,8 @@ Please visit the download page to update manually. - Downloading update... + Downloading update: %1 + Downloading update... @@ -2314,49 +2745,52 @@ Please visit the download page to update manually. - Unfortunately there are no download packages available for your operating system. -You may have to build from source yourself. + Unfortunately, the automatic updater failed to find a compatible download. +You may have to manually download the new version. + Unfortunately there are no download packages available for your operating system. +You may have to build from source yourself. - Please check the download page manually and visit the wiki for instructions on compiling. + Please check the <a href="%1">releases page</a> on our Github and download the build for your system. + Please check the download page manually and visit the wiki for instructions on compiling. - - - + + + Update Error - + An error occurred while checking for updates: - + An error occurred while downloading an update: - + Installing... - + Cockatrice is unable to open the installer. - + Try to update manually by closing Cockatrice and running the installer. - + Download location @@ -2621,97 +3055,102 @@ You may have to build from source yourself. GeneralSettingsPage - + Reset all paths - + All paths have been reset - - - - - - + + + + + + Choose path - + Personal settings - + Language: - + Paths (editing disabled in portable mode) - + Paths - - - Decks directory: - - - - - Replays directory: - - - - - Pictures directory: - - - - - Card database: - - - - - Custom database directory: - - - Token database: + How to help with translations - Update channel + Decks directory: - Check for client updates on startup + Replays directory: - Notify if a feature supported by the server is missing in my client + Pictures directory: - Automatically run Oracle when running a new version of Cockatrice + Card database: + Custom database directory: + + + + + Token database: + + + + + Update channel + + + + + Check for client updates on startup + + + + + Notify if a feature supported by the server is missing in my client + + + + + Automatically run Oracle when running a new version of Cockatrice + + + + Show tips on startup @@ -2919,7 +3358,7 @@ Will now login. - + Error @@ -3389,7 +3828,7 @@ Read more about changing the set order or disabling specific sets and consequent - + Information @@ -3405,41 +3844,42 @@ Read more about changing the set order or disabling specific sets and consequent - failed to start. + Failed to start. The file might be missing, or permissions might be incorrect. - crashed. + The process crashed some time after starting successfully. - - timed out. + + Timed out. The process took too long to respond. The last waitFor...() function timed out. - - write error. + + An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel. - - read error. + + An error occurred when attempting to read from the process. For example, the process may not be running. - - unknown error. + + Unknown error occurred. - - The card database updater exited with an error: %1 + + The card database updater exited with an error: +%1 - + This server supports additional features that your client doesn't have. This is most likely not a problem, but this message might mean there is a new version of Cockatrice available or this server is running a custom or pre-release version. @@ -3447,54 +3887,54 @@ To update your client, go to Help -> Check for Updates. - - - - - + + + + + Load sets/cards - + Selected file cannot be found. - + You can only import XML databases at this time. - + The new sets/cards have been added successfully. Cockatrice will now reload the card database. - + Sets/cards failed to import. - - - + + + Reset Password - + Your password has been reset successfully, you can now log in using the new credentials. - + Failed to reset user account password, please contact the server operator to reset your password. - + Activation request received, please check your email for an activation token. @@ -4110,110 +4550,110 @@ Cockatrice will now reload the card database. MessagesSettingsPage - + Word1 Word2 Word3 - + Add New Message - + Edit Message - + Remove Message - + Add message - - + + Message: - + Edit message - + Chat settings - + Custom alert words - + Enable chat mentions - + Enable mention completer - + In-game message macros - + How to use in-game message macros - + Ignore chat room messages sent by unregistered users - + Ignore private messages sent by unregistered users - - + + Invert text color - + Enable desktop notifications for private messages - + Enable desktop notification for mentions - + Enable room message history on join - - + + (Color is hexadecimal) - + Separate words with a space, alphanumeric characters only @@ -4422,639 +4862,669 @@ Cockatrice will now reload the card database. Player - + Reveal top cards of library - - + - - - - - - - + + + + + + + + + + Number of cards: (max. %1) - + &View graveyard - + &View exile - + Player "%1" - - - - + + + + &Graveyard - - + - + + &Exile - + &Move hand to... - + &Top of library - + &Bottom of library - + &Move graveyard to... - - - + + + &Hand - + &Move exile to... - + &View library - + &View hand - + View &top cards of library... - + Reveal &library to... - + &Always reveal top card - + &View sideboard - + &Draw card - + D&raw cards... - + &Undo last draw - + Take &mulligan - - &Shuffle - - - - + Play top card &face down - + Move top card to grave&yard - + Move top card to e&xile - + Move top cards to &graveyard... - + Move top cards to &exile... - + Put top card on &bottom - + View bottom cards of library... - + Lend library to... - + + Shuffle + + + + Put top cards on stack &until... Take top cards &until... - - &Reveal hand to... + + Shuffle top cards... - - Reveal r&andom card to... - - - - - Reveal random card to... - - - - - &Sideboard - - - - - &Library - - - - - &Counters - - - - - &Untap all permanents - - - - - R&oll die... + + Shuffle bottom cards... - &Create token... + &Reveal hand to... - C&reate another token + Reveal r&andom card to... - Cr&eate predefined token + Reveal random card to... + + + + + &Sideboard + + + + + &Library + + + + + &Counters + + + + + &Untap all permanents + + + + + R&oll die... + + + + + &Create token... - + C&reate another token + + + + + Cr&eate predefined token + + + + + &All players - + S&ay - + &Select All - + S&elect Row - + S&elect Column - + &Play - + &Hide - + Play &Face Down - + &Tap / Untap Turn sideways or back again - + Toggle &normal untapping - + T&urn Over Turn face up/face down - + &Peek at card face - + &Clone - + Attac&h to card... - + Unattac&h - + &Draw arrow... - + &Increase power - + &Decrease power - + I&ncrease toughness - + D&ecrease toughness - + In&crease power and toughness - + Dec&rease power and toughness - + Increase power and decrease toughness - + Decrease power and increase toughness - + Set &power and toughness... - + Reset p&ower and toughness - + &Set annotation... - + Red - + Yellow - + Green - + &Add counter (%1) - + &Remove counter (%1) - + &Set counters (%1)... - + &Top of library in random order - + X cards from the top of library... - + &Bottom of library in random order - + View top cards of library - + View bottom cards of library - + + Shuffle top cards of library + + + + + Shuffle bottom cards of library + + + + Which position should this card be placed: - + (max. %1) - + Draw hand - + 0 and lower are in comparison to current hand size - + Draw cards - - + + Number: - + Move top cards to grave - + Reveal &top cards to... - + &Top of library... - + &Bottom of library... - + &Always look at top card - + &Open deck in deck editor - + &Play top card - + &Draw bottom card - + D&raw bottom cards... - + &Play bottom card - + Play bottom card &face down - + Move bottom card to grave&yard - + Move bottom card to e&xile - + Move bottom cards to &graveyard... - + Move bottom cards to &exile... - + Put bottom card on &top - + Selec&ted cards - + Move top cards to exile - + Move bottom cards to grave - + Move bottom cards to exile - + Draw bottom cards - - + + C&reate another %1 token - + Create tokens - + Place card X cards from top of library - + Change power/toughness - + Change stats to: - + Set annotation - + Please enter the new annotation: - + Set counters - + Re&veal to... - + View related cards - + Token: - + All tokens + + PrintingSelector + + + Display Navigation Buttons + + + PrintingSelectorCardOverlayWidget @@ -5117,48 +5587,17 @@ Cockatrice will now reload the card database. - - + + Descending - + Ascending - - PrintingSelectorViewOptionsToolbarWidget - - - Display Options - - - - - PrintingSelectorViewOptionsWidget - - - Display Sorting Options - - - - - Display Search Bar - - - - - Display Card Size Slider - - - - - Display Navigation Buttons - - - QMenuBar @@ -5206,7 +5645,6 @@ Cockatrice will now reload the card database. - All files (*.*) @@ -5215,11 +5653,6 @@ Cockatrice will now reload the card database. Cockatrice replays (*.cor) - - - Common deck formats (*.cod *.dec *.dek *.txt *.mwDeck) - - Maindeck @@ -5482,53 +5915,53 @@ Cockatrice will now reload the card database. ShortcutSettingsPage - - + + Restore all default shortcuts - + Do you really want to restore all default shortcuts? - + Clear all default shortcuts - + Do you really want to clear all shortcuts? - + Section: - + Action: - + Shortcut: - + How to set custom shortcuts - + Clear all shortcuts - + Search by shortcut name @@ -5582,27 +6015,27 @@ Please check your shortcut settings! SoundSettingsPage - + Enable &sounds - + Current sounds theme: - + Test system sound engine - + Sound settings - + Master volume @@ -5659,27 +6092,27 @@ Please check your shortcut settings! StableReleaseChannel - + Default - + No reply received from the release update server. - + Invalid reply received from the release update server. - + No reply received from the tag update server. - + Invalid reply received from the tag update server. @@ -5818,430 +6251,192 @@ Please check your shortcut settings! TabDeckEditor - - Banner Card - - - - - Search by card name (or search expressions) - Search by card name - - - - - Add to Deck - - - - - Add to Sideboard - - - - - - Select Printing - - - - - Show on EDHREC (Commander) - - - - - Show on EDHREC (Card) - - - - - Show Related cards - - - - - &Clear all filters - - - - - Delete selected - - - - - Deck &name: - - - - - &Comments: - - - - - Hash: - - - - - &New deck - - - - - &Load deck... - - - - - Load recent deck... - - - - - Clear - - - - - &Save deck - - - - - Save deck &as... - - - - - Load deck from cl&ipboard... - - - - - Save deck to clipboard - - - - - Annotated - - - - - Annotated (No set name or number) - - - - - Not Annotated - - - - - Not Annotated (No set name or number) - - - - - &Print deck... - - - - - &Send deck to online service - - - - - Create decklist (decklist.org) - - - - - Analyze deck (deckstats.net) - - - - - Analyze deck (tappedout.net) - - - - - &Close - - - - - Add card to &maindeck - - - - - Add card to &sideboard - - - - - &Remove row - - - - - &Increment number - - - - - &Decrement number - - - - - Swap card to/from sideboard - - - - - &Deck Editor - - - - - + Card Info - - + Deck - - + Filters - - Printing Selector - - - - + &View - + Printing - - - - + + + + Visible - - - - + + + + Floating - + Reset layout - + Deck: %1 - - - Could not open deck at %1 - - - - - Open in new tab - - - - - Are you sure? - - - - - The decklist has been modified. -Do you want to save the changes? - - - - - - - - - - - Error - - - - - The deck could not be saved. - - - - - Could not save remote deck - - - - - - The deck could not be saved. -Please check that the directory is writable and try again. - - - - - Save deck - - - - - There are no cards in your deck to be exported - - - - - No deck was selected to be saved. - - TabDeckStorage - + Local file system - + Server deck storage - - + + Open in deck editor - - Upload deck - - - - - Download deck - - - - - - - New folder + Rename deck or folder - - Delete + Upload deck + Download deck + + + + + + + + New folder + + + + + + Delete + + + + Open decks folder - - - + + Rename local folder + + + + + Rename local file + + + + + New name: + + + + + + + Error - - + + Rename failed + + + + + Invalid deck file - + Enter deck name - + This decklist does not have a name. Please enter a name: - + Unnamed deck - + Failed to upload deck to server - + Delete local file - + Are you sure you want to delete the selected files? - + Delete remote decks - + Are you sure you want to delete the selected decks? - - + + Name of new folder: - + Deck Storage @@ -6253,6 +6448,16 @@ Please enter a name: Visual Deck Storage + + + Error + + + + + Could not open deck at %1 + + TabEdhRec @@ -6265,175 +6470,175 @@ Please enter a name: TabGame - - - + + + Replay - - + + Game - - + + Player List - - + + Card Info - - + + Messages - - + + Replay Timeline - + &Phases - + &Game - + Next &phase - + Next phase with &action - + Next &turn - + Reverse turn order - + &Remove all local arrows - + Rotate View Cl&ockwise - + Rotate View Co&unterclockwise - + Game &information - + Un&concede - + &Concede - + &Leave game - + C&lose replay - + &Focus Chat - + &Say: - + &View - - - - + + + + Visible - - - - + + + + Floating - + Reset layout - + Concede - + Are you sure you want to concede this game? - + Unconcede - + You have already conceded. Do you want to return to this game? - + Leave game - + Are you sure you want to leave this game? @@ -6443,37 +6648,37 @@ Please enter a name: - + A player has joined game #%1 - + %1 has joined the game - + kicked by game host or moderator - + player left the game - + player disconnected from server - + reason unknown - + You have been kicked out of the game. @@ -6907,32 +7112,32 @@ The more information you put in, the more specific your results will be. - + Are you sure? - + There are still open games. Are you sure you want to quit? - + Click to view - + Your buddy %1 has signed on! - + Unknown Event - + The server has sent you a message that your client does not understand. This message might mean there is a new version of Cockatrice available or this server is running a custom or pre-release version. @@ -6940,38 +7145,38 @@ To update your client, go to Help -> Check for Updates. - + Idle Timeout - + You are about to be logged out due to inactivity. - + Promotion - + You have been promoted. Please log out and back in for changes to take effect. - + Warned - + You have received a warning due to %1. Please refrain from engaging in this activity or further actions may be taken against you. If you have any questions, please private message a moderator. - + You have received the following message from the server. (custom messages like these could be untranslated) @@ -7425,102 +7630,102 @@ Please refrain from engaging in this activity or further actions may be taken ag UserInterfaceSettingsPage - + General interface settings - + &Double-click cards to play them (instead of single-click) - + &Clicking plays all selected cards (instead of just the clicked card) - + &Play all nonlands onto the stack (not the battlefield) by default - + Close card view window when last card is removed - + Annotate card text on tokens - + Use tear-off menus, allowing right click menus to persist on screen - + Notifications settings - + Enable notifications in taskbar - + Notify in the taskbar for game events while you are spectating - + Notify in the taskbar when users in your buddy list connect - + Animation settings - + &Tap/untap animation - + Deck editor/storage settings - + Open deck in new tab by default - + Prompt before converting .txt decks to .cod format - + Always convert if not prompted - + Use visual deck storage in game lobby - + Replay settings - + Buffer time for backwards skip via shortcut: @@ -7528,22 +7733,22 @@ Please refrain from engaging in this activity or further actions may be taken ag UserListWidget - + Users connected to server: %1 - + Users in this room: %1 - + Buddies online: %1 / %2 - + Ignored users online: %1 / %2 @@ -7551,7 +7756,7 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageFolderDisplayWidget - + Deck Storage @@ -7559,7 +7764,7 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageSearchWidget - + Search by filename @@ -7590,10 +7795,45 @@ Please refrain from engaging in this activity or further actions may be taken ag VisualDeckStorageWidget - + Loading database ... + + + Show Folders + + + + + Show Tag Filter + + + + + Show Tags On Deck Previews + + + + + Show Banner Card Selection Option + + + + + Include Folder Names in Search + + + + + Draw unused Color Identities + + + + + Unused Color Identities Opacity + + WarningDialog @@ -7847,12 +8087,12 @@ Please refrain from engaging in this activity or further actions may be taken ag main - + Connect on startup - + Debug to file @@ -7866,7 +8106,7 @@ Please refrain from engaging in this activity or further actions may be taken ag - + Deck Editor @@ -7947,7 +8187,7 @@ Please refrain from engaging in this activity or further actions may be taken ag - + Replays @@ -8057,668 +8297,698 @@ Please refrain from engaging in this activity or further actions may be taken ag - + + Edit Deck in Clipboard, Annotated + + + + + Edit Deck in Clipboard + + + + New Deck - + Open Custom Pictures Folder - + Print Deck... - + Delete Card - - + + Reset Layout - + Save Deck - + Save Deck as... - + Save Deck to Clipboard, Annotated - + + Save Deck to Clipboard, Annotated (No Set Info) + + + + Save Deck to Clipboard - - - Load Local Deck... - - - - - Load Remote Deck... - - - - - Set Ready to Start - - - - - Toggle Sideboard Lock - - - - Add Green Counter + Save Deck to Clipboard (No Set Info) - - Remove Green Counter + Load Local Deck... - - Set Green Counters... + Load Remote Deck... + Set Ready to Start + + + + + Toggle Sideboard Lock + + + + + + Add Green Counter + + + + + + Remove Green Counter + + + + + + Set Green Counters... + + + + Add Yellow Counter - + Remove Yellow Counter - + Set Yellow Counters... - - + + Add Red Counter - - + + Remove Red Counter - - + + Set Red Counters... - + Add Life Counter - + Remove Life Counter - + Set Life Counters... - + Add White Counter - + Remove White Counter - + Set White Counters... - + Add Blue Counter - + Remove Blue Counter - + Set Blue Counters... - + Add Black Counter - + Remove Black Counter - + Set Black Counters... - + Add Colorless Counter - + Remove Colorless Counter - + Set Colorless Counters... - + Add Other Counter - + Remove Other Counter - + Set Other Counters... - + Add Power (+1/+0) - + Remove Power (-1/-0) - + Move Toughness to Power (+1/-1) - + Add Toughness (+0/+1) - + Remove Toughness (-0/-1) - + Move Power to Toughness (-1/+1) - + Add Power and Toughness (+1/+1) - + Remove Power and Toughness (-1/-1) - + Set Power and Toughness... - + Reset Power and Toughness - + Untap - + Upkeep - + Draw - + First Main Phase - + Start Combat - + Attack - + Block - + Damage - + End Combat - + Second Main Phase - + End - + Next Phase - + Next Phase Action - + Next Turn - + Hide Card in Reveal Window - + Tap / Untap Card - + Untap All - + Toggle Untap - + Turn Card Over - + Peek Card - + Play Card - + Attach Card... - + Unattach Card - + Clone Card - + Create Token... - + Create All Related Tokens - + Create Another Token - + Set Annotation... - + Select All Cards in Zone - + Select All Cards in Row - + Select All Cards in Column - - + + Bottom of Library - - - - + + + + Exile - - - - + + + + Graveyard - - + + Hand - - + + Top of Library - - - + + + Battlefield, Face Down - + Battlefield - + Library - + Sideboard - + Top Cards of Library - + Bottom Cards of Library - + Close Recent View - - + + Stack - - + + Graveyard (Multiple) - - + + Exile (Multiple) - + Stack Until Found - + Draw Bottom Card - + Draw Multiple Cards from Bottom... - + Draw Arrow... - + Remove Local Arrows - + Leave Game - + Concede - + Roll Dice... - + Shuffle Library - + + Shuffle Top Cards of Library + + + + + Shuffle Bottom Cards of Library + + + + Mulligan - + Draw a Card - + Draw Multiple Cards... - + Undo Draw - + Always Reveal Top Card - + Always Look At Top Card - + Rotate View Clockwise - + Rotate View Counterclockwise - + Unfocus Text Box - + Focus Chat - + Clear Chat - + Refresh - + Skip Forward - + Skip Backward - + Skip Forward by a lot - + Skip Backward by a lot - + Play/Pause - + Toggle Fast Forward - + Visual Deck Storage - + Deck Storage - + Server - + Account - + Administration - + Logs diff --git a/cockatrice/resources/config/qtlogging.ini b/cockatrice/resources/config/qtlogging.ini index 378b962b7..60a123d5e 100644 --- a/cockatrice/resources/config/qtlogging.ini +++ b/cockatrice/resources/config/qtlogging.ini @@ -47,12 +47,10 @@ # card_info = 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 \ No newline at end of file +# filter_string = false diff --git a/cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp b/cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp index 73c76c807..2d8c613a5 100644 --- a/cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp +++ b/cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp @@ -55,6 +55,9 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit aExportDeckDecklist = new QAction(QString(), this); connect(aExportDeckDecklist, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklist())); + aExportDeckDecklistXyz = new QAction(QString(), this); + connect(aExportDeckDecklistXyz, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklistXyz())); + aAnalyzeDeckDeckstats = new QAction(QString(), this); connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckDeckstats())); @@ -63,6 +66,8 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit analyzeDeckMenu = new QMenu(this); analyzeDeckMenu->addAction(aExportDeckDecklist); + analyzeDeckMenu->addAction(aExportDeckDecklistXyz); + analyzeDeckMenu->addSeparator(); analyzeDeckMenu->addAction(aAnalyzeDeckDeckstats); analyzeDeckMenu->addAction(aAnalyzeDeckTappedout); @@ -160,6 +165,7 @@ void DeckEditorMenu::retranslateUi() analyzeDeckMenu->setTitle(tr("&Send deck to online service")); aExportDeckDecklist->setText(tr("Create decklist (decklist.org)")); + aExportDeckDecklistXyz->setText(tr("Create decklist (decklist.xyz)")); aAnalyzeDeckDeckstats->setText(tr("Analyze deck (deckstats.net)")); aAnalyzeDeckTappedout->setText(tr("Analyze deck (tappedout.net)")); @@ -172,13 +178,17 @@ void DeckEditorMenu::refreshShortcuts() 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")); aEditDeckInClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aEditDeckInClipboard")); aEditDeckInClipboardRaw->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aEditDeckInClipboardRaw")); aPrintDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aPrintDeck")); + + aExportDeckDecklist->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklist")); + aExportDeckDecklistXyz->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklistXyz")); aAnalyzeDeckDeckstats->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aAnalyzeDeck")); + aAnalyzeDeckTappedout->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aAnalyzeDeckTappedout")); + aClose->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClose")); aSaveDeckToClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckToClipboard")); diff --git a/cockatrice/src/client/menus/deck_editor/deck_editor_menu.h b/cockatrice/src/client/menus/deck_editor/deck_editor_menu.h index 50ddc795a..a713b009f 100644 --- a/cockatrice/src/client/menus/deck_editor/deck_editor_menu.h +++ b/cockatrice/src/client/menus/deck_editor/deck_editor_menu.h @@ -17,7 +17,7 @@ public: QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard, *aEditDeckInClipboard, *aEditDeckInClipboardRaw, *aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetInfo, *aSaveDeckToClipboardRaw, *aSaveDeckToClipboardRawNoSetInfo, *aPrintDeck, *aExportDeckDecklist, - *aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose; + *aExportDeckDecklistXyz, *aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose; QMenu *loadRecentDeckMenu, *analyzeDeckMenu, *editDeckInClipboardMenu, *saveDeckToClipboardMenu; void setSaveStatus(bool newStatus); diff --git a/cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp b/cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp index 734ed1298..fe2148293 100644 --- a/cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp +++ b/cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp @@ -455,17 +455,12 @@ void AbstractTabDeckEditor::actPrintDeck() dlg->exec(); } -// Action called when export deck to decklist menu item is pressed. -void AbstractTabDeckEditor::actExportDeckDecklist() +void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website) { - // 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) { + if (DeckLoader *const deck = getDeckList()) { // Get the decklist url string from the deck loader class. - decklistUrlString = deck->exportDeckToDecklist(); + QString decklistUrlString = deck->exportDeckToDecklist(website); // 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. @@ -481,10 +476,26 @@ void AbstractTabDeckEditor::actExportDeckDecklist() 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.")); + QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be exported.")); } } +/** + * Exports the deck to www.decklist.org (the old website) + */ +void AbstractTabDeckEditor::actExportDeckDecklist() +{ + exportToDecklistWebsite(DeckLoader::DecklistOrg); +} + +/** + * Exports the deck to www.decklist.xyz (the new website) + */ +void AbstractTabDeckEditor::actExportDeckDecklistXyz() +{ + exportToDecklistWebsite(DeckLoader::DecklistXyz); +} + void AbstractTabDeckEditor::actAnalyzeDeckDeckstats() { auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), diff --git a/cockatrice/src/client/tabs/abstract_tab_deck_editor.h b/cockatrice/src/client/tabs/abstract_tab_deck_editor.h index 9f3cca0e1..0a5f97f56 100644 --- a/cockatrice/src/client/tabs/abstract_tab_deck_editor.h +++ b/cockatrice/src/client/tabs/abstract_tab_deck_editor.h @@ -100,6 +100,7 @@ protected slots: void actSaveDeckToClipboardRawNoSetInfo(); void actPrintDeck(); void actExportDeckDecklist(); + void actExportDeckDecklistXyz(); void actAnalyzeDeckDeckstats(); void actAnalyzeDeckTappedout(); @@ -119,6 +120,7 @@ protected slots: private: virtual void setDeck(DeckLoader *_deck); void editDeckInClipboard(bool annotated); + void exportToDecklistWebsite(DeckLoader::DecklistWebsite website); protected: /** diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp index ae09305d1..97825ff21 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.cpp @@ -14,7 +14,7 @@ #include DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_parent, DeckList *_deckList) - : QWidget(_parent), deckList(_deckList) + : QWidget(_parent), deckList(nullptr) { setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); @@ -27,8 +27,8 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_par flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded); - if (deckList) { - connectDeckList(deckList); + if (_deckList) { + connectDeckList(_deckList); } layout->addWidget(flowWidget); @@ -36,10 +36,20 @@ DeckPreviewDeckTagsDisplayWidget::DeckPreviewDeckTagsDisplayWidget(QWidget *_par void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList) { - flowWidget->clearLayout(); + if (deckList) { + disconnect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags); + } + deckList = _deckList; connect(deckList, &DeckList::deckTagsChanged, this, &DeckPreviewDeckTagsDisplayWidget::refreshTags); + refreshTags(); +} + +void DeckPreviewDeckTagsDisplayWidget::refreshTags() +{ + flowWidget->clearLayout(); + for (const QString &tag : deckList->getTags()) { flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); } @@ -50,16 +60,6 @@ void DeckPreviewDeckTagsDisplayWidget::connectDeckList(DeckList *_deckList) flowWidget->addWidget(tagAdditionWidget); } -void DeckPreviewDeckTagsDisplayWidget::refreshTags() -{ - flowWidget->clearLayout(); - QStringList tags = deckList->getTags(); - for (const QString &tag : tags) { - flowWidget->addWidget(new DeckPreviewTagDisplayWidget(this, tag)); - } - flowWidget->addWidget(new DeckPreviewTagAdditionWidget(this, tr("Edit tags ..."))); -} - /** * Gets the filepath of all files (no directories) in target directory and all subdirectories */ @@ -160,4 +160,4 @@ void DeckPreviewDeckTagsDisplayWidget::openTagEditDlg() } } } -} \ No newline at end of file +} diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp index b4a07386c..319244f85 100644 --- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp @@ -59,7 +59,7 @@ void VisualDeckStorageFolderDisplayWidget::refreshUi() } /** - * Gets all files in the directory that have a .txt or .cod extension + * Gets all files in the directory that have an accepted decklist file extension * * @param filePath The directory to search through * @param recursive Whether to search through subdirectories diff --git a/cockatrice/src/deck/deck_loader.cpp b/cockatrice/src/deck/deck_loader.cpp index 16132c571..8130752b7 100644 --- a/cockatrice/src/deck/deck_loader.cpp +++ b/cockatrice/src/deck/deck_loader.cpp @@ -226,6 +226,19 @@ bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, FileFormat f return result; } +static QString getDomainForWebsite(DeckLoader::DecklistWebsite website) +{ + switch (website) { + case DeckLoader::DecklistOrg: + return "www.decklist.org"; + case DeckLoader::DecklistXyz: + return "www.decklist.xyz"; + default: + qCWarning(DeckLoaderLog) << "Invalid decklist website enum:" << website; + return ""; + } +} + // This struct is here to support the forEachCard function call, defined in decklist. It // requires a function to be called for each card, and passes an inner node and a card for // each card in the decklist. @@ -275,11 +288,14 @@ struct FormatDeckListForExport } }; -// Export deck to decklist function, called to format the deck in a way to be sent to a server -QString DeckLoader::exportDeckToDecklist() +/** + * Export deck to decklist function, called to format the deck in a way to be sent to a server + * @param website The website we're sending the deck to + */ +QString DeckLoader::exportDeckToDecklist(DecklistWebsite website) { // Add the base url - QString deckString = "https://www.decklist.org/?"; + QString deckString = "https://" + getDomainForWebsite(website) + "/?"; // Create two strings to pass to function QString mainBoardCards, sideBoardCards; // Set up the struct to call. diff --git a/cockatrice/src/deck/deck_loader.h b/cockatrice/src/deck/deck_loader.h index c62fd45c9..53dd1f711 100644 --- a/cockatrice/src/deck/deck_loader.h +++ b/cockatrice/src/deck/deck_loader.h @@ -31,6 +31,12 @@ public: */ static const QStringList FILE_NAME_FILTERS; + enum DecklistWebsite + { + DecklistOrg, + DecklistXyz + }; + private: QString lastFileName; FileFormat lastFileFormat; @@ -71,7 +77,7 @@ public: bool loadFromRemote(const QString &nativeString, int remoteDeckId); bool saveToFile(const QString &fileName, FileFormat fmt); bool updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt); - QString exportDeckToDecklist(); + QString exportDeckToDecklist(DecklistWebsite website); void resolveSetNameAndNumberToProviderID(); diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp index 4f0207155..edf593571 100644 --- a/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.cpp @@ -3,7 +3,6 @@ #include "../game/cards/card_database.h" #include "../game/cards/card_database_manager.h" #include "../game/filters/filter_string.h" -#include "trice_limits.h" #include #include @@ -14,15 +13,17 @@ #include #include -DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint _numberOfHits, bool autoPlay) +DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QStringList exprs, uint _numberOfHits, bool autoPlay) : QDialog(parent) { exprLabel = new QLabel(tr("Card name (or search expressions):")); - exprEdit = new QLineEdit(this); - exprEdit->setFocus(); - exprEdit->setText(_expr); - exprLabel->setBuddy(exprEdit); + exprComboBox = new QComboBox(this); + exprComboBox->setFocus(); + exprComboBox->setEditable(true); + exprComboBox->setInsertPolicy(QComboBox::InsertAtTop); + exprComboBox->insertItems(0, exprs); + exprLabel->setBuddy(exprComboBox); numberOfHitsLabel = new QLabel(tr("Number of hits:")); numberOfHitsEdit = new QSpinBox(this); @@ -43,7 +44,7 @@ DlgMoveTopCardsUntil::DlgMoveTopCardsUntil(QWidget *parent, QString _expr, uint auto *mainLayout = new QVBoxLayout; mainLayout->addWidget(exprLabel); - mainLayout->addWidget(exprEdit); + mainLayout->addWidget(exprComboBox); mainLayout->addItem(grid); mainLayout->addWidget(autoPlayCheckBox); mainLayout->addWidget(buttonBox); @@ -92,7 +93,7 @@ bool DlgMoveTopCardsUntil::validateMatchExists(const FilterString &filterString) void DlgMoveTopCardsUntil::validateAndAccept() { - auto movingCardsUntilFilter = FilterString(exprEdit->text()); + auto movingCardsUntilFilter = FilterString(exprComboBox->currentText()); if (!movingCardsUntilFilter.valid()) { QMessageBox::warning(this, tr("Invalid filter"), movingCardsUntilFilter.error(), QMessageBox::Ok); return; @@ -102,12 +103,29 @@ void DlgMoveTopCardsUntil::validateAndAccept() return; } + // move currently selected text to top of history list + if (exprComboBox->currentIndex() != 0) { + QString currentExpr = exprComboBox->currentText(); + exprComboBox->removeItem(exprComboBox->currentIndex()); + exprComboBox->insertItem(0, currentExpr); + exprComboBox->setCurrentIndex(0); + } + accept(); } QString DlgMoveTopCardsUntil::getExpr() const { - return exprEdit->text(); + return exprComboBox->currentText(); +} + +QStringList DlgMoveTopCardsUntil::getExprs() const +{ + QStringList exprs; + for (int i = 0; i < exprComboBox->count(); ++i) { + exprs.append(exprComboBox->itemText(i)); + } + return exprs; } uint DlgMoveTopCardsUntil::getNumberOfHits() const diff --git a/cockatrice/src/dialogs/dlg_move_top_cards_until.h b/cockatrice/src/dialogs/dlg_move_top_cards_until.h index c4cc2e0cb..d41d029d6 100644 --- a/cockatrice/src/dialogs/dlg_move_top_cards_until.h +++ b/cockatrice/src/dialogs/dlg_move_top_cards_until.h @@ -2,10 +2,10 @@ #define DLG_MOVE_TOP_CARDS_UNTIL_H #include +#include #include #include #include -#include #include class FilterString; @@ -15,7 +15,7 @@ class DlgMoveTopCardsUntil : public QDialog Q_OBJECT QLabel *exprLabel, *numberOfHitsLabel; - QLineEdit *exprEdit; + QComboBox *exprComboBox; QSpinBox *numberOfHitsEdit; QDialogButtonBox *buttonBox; QCheckBox *autoPlayCheckBox; @@ -25,10 +25,11 @@ class DlgMoveTopCardsUntil : public QDialog public: explicit DlgMoveTopCardsUntil(QWidget *parent = nullptr, - QString expr = QString(), + QStringList exprs = QStringList(), uint numberOfHits = 1, bool autoPlay = false); QString getExpr() const; + QStringList getExprs() const; uint getNumberOfHits() const; bool isAutoPlay() const; }; diff --git a/cockatrice/src/game/cards/abstract_card_item.cpp b/cockatrice/src/game/cards/abstract_card_item.cpp index 0b73d5489..f3e9b06db 100644 --- a/cockatrice/src/game/cards/abstract_card_item.cpp +++ b/cockatrice/src/game/cards/abstract_card_item.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, @@ -19,7 +18,7 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, Player *_owner, int _id) : ArrowTarget(_owner, parent), id(_id), name(_name), providerId(_providerId), tapped(false), facedown(false), - tapAngle(0), bgColor(Qt::transparent), realZValue(0) + tapAngle(0), bgColor(Qt::transparent), isHovered(false), realZValue(0) { setCursor(Qt::OpenHandCursor); setFlag(ItemIsSelectable); @@ -28,8 +27,6 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, connect(&SettingsCache::instance(), &SettingsCache::displayCardNamesChanged, this, [this] { update(); }); refreshCardInfo(); - setAcceptHoverEvents(true); - connect(&SettingsCache::instance(), &SettingsCache::roundCardCornersChanged, this, [this](bool _roundCardCorners) { Q_UNUSED(_roundCardCorners); @@ -168,7 +165,7 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS painter->restore(); } -void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * /*widget*/) +void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { painter->save(); @@ -177,7 +174,6 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * painter->setRenderHint(QPainter::Antialiasing, false); - bool isHovered = option->state.testFlag(QStyle::State_MouseOver); if (isSelected() || isHovered) { QPen pen; if (isHovered) @@ -220,24 +216,17 @@ void AbstractCardItem::setProviderId(const QString &_providerId) refreshCardInfo(); } -void AbstractCardItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +void AbstractCardItem::setHovered(bool _hovered) { - Q_UNUSED(event); + if (isHovered == _hovered) + return; - emit hovered(this); - setZValue(2000000004); - setScale(SettingsCache::instance().getScaleCards() ? 1.1 : 1); - setTransformOriginPoint(CARD_WIDTH / 2, CARD_HEIGHT / 2); - update(); -} - -void AbstractCardItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event); - - setZValue(realZValue); - setScale(1); - setTransformOriginPoint(0, 0); + if (_hovered) + processHoverEvent(); + isHovered = _hovered; + setZValue(_hovered ? 2000000004 : realZValue); + setScale(_hovered && SettingsCache::instance().getScaleCards() ? 1.1 : 1); + setTransformOriginPoint(_hovered ? CARD_WIDTH / 2 : 0, _hovered ? CARD_HEIGHT / 2 : 0); update(); } @@ -333,6 +322,11 @@ void AbstractCardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) event->accept(); } +void AbstractCardItem::processHoverEvent() +{ + emit hovered(this); +} + QVariant AbstractCardItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) { if (change == ItemSelectedHasChanged) { diff --git a/cockatrice/src/game/cards/abstract_card_item.h b/cockatrice/src/game/cards/abstract_card_item.h index cc13fe993..51b345267 100644 --- a/cockatrice/src/game/cards/abstract_card_item.h +++ b/cockatrice/src/game/cards/abstract_card_item.h @@ -24,6 +24,7 @@ protected: QColor bgColor; private: + bool isHovered; qreal realZValue; private slots: void pixmapUpdated(); @@ -85,6 +86,7 @@ public: return realZValue; } void setRealZValue(qreal _zValue); + void setHovered(bool _hovered); QString getColor() const { return color; @@ -100,6 +102,7 @@ public: return facedown; } void setFaceDown(bool _facedown); + void processHoverEvent(); void deleteCardInfoPopup() { emit deleteCardInfoPopup(name); @@ -111,9 +114,6 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override; void cacheBgColor(); - - void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; - void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; }; #endif diff --git a/cockatrice/src/game/cards/card_item.cpp b/cockatrice/src/game/cards/card_item.cpp index 44a7c0880..f5426a60f 100644 --- a/cockatrice/src/game/cards/card_item.cpp +++ b/cockatrice/src/game/cards/card_item.cpp @@ -469,6 +469,7 @@ bool CardItem::animationEvent() .translate(CARD_WIDTH_HALF, CARD_HEIGHT_HALF) .rotate(tapAngle) .translate(-CARD_WIDTH_HALF, -CARD_HEIGHT_HALF)); + setHovered(false); update(); return animationIncomplete; diff --git a/cockatrice/src/game/deckview/deck_view.cpp b/cockatrice/src/game/deckview/deck_view.cpp index 867788338..f1470a23f 100644 --- a/cockatrice/src/game/deckview/deck_view.cpp +++ b/cockatrice/src/game/deckview/deck_view.cpp @@ -164,6 +164,12 @@ void DeckView::mouseDoubleClickEvent(QMouseEvent *event) } } +void DeckViewCard::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + event->accept(); + processHoverEvent(); +} + DeckViewCardContainer::DeckViewCardContainer(const QString &_name) : QGraphicsItem(), name(_name), width(0), height(0) { setCacheMode(DeviceCoordinateCache); diff --git a/cockatrice/src/game/deckview/deck_view.h b/cockatrice/src/game/deckview/deck_view.h index 14c8f9da1..777298714 100644 --- a/cockatrice/src/game/deckview/deck_view.h +++ b/cockatrice/src/game/deckview/deck_view.h @@ -37,6 +37,7 @@ public: protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; + void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; }; class DeckViewCardDragItem : public AbstractCardDragItem diff --git a/cockatrice/src/game/game_scene.cpp b/cockatrice/src/game/game_scene.cpp index 53851e31a..e649bbb2a 100644 --- a/cockatrice/src/game/game_scene.cpp +++ b/cockatrice/src/game/game_scene.cpp @@ -253,6 +253,51 @@ void GameScene::processViewSizeChange(const QSize &newSize) } } +void GameScene::updateHover(const QPointF &scenePos) +{ + QList itemList = + items(scenePos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder, getViewTransform()); + + // Search for the topmost zone and ignore all cards not belonging to that zone. + CardZone *zone = 0; + for (int i = 0; i < itemList.size(); ++i) + if ((zone = qgraphicsitem_cast(itemList[i]))) + break; + + CardItem *maxZCard = 0; + if (zone) { + qreal maxZ = -1; + for (int i = 0; i < itemList.size(); ++i) { + CardItem *card = qgraphicsitem_cast(itemList[i]); + if (!card) + continue; + if (card->getAttachedTo()) { + if (card->getAttachedTo()->getZone() != zone) + continue; + } else if (card->getZone() != zone) + continue; + + if (card->getRealZValue() > maxZ) { + maxZ = card->getRealZValue(); + maxZCard = card; + } + } + } + if (hoveredCard && (maxZCard != hoveredCard)) + hoveredCard->setHovered(false); + if (maxZCard && (maxZCard != hoveredCard)) + maxZCard->setHovered(true); + hoveredCard = maxZCard; +} + +bool GameScene::event(QEvent *event) +{ + if (event->type() == QEvent::GraphicsSceneMouseMove) + updateHover(static_cast(event)->scenePos()); + + return QGraphicsScene::event(event); +} + void GameScene::timerEvent(QTimerEvent * /*event*/) { QMutableSetIterator i(cardsToAnimate); diff --git a/cockatrice/src/game/game_scene.h b/cockatrice/src/game/game_scene.h index e580f1e33..801acacee 100644 --- a/cockatrice/src/game/game_scene.h +++ b/cockatrice/src/game/game_scene.h @@ -30,9 +30,11 @@ private: QList> playersByColumn; QList zoneViews; QSize viewSize; + QPointer hoveredCard; QBasicTimer *animationTimer; QSet cardsToAnimate; int playerRotation; + void updateHover(const QPointF &scenePos); public: explicit GameScene(PhasesToolbar *_phasesToolbar, QObject *parent = nullptr); @@ -63,6 +65,7 @@ public slots: void rearrange(); protected: + bool event(QEvent *event) override; void timerEvent(QTimerEvent *event) override; signals: void sigStartRubberBand(const QPointF &selectionOrigin); diff --git a/cockatrice/src/game/player/player.cpp b/cockatrice/src/game/player/player.cpp index 3c31f1f83..8244f35c0 100644 --- a/cockatrice/src/game/player/player.cpp +++ b/cockatrice/src/game/player/player.cpp @@ -1443,19 +1443,20 @@ void Player::actMoveTopCardsUntil() { stopMoveTopCardsUntil(); - DlgMoveTopCardsUntil dlg(game, movingCardsUntilExpr, movingCardsUntilNumberOfHits, movingCardsUntilAutoPlay); + DlgMoveTopCardsUntil dlg(game, movingCardsUntilExprs, movingCardsUntilNumberOfHits, movingCardsUntilAutoPlay); if (!dlg.exec()) { return; } - movingCardsUntilExpr = dlg.getExpr(); + auto expr = dlg.getExpr(); + movingCardsUntilExprs = dlg.getExprs(); movingCardsUntilNumberOfHits = dlg.getNumberOfHits(); movingCardsUntilAutoPlay = dlg.isAutoPlay(); if (zones.value("deck")->getCards().empty()) { stopMoveTopCardsUntil(); } else { - movingCardsUntilFilter = FilterString(movingCardsUntilExpr); + movingCardsUntilFilter = FilterString(expr); movingCardsUntilCounter = movingCardsUntilNumberOfHits; movingCardsUntil = true; actMoveTopCardToPlay(); @@ -2386,6 +2387,7 @@ void Player::eventMoveCard(const Event_MoveCard &event, const GameEventContext & card->setFaceDown(event.face_down()); if (startZone != targetZone) { card->setBeingPointedAt(false); + card->setHovered(false); const QList &attachedCards = card->getAttachedCards(); for (auto attachedCard : attachedCards) { diff --git a/cockatrice/src/game/player/player.h b/cockatrice/src/game/player/player.h index 66f3089ed..26df3ae50 100644 --- a/cockatrice/src/game/player/player.h +++ b/cockatrice/src/game/player/player.h @@ -279,7 +279,7 @@ private: bool movingCardsUntil; QTimer *moveTopCardTimer; - QString movingCardsUntilExpr = {}; + QStringList movingCardsUntilExprs = {}; int movingCardsUntilNumberOfHits = 1; bool movingCardsUntilAutoPlay = false; FilterString movingCardsUntilFilter; diff --git a/cockatrice/src/game/zones/pile_zone.cpp b/cockatrice/src/game/zones/pile_zone.cpp index 62fa44a77..bf0f7920e 100644 --- a/cockatrice/src/game/zones/pile_zone.cpp +++ b/cockatrice/src/game/zones/pile_zone.cpp @@ -139,7 +139,6 @@ void PileZone::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/) void PileZone::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { if (!cards.isEmpty()) - emit cards[0]->hovered(cards[0]); - + cards[0]->processHoverEvent(); QGraphicsItem::hoverEnterEvent(event); } diff --git a/cockatrice/src/game/zones/stack_zone.cpp b/cockatrice/src/game/zones/stack_zone.cpp index 2f307085c..b597a9e81 100644 --- a/cockatrice/src/game/zones/stack_zone.cpp +++ b/cockatrice/src/game/zones/stack_zone.cpp @@ -66,26 +66,25 @@ void StackZone::handleDropEvent(const QList &dragItems, CardZone cmd.set_target_zone(getName().toStdString()); int index = 0; - if (cards.isEmpty()) { - index = 0; - } else { + + if (!cards.isEmpty()) { const auto cardCount = static_cast(cards.size()); const auto &card = cards.at(0); - if (card == nullptr) { - qCWarning(StackZoneLog) << "Attempted to move card from" << startZone->getName() << ", but was null"; - return; - } - index = qRound(divideCardSpaceInZone(dropPoint.y(), cardCount, boundingRect().height(), card->boundingRect().height(), true)); - } - if (startZone == this) { - const auto &dragItem = dragItems.at(0); - const auto &card = cards.at(index); - if (card != nullptr && dragItem != nullptr && card->getId() == dragItem->getId()) { - return; + // divideCardSpaceInZone is not guaranteed to return a valid index + // currently, so clamp it to avoid crashes. + index = qBound(0, index, cardCount - 1); + + if (startZone == this) { + const auto &dragItem = dragItems.at(0); + const auto &card = cards.at(index); + + if (card->getId() == dragItem->getId()) { + return; + } } } diff --git a/cockatrice/src/game/zones/stack_zone.h b/cockatrice/src/game/zones/stack_zone.h index 4ef06ea9a..38dee0aca 100644 --- a/cockatrice/src/game/zones/stack_zone.h +++ b/cockatrice/src/game/zones/stack_zone.h @@ -3,8 +3,6 @@ #include "select_zone.h" -inline Q_LOGGING_CATEGORY(StackZoneLog, "stack_zone"); - class StackZone : public SelectZone { Q_OBJECT diff --git a/cockatrice/src/settings/shortcuts_settings.h b/cockatrice/src/settings/shortcuts_settings.h index 0dcbcbad0..595932623 100644 --- a/cockatrice/src/settings/shortcuts_settings.h +++ b/cockatrice/src/settings/shortcuts_settings.h @@ -173,9 +173,13 @@ private: {"MainWindow/aWatchReplay", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Watch Replay..."), parseSequenceString(""), ShortcutGroup::Main_Window)}, - {"TabDeckEditor/aAnalyzeDeck", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Analyze Deck"), + {"TabDeckEditor/aAnalyzeDeck", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Analyze Deck (deckstats.net)"), parseSequenceString(""), ShortcutGroup::Deck_Editor)}, + {"TabDeckEditor/aAnalyzeDeckTappedout", + ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Analyze Deck (tappedout.net)"), + parseSequenceString(""), + ShortcutGroup::Deck_Editor)}, {"TabDeckEditor/aClearFilterAll", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Clear All Filters"), parseSequenceString(""), ShortcutGroup::Deck_Editor)}, @@ -193,9 +197,14 @@ private: {"TabDeckEditor/aEditTokens", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Edit Custom Tokens..."), parseSequenceString(""), ShortcutGroup::Deck_Editor)}, - {"TabDeckEditor/aExportDeckDecklist", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Export Deck"), - parseSequenceString(""), - ShortcutGroup::Deck_Editor)}, + {"TabDeckEditor/aExportDeckDecklist", + ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Export Deck (decklist.org)"), + parseSequenceString(""), + ShortcutGroup::Deck_Editor)}, + {"TabDeckEditor/aExportDeckDecklistXyz", + ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Export Deck (decklist.xyz)"), + parseSequenceString(""), + ShortcutGroup::Deck_Editor)}, {"TabDeckEditor/aIncrement", ShortcutKey(QT_TRANSLATE_NOOP("shortcutsTab", "Add Card"), parseSequenceString("+"), ShortcutGroup::Deck_Editor)}, diff --git a/oracle/oracle_en@source.ts b/oracle/oracle_en@source.ts index 433176c57..7c085344a 100644 --- a/oracle/oracle_en@source.ts +++ b/oracle/oracle_en@source.ts @@ -1,6 +1,29 @@ + + BetaReleaseChannel + + + Beta + + + + + No reply received from the release update server. + + + + + Invalid reply received from the release update server. + + + + + No reply received from the file update server. + + + IntroPage @@ -63,7 +86,8 @@ - Sets JSON file (%1) + Sets file (%1) + Sets JSON file (%1) @@ -247,7 +271,7 @@ OracleImporter - + Dummy set containing tokens @@ -283,6 +307,15 @@ + + PictureLoader + + + en + code for scryfall's language property, not available for all languages + + + SaveSetsPage @@ -357,6 +390,21 @@ + + ShortcutsSettings + + + Your configuration file contained invalid shortcuts. +Please check your shortcut settings! + + + + + The following shortcuts have been set to default: + + + + SimpleDownloadFilePage @@ -392,6 +440,34 @@ + + StableReleaseChannel + + + Default + + + + + No reply received from the release update server. + + + + + Invalid reply received from the release update server. + + + + + No reply received from the tag update server. + + + + + Invalid reply received from the tag update server. + + + UnZip @@ -537,6 +613,7 @@ i18n + English