Kexi/Junior Jobs/Web Browser Form Widget: Difference between revisions
No edit summary |
|||
(25 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
'''Status: done'''<br/> | |||
Web browser widget is a GUI element that displays web page and allows for navigation experience similar to regular web browsers. | Web browser widget is a GUI element that displays web page and allows for navigation experience similar to regular web browsers. | ||
Line 13: | Line 14: | ||
*Deliver extra "Web Browser" widget compatible with Kexi Forms. | *Deliver extra "Web Browser" widget compatible with Kexi Forms. | ||
*Deliver extra "Web Browser" report element compatible with Kexi Report. | *Deliver extra "Web Browser" report element compatible with Kexi Report. | ||
*Deliver "web" element as a flake shape for any Flake-capable app. | *<strike>Deliver "web" element as a flake shape for any Flake-capable app.</strike> | ||
==Requirements== | ==Requirements== | ||
Line 60: | Line 61: | ||
**For this Kexi's web widget would need to provide functions to users for saving snapshot of a web page in expected format (archived snapshot) | **For this Kexi's web widget would need to provide functions to users for saving snapshot of a web page in expected format (archived snapshot) | ||
**TODO: do some research for open formats for such a snapshot, find one for possible re-use, finc code for possible re-use | **TODO: do some research for open formats for such a snapshot, find one for possible re-use, finc code for possible re-use | ||
====Form Widget TODOs==== | |||
Requirements: | |||
<strike>*TODO 001: Improve back/forward buttons: use QPair<KGuiItem, KGuiItem> KStandardGuiItem::backAndForward() to get KGuiItem instances, then use KPushButton(KGuiItem) ctors to create buttons with standard icons and texts as in konqueror</strike> | |||
<strike>*TODO 002: Add "Stop" action after "Reload" button. Use KPushButton ctor with KStandardGuiItem::stop() argument; link the button to the stop action of QWebPage, to trigger action use QWebPage::triggerAction(QWebPage::Stop)</strike> | |||
*TODO 003: Use QWebHistory * QWebPage::history() const to track history buffer and add back/forward histories for back/forward buttons. | |||
<strike>*TODO 004: Look at history (QWebPage::history()) and disable/enable back/forward button when back/forward action is impossible/possible to trigger</strike> | |||
*TODO 005: Enable Reload/Stop/Back/Forward buttons only when there is content set | |||
<strike>*TODO 006: Add progress bar widget at the right hand of the web toolbar.</strike> | |||
<strike>**TODO 006.1: Use QWebPage::loadProgress ( int progress ) signal to update the progress bar</strike> | |||
<strike>**TODO 006.2: Show the bar when loadStarted() signal is emitted</strike> | |||
<strike>**TODO 006.3: Hide when loadFinished()</strike> | |||
<strike>**TODO 006.4: do not display the bar when there is no page loading process</strike> | |||
<strike>*TODO 007: Create zoomFactor property in WebBrowserWidget and then have method qreal WebBrowserWidget::zoomFactor() { return m_view->zoomFactor(); } and similarly for the setZoomFactor() setter. Since QWebView is a component of the WebBrowserWidget, we need to 'pull down' properties from QWebView by hand to WebBrowserWidget.</strike> | |||
<strike>*TODO 008: Add QString title property (read only, will be usable for scripting)</strike> | |||
<strike>*TODO 009: add bool modified property (read only, will be usable for scripting)</strike> | |||
<strike>*TODO 010: add QString selectedText property (read only, will be usable for scripting) </strike> | |||
<strike>*TODO 011: add const QIcon icon property (read only, will be usable for scripting) </strike> | |||
<strike>*TODO 012: add qreal textScale property (r/w, uses textSizeMultiplier/setTextSizeMultiplier methods)</strike> | |||
<strike>*TODO: 013: in WebBrowserWidget.cpp: Use m_view->forward() directly, without history() and without checking any conditions (these are checked already by Qt)</strike> | |||
<strike>*TODO 014: in WebBrowserWidget.cpp: Code clarity note: always use static connect( const QObject * sender, const char * signal, const | |||
QObject * receiver, const char * method) i.e. with 4 arguments to avoid mistakes. So fix 7 connect() lines.</strike> | |||
<strike>*TODO 015: in WebBrowserWidget.cpp: Code simplicity note: you do not need to add slots to connect signal to signal, e.g. connect(m_backButton, SIGNAL(clicked()), this, SIGNAL(goBack()))</strike> | |||
<strike>*TODO 016: Improvement for the toolbar: implement updateToolbar() in the toolbar class:</strike> | |||
<strike>inside: call setEnabled(history()->canGoBack()) for back button, do similarly for the forward button.</strike> | |||
*TODO 017: Improvement for the toolbar: add url bar of class [http://api.kde.org/4.0-api/kdelibs-apidocs/kio/html/classKUrlComboBox.html KUrlComboCox] | |||
**TODO 017.1: Update contents of the bar in updateToolbar() defined in point whenever your current url changes (in setUrl() and for signal linkClicked()) | |||
*TODO 018: after moving to another record on the form (using record navigator), browser's history should be cleared. Otherwise clicking Back/Forward button switches to previously visited pages unrelated to the current record's URL value. This means, clear history in WebBrowserWidget::setValueInternal(). See QWebHistory for info on how to clear browser's history. | |||
====Report Element TODOs==== | |||
*(by jstaniek) user has no way to know the report page has been loaded. Perhaps some feedback like QProgressBar in the record navigator bar could be enough. Use QProgressBar::setRange(0, 0) to avoid setting scale (we do not know scale). | |||
*Add '''bool scaledContents''' property; if set the contents of the web page are scaled regardles of the zoom level | |||
*Add '''qreal zoomFactor''' property | |||
===Kexi Report Element=== | ===Kexi Report Element=== | ||
*Expose the web to Kexi Reports via the KoReports official API for elements | *Expose the web to Kexi Reports via the KoReports official API for elements | ||
*The element should inserted into a separate report plugin | <strike>*The element should inserted into a separate report plugin</strike> | ||
===Flake Shape=== | ===Flake Shape=== | ||
Line 83: | Line 125: | ||
==After implementation== | ==After implementation== | ||
TODO: we have to update calligra/README.PACKAGERS document to indicate that the plugin must be packaged separately to avoid hard dependency on QtWebKit | TODO: we have to update [http://quickgit.kde.org/index.php?p=calligra.git&a=blob_plain&f=README.PACKAGERS calligra/README.PACKAGERS] document to indicate that the plugin must be packaged separately to avoid hard dependency on QtWebKit | ||
==Development== | ==Development== |
Latest revision as of 21:13, 17 February 2013
Status: done
Web browser widget is a GUI element that displays web page and allows for navigation experience similar to regular web browsers.
Proposed and mentored by Jstaniek 22:37, 17 February 2011 (UTC)
See also: Map Browser Form Widget Junior Job.
Definitions
- See Definitions
The Goals
- Deliver extra "Web Browser" widget compatible with Kexi Forms.
- Deliver extra "Web Browser" report element compatible with Kexi Report.
Deliver "web" element as a flake shape for any Flake-capable app.
Requirements
Kexi Form Widget
- Design and implement the widget and provide it through separate factory using the kexi widget factory API
- All the code should be stored in this tree in calligra/:
kexi/plugins/forms/widgets/webbrowser/CMakeLists.txt kexi/plugins/forms/widgets/webbrowser/WebBrowserFactory.h kexi/plugins/forms/widgets/webbrowser/WebBrowserFactory.cpp kexi/plugins/forms/widgets/webbrowser/WebBrowserWidget.h kexi/plugins/forms/widgets/webbrowser/WebBrowserWidget.cpp kexi/plugins/forms/widgets/webbrowser/kformdesigner_webfactory.desktop
- To implement the widget derive from QWebView class, part of the QtWebKit module
- Do not export the any class, just export the plugin using K_EXPORT_KEXI_FORM_WIDGET_FACTORY_PLUGIN(WebWidgetFactory, webbrowser) in WebBrowserFactory.cpp
- Class name of the widget should be KexiWebBrowser
- User-visible name of the widget should be "Web Browser"
- Name prefix of the widget should be "web"
- User-visible description of the widget should be "Web browser"
- class name of the factory should be WebBrowserFactory, and the name passed to the KFormDesigner::WidgetFactory constructor should be "webbrowser"
- provide translations (i18n()) for all user-visible property names in the factory constructor (see StdWidgetFactory for reference), e.g.
m_propDesc["url"] = i18n("Address");
- the build should be allowed for webbrowser/CMakeLists.txt only if the QtWebKit module is present, try to check it using cmake; usually the QtWebKit is present but it is not always the case
- Testing: proper implementation should after installing provide web browser widget within the widget palette of "Form Design" tab. Inserting the web browser widget should show it, changing properties through the property editor should work, switching to data view mode should display the browser properly and the browser's contents (web page) should be available for zooming (using the wheel) and panning (using the mouse move). All these mouse actions should be disabled on the widget in design mode, so the user is able to drag and drop the widget within the form.
Hints
- The directory of the forms framework is kexi/kformeditor/, standard factory is implemented in kexi/formeditor/
- The widget factory API is provided by the KFormDesigner::WidgetFactory base class. Inherit it as StdWidgetFactory does.
- You can test QWebView widget in Qt Designer too.
Data-awarness
- Data binding: the "url" property should be made available for data bindings, what would make the web browser widget data-aware
- This means that the web widget accept data source binding as the "text box" widget in Kexi Forms does.
- The web widget should bind (two-way: read, write) the data source (of type string) to the url property
- Look at KexiDBCheckBox code which binds to a column of database (of boolean type): kexi/plugins/forms/widgets/kexidbcheckbox.h to see what to inherit and what to implement to enable bindings
- When data-awarness is properly declared in the web widget's class, Kexi will recognize that automatically and the column binding GUI will appear on the right-hand pane whenever web widget is selected in Kexi Form Designer.
- Note: to use the data-aware interfaces you need to move the webbrowser/ directory out of the formeditor/factories/ directory to kexi/plugins/forms/widgets/ directory, otherwise it won't compile. Basically, code in kexi/plugins/forms/ depends on kexi/formeditor/, not the other way round. Sorry about that. Do not forget to provide proper kformdesigner_webfactory.desktop and install it, as other form widget factories do.
Data-awarness - "content" extension
(initiated by Adam Pigg, explained by Jstaniek 20:05, 20 June 2011 (UTC))
- Data binding, second option: the "content" property should be made available for data bindings
- it is of string type and sets the html markup of the page using void QWebView::setHtml( const QString & html, const QUrl & baseUrl = QUrl() )
- TODO: the method has baseUrl argument: external objects such as stylesheets or images referenced in the HTML document are located relative to baseUrl. But this means the "content" property would not define all the content, media files, code and style sheets have to be provided.
- Possible solution: have the full content (compressed snapshot of a web page or pages in a BLOB field)
- For this Kexi's web widget would need to provide functions to users for saving snapshot of a web page in expected format (archived snapshot)
- TODO: do some research for open formats for such a snapshot, find one for possible re-use, finc code for possible re-use
Form Widget TODOs
Requirements:
*TODO 001: Improve back/forward buttons: use QPair<KGuiItem, KGuiItem> KStandardGuiItem::backAndForward() to get KGuiItem instances, then use KPushButton(KGuiItem) ctors to create buttons with standard icons and texts as in konqueror
*TODO 002: Add "Stop" action after "Reload" button. Use KPushButton ctor with KStandardGuiItem::stop() argument; link the button to the stop action of QWebPage, to trigger action use QWebPage::triggerAction(QWebPage::Stop)
- TODO 003: Use QWebHistory * QWebPage::history() const to track history buffer and add back/forward histories for back/forward buttons.
*TODO 004: Look at history (QWebPage::history()) and disable/enable back/forward button when back/forward action is impossible/possible to trigger
- TODO 005: Enable Reload/Stop/Back/Forward buttons only when there is content set
*TODO 006: Add progress bar widget at the right hand of the web toolbar.
**TODO 006.1: Use QWebPage::loadProgress ( int progress ) signal to update the progress bar
**TODO 006.2: Show the bar when loadStarted() signal is emitted
**TODO 006.3: Hide when loadFinished()
**TODO 006.4: do not display the bar when there is no page loading process
*TODO 007: Create zoomFactor property in WebBrowserWidget and then have method qreal WebBrowserWidget::zoomFactor() { return m_view->zoomFactor(); } and similarly for the setZoomFactor() setter. Since QWebView is a component of the WebBrowserWidget, we need to 'pull down' properties from QWebView by hand to WebBrowserWidget.
*TODO 008: Add QString title property (read only, will be usable for scripting)
*TODO 009: add bool modified property (read only, will be usable for scripting)
*TODO 010: add QString selectedText property (read only, will be usable for scripting)
*TODO 011: add const QIcon icon property (read only, will be usable for scripting)
*TODO 012: add qreal textScale property (r/w, uses textSizeMultiplier/setTextSizeMultiplier methods)
*TODO: 013: in WebBrowserWidget.cpp: Use m_view->forward() directly, without history() and without checking any conditions (these are checked already by Qt)
*TODO 014: in WebBrowserWidget.cpp: Code clarity note: always use static connect( const QObject * sender, const char * signal, const
QObject * receiver, const char * method) i.e. with 4 arguments to avoid mistakes. So fix 7 connect() lines.
*TODO 015: in WebBrowserWidget.cpp: Code simplicity note: you do not need to add slots to connect signal to signal, e.g. connect(m_backButton, SIGNAL(clicked()), this, SIGNAL(goBack()))
*TODO 016: Improvement for the toolbar: implement updateToolbar() in the toolbar class:
inside: call setEnabled(history()->canGoBack()) for back button, do similarly for the forward button.
- TODO 017: Improvement for the toolbar: add url bar of class KUrlComboCox
- TODO 017.1: Update contents of the bar in updateToolbar() defined in point whenever your current url changes (in setUrl() and for signal linkClicked())
- TODO 018: after moving to another record on the form (using record navigator), browser's history should be cleared. Otherwise clicking Back/Forward button switches to previously visited pages unrelated to the current record's URL value. This means, clear history in WebBrowserWidget::setValueInternal(). See QWebHistory for info on how to clear browser's history.
Report Element TODOs
- (by jstaniek) user has no way to know the report page has been loaded. Perhaps some feedback like QProgressBar in the record navigator bar could be enough. Use QProgressBar::setRange(0, 0) to avoid setting scale (we do not know scale).
- Add bool scaledContents property; if set the contents of the web page are scaled regardles of the zoom level
- Add qreal zoomFactor property
Kexi Report Element
- Expose the web to Kexi Reports via the KoReports official API for elements
*The element should inserted into a separate report plugin
Flake Shape
Update (jstaniek, August 2011): web flake shape is already part of Calligra so this subtask is dropped.
- expose the maps as a flake shape (for any Flake-capable app)
- add support for so called Replacement Images, compare:
"The OpenDocument Format contains a great idea: so called Replacement Images. The idea is that when you have an embedded object in an ODF file, perhaps not all applications can handle that particular kind of embedded object. So in addition to the object itself, a saving application has the option to save an extra image of the object alongside of the object itself. That way, the loading application can at least show the contents of the object to the user even if he or she cannot edit the object. " more
After implementation
TODO: we have to update calligra/README.PACKAGERS document to indicate that the plugin must be packaged separately to avoid hard dependency on QtWebKit
Development
This is a notepad for development
Coding standards
Assigned Developers
- Shreya Pandit (shreya.pandit25 at gmail.com) within Season of KDE
Source Code Location
The development happens in the calligra repository: [2], branch kexi-web-Shreya. Once it's ready for review, it will be provided for review at http://git.reviewboard.kde.org. Then the code will find its wat to the master branch of calligra.