MythTV master
bookmarkmanager.cpp
Go to the documentation of this file.
1// C++
2#include <algorithm>
3#include <iostream>
4
5// Qt
6#include <QString>
7
8// MythTV
17
18// mythbrowser
19#include "bookmarkmanager.h"
20#include "bookmarkeditor.h"
21#include "browserdbutil.h"
22#include "mythbrowser.h"
23#include "mythflashplayer.h"
24
25// ---------------------------------------------------
26
28{
29 // Load the theme for this screen
30 bool foundtheme = LoadWindowFromXML("browser-ui.xml", "browserconfig", this);
31 if (!foundtheme)
32 return false;
33
34 m_titleText = dynamic_cast<MythUIText *> (GetChild("title"));
35
36 if (m_titleText)
37 m_titleText->SetText(tr("MythBrowser Settings"));
38
39 m_commandEdit = dynamic_cast<MythUITextEdit *> (GetChild("command"));
40 m_zoomEdit = dynamic_cast<MythUITextEdit *> (GetChild("zoom"));
41 m_enablePluginsCheck = dynamic_cast<MythUICheckBox *> (GetChild("enablepluginscheck"));
42
43 m_descriptionText = dynamic_cast<MythUIText *> (GetChild("description"));
44
45 m_okButton = dynamic_cast<MythUIButton *> (GetChild("ok"));
46 m_cancelButton = dynamic_cast<MythUIButton *> (GetChild("cancel"));
47
49 {
50 LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
51 return false;
52 }
53
54 m_commandEdit->SetText(gCoreContext->GetSetting("WebBrowserCommand",
55 "Internal"));
56
57 m_zoomEdit->SetText(gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0"));
58
59 int setting = gCoreContext->GetNumSetting("WebBrowserEnablePlugins", 1);
60 if (setting == 1)
62
65
71
73
75
76 return true;
77}
78
80{
81 float zoom = m_zoomEdit->GetText().toFloat();
82 zoom = std::clamp(zoom, 0.3F, 5.0F);
83 gCoreContext->SaveSetting("WebBrowserZoomLevel", QString("%1").arg(zoom));
84 gCoreContext->SaveSetting("WebBrowserCommand", m_commandEdit->GetText());
85 int checkstate = 0;
87 checkstate = 1;
88 gCoreContext->SaveSetting("WebBrowserEnablePlugins", checkstate);
89
90 Close();
91}
92
93bool BrowserConfig::keyPressEvent(QKeyEvent *event)
94{
95 if (GetFocusWidget()->keyPressEvent(event))
96 return true;
97
99}
100
102{
104 return;
105
106 QString msg = "";
108 {
109 msg = tr("This is the command that will be used to show the web browser. "
110 "Use 'Internal' to use the built in web browser'. "
111 "%ZOOM% and %URL% will be replaced with the zoom level and URL list.");
112 }
113 else if (GetFocusWidget() == m_zoomEdit)
114 {
115 msg = tr("This is the default text size that will be used. Valid values "
116 "for the Internal browser are from 0.3 to 5.0 with 1.0 being "
117 "normal size less than 1 is smaller and greater than 1 is "
118 "larger than normal size.");
119 }
121 {
122 msg = tr("If checked this will enable browser plugins if the 'Internal' "
123 "browser is being used.");
124 }
125 else if (GetFocusWidget() == m_cancelButton)
126 {
127 msg = tr("Exit without saving settings");
128 }
129 else if (GetFocusWidget() == m_okButton)
130 {
131 msg = tr("Save settings and Exit");
132 }
133
135}
136
137// ---------------------------------------------------
138
140{
141 // Load the theme for this screen
142 bool foundtheme = LoadWindowFromXML("browser-ui.xml", "bookmarkmanager", this);
143 if (!foundtheme)
144 return false;
145
146 m_groupList = dynamic_cast<MythUIButtonList *>(GetChild("grouplist"));
147 m_bookmarkList = dynamic_cast<MythUIButtonList *>(GetChild("bookmarklist"));
148
149 // optional text area warning user hasn't set any bookmarks yet
150 m_messageText = dynamic_cast<MythUIText *>(GetChild("messagetext"));
151 if (m_messageText)
152 m_messageText->SetText(tr("No bookmarks defined.\n\n"
153 "Use the 'Add Bookmark' menu option to add new bookmarks"));
154
156 {
157 LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
158 return false;
159 }
160
164
167
170
172
174
175 return true;
176}
177
179{
180 while (!m_siteList.isEmpty())
181 delete m_siteList.takeFirst();
182}
183
185{
187 QStringList groups;
188 for (int x = 0; x < m_siteList.count(); x++)
189 {
190 Bookmark *site = m_siteList.at(x);
191
192 if (groups.indexOf(site->m_category) == -1)
193 {
194 groups.append(site->m_category);
196 }
197 }
198}
199
201{
203
204 if (m_messageText)
205 m_messageText->SetVisible((m_siteList.count() == 0));
206
208 if (!item)
209 return;
210
211 QString group = item->GetText();
212
213 for (int x = 0; x < m_siteList.count(); x++)
214 {
215 Bookmark *site = m_siteList.at(x);
216
217 if (group == site->m_category)
218 {
219 auto *item2 = new MythUIButtonListItem(m_bookmarkList,
221 item2->SetText(site->m_name, "name");
222 item2->SetText(site->m_url, "url");
223 if (site->m_isHomepage)
224 item2->DisplayState("yes", "homepage");
225 item2->SetData(QVariant::fromValue(site));
226 item2->setChecked(site->m_selected ?
228 }
229 }
230}
231
233{
234 auto selected = [](auto *site){ return site && site->m_selected; };
235 return std::count_if(m_siteList.cbegin(), m_siteList.cend(), selected);
236}
237
238bool BookmarkManager::keyPressEvent(QKeyEvent *event)
239{
240 if (GetFocusWidget()->keyPressEvent(event))
241 return true;
242
243 QStringList actions;
244 bool handled = GetMythMainWindow()->TranslateKeyPress("qt", event, actions);
245
246 for (int i = 0; i < actions.size() && !handled; i++)
247 {
248
249 const QString& action = actions[i];
250 handled = true;
251
252 if (action == "MENU")
253 {
254 QString label = tr("Actions");
255
256 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
257
258 m_menuPopup = new MythDialogBox(label, popupStack, "actionmenu");
259
260 if (!m_menuPopup->Create())
261 {
262 delete m_menuPopup;
263 m_menuPopup = nullptr;
264 return true;
265 }
266
267 m_menuPopup->SetReturnEvent(this, "action");
268
271
273 {
277 }
278
279 if (GetMarkedCount() > 0)
280 {
284 }
285
287
288 popupStack->AddScreen(m_menuPopup);
289 }
290 else if (action == "INFO")
291 {
293
294 if (item)
295 {
296 auto *site = item->GetData().value<Bookmark*>();
297
299 {
301 if (site)
302 site->m_selected = true;
303 }
304 else
305 {
307 if (site)
308 site->m_selected = false;
309 }
310 }
311 }
312 else if (action == "DELETE")
313 {
315 }
316 else if (action == "EDIT")
317 {
319 }
320 else
321 {
322 handled = false;
323 }
324 }
325
326 if (!handled && MythScreenType::keyPressEvent(event))
327 handled = true;
328
329 return handled;
330}
331
333{
336}
337
339{
340 if (!item)
341 return;
342
343 auto *site = item->GetData().value<Bookmark*>();
344 if (!site)
345 return;
346
347 m_savedBookmark = *site;
348
349 QString cmd = gCoreContext->GetSetting("WebBrowserCommand", "Internal");
350 QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
351 QStringList urls;
352
353 urls.append(site->m_url);
354
355 if (cmd.toLower() == "internal")
356 {
358
359 MythScreenType *mythbrowser = nullptr;
360 if (urls[0].startsWith("mythflash://"))
361 mythbrowser = new MythFlashPlayer(mainStack, urls);
362 else
363 mythbrowser = new MythBrowser(mainStack, urls);
364
365 if (mythbrowser->Create())
366 {
367 connect(mythbrowser, &MythScreenType::Exiting, this, &BookmarkManager::slotBrowserClosed);
368 mainStack->AddScreen(mythbrowser);
369 }
370 else
371 {
372 delete mythbrowser;
373 }
374 }
375 else
376 {
377 cmd.replace("%ZOOM%", zoom);
378 cmd.replace("%URL%", urls.join(" "));
379
380 cmd.replace("&","\\&");
381 cmd.replace(";","\\;");
382
386
387 // we need to reload the bookmarks incase the user added/deleted
388 // any while in MythBrowser
390 }
391}
392
394{
395 if (edit)
396 {
398
399 if (!item || !item->GetData().isValid())
400 {
401 LOG(VB_GENERAL, LOG_ERR, "BookmarkManager: Something is wrong. "
402 "Asked to edit a non existent bookmark!");
403 return;
404 }
405 auto *site = item->GetData().value<Bookmark*>();
406 if (!site)
407 {
408 LOG(VB_GENERAL, LOG_ERR, "BookmarkManager: Something is wrong. "
409 "Existing bookmark is invalid!");
410 return;
411 }
412
413 m_savedBookmark = *site;
414 }
415
416
418
419 auto *editor = new BookmarkEditor(&m_savedBookmark, edit, mainStack,
420 "bookmarkeditor");
421
423
424 if (editor->Create())
425 mainStack->AddScreen(editor);
426}
427
429{
431}
432
434{
437
440
441 // try to set the current item to name
442 for (int x = 0; x < m_bookmarkList->GetCount(); x++)
443 {
445 if (item && item->GetData().isValid())
446 {
447 auto *site = item->GetData().value<Bookmark*>();
448 if (site && (*site == m_savedBookmark))
449 {
451 break;
452 }
453 }
454 }
455}
456
458{
460 auto *config = new BrowserConfig(mainStack, "browserconfig");
461
462 if (config->Create())
463 mainStack->AddScreen(config);
464}
465
467{
468 // Clear all homepage information
470
471 // Set the homepage information for selected bookmark
473 if (item && item->GetData().isValid())
474 {
475 auto *site = item->GetData().value<Bookmark*>();
476 if (site)
477 UpdateHomepageInDB(site);
478 }
480}
481
483{
484 ShowEditDialog(false);
485}
486
488{
489 ShowEditDialog(true);
490}
491
493{
495 return;
496
497 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
498
499 QString message = tr("Are you sure you want to delete the selected bookmark?");
500
501 auto *dialog = new MythConfirmationDialog(popupStack, message, true);
502
503 if (dialog->Create())
504 popupStack->AddScreen(dialog);
505
506 connect(dialog, &MythConfirmationDialog::haveResult,
508}
509
511{
512 if (!doDelete)
513 return;
514
516 if (item)
517 {
518 QString category = "";
519 auto *site = item->GetData().value<Bookmark*>();
520 if (site)
521 {
522 category = site->m_category;
523 RemoveFromDB(site);
524 }
525
528
529 if (category != "")
531
533 }
534}
535
537{
538 if (GetMarkedCount() == 0)
539 return;
540
541 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
542
543 QString message = tr("Are you sure you want to delete the marked bookmarks?");
544
545 auto *dialog = new MythConfirmationDialog(popupStack, message, true);
546
547 if (dialog->Create())
548 popupStack->AddScreen(dialog);
549
550 connect(dialog, &MythConfirmationDialog::haveResult,
552}
553
555{
556 if (!doDelete)
557 return;
558
559 QString category = m_groupList->GetValue();
560
561 for (auto *site : std::as_const(m_siteList))
562 {
563 if (site && site->m_selected)
564 RemoveFromDB(site);
565 }
566
569
570 if (category != "")
572
574}
575
577{
579 if (item)
581}
582
584{
585 if (GetMarkedCount() == 0)
586 return;
587
589 if (item && item->GetData().isValid())
590 {
591 auto *site = item->GetData().value<Bookmark*>();
592 if (site)
593 m_savedBookmark = *site;
594 }
595
596 QString cmd = gCoreContext->GetSetting("WebBrowserCommand", "Internal");
597 QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
598 QStringList urls;
599
600 for (const auto *site : std::as_const(m_siteList))
601 {
602 if (site && site->m_selected)
603 urls.append(site->m_url);
604 }
605
606 if (cmd.toLower() == "internal")
607 {
609
610 auto *mythbrowser = new MythBrowser(mainStack, urls);
611
612 if (mythbrowser->Create())
613 {
614 connect(mythbrowser, &MythScreenType::Exiting, this, &BookmarkManager::slotBrowserClosed);
615 mainStack->AddScreen(mythbrowser);
616 }
617 else
618 {
619 delete mythbrowser;
620 }
621 }
622 else
623 {
624 cmd.replace("%ZOOM%", zoom);
625 cmd.replace("%URL%", urls.join(" "));
626
627 cmd.replace("&","\\&");
628 cmd.replace(";","\\;");
629
633
634 // we need to reload the bookmarks incase the user added/deleted
635 // any while in MythBrowser
637 }
638}
639
641{
642 // we need to reload the bookmarks incase the user added/deleted
643 // any while in MythBrowser
645}
646
648{
649 for (int x = 0; x < m_bookmarkList->GetCount(); x++)
650 {
652 if (item)
653 {
655
656 auto *site = item->GetData().value<Bookmark*>();
657 if (site)
658 site->m_selected = false;
659 }
660 }
661}
int GetSiteList(QList< Bookmark * > &siteList)
bool RemoveFromDB(Bookmark *site)
bool UpdateHomepageInDB(Bookmark *site)
bool ResetHomepageFromDB()
Site category, name and URL edit screen.
void slotDeleteCurrent(void)
bool Create(void) override
void ShowEditDialog(bool edit)
MythUIButtonList * m_bookmarkList
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
void slotClearMarked(void)
void ReloadBookmarks(void)
void slotShowMarked(void)
void slotGroupSelected(MythUIButtonListItem *item)
Bookmark m_savedBookmark
void slotAddBookmark(void)
void slotDoDeleteCurrent(bool doDelete)
MythUIButtonList * m_groupList
void slotEditBookmark(void)
void slotDeleteMarked(void)
void slotShowCurrent(void)
MythDialogBox * m_menuPopup
static void slotSettings(void)
void slotDoDeleteMarked(bool doDelete)
void slotBookmarkClicked(MythUIButtonListItem *item)
void UpdateURLList(void)
~BookmarkManager() override
void slotBrowserClosed(void)
void UpdateGroupList(void)
void slotEditDialogExited(void)
MythUIText * m_messageText
QList< Bookmark * > m_siteList
void slotSetHomepage(void)
uint GetMarkedCount(void)
bool m_selected
QString m_category
QString m_name
QString m_url
bool m_isHomepage
MythUIButton * m_cancelButton
MythUIText * m_titleText
void slotFocusChanged(void)
bool Create(void) override
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
MythUIButton * m_okButton
MythUITextEdit * m_zoomEdit
MythUIText * m_descriptionText
MythUICheckBox * m_enablePluginsCheck
MythUITextEdit * m_commandEdit
void slotSave(void)
Dialog asking for user confirmation.
void SaveSetting(const QString &key, int newValue)
QString GetSetting(const QString &key, const QString &defaultval="")
int GetNumSetting(const QString &key, int defaultval=0)
Basic menu dialog, message and a list of options.
void AddButton(const QString &title)
void SetReturnEvent(QObject *retobject, const QString &resultid)
bool Create(void) override
MythScreenStack * GetMainStack()
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MythScreenStack * GetStack(const QString &Stackname)
void AllowInput(bool Allow)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
virtual bool Create(void)
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool SetFocusWidget(MythUIType *widget=nullptr)
virtual void Close()
CheckState state() const
void setChecked(CheckState state)
QString GetText(const QString &name="") const
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
virtual QString GetValue() const
MythUIButtonListItem * GetItemCurrent() const
void SetItemCurrent(MythUIButtonListItem *item)
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
void itemClicked(MythUIButtonListItem *item)
MythUIButtonListItem * GetItemAt(int pos) const
bool MoveToNamedPosition(const QString &position_name)
void itemSelected(MythUIButtonListItem *item)
A single button widget.
Definition: mythuibutton.h:22
void Clicked()
A checkbox widget supporting three check states - on,off,half and two conditions - selected and unsel...
void SetCheckState(MythUIStateType::StateType state)
MythUIStateType::StateType GetCheckState() const
A text entry and edit widget.
QString GetText(void) const
void SetText(const QString &text, bool moveCursor=true)
All purpose text widget, displays a text string.
Definition: mythuitext.h:29
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
void TakingFocus(void)
virtual void SetVisible(bool visible)
void Refresh(void)
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:138
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
unsigned int uint
Definition: freesurround.h:24
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
@ kMSDontDisableDrawing
avoid disabling UI drawing
Definition: mythsystem.h:37
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:206