summaryrefslogtreecommitdiff
path: root/src/frontend/bookshelfmanager/installpage
diff options
context:
space:
mode:
authorRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:35 -0400
committerRoberto C. Sanchez <roberto@connexer.com>2014-10-21 22:48:35 -0400
commitdf8f1d512c60a96f9041f9663b3fdc2db51cba33 (patch)
tree3d2bdbd4732d417aca73be022ae9044eac96b7d3 /src/frontend/bookshelfmanager/installpage
parent4885bfcef4d89cf0cb391e00af617b9fd19c9cbb (diff)
Imported Upstream version 2.8.1
Diffstat (limited to 'src/frontend/bookshelfmanager/installpage')
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp164
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h50
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp136
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h44
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpage.cpp423
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpage.h65
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp87
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h33
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp140
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h59
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp21
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h2
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp117
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h9
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallthread.cpp28
-rw-r--r--src/frontend/bookshelfmanager/installpage/btinstallthread.h12
-rw-r--r--src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp62
-rw-r--r--src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h38
-rw-r--r--src/frontend/bookshelfmanager/installpage/btsourcearea.cpp282
-rw-r--r--src/frontend/bookshelfmanager/installpage/btsourcearea.h96
-rw-r--r--src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp399
-rw-r--r--src/frontend/bookshelfmanager/installpage/btsourcewidget.h86
22 files changed, 1163 insertions, 1190 deletions
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp
index 8fd87ec..01ca55b 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp
+++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.cpp
@@ -1,127 +1,83 @@
/*********
*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2009 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
*
**********/
#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h"
-#include <QBrush>
-#include <QDebug>
-#include <QList>
-#include <QPushButton>
-#include <QString>
-#include <QTreeWidgetItem>
-#include <QWidget>
-#include "backend/btmoduletreeitem.h"
-#include "backend/drivers/cswordmoduleinfo.h"
-#include "frontend/cmodulechooserdialog.h"
+#include <QAction>
+#include <QHeaderView>
+#include <QToolButton>
+#include "backend/bookshelfmodel/btbookshelffiltermodel.h"
+#include "frontend/btbookshelfview.h"
+#include "util/tool.h"
-BtInstallModuleChooserDialog::BtInstallModuleChooserDialog(QWidget* parent, QString title, QString label, QList<CSwordModuleInfo*>* empty)
- : CModuleChooserDialog(parent, title, label, empty) {
- qDebug() << "BtInstallModuleChooserDialog::BtInstallModuleChooserDialog start";
- init();
- okButton()->setText(tr("Install"));
- m_nameList = QStringList();
+namespace {
+const QString groupingOrderKey("GUI/BookshelfManager/InstallConfirmDialog/grouping");
}
-// Do nothing, the tree is initialized outside this class.
-void BtInstallModuleChooserDialog::initModuleItem(BTModuleTreeItem*, QTreeWidgetItem*) {}
-
-void BtInstallModuleChooserDialog::initModuleItem(QString name, QTreeWidgetItem* sourceItem) {
- /// \todo Use new bookshelf model instead
- /// \bug Valgrind reports memory leak:
- QTreeWidgetItem* moduleItem = new QTreeWidgetItem(sourceItem);
- moduleItem->setText(0, name);
- moduleItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
- moduleItem->setCheckState(0, Qt::Checked);
+BtInstallModuleChooserDialog::BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g,
+ QWidget *parent,
+ Qt::WindowFlags flags)
+ : BtModuleChooserDialog(parent, flags), m_shown(false)
+{
+ resize(550, 340);
- // prevent double items
- if (m_nameList.contains(name)) {
- qDebug() << "item already in list:" << name;
- //moduleItem->setCheckState(0, Qt::Unchecked);
- QBrush bg(Qt::red);
- moduleItem->setBackground(0, bg);
- //find and change the other offending items
- foreach (QTreeWidgetItem* doubleItem, treeWidget()->findItems(name, Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive, 0)) {
- //doubleItem->setCheckState(0, Qt::Unchecked);
- //qDebug() << "CInstallModuleChooserDialog::initModuleItem" << doubleItem;
- doubleItem->setBackground(0, bg);
- }
- m_doubleCheckedModules[name] = true;
- enableOk(false);
+ // Read grouping order from settings or the default from argument:
+ BtBookshelfTreeModel::Grouping groupingOrder(false);
+ if (!groupingOrder.loadFrom(groupingOrderKey)) {
+ groupingOrder = g;
}
- m_nameList << name;
-}
-void BtInstallModuleChooserDialog::slotItemChecked(QTreeWidgetItem* item, int column) {
- QString moduleName = item->text(0);
- qDebug() << "BtInstallModuleChooserDialog::slotItemChecked start";
- // handle only non-toplevel items which has duplicates and where the first column was changed
- if (item->parent() && column == 0 && (findModuleItemsByName(moduleName).count() > 1)) {
- //prevent handling when the color is changed
- if (item->data(1, Qt::UserRole).toBool() == false) {
- qDebug() << "was not updating";
- item->setData(1, Qt::UserRole, true);
- }
- else {
- qDebug() << "was updating";
- item->setData(1, Qt::UserRole, false);
- return;
- }
+ BtInstallModuleChooserDialogModel *treeModel;
+ treeModel = new BtInstallModuleChooserDialogModel(groupingOrder, this);
+ connect(treeModel, SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)),
+ this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&)));
- QList<QTreeWidgetItem*> doubleNameItems = findModuleItemsByName(moduleName);
- QList<QTreeWidgetItem*> doubleCheckedItems;
- foreach (QTreeWidgetItem* nItem, doubleNameItems) {
- if (nItem->checkState(0) == Qt::Checked) {
- doubleCheckedItems << nItem;
- }
- }
+ m_bookshelfModel = new BtBookshelfModel(this);
+ bookshelfWidget()->postFilterModel()->setShowShown(true);
+ bookshelfWidget()->setTreeModel(treeModel);
+ bookshelfWidget()->setSourceModel(m_bookshelfModel);
+ bookshelfWidget()->showHideAction()->setVisible(false);
+ bookshelfWidget()->showHideButton()->hide();
+ bookshelfWidget()->treeView()->header()->show();
- if (doubleCheckedItems.count() > 1) {
- enableOk(false);
- // color the items
- qDebug() << "there were more than 1 item of the name" << moduleName;
- foreach (QTreeWidgetItem* i, doubleNameItems) {
- QBrush bg(Qt::red);
- i->setBackground(0, bg);
- }
- m_doubleCheckedModules[moduleName] = true;
- }
- else if (doubleCheckedItems.count() == 1) {
- qDebug() << "there were 1 checked items of the name" << moduleName;
- // uncolor the items
- foreach (QTreeWidgetItem* i, doubleNameItems) {
- i->setBackground(0, i->parent()->background(0));
- }
- m_doubleCheckedModules.remove(moduleName);
- if (m_doubleCheckedModules.count() == 0) {
- enableOk(true);
- }
- }
- }
+ retranslateUi();
}
-QList<QTreeWidgetItem*> BtInstallModuleChooserDialog::findModuleItemsByName(QString name) {
- qDebug() << "BtInstallModuleChooserDialog::findModuleItemsByName:" << name << treeWidget()->topLevelItemCount();
- QList<QTreeWidgetItem*> doubleNamedAllItems = treeWidget()->findItems(name, Qt::MatchFixedString | Qt::MatchCaseSensitive | Qt::MatchRecursive);
- //qDebug() << "doubleNamedAllItems: " << doubleNamedAllItems.count();
- QList<QTreeWidgetItem*> doubleNamedModuleItems;
- foreach (QTreeWidgetItem* item, doubleNamedAllItems) {
- //qDebug() << "item:" << item;
- if (item->parent()) {
- doubleNamedModuleItems << item;
- }
- }
- //qDebug() << "module items:" << doubleNamedModuleItems.count();
- return doubleNamedModuleItems;
+void BtInstallModuleChooserDialog::addModuleItem(CSwordModuleInfo *module,
+ const QString &sourceName)
+{
+ module->setProperty("installSourceName", sourceName);
+ m_bookshelfModel->addModule(module);
+}
+
+void BtInstallModuleChooserDialog::retranslateUi() {
+ setWindowTitle(tr("Install/Update works?"));
+ util::tool::initExplanationLabel(
+ label(), QString::null,
+ tr("Do you really want to install these works?") + "<br/><br/><small>" +
+ tr("Only one version of a work can be installed at the same time. Select only "
+ "one if there are items marked with red.") + "</small>");
+}
+
+void BtInstallModuleChooserDialog::showEvent(QShowEvent *event) {
+ Q_UNUSED(event);
+
+ if (m_shown) return;
+ bookshelfWidget()->treeView()->expandAll();
+ bookshelfWidget()->treeView()->header()->resizeSections(QHeaderView::ResizeToContents);
+ m_shown = true;
}
-void BtInstallModuleChooserDialog::enableOk(bool enabled) {
- qDebug() << "BtInstallModuleChooserDialog::enableOk" << enabled;
- okButton()->setEnabled(enabled);
+void BtInstallModuleChooserDialog::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) {
+ g.saveTo(groupingOrderKey);
}
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h
index 06144ff..070df6f 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h
+++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h
@@ -1,51 +1,55 @@
/*********
*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
*
**********/
#ifndef BTINSTALLMODULECHOOSERDIALOG_H
#define BTINSTALLMODULECHOOSERDIALOG_H
-#include "frontend/cmodulechooserdialog.h"
+#include "frontend/btmodulechooserdialog.h"
-#include <QList>
-#include <QMap>
-#include <QObject>
-#include <QString>
+#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h"
-class BTModuleTreeItem;
-class QWidget;
-class QTreeWidgetItem;
+class BtBookshelfModel;
+class BtInstallModuleChooserDialogModel;
+class CSwordModuleInfo;
/**
* Confirmation dialog for installation. Lets the user
* uncheck modules from the list.
*/
-class BtInstallModuleChooserDialog : public CModuleChooserDialog {
- Q_OBJECT
-
+class BtInstallModuleChooserDialog: public BtModuleChooserDialog {
+ Q_OBJECT
public:
- BtInstallModuleChooserDialog(QWidget* parent, QString title, QString label, QList<CSwordModuleInfo*>* empty);
+ BtInstallModuleChooserDialog(const BtBookshelfTreeModel::Grouping &g,
+ QWidget *parent = 0,
+ Qt::WindowFlags flags = 0);
- void initModuleItem(QString name, QTreeWidgetItem* sourceItem);
- void enableOk(bool enabled);
+ inline const QSet<CSwordModuleInfo*> &checkedModules() const {
+ return bookshelfWidget()->treeModel()->checkedModules();
+ }
- public slots:
- void slotItemChecked(QTreeWidgetItem* item, int column);
+ void addModuleItem(CSwordModuleInfo *module, const QString &sourceName);
protected:
- virtual void initModuleItem(BTModuleTreeItem*, QTreeWidgetItem*);
+ void retranslateUi();
+ void showEvent(QShowEvent *event);
+
+ protected slots:
+ void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g);
- QList<QTreeWidgetItem*> findModuleItemsByName(QString name);
private:
- QStringList m_nameList;
- QMap<QString, bool> m_doubleCheckedModules;
+ BtBookshelfModel *m_bookshelfModel;
+ bool m_shown;
};
-#endif
+#endif // BTINSTALLMODULECHOOSERDIALOG_H
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp
new file mode 100644
index 0000000..880ea6a
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.cpp
@@ -0,0 +1,136 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h"
+
+#include <QBrush>
+#include "backend/drivers/cswordmoduleinfo.h"
+#include "backend/managers/cswordbackend.h"
+
+
+#define MODULEPOINTERFORINDEX(i) static_cast<CSwordModuleInfo *>(\
+ BtBookshelfTreeModel::data((i), BtBookshelfModel::ModulePointerRole).value<void*>())
+
+BtInstallModuleChooserDialogModel::BtInstallModuleChooserDialogModel(
+ const Grouping &grouping,
+ QObject *parent)
+ : BtBookshelfTreeModel(grouping, parent), m_dataChangedFired(false)
+{
+ setDefaultChecked(BtBookshelfTreeModel::CHECKED);
+ setCheckable(true);
+ connect(this, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(parentDataChanged(QModelIndex,QModelIndex)),
+ Qt::DirectConnection);
+}
+
+BtInstallModuleChooserDialogModel::~BtInstallModuleChooserDialogModel() {
+ // Intentionally empty
+}
+
+QVariant BtInstallModuleChooserDialogModel::data(const QModelIndex &i, int role) const {
+ switch (role) {
+ case Qt::BackgroundRole:
+ if (isMulti(i)) return QBrush(Qt::red);
+ return BtBookshelfTreeModel::data(i, role);
+ case Qt::ForegroundRole:
+ if (isMulti(i)) return QBrush(Qt::white);
+ return BtBookshelfTreeModel::data(i, role);
+ case Qt::DisplayRole:
+ switch (i.column()) {
+ case 0:
+ return BtBookshelfTreeModel::data(i, role);
+ case 1:
+ {
+ CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent()));
+ if (module != 0) return module->property("installSourceName");
+ break;
+ }
+ case 2:
+ {
+ CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent()));
+ if (module == 0) break;
+ CSwordBackend *b = CSwordBackend::instance();
+ CSwordModuleInfo *imodule = b->findModuleByName(module->name());
+ if (imodule == 0) {
+ return module->config(CSwordModuleInfo::ModuleVersion);
+ } else {
+ return imodule->config(CSwordModuleInfo::ModuleVersion)
+ + " => "
+ + module->config(CSwordModuleInfo::ModuleVersion);
+ }
+ }
+ default: break;
+ }
+ default:
+ if (i.column() == 0) return BtBookshelfTreeModel::data(i, role);
+ }
+
+ return QVariant();
+}
+
+int BtInstallModuleChooserDialogModel::columnCount(const QModelIndex &parent) const {
+ Q_UNUSED(parent);
+
+ return 3;
+}
+
+QVariant BtInstallModuleChooserDialogModel::headerData(int section,
+ Qt::Orientation orientation,
+ int role) const
+{
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ switch (section) {
+ case 0: return tr("Work");
+ case 1: return tr("Installation source");
+ case 2: return tr("Version");
+ default: break;
+ }
+ }
+
+ return QVariant();
+}
+
+void BtInstallModuleChooserDialogModel::parentDataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
+{
+ Q_UNUSED(topLeft);
+ Q_UNUSED(bottomRight);
+
+ if (m_dataChangedFired) return;
+ m_dataChangedFired = true;
+ resetData();
+ m_dataChangedFired = false;
+}
+
+bool BtInstallModuleChooserDialogModel::isMulti(CSwordModuleInfo *m1) const {
+ if (m1 != 0 && checkedModules().contains(m1)) {
+ Q_FOREACH(CSwordModuleInfo *m2, m_modules.keys()) {
+ if (m1 != m2 && checkedModules().contains(m2) && m1->name() == m2->name()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool BtInstallModuleChooserDialogModel::isMulti(const QModelIndex &i) const {
+ if (!i.isValid()) return false;
+
+ if (!hasChildren(i)) {
+ return isMulti(MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent())));
+ } else {
+ for (int row = 0; row < rowCount(i); row++) {
+ if (isMulti(i.child(row, 0))) return true;
+ }
+ }
+ return false;
+}
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h
new file mode 100644
index 0000000..6120fa8
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallmodulechooserdialogmodel.h
@@ -0,0 +1,44 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTINSTALLMODULECHOOSERDIALOGMODEL_H
+#define BTINSTALLMODULECHOOSERDIALOGMODEL_H
+
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+
+#include <QMap>
+
+
+class BtInstallModuleChooserDialogModel: public BtBookshelfTreeModel {
+ Q_OBJECT
+ public:
+ BtInstallModuleChooserDialogModel(const Grouping &grouping, QObject *parent = 0);
+ ~BtInstallModuleChooserDialogModel();
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+
+ private slots:
+ void parentDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+ private:
+ bool isMulti(CSwordModuleInfo *module) const;
+ bool isMulti(const QModelIndex &index) const;
+
+ private:
+ QMap<QString, int> m_nameCounts;
+ bool m_dataChangedFired;
+};
+
+#endif // BTINSTALLMODULECHOOSERDIALOGMODEL_H
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp
index b71599a..d3bac59 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpage.cpp
@@ -2,63 +2,60 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
#include "frontend/bookshelfmanager/installpage/btinstallpage.h"
-#include <QAction>
#include <QApplication>
-#include <QButtonGroup>
#include <QComboBox>
-#include <QDialog>
-#include <QFileInfo>
+#include <QGroupBox>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QLabel>
-#include <QMessageBox>
-#include <QProgressBar>
-#include <QProgressDialog>
#include <QPushButton>
-#include <QSpacerItem>
-#include <QStackedWidget>
-#include <QTabBar>
-#include <QTimer>
-#include <QTreeWidget>
-#include <QTreeWidgetItem>
+#include <QSettings>
+#include <QSharedPointer>
+#include <QStackedLayout>
#include <QToolButton>
-#include <QVBoxLayout>
-#include <QWidget>
#include "backend/config/cbtconfig.h"
-#include "backend/drivers/cswordmoduleinfo.h"
-#include "backend/managers/cswordbackend.h"
-#include "frontend/bookshelfmanager/btconfigdialog.h"
-#include "frontend/bookshelfmanager/btinstallmgr.h"
+#include "backend/btinstallbackend.h"
#include "frontend/bookshelfmanager/btmodulemanagerdialog.h"
#include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h"
+#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h"
+#include "frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h"
#include "frontend/bookshelfmanager/installpage/btinstallpathdialog.h"
#include "frontend/bookshelfmanager/installpage/btinstallprogressdialog.h"
-#include "frontend/bookshelfmanager/installpage/btsourcewidget.h"
-#include "frontend/bookshelfmanager/installpage/btsourcearea.h"
-#include "frontend/bookshelfmanager/instbackend.h"
-#include "frontend/cmodulechooserdialog.h"
-#include "util/directory.h"
-#include "util/cpointers.h"
+#include "frontend/btbookshelfview.h"
#include "util/cresmgr.h"
+#include "util/dialogutil.h"
+#include "util/directory.h"
+#include "util/tool.h"
+
-// Sword includes:
-#include <swversion.h>
+namespace {
+const QString groupingOrderKey ("GUI/BookshelfManager/InstallPage/grouping");
+const QString headerStateKey ("GUI/BookshelfManager/InstallPage/headerState");
+const QString selectedModuleKey("GUI/BookshelfManager/InstallPage/selectedModule");
+} // anonymous namespace
// *********************************************************
// *********** Config dialog page: Install/Update **********
// *********************************************************
-BtInstallPage::BtInstallPage()
- : BtConfigPage() {
- qDebug() << "BtInstallPage::BtInstallPage() start";
+BtInstallPage::BtInstallPage(QWidget *parent)
+ : BtConfigPage(parent)
+ , m_groupingOrder(groupingOrderKey)
+ , m_modulesSelected(0)
+ , m_modulesSelectedSources(0)
+{
+ // Read settings:
+ m_headerState = CBTConfig::getConfig()->value(headerStateKey).toByteArray();
+
+ // Initialize widgets:
initView();
initConnections();
}
@@ -75,68 +72,105 @@ QString BtInstallPage::selectedInstallPath() {
void BtInstallPage::initView() {
namespace DU = util::directory;
- qDebug() << "void BtInstallPage::initView() start";
- QVBoxLayout *mainLayout = new QVBoxLayout(this);
-
- // installation path chooser
- QHBoxLayout* pathLayout = new QHBoxLayout();
- // beautify the layout
- int top;
- int bottom;
- int left;
- int right;
- pathLayout->getContentsMargins(&left, &top, &right, &bottom);
- pathLayout->setContentsMargins(left, top + 7, right, bottom + 7 );
- QLabel* pathLabel = new QLabel(tr("Install folder:"));
- m_pathCombo = new QComboBox();
+ // Warning label:
+
+ m_warningLabel = util::tool::explanationLabel(this, tr("WARNING!!!"),
+ tr("If you live in a persecuted country and don't want to risk "
+ "detection don't use remote sources."));
+
+ // Source chooser:
+ m_sourceGroupBox = new QGroupBox(tr("Select installation &source:"), this);
+ m_sourceGroupBox->setFlat(true);
+
+ m_sourceComboBox = new QComboBox(this);
+ m_sourceComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ initSourcesCombo();
+
+ m_sourceAddButton = new QPushButton(tr("&Add..."));
+ m_sourceAddButton ->setToolTip(tr("Add new source"));
+ m_sourceAddButton ->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::add_icon));
+
+ m_sourceDeleteButton = new QPushButton(tr("&Delete..."));
+ m_sourceDeleteButton->setToolTip(tr("Delete this source"));
+ m_sourceDeleteButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::delete_icon));
+
+ QHBoxLayout *sourceChooserLayout = new QHBoxLayout();
+ sourceChooserLayout->setContentsMargins(0, 0, 0, 0);
+ sourceChooserLayout->addWidget(m_sourceComboBox, 1);
+ sourceChooserLayout->addWidget(m_sourceAddButton);
+ sourceChooserLayout->addWidget(m_sourceDeleteButton);
+ m_sourceGroupBox->setLayout(sourceChooserLayout);
+
+ // Works chooser:
+ m_worksGroupBox = new QGroupBox(tr("Select &works to install:"), this);
+ m_worksGroupBox->setFlat(true);
+ m_worksLayout = new QStackedLayout();
+ m_worksGroupBox->setLayout(m_worksLayout);
+ slotSourceIndexChanged(m_sourceComboBox->currentIndex());
+
+ // Installation path chooser:
+ m_installGroupBox = new QGroupBox(this);
+ m_installGroupBox->setFlat(true);
+ retranslateInstallGroupBox();
+
+ m_pathLabel = new QLabel(tr("Install &folder:"));
+ m_pathCombo = new QComboBox(this);
m_pathCombo->setMinimumContentsLength(20);
m_pathCombo->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
m_pathCombo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
m_pathCombo->setToolTip(tr("The folder where the new works will be installed"));
m_pathCombo->view()->setTextElideMode(Qt::ElideMiddle);
- initPathCombo(); // set the paths and the current path
+ m_pathLabel->setBuddy(m_pathCombo);
+ initPathCombo();
+
m_configurePathButton = new QToolButton(this);
m_configurePathButton->setToolTip(tr("Configure folders where works are installed and found"));
m_configurePathButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::path_icon));
- pathLayout->addWidget(pathLabel);
- pathLayout->addWidget(m_pathCombo);
- pathLayout->addWidget(m_configurePathButton);
- mainLayout->addLayout(pathLayout);
-
- // Source widget
- m_sourceWidget = new BtSourceWidget(this);
- mainLayout->addWidget(m_sourceWidget);
- // Install button
- QHBoxLayout *installButtonLayout = new QHBoxLayout();
- installButtonLayout->setContentsMargins(0, 5, 0, 5);
- QSpacerItem *installButtonSpacer = new QSpacerItem(371, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- installButtonLayout->addItem(installButtonSpacer);
- m_installButton = new QPushButton(tr("Install..."), this);
+ m_installButton = new QPushButton(tr("&Install..."), this);
m_installButton->setToolTip(tr("Install or update selected works"));
m_installButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::install_icon));
m_installButton->setEnabled(false);
- installButtonLayout->addWidget(m_installButton);
- mainLayout->addLayout(installButtonLayout);
+ QHBoxLayout *pathLayout = new QHBoxLayout();
+ pathLayout->setContentsMargins(0, 0, 0, 0);
+ pathLayout->addWidget(m_pathLabel);
+ pathLayout->addWidget(m_pathCombo);
+ pathLayout->addWidget(m_configurePathButton);
+ pathLayout->addWidget(m_installButton);
+ m_installGroupBox->setLayout(pathLayout);
+
+ Q_ASSERT(qobject_cast<QVBoxLayout*>(layout()) != 0);
+ QVBoxLayout *mainLayout = static_cast<QVBoxLayout*>(layout());
+ mainLayout->addWidget(m_warningLabel);
+ mainLayout->addWidget(m_sourceGroupBox);
+ mainLayout->addWidget(m_worksGroupBox, 1);
+ mainLayout->addWidget(m_installGroupBox);
}
void BtInstallPage::initConnections() {
- qDebug() << "void BtInstallPage::initConnections() start";
- QObject::connect(m_pathCombo, SIGNAL(activated(const QString&)), this , SLOT(slotPathChanged(const QString&)));
- QObject::connect(m_configurePathButton, SIGNAL(clicked()), this, SLOT(slotEditPaths()));
- QObject::connect(m_installButton, SIGNAL(clicked()), m_sourceWidget, SLOT(slotInstall()) );
-
- QObject::connect(CPointers::backend(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), this, SLOT(slotSwordSetupChanged()));
- //source widget has its own connections, not here
+ connect(m_sourceComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(slotSourceIndexChanged(int)));
+ connect(m_sourceAddButton, SIGNAL(clicked()),
+ this, SLOT(slotSourceAdd()));
+ connect(m_sourceDeleteButton, SIGNAL(clicked()),
+ this, SLOT(slotSourceDelete()));
+ connect(m_installButton, SIGNAL(clicked()),
+ this, SLOT(slotInstall()));
+ connect(m_pathCombo, SIGNAL(activated(const QString&)),
+ this , SLOT(slotPathChanged(const QString&)));
+ connect(m_configurePathButton, SIGNAL(clicked()),
+ this, SLOT(slotEditPaths()));
+ connect(CSwordBackend::instance(),
+ SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)),
+ this, SLOT(slotSwordSetupChanged()));
}
void BtInstallPage::initPathCombo() {
- qDebug() << "void BtInstallPage::initPathCombo() start";
//populate the combo list
m_pathCombo->clear();
- QStringList targets = instbackend::targetList();
+ QStringList targets = BtInstallBackend::targetList();
for (QStringList::iterator it = targets.begin(); it != targets.end(); ++it) {
// Add the path only if it's writable
if ((*it).isEmpty()) continue;
@@ -154,43 +188,252 @@ void BtInstallPage::initPathCombo() {
m_pathCombo->setCurrentIndex(index);
}
+void BtInstallPage::initSourcesCombo() {
+ /// \todo Implement a proper model for this
+
+ m_sourceComboBox->clear();
+ QStringList sourceList = BtInstallBackend::sourceNameList();
+
+ // Add a default entry, the Crosswire main repository
+ if (sourceList.empty()) {
+ /// \todo Open a dialog which asks whether to get list from server and add sources
+ sword::InstallSource is("FTP"); //default return value
+ is.caption = "CrossWire Bible Society";
+ is.source = "ftp.crosswire.org";
+ is.directory = "/pub/sword/raw";
+ // passive ftp is not needed here, it's the default
+
+ BtInstallBackend::addSource(is);
+
+ sourceList = BtInstallBackend::sourceNameList();
+ Q_ASSERT(!sourceList.empty());
+ }
+
+ // Read selected module from config:
+ QString selected = CBTConfig::getConfig()->value(selectedModuleKey).toString();
+
+ // Populate combo box
+ bool selectionOk = false;
+ for (int i = 0; i < sourceList.size(); i++) {
+ m_sourceComboBox->addItem(sourceList.at(i));
+
+ // Select configured item:
+ if (!selectionOk && sourceList.at(i) == selected) {
+ m_sourceComboBox->setCurrentIndex(i);
+ selectionOk = true;
+ }
+ }
+
+ // Set selection, if it wasn't properly configured:
+ if (!selectionOk) {
+ m_sourceComboBox->setCurrentIndex(0);
+ CBTConfig::getConfig()->setValue(selectedModuleKey, sourceList.at(0));
+ }
+}
+
+void BtInstallPage::activateSource(const sword::InstallSource &src) {
+ qDebug() << "Selected source" << src.caption;
+ qApp->setOverrideCursor(Qt::WaitCursor);
+ BtInstallPageWorksWidget *w = m_sourceMap.value(QString(src.caption), 0);
+ if (w == 0) {
+ if (parentDialog() != 0) parentDialog()->setEnabled(false);
+ qApp->processEvents();
+ w = new BtInstallPageWorksWidget(src, m_groupingOrder, this);
+ m_sourceMap.insert(QString(src.caption), w);
+ m_worksLayout->addWidget(w);
+ connect(w->treeModel(), SIGNAL(groupingOrderChanged(BtBookshelfTreeModel::Grouping)),
+ this, SLOT(slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping&)));
+ connect(w->treeModel(), SIGNAL(moduleChecked(CSwordModuleInfo*,bool)),
+ this, SLOT(slotSelectedModulesChanged()));
+ if (parentDialog() != 0) parentDialog()->setEnabled(true);
+ } else {
+ disconnect(w->treeView()->header(), SIGNAL(geometriesChanged()),
+ this, SLOT(slotHeaderChanged()));
+ }
+ m_worksLayout->setCurrentWidget(w);
+ w->treeModel()->setGroupingOrder(m_groupingOrder);
+ w->treeView()->header()->restoreState(m_headerState);
+ connect(w->treeView()->header(), SIGNAL(geometriesChanged()),
+ this, SLOT(slotHeaderChanged()));
+ qApp->restoreOverrideCursor();
+}
+
+void BtInstallPage::retranslateInstallGroupBox() {
+ if (m_modulesSelected > 0) {
+ m_installGroupBox->setTitle(tr("Start installation of %1 works from %2 sources:")
+ .arg(m_modulesSelected)
+ .arg(m_modulesSelectedSources));
+ } else {
+ m_installGroupBox->setTitle(tr("Start installation:"));
+ }
+}
+
+void BtInstallPage::slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g) {
+ m_groupingOrder = g;
+ m_groupingOrder.saveTo(groupingOrderKey);
+}
+
+void BtInstallPage::slotHeaderChanged() {
+ typedef BtInstallPageWorksWidget IPWW;
+ Q_ASSERT(qobject_cast<IPWW*>(m_worksLayout->currentWidget()) != 0);
+ IPWW *w = static_cast<IPWW*>(m_worksLayout->currentWidget());
+ m_headerState = w->treeView()->header()->saveState();
+ CBTConfig::getConfig()->setValue(headerStateKey, m_headerState);
+}
+
+void BtInstallPage::slotInstall() {
+ qDebug() << "BtInstallPage::slotInstall";
+
+ // check that the destination path is writable, do nothing if not and user doesn't want to continue
+ QDir dir = selectedInstallPath();
+ bool canWrite = true;
+ if (dir.isReadable()) {
+ const QFileInfo fi( dir.canonicalPath() );
+ if (!fi.exists() || !fi.isWritable()) {
+ canWrite = false;
+ }
+ }
+ else {
+ canWrite = false;
+ }
+ if (!canWrite) {
+ const int result = util::showWarning(this, tr("Warning"), tr("The destination directory is not writable or does not exist. Installation will fail unless this has first been fixed."), QMessageBox::Ignore | QMessageBox::Cancel, QMessageBox::Cancel);
+ if (result != QMessageBox::Ignore) {
+ return;
+ }
+ }
+
+ // create the confirmation dialog
+ BtInstallModuleChooserDialog *dlg = new BtInstallModuleChooserDialog(m_groupingOrder, this);
+
+ // Add all checked modules from all tabs:
+ Q_FOREACH (BtInstallPageWorksWidget *w, m_sourceMap.values()) {
+ Q_FOREACH (CSwordModuleInfo *module, w->treeModel()->checkedModules()) {
+ dlg->addModuleItem(module, QString(w->installSource().caption));
+ }
+ }
+
+ if (dlg->exec() == QDialog::Accepted) {
+ QSet<const CSwordModuleInfo*> cm;
+ Q_FOREACH(const CSwordModuleInfo *m, dlg->checkedModules()) {
+ cm.insert(m);
+ }
+
+ if (cm.empty()) return;
+
+ /// \todo first remove all modules which will be updated from the module list
+ // but what modules? all with the same real name? (there may be _n modules...)
+
+ BtModuleManagerDialog *parentDlg = dynamic_cast<BtModuleManagerDialog*>(parentDialog());
+
+ BtInstallProgressDialog *dlg = new BtInstallProgressDialog(cm, selectedInstallPath(), parentDlg);
+
+ if (!parentDlg) qDebug() << "error, wrong parent!";
+
+ m_installButton->setEnabled(false);
+
+ // the progress dialog is now modal, it can be made modeless later.
+ dlg->exec();
+
+ qDebug() << "BtSourceWidget::slotInstallAccepted end";
+ }
+ delete dlg;
+}
+
void BtInstallPage::slotPathChanged(const QString& /*pathText*/) {
CBTConfig::set(CBTConfig::installPathIndex, m_pathCombo->currentIndex( ) );
}
void BtInstallPage::slotEditPaths() {
- qDebug() << "void BtInstallPage::slotEditPaths() start";
-
BtInstallPathDialog* dlg = new BtInstallPathDialog();
int result = dlg->exec();
if (result == QDialog::Accepted) {
//dynamic_cast<BtModuleManagerDialog*>(parentDialog())->slotSwordSetupChanged();
- CPointers::backend()->reloadModules(CSwordBackend::PathChanged);
+ CSwordBackend::instance()->reloadModules(CSwordBackend::PathChanged);
}
}
-// implement the BtConfigPage methods
+void BtInstallPage::slotSourceAdd() {
+ typedef CSwordSetupInstallSourcesDialog SSISD;
-QString BtInstallPage::iconName() {
- return CResMgr::bookshelfmgr::installpage::icon;
+ QSharedPointer<SSISD> dlg(new SSISD());
+ if (dlg->exec() == QDialog::Accepted) {
+ if (!dlg->wasRemoteListAdded()) {
+ sword::InstallSource newSource = dlg->getSource();
+ if ( !((QString)newSource.type.c_str()).isEmpty() ) { // we have a valid source to add
+ BtInstallBackend::addSource(newSource);
+ }
+ initSourcesCombo();
+ for (int i = 0; i < m_sourceComboBox->count(); i++) {
+ if (m_sourceComboBox->itemText(i) == newSource.caption) {
+ m_sourceComboBox->setCurrentIndex(i);
+ break;
+ }
+ }
+ }
+ }
}
-QString BtInstallPage::label() {
- // \todo move the warning to a dialog which is shown when adding a source.
- return tr("Install and update works. Add remote or local sources, refresh them, select the works to be installed/updated and click Install.<br/><b>WARNING:</b> If you live in a persecuted country and don't want to risk detection don't use remote sources.");
+
+void BtInstallPage::slotSourceDelete() {
+ typedef BtInstallPageWorksWidget IPWW;
+
+ int ret = util::showWarning(this, tr("Delete Source?"),
+ tr("Do you really want to delete this source?"),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (ret == QMessageBox::Yes) {
+ Q_ASSERT(qobject_cast<IPWW*>(m_worksLayout->currentWidget()));
+ IPWW *w = static_cast<IPWW*>(m_worksLayout->currentWidget());
+ w->deleteSource();
+ initSourcesCombo();
+ slotSourceIndexChanged(m_sourceComboBox->currentIndex());
+ delete w;
+ }
}
-QString BtInstallPage::header() {
- return tr("Install/Update");
+
+void BtInstallPage::slotSourceIndexChanged(int index) {
+ if (index < 0) index = 0;
+
+ /// \todo use pointers instead of text
+ QString moduleName = m_sourceComboBox->itemText(index);
+ CBTConfig::getConfig()->setValue(selectedModuleKey, moduleName);
+ activateSource(BtInstallBackend::source(moduleName));
}
-void BtInstallPage::slotSwordSetupChanged() {
- qDebug() << "BtInstallPage::slotSwordSetupChanged";
- initPathCombo();
-// for (int i = 0; i < m_sourceWidget->count(); i++ ) {
-// BtSourceArea* sourceArea = dynamic_cast<BtSourceArea*>(m_sourceWidget->widget(i));
-// Q_ASSERT(sourceArea);
-// sourceArea->createModuleTree();
-// }
+void BtInstallPage::slotSelectedModulesChanged() {
+ m_modulesSelected = 0;
+ m_modulesSelectedSources = 0;
+ Q_FOREACH (BtInstallPageWorksWidget *w, m_sourceMap.values()) {
+ int selected = w->treeModel()->checkedModules().size();
+ if (selected > 0) {
+ m_modulesSelectedSources++;
+ m_modulesSelected += selected;
+ }
+ }
+
+ m_installButton->setEnabled(m_modulesSelected > 0);
+ retranslateInstallGroupBox();
+}
+
+// implement the BtConfigPage methods
+
+const QIcon &BtInstallPage::icon() const {
+ return util::directory::getIcon(CResMgr::bookshelfmgr::installpage::icon);
}
+QString BtInstallPage::header() const {
+ return tr("Install/Update");
+}
+void BtInstallPage::slotSwordSetupChanged() {
+ QString moduleName = m_sourceComboBox->currentText();
+ initSourcesCombo();
+ qDeleteAll(m_sourceMap.values());
+ m_sourceMap.clear();
+ m_sourceComboBox->setCurrentIndex(m_sourceComboBox->findText(moduleName));
+ initPathCombo();
+ m_modulesSelected = 0;
+ m_modulesSelectedSources = 0;
+ retranslateInstallGroupBox();
+}
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpage.h b/src/frontend/bookshelfmanager/installpage/btinstallpage.h
index fde9919..88d1f92 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallpage.h
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpage.h
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -12,29 +12,34 @@
#include "frontend/bookshelfmanager/btconfigdialog.h"
-#include <QString>
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
-// Sword includes:
-#include <installmgr.h>
+namespace sword {
+class InstallSource;
+}
-class BtSourceWidget;
+class BtInstallPageWorksWidget;
class QComboBox;
+class QGroupBox;
class QPushButton;
+class QStackedLayout;
class QToolButton;
/**
* The Install page includes module path chooser, source/module handler and install button.
*/
-class BtInstallPage : public BtConfigPage {
+class BtInstallPage: public BtConfigPage {
Q_OBJECT
+
public:
- BtInstallPage();
+ BtInstallPage(QWidget *parent = 0);
+
+ /** Reimplemented from BtConfigPage. */
+ virtual const QIcon &icon() const;
- // reimplemented from btinstallpage
- QString iconName();
- QString label();
- QString header();
+ /** Reimplemented from BtConfigPage. */
+ virtual QString header() const;
void setInstallEnabled(bool b);
@@ -47,18 +52,46 @@ class BtInstallPage : public BtConfigPage {
void initView();
void initConnections();
void initPathCombo();
+ void initSourcesCombo();
+
+ void activateSource(const sword::InstallSource &src);
+ void retranslateInstallGroupBox();
private slots:
+ void slotGroupingOrderChanged(const BtBookshelfTreeModel::Grouping &g);
+ void slotHeaderChanged();
+ void slotInstall();
void slotPathChanged(const QString& pathText);
void slotEditPaths();
+ void slotSourceAdd();
+ void slotSourceDelete();
+ void slotSourceIndexChanged(int index);
+ void slotSelectedModulesChanged();
private:
+ BtBookshelfTreeModel::Grouping m_groupingOrder;
+ QByteArray m_headerState;
+
+ QMap<QString, BtInstallPageWorksWidget*> m_sourceMap;
+
+ QLabel *m_warningLabel;
+
+ QGroupBox *m_sourceGroupBox;
+ QComboBox *m_sourceComboBox;
+ QPushButton *m_sourceAddButton;
+ QPushButton *m_sourceDeleteButton;
+
+ QGroupBox *m_worksGroupBox;
+ QStackedLayout *m_worksLayout;
+
+ QGroupBox *m_installGroupBox;
+ QLabel *m_pathLabel;
+ QComboBox *m_pathCombo;
+ QToolButton *m_configurePathButton;
+ QPushButton *m_installButton;
- QComboBox* m_pathCombo;
- //QPushButton* m_configurePathButton;
- QToolButton* m_configurePathButton;
- BtSourceWidget* m_sourceWidget;
- QPushButton* m_installButton;
+ unsigned m_modulesSelected;
+ unsigned m_modulesSelectedSources;
};
#endif
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp
new file mode 100644
index 0000000..9aa6743
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.cpp
@@ -0,0 +1,87 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#include "frontend/bookshelfmanager/installpage/btinstallpagemodel.h"
+
+
+#include "backend/drivers/cswordmoduleinfo.h"
+#include "backend/managers/cswordbackend.h"
+
+
+#define MODULEPOINTERFORINDEX(i) static_cast<CSwordModuleInfo *>(\
+ BtBookshelfTreeModel::data((i), BtBookshelfModel::ModulePointerRole).value<void*>())
+
+BtInstallPageModel::BtInstallPageModel(const Grouping &grouping, QObject *parent)
+ : BtBookshelfTreeModel(grouping, parent)
+{
+ setDefaultChecked(BtBookshelfTreeModel::UNCHECKED);
+ setCheckable(true);
+}
+
+BtInstallPageModel::~BtInstallPageModel() {
+ // Intentionally empty
+}
+
+QVariant BtInstallPageModel::data(const QModelIndex &i, int role) const {
+ switch (role) {
+ case Qt::DisplayRole:
+ switch (i.column()) {
+ case 0:
+ return BtBookshelfTreeModel::data(i, role);
+ case 1:
+ {
+ CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent()));
+ if (module == 0) break;
+ CSwordBackend *b = CSwordBackend::instance();
+ CSwordModuleInfo *imodule = b->findModuleByName(module->name());
+ if (imodule == 0) {
+ return module->config(CSwordModuleInfo::ModuleVersion);
+ } else {
+ return imodule->config(CSwordModuleInfo::ModuleVersion)
+ + " => "
+ + module->config(CSwordModuleInfo::ModuleVersion);
+ }
+ }
+ case 2:
+ {
+ CSwordModuleInfo *module = MODULEPOINTERFORINDEX(index(i.row(), 0, i.parent()));
+ if (module != 0) return module->config(CSwordModuleInfo::Description);
+ }
+ default: break;
+ }
+ default:
+ if (i.column() == 0) return BtBookshelfTreeModel::data(i, role);
+ }
+
+ return QVariant();
+}
+
+int BtInstallPageModel::columnCount(const QModelIndex &parent) const {
+ Q_UNUSED(parent);
+
+ return 3;
+}
+
+QVariant BtInstallPageModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ switch (section) {
+ case 0: return tr("Work");
+ case 1: return tr("Version");
+ case 2: return tr("Description");
+ default: break;
+ }
+ }
+
+ return QVariant();
+}
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h
new file mode 100644
index 0000000..8a02409
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpagemodel.h
@@ -0,0 +1,33 @@
+/*********
+*
+* In the name of the Father, and of the Son, and of the Holy Spirit.
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License
+* version 2.0.
+*
+**********/
+
+#ifndef BTINSTALLPAGEMODEL_H
+#define BTINSTALLPAGEMODEL_H
+
+#include "backend/bookshelfmodel/btbookshelftreemodel.h"
+
+#include <QMap>
+
+
+class BtInstallPageModel: public BtBookshelfTreeModel {
+ Q_OBJECT
+ public:
+ BtInstallPageModel(const Grouping &grouping, QObject *parent = 0);
+ ~BtInstallPageModel();
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+};
+
+#endif // BTINSTALLPAGEMODEL_H
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp
new file mode 100644
index 0000000..6b9fb53
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.cpp
@@ -0,0 +1,140 @@
+/*********
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+*
+**********/
+
+#include "frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h"
+
+#include <QApplication>
+#include <QAction>
+#include <QDebug>
+#include <QTimer>
+#include <QToolButton>
+#include "backend/btinstallbackend.h"
+#include "backend/managers/cswordbackend.h"
+#include "frontend/bookshelfmanager/installpage/btinstallpage.h"
+#include "frontend/bookshelfmanager/installpage/btinstallpagemodel.h"
+#include "frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h"
+#include "frontend/btbookshelfview.h"
+#include "util/cresmgr.h"
+#include "util/directory.h"
+
+
+namespace {
+
+/** Filters out already installed modules which can't be updated right now. */
+bool filter(CSwordModuleInfo *mInfo) {
+ typedef CSwordModuleInfo CSMI;
+ typedef sword::SWVersion SV;
+
+ const CSMI *installedModule = CSwordBackend::instance()->findModuleByName(mInfo->name());
+ if (installedModule) {
+ // Already installed, check if it's an update:
+ const SV curVersion(installedModule->config(CSMI::ModuleVersion).toLatin1());
+ const SV newVersion(mInfo->config(CSMI::ModuleVersion).toLatin1());
+ if (curVersion >= newVersion) {
+ return false;
+ }
+ }
+ return true;
+}
+
+}
+
+BtInstallPageWorksWidget::BtInstallPageWorksWidget(
+ const sword::InstallSource &source,
+ const BtBookshelfTreeModel::Grouping &g,
+ BtInstallPage *parent, Qt::WindowFlags flags)
+ : BtBookshelfWidget(parent, flags)
+ , m_source(source)
+ , m_parent(parent)
+ , m_backend(0)
+ , m_myModel(0)
+{
+ namespace DU = util::directory;
+
+ qDebug() << "Creating new BtInstallPageWorksWidget for source" << source.caption;
+
+ setTreeModel(new BtInstallPageModel(g, this));
+
+ treeView()->setHeaderHidden(false);
+ showHideButton()->hide();
+ showHideAction()->setVisible(false);
+
+ m_sourceRefreshButton = new QToolButton(this);
+ m_sourceRefreshButton->setAutoRaise(true);
+ m_sourceRefreshButton ->setToolTip(tr("Refresh the list of works from this source"));
+ m_sourceRefreshButton ->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::refresh_icon));
+ setRightCornerWidget(m_sourceRefreshButton);
+
+ connect(m_sourceRefreshButton, SIGNAL(clicked()),
+ this, SLOT(slotSourceRefresh()));
+
+ // Delayed init, part 1 - disable parent:
+ parent->setEnabled(false);
+}
+
+BtInstallPageWorksWidget::~BtInstallPageWorksWidget() {
+ qDebug() << "Deleting BtInstallPageWorksWidget for source" << m_source.caption;
+
+ delete m_backend;
+}
+
+void BtInstallPageWorksWidget::deleteSource() {
+ qDebug() << "Deleting source" << m_source.caption;
+
+ setEnabled(false);
+ m_myModel->clear();
+ BtInstallBackend::deleteSource(QString(m_source.caption));
+}
+
+void BtInstallPageWorksWidget::updateTree() {
+ qDebug() << "Updating BtInstallPageWorksWidget tree for source" << m_source.caption;
+
+ m_myModel->clear();
+
+ // Is this necessary?
+ m_source = BtInstallBackend::source(QString(m_source.caption));
+ m_backend = BtInstallBackend::backend(m_source);
+
+ // Repopulate model:
+ Q_FOREACH(CSwordModuleInfo *module, m_backend->moduleList()) {
+ if (filter(module)) m_myModel->addModule(module);
+ }
+}
+
+void BtInstallPageWorksWidget::paintEvent(QPaintEvent *e) {
+ // Delayed init, part 2 - queue init when painted:
+ if (m_myModel == 0) {
+ QTimer::singleShot(0, this, SLOT(slotDelayedInit()));
+ }
+ BtBookshelfWidget::paintEvent(e);
+}
+
+void BtInstallPageWorksWidget::slotDelayedInit() {
+ // Delayed init, part 3 - initialize + reenable parent
+ qApp->setOverrideCursor(Qt::WaitCursor);
+ m_backend = BtInstallBackend::backend(m_source);
+ Q_ASSERT(m_backend != 0);
+ m_myModel = new BtBookshelfModel(this);
+ Q_FOREACH(CSwordModuleInfo *module, m_backend->moduleList()) {
+ if (filter(module)) m_myModel->addModule(module);
+ }
+ setSourceModel(m_myModel);
+ m_parent->setEnabled(true);
+ qApp->restoreOverrideCursor();
+}
+
+void BtInstallPageWorksWidget::slotSourceRefresh() {
+ qDebug() << "Refreshing source" << m_source.caption;
+
+ if (BtInstallBackend::isRemote(m_source)) {
+ BtRefreshProgressDialog d(m_source, this);
+ if (!d.runAndDelete()) return;
+ }
+ updateTree();
+}
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h
new file mode 100644
index 0000000..1a9bd8f
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpageworkswidget.h
@@ -0,0 +1,59 @@
+/*********
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+*
+**********/
+
+#ifndef BTINSTALLPAGEWORKSWIDGET_H
+#define BTINSTALLPAGEWORKSWIDGET_H
+
+
+#include "frontend/btbookshelfwidget.h"
+
+// Sword includes
+#include <installmgr.h>
+
+
+class BtInstallPage;
+
+class BtInstallPageWorksWidget: public BtBookshelfWidget {
+ Q_OBJECT
+
+ public: /* Methods: */
+
+ BtInstallPageWorksWidget(const sword::InstallSource &source,
+ const BtBookshelfTreeModel::Grouping &g,
+ BtInstallPage *parent, Qt::WindowFlags f = 0);
+
+ ~BtInstallPageWorksWidget();
+
+ inline const sword::InstallSource &installSource() const {
+ return m_source;
+ }
+ void deleteSource();
+
+ private: /* Methods: */
+
+ void updateTree();
+
+ /** Reimplemented from QWidget. */
+ virtual void paintEvent(QPaintEvent *e);
+
+ private slots:
+
+ void slotDelayedInit();
+ void slotSourceRefresh();
+
+ private: /* Fields: */
+
+ sword::InstallSource m_source;
+ BtInstallPage *m_parent;
+ QToolButton *m_sourceRefreshButton;
+ CSwordBackend *m_backend;
+ BtBookshelfModel *m_myModel;
+};
+
+#endif // BTINSTALLPAGEWORKSWIDGET_H
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp
index 9efb9f0..a272d89 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -15,13 +15,12 @@
#include <QDir>
#include <QFileDialog>
#include <QGridLayout>
-#include <QHeaderView>
#include <QLabel>
#include <QPushButton>
#include <QString>
#include <QTreeWidget>
#include <QTreeWidgetItem>
-#include "frontend/bookshelfmanager/instbackend.h"
+#include "backend/btinstallbackend.h"
#include "util/dialogutil.h"
#include "util/directory.h"
#include "util/cresmgr.h"
@@ -47,7 +46,7 @@ BtInstallPathDialog::BtInstallPathDialog() {
tr("Configure bookshelf folders"), l1 + QString("<small><br/><br/>") + l2 + QString("</small>"));
mainLayout->addWidget(mainLabel);
- QString swordConfPath = instbackend::swordConfigFilename();
+ QString swordConfPath = BtInstallBackend::swordConfigFilename();
/// \todo After releasing 2.4, change the following line to: QLabel *confPathLabel = new QLabel(tr("Configuration file for the folders is: <b>%1</b>").arg(swordConfPath), this);
QLabel* confPathLabel = new QLabel(tr("Configuration file for the folders is: ").append("<b>%1</b>").arg(swordConfPath), this);
confPathLabel->setWordWrap(true);
@@ -55,7 +54,7 @@ BtInstallPathDialog::BtInstallPathDialog() {
m_swordPathListBox = new QTreeWidget(this);
- m_swordPathListBox->header()->hide();
+ m_swordPathListBox->setHeaderHidden(true);
QString rwfolderitem(tr("Folders where new works can be installed"));
m_writableItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(rwfolderitem));;
@@ -65,7 +64,7 @@ BtInstallPathDialog::BtInstallPathDialog() {
m_nonexistingItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(tr("Nonexistent folders")));;
m_nonexistingItem->setFlags(Qt::ItemIsEnabled);
- QStringList targets = instbackend::targetList();
+ QStringList targets = BtInstallBackend::targetList();
foreach (QString pathname, targets) {
addPathToList(pathname);
@@ -76,19 +75,19 @@ BtInstallPathDialog::BtInstallPathDialog() {
QVBoxLayout* buttonLayout = new QVBoxLayout();
- m_addButton = new QPushButton(tr("Add..."), this);
+ m_addButton = new QPushButton(tr("&Add..."), this);
m_addButton->setToolTip(tr("Add new folder"));
m_addButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::add_icon));
connect(m_addButton, SIGNAL(clicked()), this, SLOT(slotAddClicked()));
buttonLayout->addWidget(m_addButton);
- m_editButton = new QPushButton(tr("Edit..."), this);
+ m_editButton = new QPushButton(tr("&Edit..."), this);
m_editButton->setToolTip(tr("Edit the selected folder"));
m_editButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::edit_icon));
connect(m_editButton, SIGNAL(clicked()), this, SLOT(slotEditClicked()));
buttonLayout->addWidget(m_editButton);
- m_removeButton = new QPushButton(tr("Remove"), this);
+ m_removeButton = new QPushButton(tr("&Remove"), this);
m_removeButton->setToolTip(tr("Remove the selected folder"));
m_removeButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::remove_icon));
connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveClicked()));
@@ -162,7 +161,7 @@ void BtInstallPathDialog::addPathToList(QString pathname) {
i = new QTreeWidgetItem(m_readableItem, QStringList(pathname) );
}
}
- if (i && QDir(pathname) == instbackend::swordDir()) {
+ if (i && QDir(pathname) == BtInstallBackend::swordDir()) {
i->setFlags(Qt::NoItemFlags);
i->setToolTip(0, tr("This default folder in your home directory can't be removed"));
}
@@ -231,7 +230,7 @@ void BtInstallPathDialog::writeSwordConfig() {
++it;
}
qDebug() << "save the target list" << targets;
- instbackend::setTargetList(targets); //creates new Sword config
+ BtInstallBackend::setTargetList(targets); //creates new Sword config
}
void BtInstallPathDialog::accept() {
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h
index e72da3c..9adf6bc 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h
+++ b/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.h
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
index 365d5c8..465ec03 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
+++ b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.cpp
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -22,11 +22,13 @@
#include <QVBoxLayout>
#include "backend/managers/cswordbackend.h"
#include "frontend/bookshelfmanager/installpage/btinstallthread.h"
-#include "util/cpointers.h"
-BtInstallProgressDialog::BtInstallProgressDialog(QWidget* parent, QTreeWidget* selectedModulesTreeWidget, QString destination)
- : QDialog(parent) {
+BtInstallProgressDialog::BtInstallProgressDialog(
+ const QSet<const CSwordModuleInfo*> &modules,
+ const QString &destination, QWidget *parent, Qt::WindowFlags flags)
+ : QDialog(parent, flags)
+{
// we want this dialog to be deleted when user closes it or the downloads are completed
setAttribute(Qt::WA_DeleteOnClose, true);
setWindowTitle(tr("Install Progress"));
@@ -39,39 +41,34 @@ BtInstallProgressDialog::BtInstallProgressDialog(QWidget* parent, QTreeWidget* s
m_statusWidget->header()->setMovable(false);
//m_statusWidget->setColumnWidth(1, util::tool::mWidth(m_statusWidget, 2));
- foreach (QTreeWidgetItem* sourceItem, selectedModulesTreeWidget->invisibleRootItem()->takeChildren()) {
- // create items and threads for modules under this source
- foreach (QTreeWidgetItem* moduleItem, sourceItem->takeChildren()) {
- if (moduleItem->checkState(0) == Qt::Checked) {
- // create a thread for this module
- BtInstallThread* thread = new BtInstallThread(this, moduleItem->text(0), sourceItem->text(0), destination);
- m_waitingThreads.insert(sourceItem->text(0), thread);
- m_threadsByModule.insert(moduleItem->text(0), thread);
- // progress widget/item
- QPushButton* stopButton = new QPushButton(tr("Stop"), m_statusWidget);
- stopButton->setFixedSize(stopButton->sizeHint());
-
- // the item
- QTreeWidgetItem* progressItem = new QTreeWidgetItem(m_statusWidget);
- m_statusWidget->setColumnWidth(2, stopButton->sizeHint().width());
- progressItem->setSizeHint(2, stopButton->sizeHint());
- progressItem->setText(0, moduleItem->text(0));
- progressItem->setFlags(Qt::ItemIsEnabled);
- m_statusWidget->setItemWidget(progressItem, 2, stopButton);
- progressItem->setText(1, tr("Waiting for turn..."));
-
- //connect the signals between the dialog, items and threads
- QObject::connect(stopButton, SIGNAL(clicked()), thread, SLOT(slotStopInstall()), Qt::QueuedConnection);
- QObject::connect(thread, SIGNAL(installStopped(QString, QString)), this, SLOT(slotOneItemStopped(QString, QString)), Qt::QueuedConnection);
- //is this needed or is statusUpdated enough?
- QObject::connect(thread, SIGNAL(installCompleted(QString, QString, int)), this, SLOT(slotOneItemCompleted(QString, QString, int)), Qt::QueuedConnection);
- QObject::connect(thread, SIGNAL(statusUpdated(QString, int)), this, SLOT(slotStatusUpdated(QString, int)), Qt::QueuedConnection);
- QObject::connect(thread, SIGNAL(downloadStarted(QString)), this, SLOT(slotDownloadStarted(QString)), Qt::QueuedConnection);
-
- QObject::connect(thread, SIGNAL(preparingInstall(QString, QString)), this, SLOT(slotInstallStarted(QString, QString)), Qt::QueuedConnection);
-
- }
- }
+ Q_FOREACH(const CSwordModuleInfo *module, modules) {
+ const QString sourceName(module->property("installSourceName").toString());
+ // create a thread for this module
+ BtInstallThread* thread = new BtInstallThread(module->name(), sourceName, destination);
+ m_waitingThreads.insert(sourceName, thread);
+ m_threadsByModule.insert(module->name(), thread);
+ // progress widget/item
+ QPushButton* stopButton = new QPushButton(tr("Stop"), m_statusWidget);
+ stopButton->setFixedSize(stopButton->sizeHint());
+
+ // the item
+ QTreeWidgetItem* progressItem = new QTreeWidgetItem(m_statusWidget);
+ m_statusWidget->setColumnWidth(2, stopButton->sizeHint().width());
+ progressItem->setSizeHint(2, stopButton->sizeHint());
+ progressItem->setText(0, module->name());
+ progressItem->setFlags(Qt::ItemIsEnabled);
+ m_statusWidget->setItemWidget(progressItem, 2, stopButton);
+ progressItem->setText(1, tr("Waiting for turn..."));
+
+ //connect the signals between the dialog, items and threads
+ QObject::connect(stopButton, SIGNAL(clicked()), thread, SLOT(slotStopInstall()), Qt::QueuedConnection);
+ QObject::connect(thread, SIGNAL(installStopped(QString, QString)), this, SLOT(slotOneItemStopped(QString, QString)), Qt::QueuedConnection);
+ //is this needed or is statusUpdated enough?
+ QObject::connect(thread, SIGNAL(installCompleted(QString, QString, int)), this, SLOT(slotOneItemCompleted(QString, QString, int)), Qt::QueuedConnection);
+ QObject::connect(thread, SIGNAL(statusUpdated(QString, int)), this, SLOT(slotStatusUpdated(QString, int)), Qt::QueuedConnection);
+ QObject::connect(thread, SIGNAL(downloadStarted(QString)), this, SLOT(slotDownloadStarted(QString)), Qt::QueuedConnection);
+
+ QObject::connect(thread, SIGNAL(preparingInstall(QString, QString)), this, SLOT(slotInstallStarted(QString, QString)), Qt::QueuedConnection);
}
m_statusWidget->setMinimumWidth(m_statusWidget->size().width());
@@ -93,22 +90,22 @@ void BtInstallProgressDialog::startThreads() {
// remove all the updated modules from the backend module list at once
//foreach (QString mName, m_threadsByModule.keys()) {
//}
- //QList<CSwordModuleInfo*> CPointers::backend()->takeModulesFromList(m_threadsByModule.keys());
+ //QList<CSwordModuleInfo*> CSwordBackend::instance()()->takeModulesFromList(m_threadsByModule.keys());
qDebug() << "start threads...";
//loop through the multimap of the waiting threads, start at most 3 threads for each source
QMultiMap<QString, BtInstallThread*>::iterator threadIterator = m_waitingThreads.end();
// concurrency is disabled for now
-// while (threadIterator != m_waitingThreads.end()) {
-// QString sourceName = threadIterator.key();
-// qDebug() << sourceName;
-// if (m_runningThreads.values(sourceName).count() < 3) {
-// BtInstallThread* t = threadIterator.value();
-// m_runningThreads.insert(sourceName, t);
-// threadIterator = m_waitingThreads.erase(threadIterator);
-// t->start();
-// }
-// else ++threadIterator;
-// }
+// while (threadIterator != m_waitingThreads.end()) {
+// QString sourceName = threadIterator.key();
+// qDebug() << sourceName;
+// if (m_runningThreads.values(sourceName).count() < 3) {
+// BtInstallThread* t = threadIterator.value();
+// m_runningThreads.insert(sourceName, t);
+// threadIterator = m_waitingThreads.erase(threadIterator);
+// t->start();
+// }
+// else ++threadIterator;
+// }
//non-concurrent
if (threadIterator != m_waitingThreads.begin()) {
// go to the last item which is actually the first in the visible list
@@ -157,16 +154,16 @@ void BtInstallProgressDialog::oneItemStoppedOrCompleted(QString module, QString
m_waitingThreads.remove(source, m_threadsByModule.value(module));
//concurrency is disabled for now
-// //start a waiting thread if there are any
-// QList<BtInstallThread*> threadsForSource = m_waitingThreads.values(source);
-// qDebug() << threadsForSource;
-// if (!threadsForSource.isEmpty()) {
-// qDebug() << "Threads are waiting for turn";
-// BtInstallThread* thread = threadsForSource.at(0);
-// m_waitingThreads.remove(source, thread);
-// m_runningThreads.insert(source, thread);
-// thread->start();
-// }
+// //start a waiting thread if there are any
+// QList<BtInstallThread*> threadsForSource = m_waitingThreads.values(source);
+// qDebug() << threadsForSource;
+// if (!threadsForSource.isEmpty()) {
+// qDebug() << "Threads are waiting for turn";
+// BtInstallThread* thread = threadsForSource.at(0);
+// m_waitingThreads.remove(source, thread);
+// m_runningThreads.insert(source, thread);
+// thread->start();
+// }
//non-concurrent
QMultiMap<QString, BtInstallThread*>::iterator threadIterator = m_waitingThreads.end();
@@ -238,7 +235,7 @@ void BtInstallProgressDialog::closeEvent(QCloseEvent* event) {
return;
}
// other parts of the UI/engine must be updated
- CPointers::backend()->reloadModules(CSwordBackend::AddedModules);
+ CSwordBackend::instance()->reloadModules(CSwordBackend::AddedModules);
}
bool BtInstallProgressDialog::threadsDone() {
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h
index 1d8113a..8b990ad 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h
+++ b/src/frontend/bookshelfmanager/installpage/btinstallprogressdialog.h
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -17,13 +17,16 @@
class BtInstallThread;
+class CSwordModuleInfo;
class QTreeWidget;
class QTreeWidgetItem;
class BtInstallProgressDialog : public QDialog {
Q_OBJECT
public:
- BtInstallProgressDialog(QWidget* parent, QTreeWidget* selectedModulesTreeWidget, QString destination);
+ BtInstallProgressDialog(const QSet<const CSwordModuleInfo*> &modules,
+ const QString &destination, QWidget *parent = 0,
+ Qt::WindowFlags flags = 0);
~BtInstallProgressDialog();
@@ -43,7 +46,7 @@ class BtInstallProgressDialog : public QDialog {
virtual void closeEvent(QCloseEvent* event);
//signals:
-// void swordSetupChanged();
+// void swordSetupChanged();
private:
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp b/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp
index 53ae071..2d04a51 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp
+++ b/src/frontend/bookshelfmanager/installpage/btinstallthread.cpp
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -16,14 +16,14 @@
#include <QThread>
#include "backend/managers/cswordbackend.h"
#include "frontend/bookshelfmanager/btinstallmgr.h"
-#include "frontend/bookshelfmanager/instbackend.h"
-#include "util/cpointers.h"
+#include "backend/btinstallbackend.h"
// Sword includes:
#include <filemgr.h>
-BtInstallThread::BtInstallThread(QObject* parent, QString moduleName, QString sourceName, QString destinationName)
+BtInstallThread::BtInstallThread(const QString &moduleName, const QString &sourceName,
+ const QString &destinationName, QObject *parent)
: QThread(parent),
done(false),
m_module(moduleName),
@@ -45,8 +45,8 @@ void BtInstallThread::run() {
emit preparingInstall(m_module, m_source);
//This is 0 before set here - remember when using the value when cancelling
// the installation before this has been run
- m_installSource.reset(new sword::InstallSource(instbackend::source(m_source)));
- m_backendForSource.reset(instbackend::backend(*m_installSource));
+ m_installSource = QSharedPointer<sword::InstallSource>(new sword::InstallSource(BtInstallBackend::source(m_source)));
+ m_backendForSource = QSharedPointer<CSwordBackend>(BtInstallBackend::backend(*m_installSource));
//make sure target/mods.d and target/modules exist
/// \todo move this to some common precondition
@@ -74,9 +74,9 @@ void BtInstallThread::run() {
// manager for the destination path
sword::SWMgr lMgr( m_destination.toLatin1() );
- if (instbackend::isRemote(*m_installSource)) {
+ if (BtInstallBackend::isRemote(*m_installSource)) {
qDebug() << "calling install";
- int status = m_iMgr->installModule(&lMgr, 0, m_module.toLatin1(), m_installSource.get());
+ int status = m_iMgr->installModule(&lMgr, 0, m_module.toLatin1(), m_installSource.data());
if (status != 0) {
qWarning() << "Error with install: " << status << "module:" << m_module;
}
@@ -123,7 +123,7 @@ void BtInstallThread::slotStopInstall() {
qDebug() << "BtInstallThread::slotStopInstall 3";
// cleanup: remove the module, remove the temp files
// if installation has already started
- if (m_installSource.get() != 0) {
+ if (m_installSource.data() != 0) {
qDebug() << "BtInstallThread::slotStopInstall 4";
// remove the installed module, just to be sure because mgr may
// have been terminated when copying files
@@ -148,9 +148,9 @@ void BtInstallThread::slotDownloadStarted() {
void BtInstallThread::removeModule() {
qDebug() << "BtInstallThread::removeModule start";
CSwordModuleInfo* m;
- m = CPointers::backend()->findModuleByName(m_module);
+ m = CSwordBackend::instance()->findModuleByName(m_module);
if (!m) {
- m = instbackend::backend(instbackend::source(m_destination.toLatin1()))->findModuleByName(m_module);
+ m = BtInstallBackend::backend(BtInstallBackend::source(m_destination.toLatin1()))->findModuleByName(m_module);
}
if (m) { //module found?
qDebug() << "BtInstallThread::removeModule, module" << m_module << "found";
@@ -164,7 +164,7 @@ void BtInstallThread::removeModule() {
prefixPath.remove( prefixPath.indexOf(dataPath), dataPath.length() );
}
else {
- prefixPath = QString::fromLatin1(CPointers::backend()->prefixPath);
+ prefixPath = QString::fromLatin1(CSwordBackend::instance()->prefixPath);
}
sword::SWMgr mgr(prefixPath.toLatin1());
@@ -182,8 +182,8 @@ void BtInstallThread::removeTempFiles() {
// (take the remote conf file for this module, take DataPath,
// take the absolute path of the InstallMgr)
- //sword::InstallSource is = instbackend::source(m_source);
- if (instbackend::isRemote(*m_installSource)) {
+ //sword::InstallSource is = BtInstallBackend::source(m_source);
+ if (BtInstallBackend::isRemote(*m_installSource)) {
// get the path for the module temp files
CSwordModuleInfo* mInfo = m_backendForSource->findModuleByName(m_module);
QString dataPath = mInfo->config(CSwordModuleInfo::AbsoluteDataPath);
diff --git a/src/frontend/bookshelfmanager/installpage/btinstallthread.h b/src/frontend/bookshelfmanager/installpage/btinstallthread.h
index a50910f..8bb660d 100644
--- a/src/frontend/bookshelfmanager/installpage/btinstallthread.h
+++ b/src/frontend/bookshelfmanager/installpage/btinstallthread.h
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2008 by the BibleTime developers.
+* Copyright 1999-2011 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -12,11 +12,12 @@
#include <QThread>
-#include <boost/scoped_ptr.hpp>
+#include <QSharedPointer>
#include "frontend/bookshelfmanager/btinstallmgr.h"
class BtInstallProgressDialog;
+class CSwordBackend;
/**
* Thread for installing a module.
@@ -54,7 +55,8 @@ temporary files manually.
class BtInstallThread : public QThread {
Q_OBJECT
public:
- BtInstallThread(QObject* parent, QString moduleName, QString sourceName, QString destinationName);
+ BtInstallThread(const QString &moduleName, const QString &sourceName,
+ const QString &destinationName, QObject *parent = 0);
~BtInstallThread();
@@ -77,10 +79,10 @@ class BtInstallThread : public QThread {
bool m_cancelled;
BtInstallMgr* m_iMgr;
//BtInstallMgr m_iMgr;
- boost::scoped_ptr<sword::InstallSource> m_installSource;
+ QSharedPointer<sword::InstallSource> m_installSource;
/// \todo it would be best to get the backend from the bookshelf manager install page
// where it has already been created. Could fasten the progress dialog startup.
- boost::scoped_ptr<CSwordBackend> m_backendForSource;
+ QSharedPointer<CSwordBackend> m_backendForSource;
signals:
/** Emitted when the install progress status is updated. */
diff --git a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp
new file mode 100644
index 0000000..3666888
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.cpp
@@ -0,0 +1,62 @@
+#include "frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h"
+
+#include <QApplication>
+#include <QDebug>
+#include "backend/btinstallbackend.h"
+#include "util/dialogutil.h"
+
+
+BtRefreshProgressDialog::BtRefreshProgressDialog(sword::InstallSource &source,
+ QWidget *parent,
+ Qt::WindowFlags flags)
+ : QProgressDialog(parent, flags)
+ , m_source(source)
+{
+ qDebug() << "Creating BtRefreshProgressDialog for source" << source.caption;
+
+ Q_ASSERT(BtInstallBackend::isRemote(source));
+ setWindowTitle(tr("Refreshing source %1").arg(QString(source.caption)));
+ setCancelButtonText(tr("&Cancel"));
+ setLabelText(tr("Connecting..."));
+ Q_ASSERT(minimum() == 0);
+ setMaximum(100);
+ setValue(0);
+ setWindowModality(Qt::ApplicationModal);
+ setMinimumDuration(1000);
+
+ connect(this, SIGNAL(canceled()),
+ this, SLOT(slotCanceled()));
+ connect(&m_installMgr, SIGNAL(percentCompleted(int,int)),
+ this, SLOT(slotPercentCompleted(int,int)));
+}
+
+void BtRefreshProgressDialog::slotPercentCompleted(int, int current) {
+ qDebug() << "BtRefreshProgressDialog progress:" << current;
+
+ setValue(current);
+ qApp->processEvents();
+}
+
+void BtRefreshProgressDialog::slotCanceled() {
+ qDebug() << "BtRefreshProgressDialog cancel clicked.";
+
+ m_installMgr.terminate();
+}
+
+bool BtRefreshProgressDialog::runAndDelete() {
+ qDebug() << "BtRefreshProgressDialog runAndDelete()";
+
+ show();
+ qApp->processEvents();
+ bool r = (m_installMgr.refreshRemoteSource(&m_source) == 0);
+ if (r) {
+ setValue(100);
+ qApp->processEvents();
+ } else {
+ util::showWarning(this, tr("Warning"),
+ tr("Failed to refresh source %1")
+ .arg(QString(m_source.caption)));
+ }
+ deleteLater();
+ return r;
+}
diff --git a/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h
new file mode 100644
index 0000000..dfabcf6
--- /dev/null
+++ b/src/frontend/bookshelfmanager/installpage/btrefreshprogressdialog.h
@@ -0,0 +1,38 @@
+/*********
+*
+* This file is part of BibleTime's source code, http://www.bibletime.info/.
+*
+* Copyright 1999-2011 by the BibleTime developers.
+* The BibleTime source code is licensed under the GNU General Public License version 2.0.
+*
+**********/
+
+#ifndef BTREFRESHPROGRESSDIALOG_H
+#define BTREFRESHPROGRESSDIALOG_H
+
+#include <QProgressDialog>
+
+#include "frontend/bookshelfmanager/btinstallmgr.h"
+
+
+class BtRefreshProgressDialog: public QProgressDialog {
+ Q_OBJECT
+
+ public: /* Methods: */
+ BtRefreshProgressDialog(sword::InstallSource &source,
+ QWidget *parent = 0, Qt::WindowFlags f = 0);
+
+ bool runAndDelete();
+
+ private slots:
+
+ void slotPercentCompleted(int, int);
+ void slotCanceled();
+
+ private: /* Fields: */
+
+ sword::InstallSource m_source;
+ BtInstallMgr m_installMgr;
+};
+
+#endif // BTREFRESHPROGRESSDIALOG_H
diff --git a/src/frontend/bookshelfmanager/installpage/btsourcearea.cpp b/src/frontend/bookshelfmanager/installpage/btsourcearea.cpp
deleted file mode 100644
index ca85822..0000000
--- a/src/frontend/bookshelfmanager/installpage/btsourcearea.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/*********
-*
-* This file is part of BibleTime's source code, http://www.bibletime.info/.
-*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
-*
-**********/
-
-#include "frontend/bookshelfmanager/installpage/btsourcearea.h"
-
-#include <QString>
-#include <QWidget>
-#include <QMap>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QSpacerItem>
-#include <QLabel>
-#include <QPushButton>
-#include <QTreeWidget>
-#include <QTreeWidgetItem>
-#include <QHeaderView>
-#include <QDebug>
-#include <QTime>
-#include "backend/managers/cswordbackend.h"
-#include "frontend/bookshelfmanager/instbackend.h"
-#include "frontend/btaboutmoduledialog.h"
-#include "util/directory.h"
-#include "util/cpointers.h"
-#include "util/cresmgr.h"
-#include "util/tool.h"
-
-// Sword includes:
-#include <installmgr.h>
-
-
-// ****************************************************************
-// ******** Installation source and module list widget ************
-// ****************************************************************
-
-BtSourceArea::BtSourceArea(const QString& sourceName)
- : QWidget(),
- m_sourceName(sourceName),
- m_treeAlreadyInitialized(false),
- m_remoteBackend(0) { //important!
- setObjectName(sourceName);
- m_checkedModules = QMap<QString, bool>();
- qDebug() << "BtSourceArea::BtSourceArea, " << m_sourceName;
- initView();
-}
-
-BtSourceArea::~BtSourceArea() {
- qDebug() << "BtSourceArea::~BtSourceArea" << m_sourceName;
- delete m_remoteBackend;
-}
-
-void BtSourceArea::initView() {
- namespace DU = util::directory;
-
- qDebug() << "BtSourceArea::initView";
- QVBoxLayout *mainLayout = new QVBoxLayout(this);
-
- // source related button row
- QHBoxLayout *sourceLayout = new QHBoxLayout();
- m_refreshButton = new QPushButton(tr("Refresh..."));
- m_refreshButton->setToolTip(tr("Refresh the list of works from this source"));
- m_refreshButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::refresh_icon));
- //m_refreshButton->setEnabled(false);
- QSpacerItem *sourceSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- //m_editButton = new QPushButton(tr("Edit..."));
- /// \todo after writing the edit widget:
- //m_editButton->setEnabled(false);
- m_deleteButton = new QPushButton(tr("Delete..."));
- m_deleteButton->setToolTip(tr("Delete this source"));
- m_deleteButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::delete_icon));
- //m_deleteButton->setEnabled(false);
- m_addButton = new QPushButton(tr("Add..."));
- m_addButton->setToolTip(tr("Add new source"));
- m_addButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::installpage::add_icon));
-
- sourceLayout->addWidget(m_refreshButton);
- sourceLayout->addItem(sourceSpacer);
- //sourceLayout->addWidget(m_editButton);
- sourceLayout->addWidget(m_deleteButton);
- sourceLayout->addWidget(m_addButton);
-
- mainLayout->addLayout(sourceLayout);
- // There are no views for the stack yet, see initSources
- m_view = new QTreeWidget(this);
- m_view->setHeaderLabels(QStringList() << tr("Work") << tr("Description"));
- m_view->setColumnWidth(0, util::tool::mWidth(m_view, 20));
- mainLayout->addWidget(m_view);
-
- connect(m_view, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), SLOT(slotItemDoubleClicked(QTreeWidgetItem*, int)));
- connect(CPointers::backend(), SIGNAL(sigSwordSetupChanged(CSwordBackend::SetupChangedReason)), SLOT(slotSwordSetupChanged()));
- connect(this, SIGNAL(signalCreateTree()), SLOT(slotCreateTree()), Qt::QueuedConnection);
-}
-
-void BtSourceArea::prepareRemove() {
- // don't create tree anymore, this will be removed
- disconnect(this, SIGNAL(signalCreateTree()), this, SLOT(slotCreateTree()));
-}
-
-QSize BtSourceArea::sizeHint() const {
- return QSize(100, m_refreshButton->height() + (m_view->header()->height() * 5));
-}
-
-void BtSourceArea::initTreeFirstTime() {
- if (!m_treeAlreadyInitialized) {
- createModuleTree();
- m_treeAlreadyInitialized = true;
- }
-}
-
-void BtSourceArea::createModuleTree() {
- qDebug() << "BtSourceArea::createModuleTree start";
- // Start creating tree with a queued connection.
- // This makes showing the dialog possible even before the tree is initialized.
- emit signalCreateTree();
-}
-void BtSourceArea::slotCreateTree() {
- qDebug() << "BtSourceArea::slotCreateTree" << QTime::currentTime ();
- //let the dialog become visible
- QCoreApplication::processEvents();
- // Creating the view and populating list may take time
- QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
-
- // disconnect the signal so that we don't have to run functions for every module
- // (note: what to do if we want to restore the item selection when rebuilding?
- disconnect(m_view, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotSelectionChanged(QTreeWidgetItem*, int)) );
- m_view->clear();
-
- /// \todo if the tree already exists for this source, maybe the selections should be preserved
- m_checkedModules.clear();
-
- sword::InstallSource is = instbackend::source(m_sourceName);
- delete m_remoteBackend; // the old one can be deleted
- m_remoteBackend = instbackend::backend(is);
- Q_ASSERT(m_remoteBackend);
- m_moduleList = m_remoteBackend->moduleList();
-
- // give the list to BTModuleTreeItem, create filter to remove
- // those modules which are installed already
- InstalledFilter alreadyInstalledFilter(m_sourceName);
- QList<BTModuleTreeItem::Filter*> filterList;
- filterList.append(&alreadyInstalledFilter);
- BTModuleTreeItem rootItem(filterList, BTModuleTreeItem::CatLangMod, &m_moduleList);
-
- addToTree(&rootItem, m_view->invisibleRootItem());
- QCoreApplication::processEvents();
- // receive signal when user checks modules
- connect(m_view, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotSelectionChanged(QTreeWidgetItem*, int)) );
- QApplication::restoreOverrideCursor();
- qDebug() << "BtSourceArea::createModuleTree end" << QTime::currentTime ();
-}
-
-void BtSourceArea::addToTree(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) {
- //qDebug()<<"BtSourceArea::addToTree "<<item->text();
- //qDebug() << "BTMTItem type: " << item->type();
-
- foreach (BTModuleTreeItem* i, item->children()) {
- addToTree(i, new QTreeWidgetItem(widgetItem));
- }
- if (item->type() != BTModuleTreeItem::Root) {
- CSwordModuleInfo* mInfo = item->moduleInfo();
- widgetItem->setText(0, item->text());
- if (item->type() == BTModuleTreeItem::Category || item->type() == BTModuleTreeItem::Language) {
- //qDebug() << "item"<<item->text()<< "was cat or lang";
- widgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate);
- }
- if (item->type() == BTModuleTreeItem::Module) {
- //qDebug() << "item"<<item->text()<< "was a module";
- widgetItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
- widgetItem->setCheckState(0, Qt::Unchecked);
-
- CSwordModuleInfo* const installedModule = CPointers::backend()->findModuleByName(mInfo->name());
- QString installedV;
-
- if (!installedModule) {
- /**
- \todo maybe? save the module list of a source before refreshing,
- compare after refreshing, mark the newly added modules if
- not newly added:
- state: installable (no indicator)
- else: status: newly added, color yellow
- */
- } else { // the module is already installed
- QBrush bg(QColor(255, 153, 153)); /// \bug Possible color conflict
- widgetItem->setBackground(0, bg);
- widgetItem->setBackground(1, bg);
- installedV = QString(installedModule->config(CSwordModuleInfo::ModuleVersion).toLatin1());
- // set the color for the parent items
- QTreeWidgetItem* parent1 = widgetItem->parent();
- if (parent1) {
- parent1->setBackground(0, bg);
- parent1->setBackground(1, bg);
- QTreeWidgetItem* parent2 = parent1->parent();
- if (parent2) {
- parent2->setBackground(0, bg);
- parent2->setBackground(1, bg);
- }
- }
- }
-
-
- QString descr(mInfo->config(CSwordModuleInfo::Description));
- QString toolTipText = util::tool::remoteModuleToolTip(mInfo, installedV);
-
- widgetItem->setText(1, descr);
- widgetItem->setToolTip(0, toolTipText);
- widgetItem->setToolTip(1, toolTipText);
- }
- }
-}
-
-QTreeWidget* BtSourceArea::treeWidget() {
- return m_view;
-}
-
-// return the selected modules
-QMap<QString, bool>* BtSourceArea::selectedModules() {
- return &m_checkedModules;
-}
-
-// when a module is checked/unchecked
-void BtSourceArea::slotSelectionChanged(QTreeWidgetItem* item, int column) {
- //qDebug() << "BtSourceArea::slotSelectionChanged";
- // modify the internal list of selected (actually checked) modules
- // if() leaves groups away
- if (!item->childCount() && column == 0) {
- foreach (CSwordModuleInfo* module, m_moduleList) {
- if (module->name() == item->text(0)) {
- if (item->checkState(0) == Qt::Checked) {
- qDebug() << module->name() << "was checked";
- m_checkedModules.insert(module->name(), true);
- }
- else {
- qDebug() << module->name() << "was unchecked";
- m_checkedModules.remove(module->name());
- }
- emit signalSelectionChanged(m_sourceName, m_checkedModules.count());
- break;
- }
- }
- }
-}
-
-void BtSourceArea::slotItemDoubleClicked(QTreeWidgetItem* item, int /*column*/) {
- CSwordModuleInfo* mInfo = m_remoteBackend->findModuleByName(item->text(0));
- if (mInfo) {
- BTAboutModuleDialog* dialog = new BTAboutModuleDialog(this, mInfo);
- dialog->show();
- dialog->raise();
- }
-}
-
-BtSourceArea::InstalledFilter::InstalledFilter(QString sourceName)
- : BTModuleTreeItem::Filter(),
- m_source(instbackend::source(sourceName)),
- m_swordBackend(instbackend::backend(m_source)) {
- // these are set once to optimize away repeated calls
- // m_source, m_swordBackend
-
-}
-//filter out already installed, not updateable modules
-bool BtSourceArea::InstalledFilter::filter(CSwordModuleInfo* mInfo) {
- //qDebug() << "BtSourceArea::InstalledFilter::filter, module " << mInfo->name();
- CSwordModuleInfo* const installedModule = CPointers::backend()->findModuleByName(mInfo->name());
- if (installedModule) {
- //qDebug() << "already installed, check if it's an update...";
- const sword::SWVersion installedVersion(installedModule->config(CSwordModuleInfo::ModuleVersion).toLatin1());
- const sword::SWVersion newVersion(mInfo->config(CSwordModuleInfo::ModuleVersion).toLatin1());
- if (installedVersion >= newVersion) {
- return false;
- }
- }
- return true;
-}
-
-void BtSourceArea::slotSwordSetupChanged() {
- createModuleTree();
-}
diff --git a/src/frontend/bookshelfmanager/installpage/btsourcearea.h b/src/frontend/bookshelfmanager/installpage/btsourcearea.h
deleted file mode 100644
index ece20ed..0000000
--- a/src/frontend/bookshelfmanager/installpage/btsourcearea.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*********
-*
-* This file is part of BibleTime's source code, http://www.bibletime.info/.
-*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
-*
-**********/
-
-#ifndef BTSOURCEAREA_H
-#define BTSOURCEAREA_H
-
-#include <QWidget>
-
-#include <boost/scoped_ptr.hpp>
-#include <QApplication>
-#include <QMap>
-#include "backend/btmoduletreeitem.h"
-
-// Sword includes:
-#include <installmgr.h>
-
-
-class QTreeWidget;
-class QTreeWidgetItem;
-class QLabel;
-class QPushButton;
-
-/**
-* Area for one install source.
-*
-* - Tree widget for modules
-* - Buttons for handling the source(s): refresh, edit, remove, add
-*
-* Each source has
-* QTreeWidget, populated with the module tree if the source
-* module list is in a local cache. Refreshing the source refreshes
-* the cache and rebuilds the module tree. Sources are not refreshed
-* automatically, only by the user action, one source at a time.
-*/
-class BtSourceArea : public QWidget {
- Q_OBJECT
-
- friend class BtSourceWidget;
- public:
-
- struct InstalledFilter : BTModuleTreeItem::Filter {
- InstalledFilter(QString sourceName);
- bool filter(CSwordModuleInfo*);
- sword::InstallSource m_source;
- boost::scoped_ptr<CSwordBackend> m_swordBackend;
- };
-
- BtSourceArea(const QString& sourceName);
- ~BtSourceArea();
-
- void initView();
- void prepareRemove();
- /** Reimplemented from QWidget. */
- virtual QSize sizeHint() const;
- void initTreeFirstTime();
- QTreeWidget* treeWidget();
-
- QMap<QString, bool>* selectedModules();
-
- public slots:
- void slotSwordSetupChanged();
- /** Create a module tree for a tree widget */
- void createModuleTree();
-
- signals:
- void signalSelectionChanged(QString sourceName, int selectedCount);
- void signalCreateTree();
-
- private slots:
- void slotCreateTree();
- void slotSelectionChanged(QTreeWidgetItem* item, int column);
- void slotItemDoubleClicked(QTreeWidgetItem* item, int column);
- private:
- void addToTree(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem);
-
- QString m_sourceName;
- bool m_treeAlreadyInitialized;
- QMap<QString, bool> m_checkedModules;
- CSwordBackend* m_remoteBackend; // needed for the module list
- QList<CSwordModuleInfo*> m_moduleList;
-
- QTreeWidget* m_view;
- QLabel* m_refreshTimeLabel;
- QPushButton* m_refreshButton;
- QPushButton* m_editButton;
- QPushButton* m_deleteButton;
- QPushButton* m_addButton;
-};
-
-#endif
diff --git a/src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp b/src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp
deleted file mode 100644
index 81e84fb..0000000
--- a/src/frontend/bookshelfmanager/installpage/btsourcewidget.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/*********
-*
-* This file is part of BibleTime's source code, http://www.bibletime.info/.
-*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
-*
-**********/
-
-#include "frontend/bookshelfmanager/installpage/btsourcewidget.h"
-
-#include <QApplication>
-#include <QFileInfo>
-#include <QHBoxLayout>
-#include <QLabel>
-#include <QProgressDialog>
-#include <QPushButton>
-#include <QString>
-#include <QTabBar>
-#include <QTabWidget>
-#include <QTreeWidget>
-#include <QTreeWidgetItem>
-#include <QWidget>
-#include "frontend/bookshelfmanager/btinstallmgr.h"
-#include "frontend/bookshelfmanager/btmodulemanagerdialog.h"
-#include "frontend/bookshelfmanager/cswordsetupinstallsourcesdialog.h"
-#include "frontend/bookshelfmanager/installpage/btinstallmodulechooserdialog.h"
-#include "frontend/bookshelfmanager/installpage/btinstallpage.h"
-#include "frontend/bookshelfmanager/installpage/btinstallprogressdialog.h"
-#include "frontend/bookshelfmanager/installpage/btsourcearea.h"
-#include "frontend/bookshelfmanager/instbackend.h"
-#include "util/dialogutil.h"
-
-
-/**
-* Tab Widget that holds source widgets
-*/
-BtSourceWidget::BtSourceWidget(BtInstallPage* parent)
- : QTabWidget(parent),
- m_page(parent) {
- qDebug() << "BtSourceWidget::BtSourceWidget start";
- initSources();
- // send queued event because "Delete" is initiated from tab which should be deleted
- connect(this, SIGNAL(sigInitSources()), SLOT(initSources()), Qt::QueuedConnection);
- /// \todo choose the page from config
-
-}
-
-BtSourceArea* BtSourceWidget::area() {
- return dynamic_cast<BtSourceArea*>(currentWidget());
-}
-
-QString BtSourceWidget::currentSourceName() {
- qDebug() << "BtSourceWidget::currentSourceName: " << m_sourceNameList.at(currentIndex());
- return m_sourceNameList.at(currentIndex());
-}
-
-void BtSourceWidget::initSourceConnections() {
- qDebug() << "void BtSourceWidget::initSourceConnections() start";
- if (area()) {
- connect(area()->m_refreshButton, SIGNAL(clicked()), SLOT(slotRefresh()));
- //connect(area()->m_editButton, SIGNAL(clicked()), SLOT(slotEdit()));
- connect(area()->m_deleteButton, SIGNAL(clicked()), SLOT(slotDelete()), Qt::QueuedConnection);
- connect(area()->m_addButton, SIGNAL(clicked()), SLOT(slotAdd()));
- connect(area(), SIGNAL(signalSelectionChanged(QString, int)), SLOT(slotModuleSelectionChanged(QString, int)) );
- }
- qDebug() << "void BtSourceWidget::initSourceConnections() end";
-}
-
-void BtSourceWidget::slotEdit() {
- qDebug() << "BtSourceWidget::slotEdit";
- /// \todo open the source editor dialog
-
- // if the source was changed, init the sources
-
-}
-
-void BtSourceWidget::slotDelete() {
- qDebug() << "void BtSourceWidget::slotDelete() start";
- // ask for confirmation
- int ret = util::showWarning(this, tr("Delete Source?"),
- tr("Do you really want to delete this source?"),
- QMessageBox::Yes | QMessageBox::No);
-
- if (ret == QMessageBox::Yes) {
- instbackend::deleteSource(currentSourceName());
- initSources();
- }
-}
-
-void BtSourceWidget::slotAdd() {
-
- boost::scoped_ptr<CSwordSetupInstallSourcesDialog> dlg( new CSwordSetupInstallSourcesDialog() );
- sword::InstallSource newSource(""); //empty, invalid Source
-
- if (dlg->exec() == QDialog::Accepted) {
- if (!dlg->wasRemoteListAdded()) {
- newSource = dlg->getSource();
- if ( !((QString)newSource.type.c_str()).isEmpty() ) { // we have a valid source to add
- instbackend::addSource(newSource);
- }
- }
- initSources();
- }
-}
-
-
-void BtSourceWidget::slotRefresh() {
- qDebug() << "void BtSourceWidget::slotRefresh() start";
- // (re)build the module cache for the source
-
- QString sourceName = currentSourceName();
-
- // quick enough, make it modal so that we don't need to take care of anything else
- m_progressDialog = new QProgressDialog("", tr("Cancel"), 0 , 100, this);
- m_progressDialog->setWindowTitle(tr("Refreshing Source"));
- m_progressDialog->setMinimumDuration(0);
-
- /// \todo get rid of the backend code, BtInstallMgr and progressdialog could handle this
- //write method BtInstallMgr::slotRefreshCanceled()
- connect(m_progressDialog, SIGNAL(canceled()), SLOT(slotRefreshCanceled()));
-
- // BACKEND CODE **********************************************************
- // would this be possible: instbackend::refreshSource( arguments );
- qDebug() << "void BtSourceWidget::slotRefresh 1";
- BtInstallMgr iMgr;
- m_currentInstallMgr = &iMgr; //for the progress dialog
- sword::InstallSource is = instbackend::source(sourceName);
- bool success = false;
- qDebug() << "void BtSourceWidget::slotRefresh 2";
- // connect this directly to the dialog setValue(int) if possible
- connect(&iMgr, SIGNAL(percentCompleted(const int, const int)), SLOT(slotRefreshCompleted(const int, const int)));
-
- if (instbackend::isRemote(is)) {
- m_progressDialog->show();
- qApp->processEvents();
- this->slotRefreshCompleted(0, 0);
- m_progressDialog->setLabelText(tr("Connecting..."));
- m_progressDialog->setValue(0);
- qApp->processEvents();
- qDebug() << "void BtSourceWidget::slotRefresh 3";
- bool successful = iMgr.refreshRemoteSource( &is );
- if (!successful ) { //make sure the sources were updated sucessfully
- success = true;
- m_progressDialog->setValue(100); //make sure the dialog closes
- }
- else {
- qWarning("InstallMgr: refreshRemoteSources returned an error.");
- success = false;
- }
- }
- else {
- // Local source, update the list
- success = true;
- }
-
- delete m_progressDialog;
- m_progressDialog = 0;
-
- // rebuild the view tree and refresh the view
- if (success) {
- qDebug() << "void BtSourceWidget::slotRefresh 4";
- area()->createModuleTree();
- }
-}
-
-/// \todo try to move this to BtInstallMgr
-void BtSourceWidget::slotRefreshCanceled() {
- qDebug() << "BtSourceWidget::slotRefreshCanceled";
- Q_ASSERT(m_currentInstallMgr);
- if (m_currentInstallMgr) {
- m_currentInstallMgr->terminate();
- }
- qApp->processEvents();
-}
-
-/// \todo try to move this to progress dialog
-void BtSourceWidget::slotRefreshCompleted(const int, const int current) {
- qDebug() << "BtSourceWidget::slotRefreshCompleted";
- if (m_progressDialog) {
- if (m_progressDialog->labelText() != tr("Refreshing...")) {
- m_progressDialog->setLabelText(tr("Refreshing..."));
- }
- m_progressDialog->setValue(current);
- }
- qApp->processEvents();
-}
-
-// init the tabbar, setup the module tree for the current source
-void BtSourceWidget::initSources() {
- qDebug() << "void BtSourceWidget::initSources() start";
-
- //first clear all sources
- //int i = count();
- for (int i = count() - 1; i >= 0; i--) {
- BtSourceArea* a = dynamic_cast<BtSourceArea*>(widget(i));
- a->prepareRemove();
- }
- for (int i = count() - 1; i >= 0; i--) {
- qDebug() << "remove tab" << tabText(i);
- QWidget* w = widget(i);
- removeTab(i);
- delete w;
- qDebug() << "deleted";
- }
- m_sourceNameList.clear();
-
- // ***** Use the backend to get the list of sources *****
- instbackend::initPassiveFtpMode();
- QStringList sourceList = instbackend::sourceList();
- qDebug() << "got the source list from backend:" << sourceList;
- // Add a default entry, the Crosswire main repository
- if (!sourceList.count()) {
- /// \todo Open a dialog which asks whether to get list from server and add sources
- sword::InstallSource is("FTP"); //default return value
- is.caption = "CrossWire Bible Society";
- is.source = "ftp.crosswire.org";
- is.directory = "/pub/sword/raw";
- // passive ftp is not needed here, it's the default
-
- instbackend::addSource(is);
-
- sourceList = instbackend::sourceList();
- //Q_ASSERT( sourceList.count() > 0 );
- }
- qDebug() << "void BtSourceWidget::initSources 1";
- // Add the sources to the widget
- foreach (QString sourceName, sourceList) {
- addSource(sourceName);
- }
- // connect this after the tabs have been created,
- // otherwise the signal is caught too early.
- QObject::connect(this, SIGNAL(currentChanged(int)), this, SLOT(slotTabSelected(int)));
- qDebug() << "void BtSourceWidget::initSources end";
- /// \todo select the current source from the config
- // It's important to choose something because the tree is not initialized until now
- setCurrentIndex(0);
- slotTabSelected(0); // setting the index wasn't enough if there were only 1 tab
-
- if (sourceList.count() == 0) {
- QHBoxLayout* l = new QHBoxLayout(this);
- QLabel* message = new QLabel(QString("<i>") + tr("No sources were found in the SWORD configuration and BibleTime couldn't create a default source. Check your SWORD configuration and that the configuration path is writable. Then restart the Bookshelf Manager.") + QString("</i>"), this);
- message->setWordWrap(true);
- l->addWidget(message);
- }
-}
-
-void BtSourceWidget::addSource(const QString& sourceName) {
- qDebug() << "void BtSourceWidget::addSource(const QString& sourceName) start, with name" << sourceName;
- // The source has already been added to the backend.
-
- QString type;
- QString server;
- QString path;
- sword::InstallSource is = instbackend::source(sourceName);
- if (instbackend::isRemote(is)) {
- type = tr("Remote:");
- server = is.source.c_str();
- path = is.directory.c_str();
- }
- else { // local source
- type = tr("Local:");
- QFileInfo fi( is.directory.c_str() );
- path = is.directory.c_str();
- if (!(fi.isDir() )) {
- path = path + QString(" ") + tr("Not a directory!"); /// \todo change this
- }
- if (!fi.isReadable()) {
- path = path + QString(" ") + tr("Not readable!"); /// \todo change this
- }
- }
-
- // Here the tab UI is created and added to the tab widget
- BtSourceArea* area = new BtSourceArea(sourceName);
- int tabNumber = this->addTab(area, sourceName);
-
- /// \todo add "remote/local", server, path etc.
- QString toolTip(QString("<p style='white-space:pre'>") + sourceName + QString("<br/><b>") + type + QString("</b> ") + server + path + QString("</p>"));
- tabBar()->setTabToolTip(tabNumber, toolTip);
-
- //select the new tab
- setCurrentIndex(tabNumber);
- m_sourceNameList.append(sourceName);
- initSourceConnections();
- qDebug() << "BtSourceWidget::addSource end";
-}
-
-//
-void BtSourceWidget::slotModuleSelectionChanged(QString sourceName, int selectedCount) {
- /// \todo editing sources should update the map also
- qDebug() << "BtSourceWidget::slotModuleSelectionChanged start";
-
- int overallCount = 0;
- m_selectedModulesCountMap.insert(sourceName, selectedCount);
- foreach (int count, m_selectedModulesCountMap) {
- qDebug() << "add" << count << "to overall count of selected modules";
- overallCount += count;
- }
-
- if (overallCount > 0) {
- m_page->setInstallEnabled(true);
- }
- else {
- m_page->setInstallEnabled(false);
- }
-}
-
-void BtSourceWidget::slotTabSelected(int /*index*/) {
- BtSourceArea* area = dynamic_cast<BtSourceArea*>(currentWidget());
- if (area) area->initTreeFirstTime();
-}
-
-void BtSourceWidget::slotInstall() {
- qDebug() << "void BtInstallPage::slotInstall start";
-
- // check that the destination path is writable, do nothing if not and user doesn't want to continue
- QDir dir = QDir(dynamic_cast<BtInstallPage*>(parent())->selectedInstallPath());
- bool canWrite = true;
- if (dir.isReadable()) {
- const QFileInfo fi( dir.canonicalPath() );
- if (!fi.exists() || !fi.isWritable()) {
- canWrite = false;
- }
- }
- else {
- canWrite = false;
- }
- if (!canWrite) {
- const int result = util::showWarning(this, tr("Warning"), tr("The destination directory is not writable or does not exist. Installation will fail unless this has first been fixed."), QMessageBox::Ignore | QMessageBox::Cancel, QMessageBox::Cancel);
- if (result != QMessageBox::Ignore) {
- return;
- }
- }
-
- // create the confirmation dialog
- // (module tree dialog, modules taken from all sources)
- QString dlgTitle(tr("Install/Update works?"));
- QString dlgLabel(tr("Do you really want to install these works?") +
- QString("<br/><br/><small>") +
- tr("Only one version of a work can be installed at the same time. Select only one if there are items marked with red.") +
- QString("</small>"));
-
- // with empty list we avoid creating the module tree inside the dialog code
- QList<CSwordModuleInfo*> emptyList;
- BtInstallModuleChooserDialog* dlg = new BtInstallModuleChooserDialog(this, dlgTitle, dlgLabel, &emptyList);
- //dlg->setGrouping(BTModuleTreeItem::Mod);
- QTreeWidget* treeWidget = dlg->treeWidget();
- QTreeWidgetItem* rootItem = treeWidget->invisibleRootItem();
-
- QStringList nameList;
-
- // loop through each tab
- for (int tab = 0; tab < count(); ++tab) {
- BtSourceArea* sArea = dynamic_cast<BtSourceArea*>(widget(tab));
- if (sArea && sArea->selectedModules()->count() > 0) {
- // there are selected modules in the source, create items for these
- /// \todo Use new bookshelf model instead
- /// \bug Valgrind reports memory leak:
- QTreeWidgetItem* sourceItem = new QTreeWidgetItem(rootItem);
- sourceItem->setText(0, m_sourceNameList.at(tab));
- sourceItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsTristate | Qt::ItemIsEnabled);
- foreach (QString mName, sArea->selectedModules()->keys()) {
- dlg->initModuleItem(mName, sourceItem);
- }
- sourceItem->setExpanded(true);
- }
- }
-
- //user accepts the dialog
- connect(dlg, SIGNAL(modulesChanged(QList<CSwordModuleInfo*>, QTreeWidget*)), SLOT(slotInstallAccepted(QList<CSwordModuleInfo*>, QTreeWidget*)) );
- // user checks/unchecks an item, needed for preventing double items
- QObject::connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*, int)), dlg, SLOT(slotItemChecked(QTreeWidgetItem*, int)));
- dlg->exec();
- // The OK signal sent by the dialog is catched with slotInstallAccepted.
-}
-
-void BtSourceWidget::slotStopInstall(QTreeWidget* /*treeWidget*/) {
- qDebug() << "BtSourceWidget::slotStopInstall";
- // not needed?
-}
-
-void BtSourceWidget::slotInstallAccepted(QList<CSwordModuleInfo*> /*modules*/, QTreeWidget* treeWidget) {
- qDebug() << "BtSourceWidget::slotInstallAccepted";
-
- /// \todo first remove all modules which will be updated from the module list
- // but what modules? all with the same real name? (there may be _n modules...)
-
- BtModuleManagerDialog* parentDialog = dynamic_cast<BtModuleManagerDialog*>(dynamic_cast<BtInstallPage*>(parent())->parentDialog());
-
- BtInstallProgressDialog* dlg = new BtInstallProgressDialog(parentDialog, treeWidget, dynamic_cast<BtInstallPage*>(parent())->selectedInstallPath());
-
- if (!parentDialog) qDebug() << "error, wrong parent!";
-
- m_page->setInstallEnabled(false);
- // the progress dialog is now modal, it can be made modeless later.
- dlg->exec();
-
- qDebug() << "BtSourceWidget::slotInstallAccepted end";
-}
diff --git a/src/frontend/bookshelfmanager/installpage/btsourcewidget.h b/src/frontend/bookshelfmanager/installpage/btsourcewidget.h
deleted file mode 100644
index fbe8426..0000000
--- a/src/frontend/bookshelfmanager/installpage/btsourcewidget.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*********
-*
-* This file is part of BibleTime's source code, http://www.bibletime.info/.
-*
-* Copyright 1999-2008 by the BibleTime developers.
-* The BibleTime source code is licensed under the GNU General Public License version 2.0.
-*
-**********/
-#ifndef BTSOURCEWIDGET_H
-#define BTSOURCEWIDGET_H
-
-#include <QTabWidget>
-
-#include <QMap>
-#include <QString>
-
-
-class BtInstallMgr;
-class BtInstallPage;
-class BtSourceArea;
-class CSwordModuleInfo;
-class QProgressDialog;
-class QTreeWidget;
-
-/**
-* Tabwidget which holds the source widgets.
-* This widget implements the slots for the source action buttons and
-* applies the actions to the proper source(s).
-*/
-class BtSourceWidget : public QTabWidget {
- Q_OBJECT
- public:
- friend class BtInstallPage;
-
- BtSourceWidget(BtInstallPage* parent);
- virtual ~BtSourceWidget() {}
-
- BtSourceArea* area();
- QString currentSourceName();
-
- public slots:
- /** Install button has been clicked. */
- void slotInstall();
- /** "Stop All" button clicked */
- void slotStopInstall(QTreeWidget* treeWidget);
-
- private:
- void initSourceConnections();
-
- /** Add one source to tabs/stack. */
- void addSource(const QString& sourceName);
-
- private slots:
- /** Add tabs/views for each source. */
- void initSources();
-
- void slotRefresh();
-
- void slotRefreshCanceled();
-
- void slotRefreshCompleted(int, int);
-
- /** Edit button clicked. */
- void slotEdit();
- /** Delete button clicked. */
- void slotDelete();
- /** Add button clicked. */
- void slotAdd();
- /** Modules have been checked/unchecked in the view. */
- void slotModuleSelectionChanged(QString sourceName, int selectedCount);
-
- void slotTabSelected(int index);
- void slotInstallAccepted(QList<CSwordModuleInfo*> mi, QTreeWidget* treeWidget);
-
- signals:
- void sigInitSources();
-
- private:
- QStringList m_sourceNameList;
- BtInstallPage* m_page;
- QProgressDialog* m_progressDialog; // for refreshing
- BtInstallMgr* m_currentInstallMgr; // for refreshing
- QMap<QString, int> m_selectedModulesCountMap;
-};
-
-#endif