Subversion Repositories Scribus

Rev

Rev 24665 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
22886 jghali 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
 
8
#include "ui/prefs_fonts.h"
9
#include "prefsstructs.h"
10
 
11
 
23354 jghali 12
#include <QComboBox>
22886 jghali 13
#include <QListWidget>
14
#include <QListWidgetItem>
15
#include <QTreeWidget>
16
#include <QTreeWidgetItem>
17
#include <QTableWidget>
18
#include <QHeaderView>
19
#include <QLabel>
20
#include <QDir>
21
#include <QFileDialog>
22
#include <QFileInfo>
23
#include <QFile>
24
#include <QSpacerItem>
25
#include <QPixmap>
26
 
27
#include "prefscontext.h"
28
#include "prefsfile.h"
29
#include "scribuscore.h"
30
#include "scribusdoc.h"
31
#include "prefsmanager.h"
32
#include "scconfig.h"
33
#include "util.h"
34
#include "util_color.h"
35
#include "scpaths.h"
36
#include "fontlistmodel.h"
37
#include "fontlistview.h"
38
 
39
Prefs_Fonts::Prefs_Fonts(QWidget* parent, ScribusDoc* doc)
40
        : Prefs_Pane(parent),
41
        m_doc(doc)
42
{
43
        setupUi(this);
23116 craig 44
        languageChange();
22886 jghali 45
 
23116 craig 46
        m_caption = tr("Fonts");
47
        m_icon = "16/preferences-desktop-font.png";
48
 
23060 craig 49
        RList = PrefsManager::instance().appPrefs.fontPrefs.GFontSub;
22886 jghali 50
 
23612 craig 51
        setMinimumSize(fontMetrics().horizontalAdvance( tr( "Available Fonts" )+ tr( "Font Substitutions" )+ tr( "Additional Paths" )+ tr( "Rejected Fonts" ))+180, 200);
22886 jghali 52
 
53
        fontListTableView->setModel(new FontListModel(fontListTableView, m_doc, true));
54
 
55
        fontSubstitutionsTableWidget->setRowCount(RList.count());
56
        fontSubstitutionsTableWidget->setColumnCount(2);
57
        fontSubstitutionsTableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem( tr("Font Name")));
58
        fontSubstitutionsTableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem( tr("Replacement")));
59
        fontSubstitutionsTableWidget->setSortingEnabled(false);
60
        fontSubstitutionsTableWidget->setSelectionBehavior( QAbstractItemView::SelectRows );
61
        QHeaderView *header = fontSubstitutionsTableWidget->horizontalHeader();
62
        header->setSectionsMovable(false);
63
        header->setSectionsClickable(false);
64
        header->setSectionResizeMode(QHeaderView::Stretch);
65
        fontSubstitutionsTableWidget->verticalHeader()->hide();
66
        fontSubstitutionsTableWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
67
 
68
 
69
        // If we're being called for global application preferences, not document
70
        // preferences, we let the user customize font search paths. Because things
71
        // go rather badly if paths are changed/removed while a doc is open, the
72
        // control is also not displayed if there is a document open.
73
        if (m_doc==nullptr && !ScCore->primaryMainWindow()->HaveDoc)
74
        {
75
                whyBlankLabel->resize(0,0);
76
                whyBlankLabel->hide();
77
                readPaths();
78
                changeButton->setEnabled(false);
79
                removeButton->setEnabled(false);
80
                connect(pathListWidget, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(SelectPath(QListWidgetItem*)));
81
                connect(addButton, SIGNAL(clicked()), this, SLOT(AddPath()));
82
                connect(changeButton, SIGNAL(clicked()), this, SLOT(ChangePath()));
83
                connect(removeButton, SIGNAL(clicked()), this, SLOT(DelPath()));
84
        }
85
        else
86
        {
87
                pathListWidget->resize(0,0);
88
                changeButton->resize(0,0);
89
                addButton->resize(0,0);
90
                removeButton->resize(0,0);
91
                pathListWidget->hide();
92
                changeButton->hide();
93
                addButton->hide();
94
                removeButton->hide();
95
 
96
                // Rather than just making the tab vanish when editing doc-specific settings
97
                // (we don't support per-doc font paths), show a useful explanation.
98
                whyBlankLabel->setText("<qt>" +
99
                                tr("Font search paths can only be set in File > Preferences, and only when "
100
                                   "there is no document currently open. Close any open documents, then "
101
                                   "use File > Preferences > Fonts to change the font search path.") + "</qt>");
102
                additionalPathsButtonsVerticalSpacer->changeSize(0,0);
103
                //additionalPathsButtonsVerticalSpacer->invalidate();
104
                additionalPathsLabelVerticalSpacer->changeSize(0,0,QSizePolicy::Expanding, QSizePolicy::Expanding);
105
                additionalPathsLabelVerticalSpacer->invalidate();
106
        }
107
 
108
        // signals and slots connections
109
        connect(fontSubstitutionsTableWidget, SIGNAL(itemSelectionChanged()), this, SLOT(ReplaceSel()));
110
        connect(deleteSubstitutionButton, SIGNAL(clicked()), this, SLOT(DelEntry()));
111
 
112
 
113
 
114
        //fontListTableView
115
//fontSubstitutionsTableWidget
116
}
117
 
118
void Prefs_Fonts::languageChange()
119
{
24749 jghali 120
        // No need to do anything here, the UI language cannot change while prefs dialog is opened
22886 jghali 121
}
122
 
123
void Prefs_Fonts::restoreDefaults(struct ApplicationPrefs *prefsData)
124
{
125
        m_availFonts = prefsData->fontPrefs.AvailFonts;
126
        fontListTableView->setFonts(m_availFonts);
127
 
128
        FlagsRepl.clear();
129
        fontSubstitutionsTableWidget->clearContents();
130
        m_GFontSub = prefsData->fontPrefs.GFontSub;
24749 jghali 131
 
132
        int i = 0;
22886 jghali 133
        for (auto itfsu = RList.begin(); itfsu != RList.end(); ++itfsu)
134
        {
135
                QTableWidgetItem* tWidgetItem = new QTableWidgetItem(itfsu.key());
136
                tWidgetItem->setFlags(tWidgetItem->flags() & ~Qt::ItemIsEditable);
24749 jghali 137
                fontSubstitutionsTableWidget->setItem(i, 0, tWidgetItem);
23354 jghali 138
                auto item = new QComboBox(fontSubstitutionsTableWidget);
24749 jghali 139
                fontSubstitutionsTableWidget->setCellWidget(i, 1, item);
22886 jghali 140
                item->setEditable(false);
141
                item->addItem(itfsu.value());
142
                setCurrentComboItem(item, itfsu.value());
143
                FlagsRepl.append(item);
24749 jghali 144
                i++;
22886 jghali 145
        }
146
        deleteSubstitutionButton->setEnabled(false);
147
 
148
        fontsRejectedTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
149
        auto headerView = fontsRejectedTableWidget->horizontalHeader();
150
        headerView->resizeSection(0, 150);
151
        headerView->resizeSection(1, 250);
152
        headerView->setStretchLastSection(true);
153
 
154
        updateFontList();
155
        updateRejectedFontList();
156
}
157
 
158
void Prefs_Fonts::saveGuiToPrefs(struct ApplicationPrefs *prefsData) const
159
{
160
        int fontCount = fontListTableView->model()->rowCount();
161
        for (int i = 0; i < fontCount; ++i)
162
        {
163
                QString fontName = fontListTableView->fontName(i);
164
                ScFace face = m_availFonts[fontName];
165
 
166
                face.usable(fontListTableView->isFontUsable(i));
167
                face.subset(fontListTableView->isFontSubsetted(i));
168
        }
169
 
170
        if (m_doc==nullptr)
171
                writePaths();
172
 
173
        prefsData->fontPrefs.GFontSub.clear();
174
        uint a = 0;
175
        for (QMap<QString,QString>::ConstIterator itfsu = RList.begin(); itfsu != RList.end(); ++itfsu)
176
                prefsData->fontPrefs.GFontSub[itfsu.key()] = FlagsRepl.at(a++)->currentText();
177
}
178
 
179
void Prefs_Fonts::changeUnit(ApplicationPrefs *prefsData) const
180
{
181
        //Blank, no units on this tab, yet
182
}
183
 
184
void Prefs_Fonts::ReplaceSel()
185
{
186
        int selCount = fontSubstitutionsTableWidget->selectedItems().count();
187
        deleteSubstitutionButton->setEnabled(selCount > 0);
188
}
189
 
190
void Prefs_Fonts::updateFontList()
191
{
24749 jghali 192
        m_usedFonts.clear();
22886 jghali 193
        SCFontsIterator it(m_availFonts);
194
        for ( ; it.hasNext() ; it.next())
195
        {
196
                if (m_availFonts[it.currentKey()].usable())
24749 jghali 197
                        m_usedFonts.append(it.currentKey());
22886 jghali 198
        }
24749 jghali 199
        m_usedFonts.sort();
200
 
22886 jghali 201
        QString tmp;
202
        for (int b = 0; b < FlagsRepl.count(); ++b)
203
        {
204
                tmp = FlagsRepl.at(b)->currentText();
205
                FlagsRepl.at(b)->clear();
24749 jghali 206
                FlagsRepl.at(b)->addItems(m_usedFonts);
207
                if (m_usedFonts.contains(tmp) != 0)
22886 jghali 208
                        setCurrentComboItem(FlagsRepl.at(b), tmp);
209
                else
210
                        FlagsRepl.at(b)->setCurrentIndex(0);
211
        }
212
}
213
 
214
void Prefs_Fonts::updateRejectedFontList()
215
{
216
        const auto& rejectedFonts = m_availFonts.rejectedFonts;
217
 
218
        fontsRejectedTableWidget->clearContents();
219
 
220
        int i = 0;
221
        for (auto it = rejectedFonts.cbegin(); it != rejectedFonts.cend(); ++it)
222
        {
223
                const auto& key = it.key();
224
                const auto& value = it.value();
225
                const auto  baseName = QFileInfo(key).baseName();
226
 
227
                fontsRejectedTableWidget->insertRow(i);
228
                fontsRejectedTableWidget->setItem(i, 0, new QTableWidgetItem(baseName));
229
                fontsRejectedTableWidget->setItem(i, 1, new QTableWidgetItem(value));
230
                fontsRejectedTableWidget->setItem(i, 2, new QTableWidgetItem(key));
231
        }
22887 jghali 232
 
233
        fontsRejectedTableWidget->sortItems(0, Qt::AscendingOrder);
22886 jghali 234
}
235
 
236
void Prefs_Fonts::DelEntry()
237
{
238
        // This works a because selection mode is "Full rows"
239
        QList<QTableWidgetItem*> selItems = fontSubstitutionsTableWidget->selectedItems();
240
        for (int i = 0; i < selItems.count(); ++i)
241
        {
242
                QTableWidgetItem* item = selItems.at(i);
243
                int r = item->row();
244
                QString tmp = fontSubstitutionsTableWidget->item(r, 0)->text();
245
                fontSubstitutionsTableWidget->removeRow(r);
246
                delete FlagsRepl.takeAt(r);
247
                RList.remove(tmp);
248
        }
249
        deleteSubstitutionButton->setEnabled(false);
250
}
251
 
252
void Prefs_Fonts::readPaths()
253
{
254
        Q_ASSERT(m_doc==nullptr); // should never be called in doc-specific prefs
23060 craig 255
        PrefsContext *fontPrefsContext = PrefsManager::instance().prefsFile->getContext("Fonts");
22886 jghali 256
        PrefsTable *fontPathTable = fontPrefsContext->getTable("ExtraFontDirs");
257
        pathListWidget->clear();
258
        for (int i = 0; i < fontPathTable->getRowCount(); ++i)
259
                pathListWidget->addItem( QDir::toNativeSeparators(fontPathTable->get(i,0)) );
260
}
261
 
262
void Prefs_Fonts::writePaths() const
263
{
264
        Q_ASSERT(m_doc==nullptr); // should never be called in doc-specific prefs
23060 craig 265
        PrefsContext *fontPrefsContext = PrefsManager::instance().prefsFile->getContext("Fonts");
22886 jghali 266
        PrefsTable *fontPathTable = fontPrefsContext->getTable("ExtraFontDirs");
267
        fontPathTable->clear();
268
        for (int i = 0; i < pathListWidget->count(); ++i)
269
                fontPathTable->set(i, 0, QDir::fromNativeSeparators(pathListWidget->item(i)->text()));
270
}
271
 
272
void Prefs_Fonts::SelectPath(QListWidgetItem *c)
273
{
274
        if (m_doc==nullptr)
275
        {
276
                changeButton->setEnabled(true);
277
                removeButton->setEnabled(true);
278
        }
24749 jghali 279
        m_currentPath = c->text();
22886 jghali 280
}
281
 
282
void Prefs_Fonts::AddPath()
283
{
284
        Q_ASSERT(m_doc==nullptr); // should never be called in doc-specific prefs
23060 craig 285
        PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
24749 jghali 286
        m_currentPath = dirs->get("fontprefs", ".");
287
        QString s = QFileDialog::getExistingDirectory(this, tr("Choose a Directory"), m_currentPath);
22886 jghali 288
        if (s.isEmpty())
289
                return;
290
 
291
        dirs->set("fontprefs", s.left(s.lastIndexOf("/", -2)));
292
        if (s.endsWith("/"))
293
                s.chop(1);
294
        QString s2 = QDir::toNativeSeparators(s);
295
        if (pathListWidget->findItems(s2, Qt::MatchExactly).count() != 0)
296
                return;
297
        pathListWidget->addItem(s2);
298
        //writePaths();
299
        changeButton->setEnabled(false);
300
        removeButton->setEnabled(false);
24749 jghali 301
        m_currentPath = s;
22886 jghali 302
        QString dir(QDir::fromNativeSeparators(s2));
23079 jghali 303
        m_availFonts.addScalableFonts(dir +"/");
22886 jghali 304
        m_availFonts.updateFontMap();
23079 jghali 305
        m_availFonts.writeFontCache();
22886 jghali 306
 
307
        updateFontList();
308
        updateRejectedFontList();
309
}
310
 
311
void Prefs_Fonts::ChangePath()
312
{
313
        Q_ASSERT(m_doc==nullptr); // should never be called in doc-specific prefs
24749 jghali 314
        QString s = QFileDialog::getExistingDirectory(this, tr("Choose a Directory"), m_currentPath);
22886 jghali 315
        if (s.isEmpty())
316
                return;
317
 
318
        if (s.endsWith("/"))
319
                s.chop(1);
320
        QString s2 = QDir::toNativeSeparators(s);
321
        if (pathListWidget->findItems(s2, Qt::MatchExactly).count() != 0)
322
                return;
323
        QString path = pathListWidget->currentItem()->text();
324
        SCFontsIterator it(m_availFonts);
325
        for ( ; it.hasNext(); it.next())
326
        {
327
                if (it.current().isNone())
328
                        continue;
329
                QFileInfo fi(it.current().fontFilePath());
330
                if (fi.absolutePath() == path)
331
                        m_availFonts.remove(it.currentKey());
332
        }
333
        pathListWidget->currentItem()->setText(s2);
334
        //writePaths();
24749 jghali 335
        m_currentPath = s;
22886 jghali 336
        QString dir = QDir::fromNativeSeparators(s2);
23079 jghali 337
        m_availFonts.addScalableFonts(dir +"/");
22886 jghali 338
        m_availFonts.updateFontMap();
339
        updateFontList();
340
        updateRejectedFontList();
341
        changeButton->setEnabled(false);
342
        removeButton->setEnabled(false);
343
}
344
 
345
void Prefs_Fonts::DelPath()
346
{
347
        Q_ASSERT(m_doc==nullptr); // should never be called in doc-specific prefs
24749 jghali 348
        QFile fx(PrefsManager::instance().preferencesLocation() + "/scribusfont13.rc");
22886 jghali 349
        if (!fx.open(QIODevice::WriteOnly))
350
                return;
351
 
352
        QString path = pathListWidget->currentItem()->text();
353
        if (pathListWidget->count() == 1)
354
                pathListWidget->clear();
355
        else
356
                delete pathListWidget->takeItem(pathListWidget->currentRow());
357
        //writePaths();
358
 
359
        QMutableMapIterator<QString,ScFace> it(m_availFonts);
360
        while (it.hasNext())
361
        {
362
                it.next();
363
                if (it.value().isNone())
364
                        continue;
365
                QFileInfo fi(it.value().fontFilePath());
366
                if (fi.absolutePath() == path)
367
                        m_availFonts.remove(it.key());
368
        }
369
        m_availFonts.updateFontMap();
24749 jghali 370
        m_currentPath.clear();
22886 jghali 371
        updateFontList();
372
        changeButton->setEnabled(false);
373
        removeButton->setEnabled(false);
374
}
375