Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fenêtre contenus Geotribu #157

Merged
merged 34 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d5d4436
Add RSS methods to get last X articles and/or RDP items
gounux Mar 13, 2024
0bb5c0d
Add geotribu toolbox
gounux Mar 13, 2024
a58d2ec
Ignore jb stuff
gounux Mar 13, 2024
93b1c61
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 13, 2024
a178432
Add JSON feed client
gounux Mar 14, 2024
56955d0
Add geotribu contents QDialog
gounux Mar 14, 2024
76bdb3f
Add plugin actions to open contents dialog
gounux Mar 14, 2024
7cfa153
Resolve conflicts
gounux Mar 14, 2024
60029e8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 14, 2024
ea3bde4
Fix illogic stuff
gounux Mar 14, 2024
0e0e3cf
Add context menu on content right clic
gounux Mar 18, 2024
d3d2494
Merge branch 'main' into feature/geotribu-toolbox
gounux Mar 18, 2024
14c7d56
Refactor url in browser opening
gounux Apr 13, 2024
78e6771
Fix QDesktopServices imports
gounux Apr 13, 2024
5e5dd90
Add docstring
gounux Apr 13, 2024
ae8f425
Fix open url calls
gounux Apr 13, 2024
912c16e
Delete empty file
gounux Apr 13, 2024
d80ed29
Fix post rdp form connect
gounux Apr 13, 2024
c812fe9
Add categories combobox and treewidget
gounux Apr 15, 2024
ced5979
Add docstrings
gounux Apr 15, 2024
423ef43
Edit icons
gounux Apr 15, 2024
9533caa
Change toolbar icon
gounux Apr 28, 2024
51d605d
Set tooltip on all columns
gounux Apr 28, 2024
4d98baa
Add authors combobox
gounux Apr 28, 2024
802977b
Add marker value
gounux Apr 28, 2024
b76ae01
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 28, 2024
2d8c5b8
Refactor opening in webviewer methods
gounux Apr 28, 2024
f6f7e99
Add article suggestion form
gounux Apr 28, 2024
10a37b2
Merge branch 'feature/geotribu-toolbox' of github.com:geotribu/qtribu…
gounux Apr 28, 2024
5d9b8e1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 28, 2024
7af3431
Merge branch 'main' into feature/geotribu-toolbox
gounux Apr 28, 2024
29a980d
ui: change donate icon
Guts Apr 28, 2024
2eeeee4
ui: change content browser icon
Guts Apr 28, 2024
ec9c839
ui: reduce dlg opacity
Guts Apr 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,6 @@ dmypy.json
qtribu/gui/*.db
*.qm
*.zip

# jb stuff
.idea
253 changes: 253 additions & 0 deletions qtribu/gui/dlg_contents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
from pathlib import Path
from typing import Callable, Dict, List

from qgis.core import QgsApplication
from qgis.PyQt import QtCore, QtWidgets, uic
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QDialog, QTreeWidgetItem, QWidget

from qtribu.__about__ import DIR_PLUGIN_ROOT
from qtribu.gui.form_article import ArticleForm
from qtribu.gui.form_rdp_news import RdpNewsForm
from qtribu.logic import RssItem
from qtribu.logic.json_feed import JsonFeedClient
from qtribu.toolbelt import PlgLogger, PlgOptionsManager
from qtribu.toolbelt.commons import open_url_in_browser, open_url_in_webviewer

MARKER_VALUE = "---"


class GeotribuContentsDialog(QDialog):
contents: Dict[int, List[RssItem]] = {}

def __init__(self, parent: QWidget = None):
"""
QDialog for geotribu contents

:param parent: parent widget or application
:type parent: QgsDockWidget
"""
super().__init__(parent)
self.log = PlgLogger().log
self.plg_settings = PlgOptionsManager()
self.json_feed_client = JsonFeedClient()
uic.loadUi(Path(__file__).parent / f"{Path(__file__).stem}.ui", self)
self.setWindowIcon(
QIcon(str(DIR_PLUGIN_ROOT / "resources/images/logo_green_no_text.svg"))
)

# buttons actions
self.form_article = None
self.form_rdp_news = None
self.submit_article_button.clicked.connect(self.submit_article)
self.submit_article_button.setIcon(
QgsApplication.getThemeIcon("mActionEditTable.svg")
)
self.submit_news_button.clicked.connect(self.submit_news)
self.submit_news_button.setIcon(
QgsApplication.getThemeIcon("mActionAllEdits.svg")
)
self.donate_button.clicked.connect(self.donate)
self.donate_button.setIcon(
QgsApplication.getThemeIcon("mIconCertificateTrusted.svg")
)

# search actions
self.search_line_edit.textChanged.connect(self.on_search_text_changed)

# authors combobox
self.authors_combobox.addItem(MARKER_VALUE)
for author in self.json_feed_client.authors():
self.authors_combobox.addItem(author)
self.authors_combobox.currentTextChanged.connect(self.on_author_changed)

# categories combobox
self.categories_combobox.addItem(MARKER_VALUE)
for cat in self.json_feed_client.categories():
self.categories_combobox.addItem(cat)
self.categories_combobox.currentTextChanged.connect(self.on_category_changed)

# tree widget initialization
self.contents_tree_widget.setHeaderLabels(
[
self.tr("Date"),
self.tr("Title"),
self.tr("Author(s)"),
self.tr("Categories"),
]
)
self.contents_tree_widget.itemClicked.connect(self.on_tree_view_item_click)

self.refresh_list(lambda: self.search_line_edit.text())
self.contents_tree_widget.expandAll()

def submit_article(self) -> None:
"""
Submit article action
Usually launched when clicking on button
"""
self.log("Opening form to submit an article")
if not self.form_article:
self.form_article = ArticleForm()
self.form_article.setModal(True)
self.form_article.finished.connect(self._post_form_article)
self.form_article.show()

def _post_form_article(self, dialog_result: int) -> None:
"""Perform actions after the article form has been closed.

:param dialog_result: dialog's result code. Accepted (1) or Rejected (0)
:type dialog_result: int
"""
if self.form_article:
# if accept button, save user inputs
if dialog_result == 1:
self.form_article.wdg_author.save_settings()
# clean up
self.form_article.deleteLater()
self.form_article = None

def submit_news(self) -> None:
"""
Submit RDP news action
Usually launched when clicking on button
"""
self.log("Opening form to submit a news")
if not self.form_rdp_news:
self.form_rdp_news = RdpNewsForm()
self.form_rdp_news.setModal(True)
self.form_rdp_news.finished.connect(self._post_form_rdp_news)
self.form_rdp_news.show()

def _post_form_rdp_news(self, dialog_result: int) -> None:
"""Perform actions after the GeoRDP news form has been closed.

:param dialog_result: dialog's result code. Accepted (1) or Rejected (0)
:type dialog_result: int
"""
if self.form_rdp_news:
# if accept button, save user inputs
if dialog_result == 1:
self.form_rdp_news.wdg_author.save_settings()
# clean up
self.form_rdp_news.deleteLater()
self.form_rdp_news = None

def donate(self) -> None:
"""
Donate action
Usually launched when clicking on button
"""
open_url_in_browser("https://geotribu.fr/team/sponsoring/")

def refresh_list(self, query_action: Callable[[], str]) -> None:
"""
Refresh content list as well as treewidget that list all contents

:param query_action: action to call for potentially filtering contents
:type query_action: Callable[[], str]
"""
# fetch last RSS items using JSONFeed
rss_contents = self.json_feed_client.fetch(query=query_action())
years = sorted(set([c.date_pub.year for c in rss_contents]), reverse=True)
self.contents = {
y: [c for c in rss_contents if c.date_pub.year == y] for y in years
}

# clean treeview items
self.contents_tree_widget.clear()

# populate treewidget
items = []
for i, year in enumerate(years):
# create root item for year
item = QTreeWidgetItem([str(year)])
# create contents items
for content in self.contents[year]:
child = self._build_tree_widget_item_from_content(content)
item.addChild(child)
items.append(item)
self.contents_tree_widget.insertTopLevelItems(0, items)
self.contents_tree_widget.expandAll()

@QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, int)
def on_tree_view_item_click(self, item: QTreeWidgetItem, column: int):
"""
Method called when a content item is clicked

:param item: item that is clicked by user
:type item: QTreeWidgetItem
:param column: column that is clicked by user
:type column: int
"""
# open URL of content (in column at index 4 which is not displayed)
url, title = item.text(4), item.text(1)
open_url_in_webviewer(url, title)

def on_search_text_changed(self) -> None:
"""
Method called when search box is changed
Should get search
"""
# do nothing if text is too small
current = self.search_line_edit.text()
if current == "":
self.refresh_list(lambda: current)
return
if len(current) < 3:
return
self.refresh_list(lambda: current)

def on_author_changed(self, value: str) -> None:
"""
Function triggered when author combobox is changed

:param value: text value of the selected author
:type value: str
"""
self.search_line_edit.setText("")
if value == MARKER_VALUE:
self.refresh_list(lambda: self.search_line_edit.text())
return
self.refresh_list(lambda: value)

def on_category_changed(self, value: str) -> None:
"""
Function triggered when category/tag combobox is changed

:param value: text value of the selected category
:type value: str
"""
self.search_line_edit.setText("")
if value == MARKER_VALUE:
self.refresh_list(lambda: self.search_line_edit.text())
return
self.refresh_list(lambda: value)

@staticmethod
def _build_tree_widget_item_from_content(content: RssItem) -> QTreeWidgetItem:
"""
Builds a QTreeWidgetItem from a RSS content item

:param content: content to generate item for
:type content: RssItem
"""
item = QTreeWidgetItem(
[
content.date_pub.strftime("%d %B"),
content.title,
",".join(content.author),
",".join(content.categories),
content.url,
]
)
for i in range(4):
item.setToolTip(i, content.abstract)
icon_file = (
"logo_orange_no_text"
if "Revue de presse" in content.title
else "logo_green_no_text"
)
icon = QIcon(str(DIR_PLUGIN_ROOT / f"resources/images/{icon_file}.svg"))
item.setIcon(1, icon)
return item
Loading
Loading