Details
- Reviewers
drosca - Commits
- R875:dacf9939baa2: Add QML Extensions API
Diff Detail
- Repository
- R875 Falkon
- Branch
- patch-qml-api-only
- Lint
No Linters Available - Unit
No Unit Test Coverage - Build Status
Buildable 1669 Build 1687: arc lint + arc unit
src/lib/history/history.h | ||
---|---|---|
72 | There is already indexesFromTimeRange that you can use instead of adding new method. Also, timestamp is integer and not double. | |
src/lib/plugins/qml/api/cookies/qmlcookies.cpp | ||
30 | This is completely wrong, it can actually lead to invalid results now due to possibility of this reference always having the same address (because it is on stack). | |
src/lib/plugins/qml/api/events/qmlkeyevent.h | ||
73 | Rename to clear() | |
src/lib/plugins/qml/api/events/qmlmouseevent.cpp | ||
34 | Don't use C-style casts, use static_cast<int> or int(value) | |
src/lib/plugins/qml/api/events/qmlqzobjects.h | ||
20 | This is not system include | |
src/lib/plugins/qml/api/history/qmlhistory.cpp | ||
44 | You can just declare result as const instead of using qAsConst. | |
src/lib/plugins/qml/api/menus/qmlaction.cpp | ||
65 | You should be able to get engine with qmlEngine(this) instead of needing to pass the plugin path manually. |
src/lib/history/history.h | ||
---|---|---|
72 | Do you want it like this - if (!map.contains(QSL("startTime")) || !map.contains(QSL("endTime"))) { qWarning() << "Error:" << "wrong arguments passed to" << __FUNCTION__; return; } const qlonglong startTime = map.value(QSL("startTime")).toLongLong(); const qlonglong endTime = map.value(QSL("endTime")).toLongLong(); QSqlQuery query(SqlDatabase::instance()->database()); query.prepare(QSL("DELETE FROM history WHERE date BETWEEN ? AND ?")); query.bindValue(0, startTime); query.bindValue(1, endTime); query.exec(); } Here deleteRange is removed from history.h. Also if indexFromTimeRange is used then it wil have to execute query twice (once to get the list of ids to remove and other to remove the ids) |
src/lib/history/history.h | ||
---|---|---|
72 |
That's fine, this won't be called often. |
src/lib/history/history.h | ||
---|---|---|
72 | Sorry, but your comment is unclear to me, do you mean the snipped I posted is fine or to delete the ids by first using indexFromTimeRange? |
src/lib/history/history.h | ||
---|---|---|
72 | Delete the ids by first using indexFromTimeRange. |
src/lib/app/mainapplication.h | ||
---|---|---|
79 ↗ | (On Diff #38847) | I have thinked over it and I am unable to find a good solution to where to include it outside of mainapplication, since its used in both qmltabs and qmlwindows. Do you have some specific location in mind? |
src/lib/app/mainapplication.h | ||
---|---|---|
79 ↗ | (On Diff #38847) | For example add new class that will hold all static data, including everything else from all *Data classes, so that way there is only one static data class. |
src/lib/plugins/qml/api/bookmarks/qmlbookmarks.cpp | ||
---|---|---|
233 ↗ | (On Diff #39399) | Why did you change the for loop? Unless there is a reason, don't use for(int i = 0, ....) |
src/lib/plugins/qml/api/browseraction/qmlbrowseraction.h | ||
164 ↗ | (On Diff #39399) | Missing initialization |
src/lib/plugins/qml/api/cookies/qmlcookie.h | ||
23 ↗ | (On Diff #39399) | This should not be needed. |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
31 | The question still stands? If it doesn't get to the QML engine, it will leak. Example where it may happen (I did not test it myself, so plase check) is if you instantiate Falkon.ExtensionScheme { } item in QML but don't create the requestStarted handler (eg. no onRequestStarted code). | |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
28 | ? | |
src/lib/plugins/qml/api/menus/qmlaction.h | ||
33 ↗ | (On Diff #39399) | Why? You can get the QmlEngine pointer with qmlEngine(QObject*) function that is called on any QObject that was created by the engine. |
src/lib/plugins/qml/api/settings/qmlsettings.cpp | ||
32 | Why not just create QSettings with correct parent? | |
src/lib/plugins/qml/api/sidebar/qmlsidebar.cpp | ||
136 ↗ | (On Diff #39399) | This seems like the same code for handling icon loading is pasted on multiple places, should be extracted to function. |
src/lib/plugins/qml/api/sidebar/qmlsidebar.h | ||
120 ↗ | (On Diff #39399) | init |
src/lib/plugins/qml/api/tabs/qmltabs.cpp | ||
323 ↗ | (On Diff #39399) | Again, use stl iterators. This creates temporary list only to iterate over it, that's not needed at all. |
src/lib/plugins/qml/api/userscript/qmluserscripts.h | ||
87 ↗ | (On Diff #39399) | QList<QObject*> |
src/lib/plugins/qml/qmlplugin.h | ||
29 ↗ | (On Diff #39399) | Just make it static variable in loadPlugin function as it is not used anywhere else. |
src/lib/plugins/qml/qmlplugininterface.cpp | ||
42 ↗ | (On Diff #39399) | Why this at all? It should just use staticData->getTab! |
src/lib/plugins/qml/qmlstaticdata.cpp | ||
36 ↗ | (On Diff #39399) | There should be no whitespace before/after increment, so it should be foo++. |
src/lib/plugins/qml/qmlstaticdata.h | ||
62 ↗ | (On Diff #39399) | remove |
66 ↗ | (On Diff #39399) | It should be something like static QmlStaticData* instance() member function and not adding staticData to global namespace. |
Again, if I say to change one thing there and it is also in multiple other places, please change it everywhere.
Also you marked as done some comments which were clearly not done at all, so in those cases please at least write reply why do you consider it done.
src/lib/plugins/qml/qmlplugins.cpp | ||
---|---|---|
66 | Move the url to variable so it isn't copied thousand times. | |
95 | Most (all?) these singletons should be shared with multiple engines (=multiple loaded qml extensions). I think it creates new instance for every engine right now. |
src/lib/plugins/qml/api/bookmarks/qmlbookmarks.cpp | ||
---|---|---|
233 ↗ | (On Diff #39399) | Doesn't for(BookmarkItem *bookmarkitem : items) detaches the list? Should I use QListIterator<BookmarkItem *> it(items) ? |
src/lib/plugins/qml/api/bookmarks/qmlbookmarks.cpp | ||
---|---|---|
233 ↗ | (On Diff #39399) | No, because items is const. As long as the Qt container is const, you can use C++11 for. |
src/lib/plugins/qml/api/browseraction/qmlbrowseraction.h | ||
---|---|---|
164 ↗ | (On Diff #39399) | Its not designed to be initialized explicitly, but checks must be added in setIcon where it can be null eq in auto qmlEngine = qobject_cast<QmlEngine*>(m_popup->creationContext()->engine()); |
src/lib/plugins/qml/api/browseraction/qmlbrowseraction.h | ||
---|---|---|
164 ↗ | (On Diff #39399) | Sorry, that was meant for m_locations, one line above. |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
37 | Its is created per engine, so shouldn't it work? |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
37 | Did you try? |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
---|---|---|
28 | Its not the extension root path which is known by QmlEngine, but the path of entry point of the qml plugin. The code here gets the plugin root path given the path of entry file. |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
---|---|---|
28 | I don't understand. Please show me example how does the "extension root path" and "path of entry point" differs and why does it matter here? |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
---|---|---|
28 | Entry path and root path differs because in metadata.desktop we can specify entry file as - X-Falkon-EntryPoint=demo/main.qml, which will point to the main.qml file within the demo directory of plugin (root-dir-of-plugin/demo/main.qml) now the extensionpath set in the QmlEngine is the entry point path. Also you told previously that the paths must be relative to root irrespective of the qml file, so I added this. For example in this case - |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
---|---|---|
28 |
This is entry point and is only needed for creating the QML component, and is never used again.
Still I don't see the problem. This path is what you have stored in QmlEngine (and if you don't, you should!) and only this path is needed to resolve relative paths. That means this is "basePath" of the extension which will be used for resolving all relative paths (including what you get in X-Falkon-EntryPoint). This also means that the only path that needs to be absolute is this, everything else can be stored as relative path and resolved against it. |
src/lib/plugins/qml/api/menus/qmlaction.h | ||
---|---|---|
33 ↗ | (On Diff #39399) | No, the menus and action are not created by the engine, but are created (menu) in qmlplugininterface (and action in menu). But it seem to me that they leak? Should I set the parent of the qmlMenu as qmlpluginInterface or store them in a list which will be deleted in the destructor of qmlplugininterface? |
src/lib/plugins/qml/api/menus/qmlaction.h | ||
---|---|---|
33 ↗ | (On Diff #39399) | You don't need to get the QmlEngine pointer in constructor, and later you call QmlEngine::newQObject on it, so after that you should get the correct pointer from qmlEngine(QObject*) I think. |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
31 ↗ | (On Diff #39399) | Well, now it doesn't leak but it will only be released on exiting application, so it's effectively the same problem and you didn't fix anything. |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
30 ↗ | (On Diff #39399) | Why? This shouldn't be needed. |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
27 ↗ | (On Diff #39399) | What does this do? |
src/lib/plugins/qml/api/tabs/qmltabs.cpp | ||
275 ↗ | (On Diff #39399) | If you know beforehand how big the resulting list will be, you should call reserve. |
325 ↗ | (On Diff #39399) | Please use STL iterators. auto h = QmlStaticData::instance().windowIdHash(); for (auto it = h.constBegin(); it != h.constEnd(); ++it) { } /// or cbegin()/cend() |
src/lib/plugins/qml/api/windows/qmlwindow.cpp | ||
39 ↗ | (On Diff #39399) | This is equivalent to return QmlStaticData::instance().windowIdHash().value(m_window, -1); |
src/lib/plugins/qml/qmlplugin.cpp | ||
33 ↗ | (On Diff #39399) | This is not member variable so it shouldn't have m_ prefix. It shouldn't have any prefix. |
66 ↗ | (On Diff #39399) | You are casting twice here, data.value<QmlPluginLoader*>() already gives you QmlPluginLoader* |
src/lib/plugins/qml/qmlplugins.cpp | ||
69 ↗ | (On Diff #39399) | const |
src/lib/plugins/qml/qmlstaticdata.cpp | ||
141 ↗ | (On Diff #39399) | Why it isn't created on heap and parented to QmlStaticData? That way you don't need to manually specify CppOwnership. Ideally you should only specify ownership explicitly only when there is no better way. |
src/lib/plugins/qml/qmlstaticdata.h | ||
52 ↗ | (On Diff #39399) | static QmlStaticData &instance(); |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
31 ↗ | (On Diff #39399) | QmlEngine::newQObject as you already used in other places. But first test if it works as expected. |
src/lib/plugins/qml/api/events/qmlkeyevent.cpp | ||
---|---|---|
26 ↗ | (On Diff #39399) | You already call newQObject on all events, which makes them JavaScriptOwnership, so it isn't needed here. |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
32 ↗ | (On Diff #39399) | You can still use the QmlWebEngineUrlRequestJob pointer in signal, not QJSValue. |
src/lib/plugins/qml/api/fileutils/qmlfileutils.cpp | ||
38 ↗ | (On Diff #39399) | Why does it use QUrl? You can just do path + / + filePath and then QDir::cleanPath. |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
27 ↗ | (On Diff #39399) | And is that really needed? |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | Then it needs to make the jsvalue return of engine->newQObject as unused? something like - |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
27 ↗ | (On Diff #39399) | You mean something like Falkon.I18n.setLocale() on qml side? |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | No, just calling qmlEngine(this)->newQObject(request); should be enough. Did you actually try it? |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
27 ↗ | (On Diff #39399) | No, on the cpp side so when/if there is a support for switching languages it is easy to implement. Also translations functions should be added to global namespace, so they are accessible with just i18n/i18np without Falkon namespace. |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | Yes I tried. But qmlEngine(this)->newQObject(request); returns QJSValue - so its need to be changed to the signal paramater |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | Tried how? Did you change the code so it just calls qmlEngine(this)->newQObject(request); and then checked if that object gets correctly garbage collected by engine (deleted)? |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | connect(m_schemeHandler, &QmlExtensionSchemeHandler::_requestStarted, this, [this](QWebEngineUrlRequestJob *job) { QmlWebEngineUrlRequestJob *request = new QmlWebEngineUrlRequestJob(job); emit requestStarted(qmlEngine(this)->newQObject(request)); }); Or did you meant the snippet which I send in previous comment? |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | I meant what I told you to do, just call qmlEngine(this)->newQObject(request); connect(m_schemeHandler, &QmlExtensionSchemeHandler::_requestStarted, this, [this](QWebEngineUrlRequestJob *job) { QmlWebEngineUrlRequestJob *request = new QmlWebEngineUrlRequestJob(job); qmlEngine(this)->newQObject(request); emit requestStarted(request); }); |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
27 ↗ | (On Diff #39399) |
Sorry, I didn't understood this. Can you please elaborate.
using engine contextProperty? or is there some other way? |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
27 ↗ | (On Diff #39399) | Something like setlocale(QLocale::system().name()) Yes, contextProperty is fine if it works. |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
27 ↗ | (On Diff #39399) | No, context property is not working. It seem like there is no way to make a method global (max is object.method ex i18n.i18n), is there some way? I couldn't found any in the documentation. |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
27 ↗ | (On Diff #39399) | This can be similar to qsTr in Qt source, something like -
Should I change I18n so that i18n adds to global namespace or leave it now? Or is there some better solution |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
---|---|---|
27 ↗ | (On Diff #39399) |
Is that an issue?
I don't see any problem with this. If it works, please do it this way. |
src/lib/plugins/qml/api/extensionscheme/qmlextensionscheme.cpp | ||
---|---|---|
32 ↗ | (On Diff #39399) | I asked you to test how it works, so what are your findings? I'm not myself sure if this is actually correct, as you may need to pass the QJSValue to QML (as you did) to not be garbage collected if the reference is held on QML side. |
src/lib/plugins/qml/api/i18n/qmli18n.cpp | ||
27 ↗ | (On Diff #39399) | I don't think it should call setlocale at all, that's QLocale job. Take a look how is this done in ki18n framework. |
src/lib/plugins/qml/qmlpluginloader.cpp | ||
74 ↗ | (On Diff #39399) | QStringLiteral |