BibleTime
btbookshelfsourcespage.cpp
Go to the documentation of this file.
1 /*********
2 *
3 * In the name of the Father, and of the Son, and of the Holy Spirit.
4 *
5 * This file is part of BibleTime's source code, https://bibletime.info/
6 *
7 * Copyright 1999-2021 by the BibleTime developers.
8 * The BibleTime source code is licensed under the GNU General Public License
9 * version 2.0.
10 *
11 **********/
12 
13 #include "btbookshelfsourcespage.h"
14 
15 #include <QApplication>
16 #include <QDialog>
17 #include <QFontMetrics>
18 #include <QHeaderView>
19 #include <QMessageBox>
20 #include <QModelIndex>
21 #include <QPushButton>
22 #include <QStandardItem>
23 #include <QStandardItemModel>
24 #include <QStringLiteral>
25 #include <QTableView>
26 #include <Qt>
27 #include <QtGlobal>
28 #include <QVariant>
29 #include <QVBoxLayout>
30 #include <QWizardPage>
31 #include "../../backend/config/btconfig.h"
32 #include "../../backend/btinstallbackend.h"
33 #include "../../util/btconnect.h"
36 #include "btbookshelfwizard.h"
37 #include "btbookshelfwizardenums.h"
38 
39 // Sword includes:
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wextra-semi"
42 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
43 #include <installmgr.h>
44 #include <swbuf.h>
45 #pragma GCC diagnostic pop
46 
47 
48 namespace {
49 char const buttonPropertyName[] = "BtBookshelfSourcesPageButtonProperty";
50 constexpr bool const ButtonTagAdd = true;
51 constexpr bool const ButtonTagRemove = false;
52 QString const SourcesKey = "GUI/BookshelfWizard/sources";
53 QStringList const initialSelection{"CrossWire", "Bible.org", "Xiphos"};
54 } // anonymous namespace
55 
56 
58  : BtBookshelfWizardPage(parent)
59 {
60  // Setup UI:
61  m_verticalLayout = new QVBoxLayout(this);
62  m_sourcesTableView = new QTableView(this);
63  m_sourcesTableView->horizontalHeader()->setVisible(false);
64  m_sourcesTableView->verticalHeader()->setVisible(false);
66 
67  // Create sources model:
68  m_model = new QStandardItemModel(this);
69  m_sourcesTableView->setModel(m_model);
70  BT_CONNECT(m_model, &QStandardItemModel::dataChanged,
71  this, &QWizardPage::completeChanged);
72 }
73 
75  setTitle(QApplication::translate("BookshelfWizard",
76  "Choose Remote Libraries"));
77  setSubTitle(QApplication::translate(
78  "BookshelfWizard",
79  "Choose one or more remote libraries to install works from."));
80 }
81 
84  languagesPage.initializeLanguages();
85  return languagesPage.skipPage()
88 }
89 
91  QStringList saveSources;
92  if (m_firstTimeInit) {
93  saveSources << btConfig().value<QStringList>(SourcesKey, QStringList{});
94  if (saveSources.empty())
95  saveSources << initialSelection;
96  m_firstTimeInit = false;
97  } else {
98  saveSources << selectedSources();
99  }
100 
101  // Do before updating models to get correct
102  // column width for buttons
103  retranslateUi();
104 
106  selectSourcesInModel(saveSources);
107 }
108 
109 void BtBookshelfSourcesPage::selectSourcesInModel(const QStringList& sources) {
110  for (int row = 0; row < m_model->rowCount(); ++row) {
111  QStandardItem * const item = m_model->item(row,0);
112  if (sources.contains(item->text()))
113  item->setCheckState(Qt::Checked);
114  }
115 }
116 
118  QStringList sourceList = BtInstallBackend::sourceNameList();
119  m_model->clear();
120  m_model->setColumnCount(2);
121 
122  auto const addButton = [this](int row, int column,
123  QString const & text, bool const tag) {
124  QPushButton * const button = new QPushButton(text, this);
125  button->setProperty(buttonPropertyName, tag);
126  m_sourcesTableView->setIndexWidget(m_model->index(row, column), button);
127  return button;
128  };
129 
130  QString const removeText = tr("Remove");
131  for (auto const & source : sourceList) {
132  auto * const item = new QStandardItem(source);
133  item->setCheckable(true);
134  m_model->appendRow(item);
135  int const row = m_model->rowCount() - 1;
136  QPushButton * button = addButton(row, 1, removeText, ButtonTagRemove);
137  BT_CONNECT(button, &QPushButton::clicked,
138  [this, row]{ slotButtonClicked(row); });
139  }
140 
141  m_model->appendRow(new QStandardItem(tr("< Add new remote library >")));
142  int const row = m_model->rowCount() - 1;
143  QString const addText = tr("Add");
144  QPushButton * const button = addButton(row, 1, addText, ButtonTagAdd);
145  BT_CONNECT(button, &QPushButton::clicked,
146  [this, row]{ slotButtonClicked(row); });
147 
148  m_sourcesTableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
149  m_sourcesTableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
150  m_sourcesTableView->setShowGrid(false);
151 
152  // Calculate button column width:
153  QFontMetrics const fontMetrics = m_sourcesTableView->fontMetrics();
154  m_sourcesTableView->setColumnWidth(
155  1,
156  qMax(fontMetrics.horizontalAdvance(removeText),
157  fontMetrics.horizontalAdvance(addText)) + 60);
158 }
159 
161  for (int row = 0; row < m_model->rowCount(); ++row)
162  if (m_model->item(row, 0)->checkState() == Qt::Checked)
163  return true;
164  return false;
165 }
166 
168  QStringList sources;
169  for (int row = 0; row < m_model->rowCount(); ++row) {
170  QStandardItem * const item = m_model->item(row, 0);
171  if (item->checkState() == Qt::Checked)
172  sources << item->text();
173  }
174  return sources;
175 }
176 
178  QModelIndex const index = m_model->index(row, 1);
179  if (static_cast<QPushButton *>(
180  m_sourcesTableView->indexWidget(index))->property(
181  buttonPropertyName).toBool() == ButtonTagRemove)
182  {
183  if (QMessageBox::warning(
184  this,
185  tr("Delete Source"),
186  tr("Do you really want to delete this source?"),
187  QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
189  m_model->item(index.row(), 0)->text());
190  QStringList const saveSources = selectedSources();
192  selectSourcesInModel(saveSources);
193  return;
194  }
195 
197  QStringList const saveSources = selectedSources();
198  if (dlg.exec() != QDialog::Accepted)
199  return;
200  if (dlg.wasRemoteListAdded()) {
202  selectSourcesInModel(saveSources);
203  return;
204  }
205  sword::InstallSource newSource = dlg.getSource();
206  if (*(newSource.type.c_str()) != '\0') // we have a valid source to add
207  BtInstallBackend::addSource(newSource);
209  selectSourcesInModel(saveSources);
210 }
@ languagesPage
@ installWorksPage
BtConfig & btConfig()
This is a shortchand for BtConfig::getInstance().
Definition: btconfig.h:305
#define BT_CONNECT(...)
Definition: btconnect.h:20
void selectSourcesInModel(QStringList const &sources)
QStandardItemModel * m_model
void initializePage() final override
BtBookshelfSourcesPage(QWidget *parent=nullptr)
bool isComplete() const final override
QStringList selectedSources() const
int nextId() const final override
BtBookshelfWizard & btWizard() const noexcept
BtBookshelfLanguagesPage & languagesPage() const noexcept
T value(QString const &key, T const &defaultValue=T()) const
Returns the settings value for the given global key.
Definition: btconfigcore.h:50
bool deleteSource(const QString &name)
bool addSource(sword::InstallSource &source)
sword::InstallSource source(const QString &name)
QStringList sourceNameList()