MythTV  master
bookmarkmanager.cpp
Go to the documentation of this file.
1 // C++
2 #include <iostream>
3 using namespace std;
4 
5 // Qt
6 #include <QString>
7 
8 // MythTV
9 #include <mythmainwindow.h>
10 #include <mythcontext.h>
11 #include <mythdbcon.h>
12 #include <mythdirs.h>
13 #include <mythuicheckbox.h>
14 #include <mythuibuttonlist.h>
15 #include <mythsystemlegacy.h>
16 
17 // mythbrowser
18 #include "bookmarkmanager.h"
19 #include "bookmarkeditor.h"
20 #include "browserdbutil.h"
21 #include "mythbrowser.h"
22 #include "mythflashplayer.h"
23 
24 // ---------------------------------------------------
25 
27 {
28  // Load the theme for this screen
29  bool foundtheme = LoadWindowFromXML("browser-ui.xml", "browserconfig", this);
30  if (!foundtheme)
31  return false;
32 
33  m_titleText = dynamic_cast<MythUIText *> (GetChild("title"));
34 
35  if (m_titleText)
36  m_titleText->SetText(tr("MythBrowser Settings"));
37 
38  m_commandEdit = dynamic_cast<MythUITextEdit *> (GetChild("command"));
39  m_zoomEdit = dynamic_cast<MythUITextEdit *> (GetChild("zoom"));
40  m_enablePluginsCheck = dynamic_cast<MythUICheckBox *> (GetChild("enablepluginscheck"));
41 
42  m_descriptionText = dynamic_cast<MythUIText *> (GetChild("description"));
43 
44  m_okButton = dynamic_cast<MythUIButton *> (GetChild("ok"));
45  m_cancelButton = dynamic_cast<MythUIButton *> (GetChild("cancel"));
46 
47  if (!m_commandEdit || !m_zoomEdit || !m_enablePluginsCheck || !m_okButton || !m_cancelButton)
48  {
49  LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
50  return false;
51  }
52 
53  m_commandEdit->SetText(gCoreContext->GetSetting("WebBrowserCommand",
54  "Internal"));
55 
56  m_zoomEdit->SetText(gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0"));
57 
58  int setting = gCoreContext->GetNumSetting("WebBrowserEnablePlugins", 1);
59  if (setting == 1)
60  m_enablePluginsCheck->SetCheckState(MythUIStateType::Full);
61 
62  connect(m_okButton, SIGNAL(Clicked()), this, SLOT(slotSave()));
63  connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(Close()));
64 
65  connect(m_commandEdit, SIGNAL(TakingFocus()), SLOT(slotFocusChanged()));
66  connect(m_zoomEdit , SIGNAL(TakingFocus()), SLOT(slotFocusChanged()));
67  connect(m_enablePluginsCheck, SIGNAL(TakingFocus()), SLOT(slotFocusChanged()));
68  connect(m_okButton, SIGNAL(TakingFocus()), SLOT(slotFocusChanged()));
69  connect(m_cancelButton, SIGNAL(TakingFocus()), SLOT(slotFocusChanged()));
70 
71  BuildFocusList();
72 
73  SetFocusWidget(m_commandEdit);
74 
75  return true;
76 }
77 
79 {
80  float zoom = m_zoomEdit->GetText().toFloat();
81  if (zoom > 5.0F)
82  zoom = 5.0F;
83  if (zoom < 0.3F)
84  zoom = 0.3F;
85  gCoreContext->SaveSetting("WebBrowserZoomLevel", QString("%1").arg(zoom));
86  gCoreContext->SaveSetting("WebBrowserCommand", m_commandEdit->GetText());
87  int checkstate = 0;
88  if (m_enablePluginsCheck->GetCheckState() == MythUIStateType::Full)
89  checkstate = 1;
90  gCoreContext->SaveSetting("WebBrowserEnablePlugins", checkstate);
91 
92  Close();
93 }
94 
95 bool BrowserConfig::keyPressEvent(QKeyEvent *event)
96 {
97  if (GetFocusWidget()->keyPressEvent(event))
98  return true;
99 
100  return MythScreenType::keyPressEvent(event);
101 }
102 
104 {
105  if (!m_descriptionText)
106  return;
107 
108  QString msg = "";
109  if (GetFocusWidget() == m_commandEdit)
110  msg = tr("This is the command that will be used to show the web browser. "
111  "Use 'Internal' to use the built in web browser'. "
112  "%ZOOM% and %URL% will be replaced with the zoom level and URL list.");
113  else if (GetFocusWidget() == m_zoomEdit)
114  msg = tr("This is the default text size that will be used. Valid values "
115  "for the Internal browser are from 0.3 to 5.0 with 1.0 being "
116  "normal size less than 1 is smaller and greater than 1 is "
117  "larger than normal size.");
118  else if (GetFocusWidget() == m_enablePluginsCheck)
119  msg = tr("If checked this will enable browser plugins if the 'Internal' "
120  "browser is being used.");
121  else if (GetFocusWidget() == m_cancelButton)
122  msg = tr("Exit without saving settings");
123  else if (GetFocusWidget() == m_okButton)
124  msg = tr("Save settings and Exit");
125 
126  m_descriptionText->SetText(msg);
127 }
128 
129 // ---------------------------------------------------
130 
132 {
133  // Load the theme for this screen
134  bool foundtheme = LoadWindowFromXML("browser-ui.xml", "bookmarkmanager", this);
135  if (!foundtheme)
136  return false;
137 
138  m_groupList = dynamic_cast<MythUIButtonList *>(GetChild("grouplist"));
139  m_bookmarkList = dynamic_cast<MythUIButtonList *>(GetChild("bookmarklist"));
140 
141  // optional text area warning user hasn't set any bookmarks yet
142  m_messageText = dynamic_cast<MythUIText *>(GetChild("messagetext"));
143  if (m_messageText)
144  m_messageText->SetText(tr("No bookmarks defined.\n\n"
145  "Use the 'Add Bookmark' menu option to add new bookmarks"));
146 
147  if (!m_groupList || !m_bookmarkList)
148  {
149  LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
150  return false;
151  }
152 
153  GetSiteList(m_siteList);
154  UpdateGroupList();
155  UpdateURLList();
156 
157  connect(m_groupList, SIGNAL(itemSelected(MythUIButtonListItem*)),
158  this, SLOT(slotGroupSelected(MythUIButtonListItem*)));
159 
160  connect(m_bookmarkList, SIGNAL(itemClicked(MythUIButtonListItem*)),
161  this, SLOT(slotBookmarkClicked(MythUIButtonListItem*)));
162 
163  BuildFocusList();
164 
165  SetFocusWidget(m_groupList);
166 
167  return true;
168 }
169 
171 {
172  while (!m_siteList.isEmpty())
173  delete m_siteList.takeFirst();
174 }
175 
177 {
178  m_groupList->Reset();
179  QStringList groups;
180  for (int x = 0; x < m_siteList.count(); x++)
181  {
182  Bookmark *site = m_siteList.at(x);
183 
184  if (groups.indexOf(site->m_category) == -1)
185  {
186  groups.append(site->m_category);
187  new MythUIButtonListItem(m_groupList, site->m_category);
188  }
189  }
190 }
191 
193 {
194  m_bookmarkList->Reset();
195 
196  if (m_messageText)
197  m_messageText->SetVisible((m_siteList.count() == 0));
198 
199  MythUIButtonListItem *item = m_groupList->GetItemCurrent();
200  if (!item)
201  return;
202 
203  QString group = item->GetText();
204 
205  for (int x = 0; x < m_siteList.count(); x++)
206  {
207  Bookmark *site = m_siteList.at(x);
208 
209  if (group == site->m_category)
210  {
211  auto *item2 = new MythUIButtonListItem(m_bookmarkList,
212  "", "", true, MythUIButtonListItem::NotChecked);
213  item2->SetText(site->m_name, "name");
214  item2->SetText(site->m_url, "url");
215  if (site->m_isHomepage)
216  item2->DisplayState("yes", "homepage");
217  item2->SetData(qVariantFromValue(site));
218  item2->setChecked(site->m_selected ?
220  }
221  }
222 }
223 
225 {
226  uint count = 0;
227 
228  for (int x = 0; x < m_siteList.size(); x++)
229  {
230  Bookmark *site = m_siteList.at(x);
231  if (site && site->m_selected)
232  count++;
233  }
234 
235  return count;
236 }
237 
238 bool 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  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 
269  m_menuPopup->AddButton(tr("Set Homepage"), SLOT(slotSetHomepage()));
270  m_menuPopup->AddButton(tr("Add Bookmark"), SLOT(slotAddBookmark()));
271 
272  if (m_bookmarkList->GetItemCurrent())
273  {
274  m_menuPopup->AddButton(tr("Edit Bookmark"), SLOT(slotEditBookmark()));
275  m_menuPopup->AddButton(tr("Delete Bookmark"), SLOT(slotDeleteCurrent()));
276  m_menuPopup->AddButton(tr("Show Bookmark"), SLOT(slotShowCurrent()));
277  }
278 
279  if (GetMarkedCount() > 0)
280  {
281  m_menuPopup->AddButton(tr("Delete Marked"), SLOT(slotDeleteMarked()));
282  m_menuPopup->AddButton(tr("Show Marked"), SLOT(slotShowMarked()));
283  m_menuPopup->AddButton(tr("Clear Marked"), SLOT(slotClearMarked()));
284  }
285 
286  m_menuPopup->AddButton(tr("Settings"), SLOT(slotSettings()));
287 
288  popupStack->AddScreen(m_menuPopup);
289  }
290  else if (action == "INFO")
291  {
292  MythUIButtonListItem *item = m_bookmarkList->GetItemCurrent();
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  slotDeleteCurrent();
314  else if (action == "EDIT")
315  slotEditBookmark();
316  else
317  handled = false;
318  }
319 
320  if (!handled && MythScreenType::keyPressEvent(event))
321  handled = true;
322 
323  return handled;
324 }
325 
327 {
328  (void) item;
329 
330  UpdateURLList();
331  m_bookmarkList->Refresh();
332 }
333 
335 {
336  if (!item)
337  return;
338 
339  auto *site = item->GetData().value<Bookmark*>();
340  if (!site)
341  return;
342 
343  m_savedBookmark = *site;
344 
345  QString cmd = gCoreContext->GetSetting("WebBrowserCommand", "Internal");
346  QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
347  QStringList urls;
348 
349  urls.append(site->m_url);
350 
351  if (cmd.toLower() == "internal")
352  {
354 
355  MythScreenType *mythbrowser = nullptr;
356  if (urls[0].startsWith("mythflash://"))
357  mythbrowser = new MythFlashPlayer(mainStack, urls);
358  else
359  mythbrowser = new MythBrowser(mainStack, urls);
360 
361  if (mythbrowser->Create())
362  {
363  connect(mythbrowser, SIGNAL(Exiting()), SLOT(slotBrowserClosed()));
364  mainStack->AddScreen(mythbrowser);
365  }
366  else
367  delete mythbrowser;
368  }
369  else
370  {
371  cmd.replace("%ZOOM%", zoom);
372  cmd.replace("%URL%", urls.join(" "));
373 
374  cmd.replace("&","\\&");
375  cmd.replace(";","\\;");
376 
377  GetMythMainWindow()->AllowInput(false);
379  GetMythMainWindow()->AllowInput(true);
380 
381  // we need to reload the bookmarks incase the user added/deleted
382  // any while in MythBrowser
383  ReloadBookmarks();
384  }
385 }
386 
388 {
389  Bookmark *site = nullptr;
390 
391  if (edit)
392  {
393  MythUIButtonListItem *item = m_bookmarkList->GetItemCurrent();
394 
395  if (item && item->GetData().isValid())
396  {
397  site = item->GetData().value<Bookmark*>();
398  m_savedBookmark = *site;
399  }
400  else
401  {
402  LOG(VB_GENERAL, LOG_ERR, "BookmarkManager: Something is wrong. "
403  "Asked to edit a non existent bookmark!");
404  return;
405  }
406  }
407 
408 
410 
411  auto *editor = new BookmarkEditor(&m_savedBookmark, edit, mainStack,
412  "bookmarkeditor");
413 
414  connect(editor, SIGNAL(Exiting()), this, SLOT(slotEditDialogExited()));
415 
416  if (editor->Create())
417  mainStack->AddScreen(editor);
418 }
419 
421 {
422  ReloadBookmarks();
423 }
424 
426 {
427  GetSiteList(m_siteList);
428  UpdateGroupList();
429 
430  m_groupList->MoveToNamedPosition(m_savedBookmark.m_category);
431  UpdateURLList();
432 
433  // try to set the current item to name
434  for (int x = 0; x < m_bookmarkList->GetCount(); x++)
435  {
436  MythUIButtonListItem *item = m_bookmarkList->GetItemAt(x);
437  if (item && item->GetData().isValid())
438  {
439  auto *site = item->GetData().value<Bookmark*>();
440  if (site && (*site == m_savedBookmark))
441  {
442  m_bookmarkList->SetItemCurrent(item);
443  break;
444  }
445  }
446  }
447 }
448 
450 {
452  auto *config = new BrowserConfig(mainStack, "browserconfig");
453 
454  if (config->Create())
455  mainStack->AddScreen(config);
456 }
457 
459 {
460  // Clear all homepage information
462 
463  // Set the homepage information for selected bookmark
464  MythUIButtonListItem *item = m_bookmarkList->GetItemCurrent();
465  if (item && item->GetData().isValid())
466  {
467  auto *site = item->GetData().value<Bookmark*>();
468  if (site)
469  UpdateHomepageInDB(site);
470  }
471  ReloadBookmarks();
472 }
473 
475 {
476  ShowEditDialog(false);
477 }
478 
480 {
481  ShowEditDialog(true);
482 }
483 
485 {
486  if (!m_bookmarkList->GetItemCurrent())
487  return;
488 
489  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
490 
491  QString message = tr("Are you sure you want to delete the selected bookmark?");
492 
493  auto *dialog = new MythConfirmationDialog(popupStack, message, true);
494 
495  if (dialog->Create())
496  popupStack->AddScreen(dialog);
497 
498  connect(dialog, SIGNAL(haveResult(bool)),
499  this, SLOT(slotDoDeleteCurrent(bool)));
500 }
501 
503 {
504  if (!doDelete)
505  return;
506 
507  MythUIButtonListItem *item = m_bookmarkList->GetItemCurrent();
508  if (item)
509  {
510  QString category = "";
511  auto *site = item->GetData().value<Bookmark*>();
512  if (site)
513  {
514  category = site->m_category;
515  RemoveFromDB(site);
516  }
517 
518  GetSiteList(m_siteList);
519  UpdateGroupList();
520 
521  if (category != "")
522  m_groupList->MoveToNamedPosition(category);
523 
524  UpdateURLList();
525  }
526 }
527 
529 {
530  if (GetMarkedCount() == 0)
531  return;
532 
533  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
534 
535  QString message = tr("Are you sure you want to delete the marked bookmarks?");
536 
537  auto *dialog = new MythConfirmationDialog(popupStack, message, true);
538 
539  if (dialog->Create())
540  popupStack->AddScreen(dialog);
541 
542  connect(dialog, SIGNAL(haveResult(bool)),
543  this, SLOT(slotDoDeleteMarked(bool)));
544 }
545 
547 {
548  if (!doDelete)
549  return;
550 
551  QString category = m_groupList->GetValue();
552 
553  for (int x = 0; x < m_siteList.size(); x++)
554  {
555  Bookmark *site = m_siteList.at(x);
556  if (site && site->m_selected)
557  RemoveFromDB(site);
558  }
559 
560  GetSiteList(m_siteList);
561  UpdateGroupList();
562 
563  if (category != "")
564  m_groupList->MoveToNamedPosition(category);
565 
566  UpdateURLList();
567 }
568 
570 {
571  MythUIButtonListItem *item = m_bookmarkList->GetItemCurrent();
572  if (item)
573  slotBookmarkClicked(item);
574 }
575 
577 {
578  if (GetMarkedCount() == 0)
579  return;
580 
581  MythUIButtonListItem *item = m_bookmarkList->GetItemCurrent();
582  if (item && item->GetData().isValid())
583  {
584  auto *site = item->GetData().value<Bookmark*>();
585  m_savedBookmark = *site;
586  }
587 
588  QString cmd = gCoreContext->GetSetting("WebBrowserCommand", "Internal");
589  QString zoom = gCoreContext->GetSetting("WebBrowserZoomLevel", "1.0");
590  QStringList urls;
591 
592  for (int x = 0; x < m_siteList.size(); x++)
593  {
594  Bookmark *site = m_siteList.at(x);
595  if (site && site->m_selected)
596  urls.append(site->m_url);
597  }
598 
599  if (cmd.toLower() == "internal")
600  {
602 
603  auto *mythbrowser = new MythBrowser(mainStack, urls);
604 
605  if (mythbrowser->Create())
606  {
607  connect(mythbrowser, SIGNAL(Exiting()), SLOT(slotBrowserClosed()));
608  mainStack->AddScreen(mythbrowser);
609  }
610  else
611  delete mythbrowser;
612  }
613  else
614  {
615  cmd.replace("%ZOOM%", zoom);
616  cmd.replace("%URL%", urls.join(" "));
617 
618  cmd.replace("&","\\&");
619  cmd.replace(";","\\;");
620 
621  GetMythMainWindow()->AllowInput(false);
623  GetMythMainWindow()->AllowInput(true);
624 
625  // we need to reload the bookmarks incase the user added/deleted
626  // any while in MythBrowser
627  ReloadBookmarks();
628  }
629 }
630 
632 {
633  // we need to reload the bookmarks incase the user added/deleted
634  // any while in MythBrowser
635  ReloadBookmarks();
636 }
637 
639 {
640  for (int x = 0; x < m_bookmarkList->GetCount(); x++)
641  {
642  MythUIButtonListItem *item = m_bookmarkList->GetItemAt(x);
643  if (item)
644  {
646 
647  auto *site = item->GetData().value<Bookmark*>();
648  if (site)
649  site->m_selected = false;
650  }
651  }
652 }
void slotBrowserClosed(void)
bool RemoveFromDB(Bookmark *site)
Dialog asking for user confirmation.
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
bool m_selected
void SaveSetting(const QString &key, int newValue)
QString m_name
virtual bool Create(void)
Basic menu dialog, message and a list of options.
void slotAddBookmark(void)
void AllowInput(bool allow)
MythScreenStack * GetStack(const QString &stackname)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythScreenStack * GetMainStack()
void slotBookmarkClicked(MythUIButtonListItem *item)
void UpdateGroupList(void)
void ShowEditDialog(bool edit)
void slotDoDeleteCurrent(bool doDelete)
void slotSetHomepage(void)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
bool Create(void) override
QString GetSetting(const QString &key, const QString &defaultval="")
void slotShowMarked(void)
bool ResetHomepageFromDB()
bool keyPressEvent(QKeyEvent *) override
Key event handler.
unsigned int uint
Definition: compat.h:140
bool keyPressEvent(QKeyEvent *) override
Key event handler.
void slotDoDeleteMarked(bool doDelete)
void slotShowCurrent(void)
uint myth_system(const QString &command, uint flags, uint timeout)
void ReloadBookmarks(void)
CheckState state() const
void slotGroupSelected(MythUIButtonListItem *item)
void slotFocusChanged(void)
void slotSave(void)
MythMainWindow * GetMythMainWindow(void)
QString GetText(const QString &name="") const
int GetNumSetting(const QString &key, int defaultval=0)
void slotClearMarked(void)
QString m_url
bool keyPressEvent(QKeyEvent *) override
Key event handler.
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
avoid disabling UI drawing
Definition: mythsystem.h:35
void slotEditDialogExited(void)
void UpdateURLList(void)
bool Create(void) override
void slotDeleteMarked(void)
uint GetMarkedCount(void)
void slotDeleteCurrent(void)
bool UpdateHomepageInDB(Bookmark *site)
Site category, name and URL edit screen.
Screen in which all other widgets are contained and rendered.
void slotEditBookmark(void)
bool m_isHomepage
static void slotSettings(void)
QString m_category
int GetSiteList(QList< Bookmark * > &siteList)
void setChecked(CheckState state)