summaryrefslogtreecommitdiff
path: root/src/frontend/bookshelfmanager/installpage/btinstallpathdialog.cpp
blob: c6175d5de25869b4e7ad26cd9d32850faf30006e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*********
*
* 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/btinstallpathdialog.h"

#include <QDebug>
#include <QDialog>
#include <QDialogButtonBox>
#include <QDir>
#include <QFileDialog>
#include <QGridLayout>
#include <QHeaderView>
#include <QLabel>
#include <QPushButton>
#include <QString>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include "frontend/bookshelfmanager/instbackend.h"
#include "util/dialogutil.h"
#include "util/directory.h"
#include "util/cresmgr.h"
#include "util/tool.h"


BtInstallPathDialog::BtInstallPathDialog() {
    namespace DU = util::directory;

    setWindowTitle(tr("Bookshelf Folders"));

    QVBoxLayout *mainLayout;
    QHBoxLayout *viewLayout;

    mainLayout = new QVBoxLayout(this);
    viewLayout = new QHBoxLayout();

    QString l1 = tr("Works can be installed in one or more folders. After setting up folders here you can choose one of them in Install page.");
    /// \bug The following string has an extra space character:
    QString l2 = tr("BibleTime and the SWORD library find the works from  all of these folders. If a folder is removed here it still exists in the system with all the works in it.");

    QLabel* mainLabel = util::tool::explanationLabel(this,
                        tr("Configure bookshelf folders"), l1 + QString("<small><br/><br/>") + l2 + QString("</small>"));
    mainLayout->addWidget(mainLabel);

    QString swordConfPath = instbackend::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);
    mainLayout->addWidget(confPathLabel);


    m_swordPathListBox = new QTreeWidget(this);
    m_swordPathListBox->header()->hide();

    QString rwfolderitem(tr("Folders where new works can be installed"));
    m_writableItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(rwfolderitem));;
    m_writableItem->setFlags(Qt::ItemIsEnabled);
    m_readableItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(tr("Read-only folders")));;
    m_readableItem->setFlags(Qt::ItemIsEnabled);
    m_nonexistingItem = new QTreeWidgetItem(m_swordPathListBox, QStringList(tr("Nonexistent folders")));;
    m_nonexistingItem->setFlags(Qt::ItemIsEnabled);

    QStringList targets = instbackend::targetList();

    foreach (QString pathname, targets)  {
        addPathToList(pathname);
    }
    updateTopLevelItems();

    viewLayout->addWidget(m_swordPathListBox);

    QVBoxLayout* buttonLayout = new QVBoxLayout();

    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->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->setToolTip(tr("Remove the selected folder"));
    m_removeButton->setIcon(DU::getIcon(CResMgr::bookshelfmgr::paths::remove_icon));
    connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveClicked()));
    buttonLayout->addWidget(m_removeButton);

    QSpacerItem* spacerItem = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
    buttonLayout->addItem(spacerItem);

    viewLayout->addLayout(buttonLayout);
    mainLayout->addLayout(viewLayout);

    QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
    buttonBox->setOrientation(Qt::Horizontal);
    buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::NoButton | QDialogButtonBox::Ok);
    util::prepareDialogBox(buttonBox);
    mainLayout->addWidget(buttonBox);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    //clumsy way to set width. Could someone please fix Qt to have an easy way to set widget sizes?
    int textWidth = fontMetrics().width(rwfolderitem.append("MMMMMMMMMM"));
    int buttonWidth = m_addButton->width();
    resize(textWidth + buttonWidth, size().height());
}

BtInstallPathDialog::~BtInstallPathDialog() {
    m_swordPathListBox->invisibleRootItem()->takeChildren();
    delete m_readableItem;
    delete m_writableItem;
    delete m_nonexistingItem;
}

void BtInstallPathDialog::updateTopLevelItems() {
    qDebug() << "BtInstallPathDialog::updateTopLevelItems";
    if (m_writableItem->childCount()) {
        m_writableItem->setHidden(false);
        m_swordPathListBox->expandItem(m_writableItem);
    } else {
        m_writableItem->setHidden(true);
    }
    if (m_readableItem->childCount()) {
        m_readableItem->setHidden(false);
        m_swordPathListBox->expandItem(m_readableItem);
    } else {
        m_readableItem->setHidden(true);
    }
    if (m_nonexistingItem->childCount()) {
        m_nonexistingItem->setHidden(false);
        m_swordPathListBox->expandItem(m_nonexistingItem);
    } else {
        m_nonexistingItem->setHidden(true);
    }
}


void BtInstallPathDialog::addPathToList(QString pathname) {
    if (pathname.isEmpty()) return;
        QTreeWidgetItem* i = 0;
        QDir dir(pathname);
        if (!dir.exists()) {
            i = new QTreeWidgetItem(m_nonexistingItem, QStringList(pathname) );
        } else if (dir.isReadable()) {
            const QFileInfo fi( dir.canonicalPath() );
            if (fi.isWritable()) {
                i = new QTreeWidgetItem(m_writableItem, QStringList(pathname) );
            } else {
                i = new QTreeWidgetItem(m_readableItem, QStringList(pathname) );
            }
        }
        if (i && QDir(pathname) == instbackend::swordDir()) {
            i->setFlags(Qt::NoItemFlags);
            i->setToolTip(0, tr("This default folder in your home directory can't be removed"));
        }
}

void BtInstallPathDialog::slotEditClicked() {
    if (QTreeWidgetItem* i = m_swordPathListBox->currentItem()) {
        QString dirname = QFileDialog::getExistingDirectory(this, tr("Choose Folder"), i->text(0), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

        if (dirname.isEmpty()) { // if user cancelled the dialog
            return;
        }
        QDir dir = QDir(dirname);
        if (dir.isReadable()) {
            const QFileInfo fi( dir.canonicalPath() );
            if (!fi.exists() || !fi.isWritable()) {
                const int result = util::showWarning(this, tr("Use Folder?"), tr("This folder is not writable, so works can not be installed here using BibleTime. Do you want to use this folder instead of the previous value?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
                if (result != QMessageBox::Yes) return;
            }
            //i->setText(0, dir.absolutePath()); // absolute, not canonical
            addPathToList(dir.absolutePath());
            delete i;
            updateTopLevelItems();
        }
    }
}

void BtInstallPathDialog::slotAddClicked() {
    QString dirname = QFileDialog::getExistingDirectory(this, tr("Choose Folder"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (dirname.isEmpty()) { // if user cancelled the dialog
        return;
    }
    QDir dir = QDir(dirname);
    if (dir.isReadable()) {
        const QFileInfo fi( dir.canonicalPath() );
        if (!fi.exists() || !fi.isWritable()) {
            const int result = util::showWarning(this, tr("Use Folder?"), tr("This folder is not writable, so works can not be installed here using BibleTime. Do you still want to add it to the list of bookshelf folders?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
            if (result != QMessageBox::Yes) {
                return;
            }
        }
        addPathToList(util::directory::convertDirSeparators(dir.canonicalPath()));
        updateTopLevelItems();
    }
}

void BtInstallPathDialog::slotRemoveClicked() {
    qDebug() << "BtInstallPathDialog::slotRemoveClicked";
    QTreeWidgetItem* i = m_swordPathListBox->selectedItems().value(0);
    qDebug() << i;
    if (i && i->parent() != m_swordPathListBox->invisibleRootItem()) {
        qDebug() << "delete" << i;
        delete i;
    }
    updateTopLevelItems();
}

void BtInstallPathDialog::writeSwordConfig() {
    qDebug() << "BtInstallPathDialog::writeSwordConfig";
    QStringList targets;
    QTreeWidgetItemIterator it(m_swordPathListBox, QTreeWidgetItemIterator::NoChildren|QTreeWidgetItemIterator::Enabled|QTreeWidgetItemIterator::NotHidden);
    while (*it) {
        if (!(*it)->text(0).isEmpty()) {
            targets << (*it)->text(0);
        }
        ++it;
    }
    qDebug() << "save the target list" << targets;
    instbackend::setTargetList(targets); //creates new Sword config
}

void BtInstallPathDialog::accept() {
    writeSwordConfig();
    QDialog::accept();
}