Port KNetAccess to KIO.
Change signature of Serializer::load, Serializer::loadCustomShape to use QString& instead of QString*
Change signature of Serializer::store: pass errorMsg
Remove unused function.
Port remaining Qt4 calls such as toAscii() or setAcceptsHoverEvents(),
Details
- Reviewers
ltoscano ouwerkerk - Group Reviewers
KDE Games - Commits
- R417:03262b5fd39e: Remove KDELibs4Support from KSudoku
Game can be played, tested loading and saving of current game.
Diff Detail
- Repository
- R417 KSudoku
- Lint
Lint Skipped - Unit
Unit Tests Skipped
Non-core sudokus are not loaded ("Unable to download file.") and then the program crash:
[KCrash Handler] #6 0x000055b4c9440908 in QVector<int>::size() const () #7 0x000055b4c944f6a0 in ksudoku::Puzzle::hasSolution() const () #8 0x000055b4c945fafb in ksudoku::WelcomeScreen::generatePuzzle() () #9 0x000055b4c9460ebd in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (ksudoku::WelcomeScreen::*)()>::call(void (ksudoku::WelcomeScreen::*)(), ksudoku::WelcomeScreen*, void**) () #10 0x000055b4c9460e4f in void QtPrivate::FunctionPointer<void (ksudoku::WelcomeScreen::*)()>::call<QtPrivate::List<>, void>(void (ksudoku::WelcomeScreen::*)(), ksudoku::WelcomeScreen*, void**) () #11 0x000055b4c9460d5b in QtPrivate::QSlotObject<void (ksudoku::WelcomeScreen::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) ()
There may be other issues.
Looks basically sane, don't have enough knowledge of the real inner workings of ksudoku to offer much more feedback than this on the proposed changes.
However we should probably take the time investigate a couple of follow-up changes:
- Certain serialisation/deserialisation functions may be consolidated into a couple of new shared functions to reduce the amount of duplicated logic there.
- There is a somewhat oddly located "globals.h" which is included all over the place and smells. What to do about this?
- KSudoku::updateShapesList() should be cleaned up, to not do hacky things with file paths when there is perfectly good Qt API for this already.
src/gui/ksudoku.cpp | ||
---|---|---|
899 | We should probably take the opportunity to tackle this here. QDir dest(destDir); dest.mkpath(dest.path()); // some of the following code elided... KIO::file_copy( Url, QUrl::fromLocalFile(dest.filePath(Url.fileName()))); | |
src/gui/serializer.cpp | ||
402 | The body of this function is basically the same as the next one which returns a Game instead. Maybe we should extract and consolidate the bulk of this to a new shared function? | |
465 | Is this safe? The docs for QTemporaryFile say:
Therefore: is it possible that two successive calls to .open() refer to different temporary files? Wouldn't it be better to have a const bool openedOK = tmpFile.open(); before the first check and then use that, as the QTemporaryFile is never closed in between? | |
721 | You should probably return false; here. | |
src/gui/symbols.cpp | ||
41 | According to the QChar docs the result of trying .toLatin1() on something that isn't 'Latin 1' will be 0. It's probably better to do a range check and if the character falls outside it return either VACANT or UNUSABLE. |
Looks like basically the same bug being tickled as with invalid QUrls. It seems to me there is a more fundamental memory management issue with Puzzles/Games that gets tickled if particular initialisation steps fail.
That is something we should investigate and fix more thoroughly later.
src/gui/serializer.cpp | ||
---|---|---|
402 | Maybe do refactoring in a separate patch? This needs to fix calls to these functions too then... But yeah, that sounds good. |
Slightly updated patch fixing most comments except for two. Maybe address them separately? As they change behaviour.
I've added a few more comments. Before landing this change please review the one on copyright in particular, as I'm not certain the way a few copyright statements were consolidated is sound (or rather that the implications are what was intended).
src/gui/ksudoku.cpp | ||
---|---|---|
5 | This change may not be sound: As I understand it:
Since the previous version did not claim copyright over 2013-2014, perhaps we should either leave both lines as is or maybe consolidate using Copyright 2012, 2015 instead? | |
src/gui/serializer.cpp | ||
402 | Agreed. | |
472 | Maybe I'm losing track here, but I think success is no longer relevant? Because the code now short-circuits by returning early, we only get here on success. The following if() check has therefore become redundant as well. |
src/gui/ksudoku.cpp | ||
---|---|---|
866 | Rechecking the code, this is part of KSudoku::loadCustomShapeFromPath(), but... is that method really used somewhere? |
src/gui/ksudoku.cpp | ||
---|---|---|
866 | Indeed, it looks like it is completely unused. ➜ src git:(frameworks) ✗ grep -R loadCustomShapeFromPath |
It does appear to be unused, OTOH its purpose appears to be to allow people to import new game variant types (shapes).
Logically that should have been wired up to a Get Hot New Stuff button/dialog for people to exchange custom puzzle variants.
Is that a feature we'd like to offer?
If I'm not mistaken, this is where the only call to that method was removed:
https://commits.kde.org/ksudoku/06cb470b229a49f714042f22094161a19ec26a73
It is not related to GHNS, thought, but about directly opening a local shape.
It is worth noting that the GHNS integration has been disabled at least since:
https://commits.kde.org/ksudoku/32e159a2a288fe9f991d85f36214c32917017010
(still in playground/games, so never worked in released versions by kde.org, only probably as standalone from sourceforge)
So: if you want to load a certain home-made Sudoku game, you can do it from File->Open (unless loadCustomShapeFromPath does something more). For more complex Sudoku, maybe yes, GHNS support could be useful, but wouldn't it be a different code anyway?
src/gui/serializer.cpp | ||
---|---|---|
408 | Is some feedback required here? | |
446 | Is some feedback required here? |
That is precisely what it does ;)
- It extracts data from an archive
- And installs this to the the writable location of XDG_DATA_DIRS underneath a "ksudoku" directory
- Then it calls updateShapesList();
updateShapesList(); is where we detect custom game variants by trawling through XDG_DATA_DIRS to find "ksudoku" directories with *.desktop files indicating custom game variants...
... My conclusion is that this function was meant for GHNS integration (or something similar to it) and for people to exchange custom puzzle types (game variants).
This is different from loading/saving an actual game or puzzle; this is about saving custom rules for *generating* custom puzzles.
EDIT to add:
Please note: I'm not categorically opposed to removing this functionality, but before we do so I'd like to be certain we are not removing something that we would consider the basis of a desirable feature. So to that end, perhaps the most relevant question is: is letting the user dynamically extend the repertoire of game variants by importing a package (archive) something we want to support in ksudoku? Specifically when we consider GHNS? Do we want to promote people designing custom sudoku variants or do we think so few people will bother it is better to support new variants via patches to the sudoku source (if at all)?
Discussed on IRC:
- GHNS manages the archives, so the code wouldn't be useful anyway;
- if QTemporaryFile fails, even without missing feedback, probably something worse is going on. Nevertheless this could be addressed later, and also in other functions (like the serialization ones).
src/gui/serializer.cpp | ||
---|---|---|
404 | This needs an if() guard: if(errorMsg) { *errorMsg = i18n("Unable to download file: URL is empty."); } | |
411 | This needs an if() guard: if(errorMsg) { *errorMsg = i18n("Unable to create temporary file."); } | |
419 | This needs an if() guard: if(errorMsg) { *errorMsg = i18n("Unable to download file."); } | |
450 | This needs an if() guard: if(errorMsg) { *errorMsg = i18n("Unable to create temporary file."); } | |
458 | This needs an if() guard: if(errorMsg) { *errorMsg = i18n("Unable to download file."); } | |
697 | Just make sure not to forget the if() guard! | |
710 | Just make sure not to forget the if() guard! |
I wonder if instead of all the if (), can't we just change the signatures to pass a real QString reference instead of a pointer?
Yes we can. In that case the callers need to be similar to:
const QString errorMsg; const auto ptr = doTheCall(..., errorMsg); if(!ptr) { KMessageBox .... }
Do we really need the auto pointer? (just to check if that would bump some requirement, maybe just for one usage is not needed)
Of course not: in each case the appropriate type should be used instead. ;)
For load() the specific check is a bit different:
const QString errorMsg; const Game game = doTheCall(... errorMsg) if(!game.puzzle()) { KMessageBox ... }
src/gui/ksudoku.cpp | ||
---|---|---|
648 | really last bit: the KMessageBox also here when !game.isValid(), as it happens later. |