diff --git a/kcms/kfontinst/apps/Installer.cpp b/kcms/kfontinst/apps/Installer.cpp
index ddd66954d..8a7c295f3 100644
--- a/kcms/kfontinst/apps/Installer.cpp
+++ b/kcms/kfontinst/apps/Installer.cpp
@@ -1,160 +1,162 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "Installer.h"
#include "Misc.h"
#include "FontsPackage.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "JobRunner.h"
#include "CreateParent.h"
#include "config-workspace.h"
namespace KFI
{
int CInstaller::install(const QSet &urls)
{
QSet::ConstIterator it(urls.begin()),
end(urls.end());
bool sysInstall(false);
CJobRunner *jobRunner=new CJobRunner(itsParent);
CJobRunner::startDbusService();
if(!Misc::root())
{
switch(KMessageBox::questionYesNoCancel(itsParent,
i18n("Do you wish to install the font(s) for personal use "
"(only available to you), or "
"system-wide (available to all users)?"),
i18n("Where to Install"), KGuiItem(i18n(KFI_KIO_FONTS_USER)),
KGuiItem(i18n(KFI_KIO_FONTS_SYS))))
{
case KMessageBox::No:
sysInstall=true;
break;
case KMessageBox::Cancel:
return -1;
default:
break;
}
}
QSet instUrls;
for(; it!=end; ++it)
{
auto job = KIO::mostLocalUrl(*it);
job->exec();
QUrl local = job->mostLocalUrl();
bool package(false);
if(local.isLocalFile())
{
QString localFile(local.toLocalFile());
if(Misc::isPackage(localFile))
{
instUrls+=FontsPackage::extract(localFile, &itsTempDir);
package=true;
}
}
if(!package)
{
QList associatedUrls;
CJobRunner::getAssociatedUrls(*it, associatedUrls, false, itsParent);
instUrls.insert(*it);
QList::Iterator aIt(associatedUrls.begin()),
aEnd(associatedUrls.end());
for(; aIt!=aEnd; ++aIt)
instUrls.insert(*aIt);
}
}
if(!instUrls.isEmpty())
{
CJobRunner::ItemList list;
QSet::ConstIterator it(instUrls.begin()),
end(instUrls.end());
for(; it!=end; ++it)
list.append(*it);
return jobRunner->exec(CJobRunner::CMD_INSTALL, list, Misc::root() || sysInstall);
}
else
return -1;
}
CInstaller::~CInstaller()
{
delete itsTempDir;
}
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
+ app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
+
KLocalizedString::setApplicationDomain(KFI_CATALOGUE);
KAboutData aboutData("kfontinst", i18n("Font Installer"), WORKSPACE_VERSION_STRING, i18n("Simple font installer"),
KAboutLicense::GPL, i18n("(C) Craig Drummond, 2007"));
KAboutData::setApplicationData(aboutData);
QGuiApplication::setWindowIcon(QIcon::fromTheme("preferences-desktop-font-installer"));
QCommandLineParser parser;
const QCommandLineOption embedOption(QLatin1String("embed"), i18n("Makes the dialog transient for an X app specified by winid"), QLatin1String("winid"));
parser.addOption(embedOption);
parser.addPositionalArgument(QLatin1String("[URL]"), i18n("URL to install"));
aboutData.setupCommandLine(&parser);
parser.process(app);
aboutData.processCommandLine(&parser);
QSet urls;
foreach (const QString &arg, parser.positionalArguments())
urls.insert(QUrl::fromUserInput(arg, QDir::currentPath()));
if (!urls.isEmpty())
{
QString opt(parser.value(embedOption));
KFI::CInstaller inst(createParent(opt.size() ? opt.toInt(nullptr, 16) : 0));
return inst.install(urls);
}
return -1;
}
diff --git a/kcms/kfontinst/kcmfontinst/16-actions-disablefont.png b/kcms/kfontinst/kcmfontinst/16-actions-font-disable.png
similarity index 100%
rename from kcms/kfontinst/kcmfontinst/16-actions-disablefont.png
rename to kcms/kfontinst/kcmfontinst/16-actions-font-disable.png
diff --git a/kcms/kfontinst/kcmfontinst/16-actions-enablefont.png b/kcms/kfontinst/kcmfontinst/16-actions-font-enable.png
similarity index 100%
rename from kcms/kfontinst/kcmfontinst/16-actions-enablefont.png
rename to kcms/kfontinst/kcmfontinst/16-actions-font-enable.png
diff --git a/kcms/kfontinst/kcmfontinst/22-actions-disablefont.png b/kcms/kfontinst/kcmfontinst/22-actions-font-disable.png
similarity index 100%
rename from kcms/kfontinst/kcmfontinst/22-actions-disablefont.png
rename to kcms/kfontinst/kcmfontinst/22-actions-font-disable.png
diff --git a/kcms/kfontinst/kcmfontinst/22-actions-enablefont.png b/kcms/kfontinst/kcmfontinst/22-actions-font-enable.png
similarity index 100%
rename from kcms/kfontinst/kcmfontinst/22-actions-enablefont.png
rename to kcms/kfontinst/kcmfontinst/22-actions-font-enable.png
diff --git a/kcms/kfontinst/kcmfontinst/CMakeLists.txt b/kcms/kfontinst/kcmfontinst/CMakeLists.txt
index 96ab28791..8e53ffefc 100644
--- a/kcms/kfontinst/kcmfontinst/CMakeLists.txt
+++ b/kcms/kfontinst/kcmfontinst/CMakeLists.txt
@@ -1,36 +1,36 @@
set(kcm_fontinst_PART_SRCS ${libkfontinstview_SRCS} ${libkfontinstjobrunner_SRCS} ${libkfontinstdbusiface_SRCS}
DuplicatesDialog.cpp FontList.cpp GroupList.cpp KCmFontInst.cpp PrintDialog.cpp
FontFilter.cpp FontFilterProxyStyle.cpp FcQuery.cpp PreviewList.cpp)
# qt5_add_dbus_interface(kcm_fontinst_PART_SRCS ../dbus/org.kde.fontinst.xml FontinstIface)
add_library(kcm_fontinst MODULE ${kcm_fontinst_PART_SRCS})
target_link_libraries(kcm_fontinst
KF5::Archive
KF5::KCMUtils
KF5::IconThemes
KF5::KIOCore
KF5::KIOWidgets
KF5::XmlGui
KF5::NewStuff
kfontinstui
kfontinst
${X11_LIBRARIES}
)
install(TARGETS kcm_fontinst DESTINATION ${KDE_INSTALL_PLUGINDIR} )
install( FILES fontinst.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} )
install( FILES kfontinst.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR} )
ecm_install_icons( ICONS
16-actions-addfont.png
- 16-actions-disablefont.png
- 16-actions-enablefont.png
+ 16-actions-font-disable.png
+ 16-actions-font-enable.png
16-actions-fontstatus.png
22-actions-addfont.png
- 22-actions-disablefont.png
- 22-actions-enablefont.png
+ 22-actions-font-disable.png
+ 22-actions-font-enable.png
22-actions-fontstatus.png
16-actions-addfont.png
DESTINATION
${KDE_INSTALL_DATADIR}/kfontinst/icons THEME hicolor)
diff --git a/kcms/kfontinst/kcmfontinst/FontFilter.cpp b/kcms/kfontinst/kcmfontinst/FontFilter.cpp
index 7522a4176..407940152 100644
--- a/kcms/kfontinst/kcmfontinst/FontFilter.cpp
+++ b/kcms/kfontinst/kcmfontinst/FontFilter.cpp
@@ -1,395 +1,373 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
+ * 2019 Guo Yunhe
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FontFilter.h"
#include "FontFilterProxyStyle.h"
#include "FontList.h"
#include
#include
#include
-#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace KFI
{
static const int constArrowPad(5);
static void deselectCurrent(QActionGroup *act)
{
QAction *prev(act->checkedAction());
if(prev)
prev->setChecked(false);
}
static void deselectCurrent(KSelectAction *act)
{
deselectCurrent(act->selectableActionGroup());
}
// FIXME: Go back to using StyleSheets instead of a proxy style
// once Qt has been fixed not to mess with widget font when
// using StyleSheets
class CFontFilterStyle : public CFontFilterProxyStyle
{
public:
CFontFilterStyle(CFontFilter *parent, int ol) : CFontFilterProxyStyle(parent), overlap(ol) {}
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override;
int overlap;
};
QRect CFontFilterStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
{
if (SE_LineEditContents==element)
{
QRect rect(style()->subElementRect(SE_LineEditContents, option, widget));
return rect.adjusted(overlap, 0, -overlap, 0);
}
return CFontFilterProxyStyle::subElementRect(element, option, widget);
}
struct SortAction
{
SortAction(QAction *a) : action(a) { }
bool operator<(const SortAction &o) const { return action->text().localeAwareCompare(o.action->text())<0; }
QAction *action;
};
static void sortActions(KSelectAction *group)
{
if(group->actions().count()>1)
{
QList actions=group->actions();
QList::ConstIterator it(actions.constBegin()),
end(actions.constEnd());
QList sorted;
for(; it!=end; ++it)
{
sorted.append(SortAction(*it));
group->removeAction(*it);
}
std::sort(sorted.begin(), sorted.end());
QList::ConstIterator s(sorted.constBegin()),
sEnd(sorted.constEnd());
for(; s!=sEnd; ++s)
group->addAction((*s).action);
}
}
CFontFilter::CFontFilter(QWidget *parent)
- : KLineEdit(parent)
+ : QWidget(parent)
{
- setClearButtonShown(true);
- setTrapReturnKey(true);
-
- itsMenuButton = new QLabel(this);
- itsMenuButton->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
- itsMenuButton->setCursor(Qt::ArrowCursor);
- itsMenuButton->setToolTip(i18n("Set Criteria"));
-
- itsMenu=new QMenu(this);
- itsPixmaps[CRIT_FAMILY]=SmallIcon("draw-text");
- itsPixmaps[CRIT_STYLE]=SmallIcon("format-text-bold");
- itsPixmaps[CRIT_FOUNDRY]=SmallIcon("user-identity");
- itsPixmaps[CRIT_FONTCONFIG]=SmallIcon("system-search");
- itsPixmaps[CRIT_FILETYPE]=SmallIcon("preferences-desktop-font-installer");
- itsPixmaps[CRIT_FILENAME]=SmallIcon("application-x-font-type1");
- itsPixmaps[CRIT_LOCATION]=SmallIcon("folder");
- itsPixmaps[CRIT_WS]=SmallIcon("character-set");
+ itsIcons[CRIT_FAMILY] = QIcon::fromTheme("draw-text");
+ itsTexts[CRIT_FAMILY] = i18n("Family");
+ itsIcons[CRIT_STYLE] = QIcon::fromTheme("format-text-bold");
+ itsTexts[CRIT_STYLE] = i18n("Style");
+ itsIcons[CRIT_FOUNDRY] = QIcon::fromTheme("user-identity");
+ itsTexts[CRIT_FOUNDRY] = i18n("Foundry");
+ itsIcons[CRIT_FONTCONFIG] = QIcon::fromTheme("system-search");
+ itsTexts[CRIT_FONTCONFIG] = i18n("FontConfig Match");
+ itsIcons[CRIT_FILETYPE] = QIcon::fromTheme("preferences-desktop-font-installer");
+ itsTexts[CRIT_FILETYPE] = i18n("File Type");
+ itsIcons[CRIT_FILENAME] = QIcon::fromTheme("application-x-font-type1");
+ itsTexts[CRIT_FILENAME] = i18n("File Name");
+ itsIcons[CRIT_LOCATION] = QIcon::fromTheme("folder");
+ itsTexts[CRIT_LOCATION] = i18n("File Location");
+ itsIcons[CRIT_WS] = QIcon::fromTheme("character-set");
+ itsTexts[CRIT_WS] = i18n("Writing System");
+
+ m_layout = new QHBoxLayout(this);
+ setLayout(m_layout);
+ m_layout->setContentsMargins(0, 0, 0, 0);
+
+ m_lineEdit = new QLineEdit(this);
+ m_lineEdit->setClearButtonEnabled(true);
+ m_layout->addWidget(m_lineEdit);
+
+ m_menuButton = new QPushButton(this);
+ m_menuButton->setIcon(QIcon::fromTheme("view-filter"));
+ m_menuButton->setText(i18n("Set Criteria"));
+ m_layout->addWidget(m_menuButton);
+
+ connect(m_lineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
+
+ m_menu=new QMenu(this);
+ m_menuButton->setMenu(m_menu);
itsActionGroup=new QActionGroup(this);
- addAction(CRIT_FAMILY, i18n("Family"), true);
- addAction(CRIT_STYLE, i18n("Style"), false);
+ addAction(CRIT_FAMILY, true);
+ addAction(CRIT_STYLE, false);
- KSelectAction *foundryMenu=new KSelectAction(QIcon(itsPixmaps[CRIT_FOUNDRY]), i18n("Foundry"), this);
+ KSelectAction *foundryMenu=new KSelectAction(itsIcons[CRIT_FOUNDRY], itsTexts[CRIT_FOUNDRY], this);
itsActions[CRIT_FOUNDRY]=foundryMenu;
- itsMenu->addAction(itsActions[CRIT_FOUNDRY]);
+ m_menu->addAction(itsActions[CRIT_FOUNDRY]);
foundryMenu->setData((int)CRIT_FOUNDRY);
foundryMenu->setVisible(false);
connect(foundryMenu, SIGNAL(triggered(QString)), SLOT(foundryChanged(QString)));
- addAction(CRIT_FONTCONFIG, i18n("FontConfig Match"), false);
-
- KSelectAction *ftMenu=new KSelectAction(QIcon(itsPixmaps[CRIT_FILETYPE]), i18n("File Type"), this);
+ addAction(CRIT_FONTCONFIG, false);
+
+ KSelectAction *ftMenu=new KSelectAction(itsIcons[CRIT_FILETYPE], itsTexts[CRIT_FILETYPE], this);
itsActions[CRIT_FILETYPE]=ftMenu;
- itsMenu->addAction(itsActions[CRIT_FILETYPE]);
+ m_menu->addAction(itsActions[CRIT_FILETYPE]);
ftMenu->setData((int)CRIT_FILETYPE);
-
+
QStringList::ConstIterator it(CFontList::fontMimeTypes.constBegin()),
end(CFontList::fontMimeTypes.constEnd());
QMimeDatabase db;
for(; it!=end; ++it)
if((*it)!="application/vnd.kde.fontspackage")
{
QMimeType mime = db.mimeTypeForName(*it);
-
+
KToggleAction *act=new KToggleAction(QIcon::fromTheme(mime.iconName()), mime.comment(), this);
ftMenu->addAction(act);
act->setChecked(false);
QStringList mimes;
foreach (QString pattern, mime.globPatterns())
mimes.append(pattern.remove(QStringLiteral("*.")));
act->setData(mimes);
}
sortActions(ftMenu);
connect(ftMenu, SIGNAL(triggered(QString)), SLOT(ftChanged(QString)));
itsCurrentFileTypes.clear();
- addAction(CRIT_FILENAME, i18n("File Name"), false);
- addAction(CRIT_LOCATION, i18n("File Location"), false);
+ addAction(CRIT_FILENAME, false);
+ addAction(CRIT_LOCATION, false);
- KSelectAction *wsMenu=new KSelectAction(QIcon(itsPixmaps[CRIT_WS]), i18n("Writing System"), this);
+ KSelectAction *wsMenu=new KSelectAction(itsIcons[CRIT_WS], itsTexts[CRIT_WS], this);
itsActions[CRIT_WS]=wsMenu;
- itsMenu->addAction(itsActions[CRIT_WS]);
+ m_menu->addAction(itsActions[CRIT_WS]);
wsMenu->setData((int)CRIT_WS);
itsCurrentWs=QFontDatabase::Any;
for(int i=QFontDatabase::Latin; iaddAction(wsAct);
wsAct->setChecked(false);
wsAct->setData(i);
}
sortActions(wsMenu);
connect(wsMenu, SIGNAL(triggered(QString)), SLOT(wsChanged(QString)));
setCriteria(CRIT_FAMILY);
- setStyle(new CFontFilterStyle(this, itsMenuButton->width()));
+ setStyle(new CFontFilterStyle(this, m_menuButton->width()));
}
void CFontFilter::setFoundries(const QSet ¤tFoundries)
{
QAction *act(((KSelectAction *)itsActions[CRIT_FOUNDRY])->currentAction());
QString prev(act && act->isChecked() ? act->text() : QString());
bool changed(false);
QList prevFoundries(((KSelectAction *)itsActions[CRIT_FOUNDRY])->actions());
QList::ConstIterator fIt(prevFoundries.constBegin()),
fEnd(prevFoundries.constEnd());
QSet foundries(currentFoundries);
// Determine which of 'foundries' are new ones, and which old ones need to be removed...
for(; fIt!=fEnd; ++fIt)
{
if(foundries.contains((*fIt)->text()))
foundries.remove((*fIt)->text());
else
{
((KSelectAction *)itsActions[CRIT_FOUNDRY])->removeAction(*fIt);
(*fIt)->deleteLater();
changed=true;
}
}
if(!foundries.isEmpty())
{
// Add foundries to menu - replacing '&' with '&&', as '&' is taken to be
// a shortcut!
QSet::ConstIterator it(foundries.begin()),
end(foundries.end());
for(; it!=end; ++it)
{
QString foundry(*it);
foundry.replace("&", "&&");
((KSelectAction *)itsActions[CRIT_FOUNDRY])->addAction(foundry);
}
changed=true;
}
if(changed)
{
sortActions((KSelectAction *)itsActions[CRIT_FOUNDRY]);
if(!prev.isEmpty())
{
act=((KSelectAction *)itsActions[CRIT_FOUNDRY])->action(prev);
if(act)
((KSelectAction *)itsActions[CRIT_FOUNDRY])->setCurrentAction(act);
else
((KSelectAction *)itsActions[CRIT_FOUNDRY])->setCurrentItem(0);
}
-
+
itsActions[CRIT_FOUNDRY]->setVisible(((KSelectAction *)itsActions[CRIT_FOUNDRY])->actions().count());
}
}
-QSize CFontFilter::sizeHint() const
-{
- return QSize(fontMetrics().width(placeholderText())+56, KLineEdit::sizeHint().height());
-}
-
void CFontFilter::filterChanged()
{
QAction *act(itsActionGroup->checkedAction());
if(act)
{
ECriteria crit((ECriteria)act->data().toInt());
if(itsCurrentCriteria!=crit)
{
deselectCurrent((KSelectAction *)itsActions[CRIT_FOUNDRY]);
deselectCurrent((KSelectAction *)itsActions[CRIT_FILETYPE]);
deselectCurrent((KSelectAction *)itsActions[CRIT_WS]);
- setText(QString());
+ m_lineEdit->setText(QString());
itsCurrentWs=QFontDatabase::Any;
itsCurrentFileTypes.clear();
setCriteria(crit);
- setPlaceholderText(i18n("Filter by %1...", act->text()));
- setReadOnly(false);
+ m_lineEdit->setPlaceholderText(i18n("Filter by %1...", act->text()));
+ m_lineEdit->setReadOnly(false);
}
}
}
void CFontFilter::ftChanged(const QString &ft)
{
deselectCurrent((KSelectAction *)itsActions[CRIT_FOUNDRY]);
deselectCurrent((KSelectAction *)itsActions[CRIT_WS]);
deselectCurrent(itsActionGroup);
QAction *act(((KSelectAction *)itsActions[CRIT_FILETYPE])->currentAction());
if(act)
itsCurrentFileTypes=act->data().toStringList();
itsCurrentCriteria=CRIT_FILETYPE;
- setReadOnly(true);
+ m_lineEdit->setReadOnly(true);
setCriteria(itsCurrentCriteria);
- setText(ft);
- setPlaceholderText(text());
+ m_lineEdit->setText(ft);
+ m_lineEdit->setPlaceholderText(m_lineEdit->text());
}
void CFontFilter::wsChanged(const QString &writingSystemName)
{
deselectCurrent((KSelectAction *)itsActions[CRIT_FOUNDRY]);
deselectCurrent((KSelectAction *)itsActions[CRIT_FILETYPE]);
deselectCurrent(itsActionGroup);
QAction *act(((KSelectAction *)itsActions[CRIT_WS])->currentAction());
if(act)
itsCurrentWs=(QFontDatabase::WritingSystem)act->data().toInt();
itsCurrentCriteria=CRIT_WS;
- setReadOnly(true);
+ m_lineEdit->setReadOnly(true);
setCriteria(itsCurrentCriteria);
- setText(writingSystemName);
- setPlaceholderText(text());
+ m_lineEdit->setText(writingSystemName);
+ m_lineEdit->setPlaceholderText(m_lineEdit->text());
}
void CFontFilter::foundryChanged(const QString &foundry)
{
deselectCurrent((KSelectAction *)itsActions[CRIT_WS]);
deselectCurrent((KSelectAction *)itsActions[CRIT_FILETYPE]);
deselectCurrent(itsActionGroup);
itsCurrentCriteria=CRIT_FOUNDRY;
- setReadOnly(true);
- setText(foundry);
- setPlaceholderText(text());
+ m_lineEdit->setReadOnly(true);
+ m_lineEdit->setText(foundry);
+ m_lineEdit->setPlaceholderText(m_lineEdit->text());
setCriteria(itsCurrentCriteria);
}
-void CFontFilter::addAction(ECriteria crit, const QString &text, bool on)
+void CFontFilter::textChanged(const QString &text)
{
- itsActions[crit]=new KToggleAction(QIcon(itsPixmaps[crit]),
- text, this);
- itsMenu->addAction(itsActions[crit]);
+ emit queryChanged(text);
+}
+
+void CFontFilter::addAction(ECriteria crit, bool on)
+{
+ itsActions[crit]=new KToggleAction(itsIcons[crit], itsTexts[crit], this);
+ m_menu->addAction(itsActions[crit]);
itsActionGroup->addAction(itsActions[crit]);
itsActions[crit]->setData((int)crit);
itsActions[crit]->setChecked(on);
if(on)
- setPlaceholderText(i18n("Filter by %1...", text));
+ m_lineEdit->setPlaceholderText(i18n("Filter by %1...", itsTexts[crit]));
connect(itsActions[crit], SIGNAL(toggled(bool)), SLOT(filterChanged()));
}
-void CFontFilter::resizeEvent(QResizeEvent *ev)
-{
- KLineEdit::resizeEvent(ev);
-
- int frameWidth(style()->pixelMetric(QStyle::PM_DefaultFrameWidth)),
- y((height()-itsMenuButton->height())/2);
-
- if (qApp->isLeftToRight())
- itsMenuButton->move(frameWidth + 2, y);
- else
- itsMenuButton->move(size().width() - frameWidth - itsMenuButton->width() - 2, y);
-}
-
-void CFontFilter::mousePressEvent(QMouseEvent *ev)
-{
- if(Qt::LeftButton==ev->button() && itsMenuButton->underMouse())
- itsMenu->popup(mapToGlobal(QPoint(0, height())), nullptr);
- else
- KLineEdit::mousePressEvent(ev);
-}
-
void CFontFilter::setCriteria(ECriteria crit)
{
- QPixmap arrowmap(itsPixmaps[crit].width()+constArrowPad, itsPixmaps[crit].height());
-
- QColor bgnd(palette().color(QPalette::Active, QPalette::Base));
- bgnd.setAlphaF(0.0);
- arrowmap.fill(bgnd);
-
- QPainter p(&arrowmap);
-
- p.drawPixmap(0, 0, itsPixmaps[crit]);
- QStyleOption opt;
- opt.state = QStyle::State_Enabled;
- opt.rect = QRect(arrowmap.width()-(constArrowPad+1), arrowmap.height()-(constArrowPad+1), constArrowPad, constArrowPad);
- style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &opt, &p, itsMenuButton);
- p.end();
-
- itsMenuButton->setPixmap(arrowmap);
- itsMenuButton->resize(arrowmap.width(), arrowmap.height());
itsCurrentCriteria=crit;
emit criteriaChanged(crit, ((qulonglong)1) << (int)itsCurrentWs, itsCurrentFileTypes);
}
}
diff --git a/kcms/kfontinst/kcmfontinst/FontFilter.h b/kcms/kfontinst/kcmfontinst/FontFilter.h
index 96dfacbc9..764c7bb79 100644
--- a/kcms/kfontinst/kcmfontinst/FontFilter.h
+++ b/kcms/kfontinst/kcmfontinst/FontFilter.h
@@ -1,97 +1,99 @@
#ifndef __FONT_FILTER_H__
#define __FONT_FILTER_H__
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
+ * 2019 Guo Yunhe
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
-#include
-#include
+#include
+#include
#include
-
-class QLabel;
-class QMenu;
-class QActionGroup;
+#include
+#include
+#include
+#include
namespace KFI
{
-class CFontFilter : public KLineEdit
+class CFontFilter : public QWidget
{
Q_OBJECT
public:
enum ECriteria
{
CRIT_FAMILY,
CRIT_STYLE,
CRIT_FOUNDRY,
CRIT_FONTCONFIG,
CRIT_FILETYPE,
CRIT_FILENAME,
CRIT_LOCATION,
CRIT_WS,
NUM_CRIT
};
CFontFilter(QWidget *parent);
~CFontFilter() override { }
void setFoundries(const QSet ¤tFoundries);
- QSize sizeHint() const override;
-
Q_SIGNALS:
void criteriaChanged(int crit, qulonglong ws, const QStringList &ft);
+ void queryChanged(QString text);
private Q_SLOTS:
void filterChanged();
+ void textChanged(const QString &text);
void ftChanged(const QString &ft);
void wsChanged(const QString &writingSystemName);
void foundryChanged(const QString &foundry);
private:
- void addAction(ECriteria crit, const QString &text, bool on);
- void resizeEvent(QResizeEvent *ev) override;
- void mousePressEvent(QMouseEvent *ev) override;
+ void addAction(ECriteria crit, bool on);
void setCriteria(ECriteria crit);
private:
- QLabel *itsMenuButton;
- QMenu *itsMenu;
+ QPushButton *m_menuButton;
+ QHBoxLayout *m_layout;
+ QMenu *m_menu;
+ QLineEdit *m_lineEdit;
ECriteria itsCurrentCriteria;
QFontDatabase::WritingSystem itsCurrentWs;
QStringList itsCurrentFileTypes;
- QPixmap itsPixmaps[NUM_CRIT];
+ QIcon itsIcons[NUM_CRIT];
+ QString itsTexts[NUM_CRIT];
QAction *itsActions[NUM_CRIT];
QActionGroup *itsActionGroup;
};
}
#endif
diff --git a/kcms/kfontinst/kcmfontinst/FontList.cpp b/kcms/kfontinst/kcmfontinst/FontList.cpp
index 45d74aa61..3f5d14dc2 100644
--- a/kcms/kfontinst/kcmfontinst/FontList.cpp
+++ b/kcms/kfontinst/kcmfontinst/FontList.cpp
@@ -1,2060 +1,2060 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FontList.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "FcEngine.h"
#include "Fc.h"
#include "KfiConstants.h"
#include "GroupList.h"
#include "FontInstInterface.h"
#include "XmlStrings.h"
#include "Family.h"
#include "Style.h"
#include "File.h"
namespace KFI
{
const QStringList CFontList::fontMimeTypes(QStringList() << "font/ttf"
<< "font/otf"
<< "application/x-font-ttf"
<< "application/x-font-otf"
<< "application/x-font-type1"
<< "application/x-font-pcf"
<< "application/x-font-bdf"
<< "application/vnd.kde.fontspackage");
static const int constMaxSlowed = 250;
static void decompose(const QString &name, QString &family, QString &style)
{
int commaPos=name.lastIndexOf(',');
family=-1==commaPos ? name : name.left(commaPos);
style=-1==commaPos ? KFI_WEIGHT_REGULAR : name.mid(commaPos+2);
}
static void addFont(CFontItem *font, CJobRunner::ItemList &urls, QStringList &fontNames,
QSet *fonts, QSet &usedFonts,
bool getEnabled, bool getDisabled)
{
if(!usedFonts.contains(font) &&
( (getEnabled && font->isEnabled()) ||
(getDisabled && !font->isEnabled()) ) )
{
urls.append(CJobRunner::Item(font->url(), font->name(), !font->isEnabled()));
fontNames.append(font->name());
usedFonts.insert(font);
if(fonts)
fonts->insert(Misc::TFont(font->family(), font->styleInfo()));
}
}
static QString replaceEnvVar(const QString &text)
{
QString mod(text);
int endPos(text.indexOf('/'));
if(endPos==-1)
endPos=text.length()-1;
else
endPos--;
if(endPos>0)
{
QString envVar(text.mid(1, endPos));
const char *val=getenv(envVar.toLatin1().constData());
if(val)
mod=Misc::fileSyntax(QFile::decodeName(val)+mod.mid(endPos+1));
}
return mod;
}
//
// Convert from list such as:
//
// Arial
// Arial, Bold
// Courier
// Times
// Times, Italic
//
// To:
//
// Arial (Regular, Bold)
// Coutier
// Times (Regular, Italic)
QStringList CFontList::compact(const QStringList &fonts)
{
QString lastFamily,
entry;
QStringList::ConstIterator it(fonts.begin()),
end(fonts.end());
QStringList compacted;
QSet usedStyles;
for(; it!=end; ++it)
{
QString family,
style;
decompose(*it, family, style);
if(family!=lastFamily)
{
usedStyles.clear();
if(entry.length())
{
entry+=')';
compacted.append(entry);
}
entry=QString(family+" (");
lastFamily=family;
}
if(!usedStyles.contains(style))
{
usedStyles.clear();
if(entry.length() && '('!=entry[entry.length()-1])
entry+=", ";
entry+=style;
usedStyles.insert(style);
}
}
if(entry.length())
{
entry+=')';
compacted.append(entry);
}
return compacted;
}
QString capitaliseFoundry(const QString &foundry)
{
QString f(foundry.toLower());
if(f==QLatin1String("ibm"))
return QLatin1String("IBM");
else if(f==QLatin1String("urw"))
return QLatin1String("URW");
else if(f==QLatin1String("itc"))
return QLatin1String("ITC");
else if(f==QLatin1String("nec"))
return QLatin1String("NEC");
else if(f==QLatin1String("b&h"))
return QLatin1String("B&H");
else if(f==QLatin1String("dec"))
return QLatin1String("DEC");
else
{
QChar *ch(f.data());
int len(f.length());
bool isSpace(true);
while(len--)
{
if (isSpace)
*ch=ch->toUpper();
isSpace=ch->isSpace();
++ch;
}
}
return f;
}
inline bool isSysFolder(const QString §)
{
return i18n(KFI_KIO_FONTS_SYS)==sect || KFI_KIO_FONTS_SYS==sect;
}
CFontItem::CFontItem(CFontModelItem *p, const Style &s, bool sys)
: CFontModelItem(p),
itsStyleName(FC::createStyleName(s.value())),
itsStyle(s)
{
refresh();
if(!Misc::root())
setIsSystem(sys);
}
void CFontItem::refresh()
{
FileCont::ConstIterator it(itsStyle.files().begin()),
end(itsStyle.files().end());
itsEnabled=false;
for(; it!=end; ++it)
if(!Misc::isHidden(Misc::getFile((*it).path())))
{
itsEnabled=true;
break;
}
}
CFamilyItem::CFamilyItem(CFontList &p, const Family &f, bool sys)
: CFontModelItem(nullptr),
itsStatus(ENABLED),
itsRealStatus(ENABLED),
itsRegularFont(nullptr),
itsParent(p)
{
itsName=f.name();
addFonts(f.styles(), sys);
//updateStatus();
}
CFamilyItem::~CFamilyItem()
{
qDeleteAll(itsFonts);
itsFonts.clear();
}
bool CFamilyItem::addFonts(const StyleCont &styles, bool sys)
{
StyleCont::ConstIterator it(styles.begin()),
end(styles.end());
bool modified=false;
for(; it!=end; ++it)
{
CFontItem *font=findFont((*it).value(), sys);
if(!font)
{
// New font style!
itsFonts.append(new CFontItem(this, *it, sys));
modified=true;
}
else
{
int before=(*it).files().size();
font->addFiles((*it).files());
if((*it).files().size()!=before)
{
modified=true;
font->refresh();
}
}
}
return modified;
}
CFontItem * CFamilyItem::findFont(quint32 style, bool sys)
{
CFontItemCont::ConstIterator fIt(itsFonts.begin()),
fEnd(itsFonts.end());
for(; fIt!=fEnd; ++fIt)
if((*(*fIt)).styleInfo()==style && (*(*fIt)).isSystem()==sys)
return (*fIt);
return nullptr;
}
void CFamilyItem::getFoundries(QSet &foundries) const
{
CFontItemCont::ConstIterator it(itsFonts.begin()),
end(itsFonts.end());
for(; it!=end; ++it)
{
FileCont::ConstIterator fIt((*it)->files().begin()),
fEnd((*it)->files().end());
for(; fIt!=fEnd; ++fIt)
if(!(*fIt).foundry().isEmpty())
foundries.insert(capitaliseFoundry((*fIt).foundry()));
}
}
bool CFamilyItem::usable(const CFontItem *font, bool root)
{
return ( root ||
(font->isSystem() && itsParent.allowSys()) ||
(!font->isSystem() && itsParent.allowUser()));
}
void CFamilyItem::addFont(CFontItem *font, bool update)
{
itsFonts.append(font);
if(update)
{
updateStatus();
updateRegularFont(font);
}
}
void CFamilyItem::removeFont(CFontItem *font, bool update)
{
itsFonts.removeAll(font);
if(update)
updateStatus();
if(itsRegularFont==font)
{
itsRegularFont=nullptr;
if(update)
updateRegularFont(nullptr);
}
delete font;
}
void CFamilyItem::refresh()
{
updateStatus();
itsRegularFont=nullptr;
updateRegularFont(nullptr);
}
bool CFamilyItem::updateStatus()
{
bool root(Misc::root());
EStatus oldStatus(itsStatus);
CFontItemCont::ConstIterator it(itsFonts.begin()),
end(itsFonts.end());
int en(0), dis(0), allEn(0), allDis(0);
bool oldSys(isSystem()),
sys(false);
itsFontCount=0;
for(; it!=end; ++it)
if(usable(*it, root))
{
if((*it)->isEnabled())
en++;
else
dis++;
if(!sys)
sys=(*it)->isSystem();
itsFontCount++;
}
else
if((*it)->isEnabled())
allEn++;
else
allDis++;
allEn+=en;
allDis+=dis;
itsStatus=en && dis
? PARTIAL
: en
? ENABLED
: DISABLED;
itsRealStatus=allEn && allDis
? PARTIAL
: allEn
? ENABLED
: DISABLED;
if(!root)
setIsSystem(sys);
return itsStatus!=oldStatus || isSystem()!=oldSys;
}
bool CFamilyItem::updateRegularFont(CFontItem *font)
{
static const quint32 constRegular=FC::createStyleVal(FC_WEIGHT_REGULAR, KFI_FC_WIDTH_NORMAL, FC_SLANT_ROMAN);
CFontItem *oldFont(itsRegularFont);
bool root(Misc::root());
if(font && usable(font, root))
{
if(itsRegularFont)
{
int regDiff=abs((long)(itsRegularFont->styleInfo()-constRegular)),
fontDiff=abs((long)(font->styleInfo()-constRegular));
if(fontDiffstyleInfo()-constRegular));
if(diff)), SLOT(fontList(int,QList)));
}
CFontList::~CFontList()
{
qDeleteAll(itsFamilies);
itsFamilies.clear();
itsFamilyHash.clear();
}
void CFontList::dbusServiceOwnerChanged(const QString &name, const QString &from, const QString &to)
{
Q_UNUSED(from);
Q_UNUSED(to);
if(name==QLatin1String(OrgKdeFontinstInterface::staticInterfaceName()))
load();
}
void CFontList::fontList(int pid, const QList &families)
{
// printf("**** fontList:%d/%d %d\n", pid, getpid(), families.count());
if(pid==getpid())
{
QList::ConstIterator it(families.begin()),
end(families.end());
int count(families.size());
for(int i=0; it!=end; ++it, ++i)
{
fontsAdded(*it);
emit listingPercent(i*100/count);
}
emit listingPercent(100);
}
}
void CFontList::unsetSlowUpdates()
{
setSlowUpdates(false);
}
void CFontList::load()
{
for(int t=0; tlist(FontInst::SYS_MASK|FontInst::USR_MASK, getpid());
}
void CFontList::setSlowUpdates(bool slow)
{
if(itsSlowUpdates!=slow)
{
if(!slow)
for(int i=0; i families;
QDataStream ds(&encodedData, QIODevice::WriteOnly);
for(; it!=end; ++it)
if((*it).isValid())
{
if((static_cast((*it).internalPointer()))->isFont())
{
CFontItem *font=static_cast((*it).internalPointer());
families.insert(font->family());
}
else
{
CFamilyItem *fam=static_cast((*it).internalPointer());
families.insert(fam->name());
}
}
ds << families;
mimeData->setData(KFI_FONT_DRAG_MIME, encodedData);
return mimeData;
}
QStringList CFontList::mimeTypes() const
{
QStringList types;
types << "text/uri-list";
return types;
}
QVariant CFontList::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal)
switch(role)
{
case Qt::DisplayRole:
switch(section)
{
case COL_FONT:
return i18n("Font");
case COL_STATUS:
return i18n("Status");
default:
break;
}
break;
// case Qt::DecorationRole:
// if(COL_STATUS==section)
-// return SmallIcon("fontstatus");
+// return QIcon::fromTheme("fontstatus");
// break;
case Qt::TextAlignmentRole:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::ToolTipRole:
if(COL_STATUS==section)
return i18n("This column shows the status of the font family, and of the "
"individual font styles.");
break;
case Qt::WhatsThisRole:
return whatsThis();
default:
break;
}
return QVariant();
}
QModelIndex CFontList::index(int row, int column, const QModelIndex &parent) const
{
if(parent.isValid()) // Then font...
{
CFamilyItem *fam=static_cast(parent.internalPointer());
if(rowfonts().count())
return createIndex(row, column, fam->fonts().at(row));
}
else // Family....
if(row(index.internalPointer());
if(mi->isFamily())
return QModelIndex();
else
{
CFontItem *font=static_cast(index.internalPointer());
return createIndex(itsFamilies.indexOf(((CFamilyItem *)font->parent())), 0, font->parent());
}
}
int CFontList::rowCount(const QModelIndex &parent) const
{
if(parent.isValid())
{
CFontModelItem *mi=static_cast(parent.internalPointer());
if(mi->isFont())
return 0;
CFamilyItem *fam=static_cast(parent.internalPointer());
return fam->fonts().count();
}
else
return itsFamilies.count();
}
void CFontList::refresh(bool allowSys, bool allowUser)
{
itsAllowSys=allowSys;
itsAllowUser=allowUser;
CFamilyItemCont::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
(*it)->refresh();
}
void CFontList::getFamilyStats(QSet &enabled, QSet &disabled, QSet &partial)
{
CFamilyItemCont::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
{
switch((*it)->realStatus())
{
case CFamilyItem::ENABLED:
enabled.insert((*it)->name());
break;
case CFamilyItem::PARTIAL:
partial.insert((*it)->name());
break;
case CFamilyItem::DISABLED:
disabled.insert((*it)->name());
break;
}
}
}
void CFontList::getFoundries(QSet &foundries) const
{
CFamilyItemCont::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
(*it)->getFoundries(foundries);
}
QString CFontList::whatsThis() const
{
return i18n("This list shows your installed fonts. The fonts are grouped by family, and the"
" number in square brackets represents the number of styles in which the family is"
" available. e.g.
"
""
"- Times [4]"
"
- Regular
"
"- Bold
"
"- Bold Italic
"
"- Italic
"
"
"
" "
"
");
}
void CFontList::fontsAdded(const KFI::Families &families)
{
// printf("**** FONT ADDED:%d\n", families.items.count());
if(itsSlowUpdates)
storeSlowedMessage(families, MSG_ADD);
else
addFonts(families.items, families.isSystem && !Misc::root());
}
void CFontList::fontsRemoved(const KFI::Families &families)
{
// printf("**** FONT REMOVED:%d\n", families.items.count());
if(itsSlowUpdates)
storeSlowedMessage(families, MSG_DEL);
else
removeFonts(families.items, families.isSystem && !Misc::root());
}
void CFontList::storeSlowedMessage(const Families &families, EMsgType type)
{
int folder=families.isSystem ? FontInst::FOLDER_SYS : FontInst::FOLDER_USER;
bool playOld=false;
for(int i=0; iconstMaxSlowed)
playOld=true;
if(playOld)
actionSlowedUpdates(families.isSystem);
FamilyCont::ConstIterator family(families.items.begin()),
fend(families.items.end());
for(; family!=fend; ++family)
{
FamilyCont::ConstIterator f=itsSlowedMsgs[type][folder].find(*family);
if(f!=itsSlowedMsgs[type][folder].end())
{
StyleCont::ConstIterator style((*family).styles().begin()),
send((*family).styles().end());
for(; style!=send; ++style)
{
StyleCont::ConstIterator st=(*f).styles().find(*style);
if(st==(*f).styles().end())
(*f).add(*style);
else
(*st).addFiles((*style).files());
}
}
else
itsSlowedMsgs[type][folder].insert(*family);
}
}
void CFontList::actionSlowedUpdates(bool sys)
{
int folder=sys ? FontInst::FOLDER_SYS : FontInst::FOLDER_USER;
for(int i=0; i modifiedFamilies;
for(; family!=end; ++family)
{
if((*family).styles().count()>0)
{
CFamilyItem *famItem=findFamily((*family).name());
if(famItem)
{
int rowFrom=famItem->fonts().count();
if(famItem->addFonts((*family).styles(), sys))
{
int rowTo=famItem->fonts().count();
if(rowTo!=rowFrom)
{
beginInsertRows(createIndex(famItem->rowNumber(), 0, famItem), rowFrom, rowTo);
endInsertRows();
}
modifiedFamilies.insert(famItem);
}
}
else
{
famItem=new CFamilyItem(*this, *family, sys);
itsFamilies.append(famItem);
itsFamilyHash[famItem->name()]=famItem;
modifiedFamilies.insert(famItem);
}
}
}
int famRowTo=itsFamilies.count();
if(famRowTo!=famRowFrom)
{
beginInsertRows(QModelIndex(), famRowFrom, famRowTo);
endInsertRows();
}
if(!modifiedFamilies.isEmpty())
{
QSet::Iterator it(modifiedFamilies.begin()),
end(modifiedFamilies.end());
for(; it!=end; ++it)
(*it)->refresh();
}
// if(emitLayout)
// emit layoutChanged();
}
void CFontList::removeFonts(const FamilyCont &families, bool sys)
{
// if(!itsSlowUpdates)
// emit layoutAboutToBeChanged();
FamilyCont::ConstIterator family(families.begin()),
end(families.end());
QSet modifiedFamilies;
for(; family!=end; ++family)
{
if((*family).styles().count()>0)
{
CFamilyItem *famItem=findFamily((*family).name());
if(famItem)
{
StyleCont::ConstIterator it((*family).styles().begin()),
end((*family).styles().end());
for(; it!=end; ++it)
{
CFontItem *fontItem=famItem->findFont((*it).value(), sys);
if(fontItem)
{
int before=fontItem->files().count();
fontItem->removeFiles((*it).files());
if(fontItem->files().count()!=before)
{
if(fontItem->files().isEmpty())
{
int row=-1;
if(1!=famItem->fonts().count())
{
row=fontItem->rowNumber();
beginRemoveRows(createIndex(famItem->rowNumber(), 0, famItem), row, row);
}
famItem->removeFont(fontItem, false);
if(-1!=row)
endRemoveRows();
}
else
fontItem->refresh();
}
}
}
if(famItem->fonts().isEmpty())
{
int row=famItem->rowNumber();
beginRemoveRows(QModelIndex(), row, row);
itsFamilyHash.remove(famItem->name());
itsFamilies.removeAt(row);
endRemoveRows();
}
else
modifiedFamilies.insert(famItem);
}
}
}
if(!modifiedFamilies.isEmpty())
{
QSet::Iterator it(modifiedFamilies.begin()),
end(modifiedFamilies.end());
for(; it!=end; ++it)
(*it)->refresh();
}
// if(!itsSlowUpdates)
// emit layoutChanged();
}
CFamilyItem * CFontList::findFamily(const QString &familyName)
{
CFamilyItemHash::Iterator it=itsFamilyHash.find(familyName);
return it==itsFamilyHash.end() ? 0L : *it;
}
inline bool matchString(const QString &str, const QString &pattern)
{
return pattern.isEmpty() || -1!=str.indexOf(pattern, 0, Qt::CaseInsensitive);
}
CFontListSortFilterProxy::CFontListSortFilterProxy(QObject *parent, QAbstractItemModel *model)
: QSortFilterProxyModel(parent),
itsGroup(nullptr),
itsFilterCriteria(CFontFilter::CRIT_FAMILY),
itsFilterWs(0),
itsFcQuery(nullptr)
{
setSourceModel(model);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(0);
setDynamicSortFilter(false);
itsTimer=new QTimer(this);
connect(itsTimer, SIGNAL(timeout()), SLOT(timeout()));
connect(model, SIGNAL(layoutChanged()), SLOT(invalidate()));
itsTimer->setSingleShot(true);
}
QVariant CFontListSortFilterProxy::data(const QModelIndex &idx, int role) const
{
if (!idx.isValid())
return QVariant();
static const int constMaxFiles=20;
QModelIndex index(mapToSource(idx));
CFontModelItem *mi=static_cast(index.internalPointer());
if(!mi)
return QVariant();
switch(role)
{
case Qt::ToolTipRole:
if(CFontFilter::CRIT_FILENAME==itsFilterCriteria || CFontFilter::CRIT_LOCATION==itsFilterCriteria ||
CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria)
{
if(mi->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
CFontItemCont::ConstIterator it(fam->fonts().begin()),
end(fam->fonts().end());
FileCont allFiles;
QString tip(""+fam->name()+"");
bool markMatch(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria);
tip+="";
for(; it!=end; ++it)
allFiles+=(*it)->files();
//qSort(allFiles);
FileCont::ConstIterator fit(allFiles.begin()),
fend(allFiles.end());
for(int i=0; fit!=fend && ifile())
tip+=""+Misc::contractHome((*fit).path())+" |
";
else
tip+=""+Misc::contractHome((*fit).path())+" |
";
if(allFiles.count()>constMaxFiles)
tip+=""+i18n("...plus %1 more", allFiles.count()-constMaxFiles)+" |
";
tip+="
";
return tip;
}
else
{
CFontItem *font=static_cast(index.internalPointer());
QString tip(""+font->name()+"");
const FileCont &files(font->files());
bool markMatch(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria);
tip+="";
//qSort(files);
FileCont::ConstIterator fit(files.begin()),
fend(files.end());
for(int i=0; fit!=fend && ifile())
tip+=""+Misc::contractHome((*fit).path())+" |
";
else
tip+=""+Misc::contractHome((*fit).path() )+" |
";
if(files.count()>constMaxFiles)
tip+=""+i18n("...plus %1 more", files.count()-constMaxFiles)+" |
";
tip+="
";
return tip;
}
}
break;
case Qt::FontRole:
if(COL_FONT==index.column() && mi->isSystem())
{
QFont font;
font.setItalic(true);
return font;
}
break;
case Qt::ForegroundRole:
if(COL_FONT==index.column() &&
( (mi->isFont() && !(static_cast(index.internalPointer()))->isEnabled()) ||
(mi->isFamily() && CFamilyItem::DISABLED==(static_cast(index.internalPointer()))->status())) )
return KColorScheme(QPalette::Active).foreground(KColorScheme::NegativeText).color();
break;
case Qt::DisplayRole:
if(COL_FONT==index.column())
{
if(mi->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
return i18n("%1 [%2]", fam->name(), fam->fontCount());
}
else
return (static_cast(index.internalPointer()))->style();
}
break;
case Qt::DecorationRole:
if(mi->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
switch(index.column())
{
case COL_STATUS:
switch(fam->status())
{
case CFamilyItem::PARTIAL:
- return SmallIcon("dialog-ok", 0, KIconLoader::DisabledState);
+ return QIcon::fromTheme("dialog-ok");
case CFamilyItem::ENABLED:
- return SmallIcon("dialog-ok");
+ return QIcon::fromTheme("dialog-ok");
case CFamilyItem::DISABLED:
- return SmallIcon("dialog-cancel");
+ return QIcon::fromTheme("dialog-cancel");
}
break;
default:
break;
}
}
else if(COL_STATUS==index.column())
- return SmallIcon( (static_cast(index.internalPointer()))->isEnabled()
- ? "dialog-ok" : "dialog-cancel", 10);
+ return QIcon::fromTheme( (static_cast(index.internalPointer()))->isEnabled()
+ ? "dialog-ok" : "dialog-cancel");
break;
case Qt::SizeHintRole:
if(mi->isFamily()) {
const int s = KIconLoader::global()->currentSize(KIconLoader::Small);
return QSize(s, s + 4);
}
default:
break;
}
return QVariant();
}
bool CFontListSortFilterProxy::acceptFont(CFontItem *fnt, bool checkFontText) const
{
if(itsGroup && (CGroupListItem::ALL!=itsGroup->type() || (!filterText().isEmpty() && checkFontText)))
{
bool fontMatch(!checkFontText);
if(!fontMatch)
switch(itsFilterCriteria)
{
case CFontFilter::CRIT_FONTCONFIG:
fontMatch=itsFcQuery
? fnt->name()==itsFcQuery->font() // || fnt->files().contains(itsFcQuery->file())
: false;
break;
case CFontFilter::CRIT_STYLE:
fontMatch=matchString(fnt->style(), itsFilterText);
break;
case CFontFilter::CRIT_FOUNDRY:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
for(; it!=end && !fontMatch; ++it)
fontMatch=0==(*it).foundry().compare(itsFilterText, Qt::CaseInsensitive);
break;
}
case CFontFilter::CRIT_FILENAME:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
for(; it!=end && !fontMatch; ++it)
{
QString file(Misc::getFile((*it).path()));
int pos(Misc::isHidden(file) ? 1 : 0);
if(pos==file.indexOf(itsFilterText, pos, Qt::CaseInsensitive))
fontMatch=true;
}
break;
}
case CFontFilter::CRIT_LOCATION:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
for(; it!=end && !fontMatch; ++it)
if(0==Misc::getDir((*it).path()).indexOf(itsFilterText, 0, Qt::CaseInsensitive))
fontMatch=true;
break;
}
case CFontFilter::CRIT_FILETYPE:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
QStringList::ConstIterator mimeEnd(itsFilterTypes.constEnd());
for(; it!=end && !fontMatch; ++it)
{
QStringList::ConstIterator mime(itsFilterTypes.constBegin());
-
+
for(; mime!=mimeEnd; ++mime)
if(Misc::checkExt((*it).path(), *mime))
fontMatch=true;
}
break;
}
case CFontFilter::CRIT_WS:
fontMatch=fnt->writingSystems()&itsFilterWs;
break;
default:
break;
}
return fontMatch && itsGroup->hasFont(fnt);
}
return true;
}
bool CFontListSortFilterProxy::acceptFamily(CFamilyItem *fam) const
{
CFontItemCont::ConstIterator it(fam->fonts().begin()),
end(fam->fonts().end());
bool familyMatch(CFontFilter::CRIT_FAMILY==itsFilterCriteria &&
matchString(fam->name(), itsFilterText));
for(; it!=end; ++it)
if(acceptFont(*it, !familyMatch))
return true;
return false;
}
bool CFontListSortFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index(sourceModel()->index(sourceRow, 0, sourceParent));
if(index.isValid())
{
CFontModelItem *mi=static_cast(index.internalPointer());
if(mi->isFont())
{
CFontItem *font=static_cast(index.internalPointer());
return acceptFont(font, !(CFontFilter::CRIT_FAMILY==itsFilterCriteria &&
matchString(font->family(), itsFilterText)));
}
else
return acceptFamily(static_cast(index.internalPointer()));
}
return false;
}
bool CFontListSortFilterProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
if(left.isValid() && right.isValid())
{
CFontModelItem *lmi=static_cast(left.internalPointer()),
*rmi=static_cast(right.internalPointer());
if(lmi->isFont()isFont())
return true;
if(lmi->isFont())
{
CFontItem *lfi=static_cast(left.internalPointer()),
*rfi=static_cast(right.internalPointer());
if(COL_STATUS==filterKeyColumn())
{
if(lfi->isEnabled()isEnabled() ||
(lfi->isEnabled()==rfi->isEnabled() &&
lfi->styleInfo()styleInfo()))
return true;
}
else
if(lfi->styleInfo()styleInfo())
return true;
}
else
{
CFamilyItem *lfi=static_cast(left.internalPointer()),
*rfi=static_cast(right.internalPointer());
if(COL_STATUS==filterKeyColumn())
{
if(lfi->status()status() ||
(lfi->status()==rfi->status() && QString::localeAwareCompare(lfi->name(), rfi->name())<0))
return true;
}
else
if(QString::localeAwareCompare(lfi->name(), rfi->name())<0)
return true;
}
}
return false;
}
void CFontListSortFilterProxy::setFilterGroup(CGroupListItem *grp)
{
if(grp!=itsGroup)
{
// bool wasNull=!itsGroup;
itsGroup=grp;
// if(!(wasNull && itsGroup && CGroupListItem::ALL==itsGroup->type()))
clear();
}
}
void CFontListSortFilterProxy::setFilterText(const QString &text)
{
if(text!=itsFilterText)
{
//
// If we are filtering on file location, then expand ~ to /home/user, etc.
if (CFontFilter::CRIT_LOCATION==itsFilterCriteria && !text.isEmpty() && ('~'==text[0] || '$'==text[0]))
if('~'==text[0])
itsFilterText=1==text.length()
? QDir::homePath()
: QString(text).replace(0, 1, QDir::homePath());
else
itsFilterText=replaceEnvVar(text);
else
itsFilterText=text;
if(itsFilterText.isEmpty())
{
itsTimer->stop();
timeout();
}
else
itsTimer->start(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria ? 750 : 400);
}
}
void CFontListSortFilterProxy::setFilterCriteria(CFontFilter::ECriteria crit, qulonglong ws, const QStringList &ft)
{
if(crit!=itsFilterCriteria || ws!=itsFilterWs || ft!=itsFilterTypes)
{
itsFilterWs=ws;
itsFilterCriteria=crit;
itsFilterTypes=ft;
if(CFontFilter::CRIT_LOCATION==itsFilterCriteria)
setFilterText(itsFilterText);
itsTimer->stop();
timeout();
}
}
void CFontListSortFilterProxy::timeout()
{
if(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria)
{
int commaPos=itsFilterText.indexOf(',');
QString query(itsFilterText);
if(-1!=commaPos)
{
QString style(query.mid(commaPos+1));
query.truncate(commaPos);
query=query.trimmed();
query+=":style=";
style=style.trimmed();
query+=style;
}
else
query=query.trimmed();
if(!itsFcQuery)
{
itsFcQuery=new CFcQuery(this);
connect(itsFcQuery, SIGNAL(finished()), SLOT(fcResults()));
}
itsFcQuery->run(query);
}
else
{
clear();
emit refresh();
}
}
void CFontListSortFilterProxy::fcResults()
{
if(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria)
{
clear();
emit refresh();
}
}
CFontListView::CFontListView(QWidget *parent, CFontList *model)
: QTreeView(parent),
itsProxy(new CFontListSortFilterProxy(this, model)),
itsModel(model),
itsAllowDrops(false)
{
setModel(itsProxy);
itsModel=model;
header()->setStretchLastSection(false);
resizeColumnToContents(COL_STATUS);
header()->setResizeMode(COL_STATUS, QHeaderView::Fixed);
header()->setResizeMode(COL_FONT, QHeaderView::Stretch);
setSelectionMode(QAbstractItemView::ExtendedSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSortingEnabled(true);
sortByColumn(COL_FONT, Qt::AscendingOrder);
setAllColumnsShowFocus(true);
setAlternatingRowColors(true);
setAcceptDrops(true);
setDropIndicatorShown(false);
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragDrop);
header()->setClickable(true);
header()->setSortIndicatorShown(true);
connect(this, SIGNAL(collapsed(QModelIndex)), SLOT(itemCollapsed(QModelIndex)));
connect(header(), SIGNAL(sectionClicked(int)), SLOT(setSortColumn(int)));
connect(itsProxy, SIGNAL(refresh()), SIGNAL(refresh()));
connect(itsModel, SIGNAL(listingPercent(int)), SLOT(listingPercent(int)));
setWhatsThis(model->whatsThis());
header()->setWhatsThis(whatsThis());
itsMenu=new QMenu(this);
itsDeleteAct=itsMenu->addAction(QIcon::fromTheme("edit-delete"), i18n("Delete"),
this, SIGNAL(del()));
itsMenu->addSeparator();
- itsEnableAct=itsMenu->addAction(QIcon::fromTheme("enablefont"), i18n("Enable"),
+ itsEnableAct=itsMenu->addAction(QIcon::fromTheme("font-enable"), i18n("Enable"),
this, SIGNAL(enable()));
- itsDisableAct=itsMenu->addAction(QIcon::fromTheme("disablefont"), i18n("Disable"),
+ itsDisableAct=itsMenu->addAction(QIcon::fromTheme("font-disable"), i18n("Disable"),
this, SIGNAL(disable()));
if(!Misc::app(KFI_VIEWER).isEmpty())
itsMenu->addSeparator();
itsPrintAct=Misc::app(KFI_VIEWER).isEmpty() ? nullptr : itsMenu->addAction(QIcon::fromTheme("document-print"), i18n("Print..."),
this, SIGNAL(print()));
itsViewAct=Misc::app(KFI_VIEWER).isEmpty() ? nullptr : itsMenu->addAction(QIcon::fromTheme("kfontview"), i18n("Open in Font Viewer"),
this, SLOT(view()));
itsMenu->addSeparator();
itsMenu->addAction(QIcon::fromTheme("view-refresh"), i18n("Reload"), model, SLOT(load()));
}
void CFontListView::getFonts(CJobRunner::ItemList &urls, QStringList &fontNames, QSet *fonts,
bool selected, bool getEnabled, bool getDisabled)
{
QModelIndexList selectedItems(selected ? selectedIndexes() : allIndexes());
QSet usedFonts;
QModelIndex index;
foreach(index, selectedItems)
if(index.isValid())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font=static_cast(realIndex.internalPointer());
addFont(font, urls, fontNames, fonts, usedFonts,
getEnabled, getDisabled);
}
else
{
CFamilyItem *fam=static_cast(realIndex.internalPointer());
for(int ch=0; chfontCount(); ++ch)
{
QModelIndex child(itsProxy->mapToSource(index.child(ch, 0)));
if(child.isValid() &&
(static_cast(child.internalPointer()))->isFont())
{
CFontItem *font=static_cast(child.internalPointer());
addFont(font, urls, fontNames, fonts, usedFonts,
getEnabled, getDisabled);
}
}
}
}
}
fontNames=CFontList::compact(fontNames);
}
QSet CFontListView::getFiles()
{
QModelIndexList items(allIndexes());
QModelIndex index;
QSet files;
foreach(index, items)
if(index.isValid())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font=static_cast(realIndex.internalPointer());
FileCont::ConstIterator it(font->files().begin()),
end(font->files().end());
for(; it!=end; ++it)
{
QStringList assoc;
files.insert((*it).path());
Misc::getAssociatedFiles((*it).path(), assoc);
QStringList::ConstIterator ait(assoc.constBegin()),
aend(assoc.constEnd());
for(; ait!=aend; ++ait)
files.insert(*ait);
}
}
}
return files;
}
void CFontListView::getPrintableFonts(QSet &items, bool selected)
{
QModelIndexList selectedItems(selected ? selectedIndexes() : allIndexes());
QModelIndex index;
foreach(index, selectedItems)
{
CFontItem *font=nullptr;
if(index.isValid() && 0==index.column())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
font=static_cast(realIndex.internalPointer());
else
{
CFamilyItem *fam=static_cast(realIndex.internalPointer());
font=fam->regularFont();
}
}
}
if(font && !font->isBitmap() && font->isEnabled())
items.insert(Misc::TFont(font->family(), font->styleInfo()));
}
}
void CFontListView::setFilterGroup(CGroupListItem *grp)
{
CGroupListItem *oldGrp(itsProxy->filterGroup());
itsProxy->setFilterGroup(grp);
itsAllowDrops=grp && !grp->isCustom();
if(!Misc::root())
{
bool refreshStats(false);
if(!grp || !oldGrp)
refreshStats=true;
else
{
// Check to see whether we have changed from listing all fonts,
// listing just system or listing personal fonts.
CGroupListItem::EType aType(CGroupListItem::CUSTOM==grp->type() ||
CGroupListItem::ALL==grp->type() ||
CGroupListItem::UNCLASSIFIED==grp->type()
? CGroupListItem::CUSTOM : grp->type()),
bType(CGroupListItem::CUSTOM==oldGrp->type() ||
CGroupListItem::ALL==oldGrp->type() ||
CGroupListItem::UNCLASSIFIED==oldGrp->type()
? CGroupListItem::CUSTOM : oldGrp->type());
refreshStats=aType!=bType;
}
if(refreshStats)
itsModel->refresh(!grp || !grp->isPersonal(),
!grp || !grp->isSystem());
}
// when switching groups, for some reason it is not always sorted.
setSortingEnabled(true);
}
void CFontListView::listingPercent(int percent)
{
// when the font list is first loaded, for some reason it is not always sorted.
// re-enabling sorting here seems to fix the issue - BUG 221610
if(100==percent)
setSortingEnabled(true);
}
void CFontListView::refreshFilter()
{
itsProxy->clear();
}
void CFontListView::filterText(const QString &text)
{
itsProxy->setFilterText(text);
}
void CFontListView::filterCriteria(int crit, qulonglong ws, const QStringList &ft)
{
itsProxy->setFilterCriteria((CFontFilter::ECriteria)crit, ws, ft);
}
void CFontListView::stats(int &enabled, int &disabled, int &partial)
{
enabled=disabled=partial=0;
for(int i=0; irowCount(); ++i)
{
QModelIndex idx(itsProxy->index(i, 0, QModelIndex()));
if(!idx.isValid())
break;
QModelIndex sourceIdx(itsProxy->mapToSource(idx));
if(!sourceIdx.isValid())
break;
if((static_cast(sourceIdx.internalPointer()))->isFamily())
switch((static_cast(sourceIdx.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
enabled++;
break;
case CFamilyItem::DISABLED:
disabled++;
break;
case CFamilyItem::PARTIAL:
partial++;
break;
}
}
}
void CFontListView::selectedStatus(bool &enabled, bool &disabled)
{
QModelIndexList selected(selectedIndexes());
QModelIndex index;
enabled=disabled=false;
foreach(index, selected)
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFamily())
{
switch((static_cast(realIndex.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
enabled=true;
break;
case CFamilyItem::DISABLED:
disabled=true;
break;
case CFamilyItem::PARTIAL:
enabled=true;
disabled=true;
break;
}
}
else
{
if((static_cast(realIndex.internalPointer()))->isEnabled())
enabled=true;
else
disabled=true;
}
}
if(enabled && disabled)
break;
}
}
QModelIndexList CFontListView::allFonts()
{
QModelIndexList rv;
int rowCount(itsProxy->rowCount());
for(int i=0; iindex(i, 0, QModelIndex()));
int childRowCount(itsProxy->rowCount(idx));
for(int j=0; jindex(j, 0, idx));
if(child.isValid())
rv.append(itsProxy->mapToSource(child));
}
}
return rv;
}
void CFontListView::selectFirstFont()
{
if(0==selectedIndexes().count())
for(int i=0; iindex(0, i, QModelIndex()));
if(idx.isValid())
selectionModel()->select(idx, QItemSelectionModel::Select);
}
}
void CFontListView::setSortColumn(int col)
{
if(col!=itsProxy->filterKeyColumn())
{
itsProxy->setFilterKeyColumn(col);
itsProxy->clear();
}
}
void CFontListView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
QAbstractItemView::selectionChanged(selected, deselected);
if(itsModel->slowUpdates())
return;
emit itemsSelected(getSelectedItems());
}
QModelIndexList CFontListView::getSelectedItems()
{
//
// Go through current selection, and for any 'font' items that are selected,
// ensure 'family' item is not...
QModelIndexList selectedItems(selectedIndexes()),
deselectList;
QModelIndex index;
QSet selectedFamilies;
bool en(false),
dis(false);
foreach(index, selectedItems)
if(index.isValid())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font=static_cast(realIndex.internalPointer());
if(font->isEnabled())
en=true;
else
dis=true;
if(!selectedFamilies.contains(font->parent()))
{
selectedFamilies.insert(font->parent());
for(int i=0; imapFromSource(
itsModel->createIndex(font->parent()->rowNumber(),
i, font->parent())));
}
}
else
{
switch((static_cast(realIndex.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
en=true;
break;
case CFamilyItem::DISABLED:
dis=true;
break;
case CFamilyItem::PARTIAL:
en=dis=true;
break;
}
}
}
}
if(deselectList.count())
foreach(index, deselectList)
selectionModel()->select(index, QItemSelectionModel::Deselect);
QModelIndexList sel;
QSet pointers;
selectedItems=selectedIndexes();
foreach(index, selectedItems)
{
QModelIndex idx(itsProxy->mapToSource(index));
if(!pointers.contains(idx.internalPointer()))
{
pointers.insert(idx.internalPointer());
sel.append(idx);
}
}
return sel;
}
void CFontListView::itemCollapsed(const QModelIndex &idx)
{
if(idx.isValid())
{
QModelIndex index(itsProxy->mapToSource(idx));
if(index.isValid() && (static_cast(index.internalPointer()))->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
CFontItemCont::ConstIterator it(fam->fonts().begin()),
end(fam->fonts().end());
for(; it!=end; ++it)
for(int i=0; iselect(itsProxy->mapFromSource(itsModel->createIndex((*it)->rowNumber(),
i, *it)),
QItemSelectionModel::Deselect);
}
}
}
static bool isScalable(const QString &str)
{
QByteArray cFile(QFile::encodeName(str));
return Misc::checkExt(cFile, "ttf") || Misc::checkExt(cFile, "otf") || Misc::checkExt(cFile, "ttc") ||
Misc::checkExt(cFile, "pfa") || Misc::checkExt(cFile, "pfb");
}
void CFontListView::view()
{
// Number of fonts user has selected, before we ask if they really want to view them all...
static const int constMaxBeforePrompt=10;
QModelIndexList selectedItems(selectedIndexes());
QModelIndex index;
QSet fonts;
foreach(index, selectedItems)
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font(static_cast(realIndex.internalPointer()));
fonts.insert(font);
}
else
{
CFontItem *font((static_cast(realIndex.internalPointer()))->regularFont());
if(font)
fonts.insert(font);
}
}
}
if(fonts.count() &&
(fonts.count()::ConstIterator it(fonts.begin()),
end(fonts.end());
QStringList args;
for(; it!=end; ++it)
{
QString file;
int index(0);
if(!(*it)->isEnabled())
{
// For a disabled font, we need to find the first scalable font entry in its file list...
FileCont::ConstIterator fit((*it)->files().begin()),
fend((*it)->files().end());
for(; fit!=fend; ++fit)
if(isScalable((*fit).path()))
{
file=(*fit).path();
index=(*fit).index();
break;
}
if(file.isEmpty())
{
file=(*it)->fileName();
index=(*it)->index();
}
}
args << FC::encode((*it)->family(), (*it)->styleInfo(), file, index).url();
}
QProcess::startDetached(Misc::app(KFI_VIEWER), args);
}
}
QModelIndexList CFontListView::allIndexes()
{
QModelIndexList rv;
int rowCount(itsProxy->rowCount());
for(int i=0; iindex(i, 0, QModelIndex()));
int childRowCount(itsProxy->rowCount(idx));
rv.append(idx);
for(int j=0; jindex(j, 0, idx));
if(child.isValid())
rv.append(child);
}
}
return rv;
}
void CFontListView::startDrag(Qt::DropActions supportedActions)
{
QModelIndexList indexes(selectedIndexes());
if (indexes.count())
{
QMimeData *data = model()->mimeData(indexes);
if (!data)
return;
QModelIndex index(itsProxy->mapToSource(indexes.first()));
const char *icon="application-x-font-pcf";
if(index.isValid())
{
CFontItem *font=(static_cast(index.internalPointer()))->isFont()
? static_cast(index.internalPointer())
: (static_cast(index.internalPointer()))->regularFont();
if(font && !font->isBitmap())
// if("application/x-font-type1"==font->mimetype())
// icon="application-x-font-type1";
// else
icon="application-x-font-ttf";
}
QPoint hotspot;
QPixmap pix(DesktopIcon(icon, KIconLoader::SizeMedium));
hotspot.setX(0); // pix.width()/2);
hotspot.setY(0); // pix.height()/2);
QDrag *drag = new QDrag(this);
drag->setPixmap(pix);
drag->setMimeData(data);
drag->setHotSpot(hotspot);
drag->start(supportedActions);
}
}
void CFontListView::dragEnterEvent(QDragEnterEvent *event)
{
if(itsAllowDrops && event->mimeData()->hasFormat("text/uri-list")) // "application/x-kde-urilist" ??
event->acceptProposedAction();
}
void CFontListView::dropEvent(QDropEvent *event)
{
if(itsAllowDrops && event->mimeData()->hasFormat("text/uri-list"))
{
event->acceptProposedAction();
QList urls(event->mimeData()->urls());
QList::ConstIterator it(urls.begin()),
end(urls.end());
QSet kurls;
QMimeDatabase db;
for (; it!=end; ++it)
{
QMimeType mime = db.mimeTypeForUrl(*it);
foreach (const QString &fontMime, CFontList::fontMimeTypes) {
if (mime.inherits(fontMime)) {
kurls.insert(*it);
break;
}
}
}
if(!kurls.isEmpty())
emit fontsDropped(kurls);
}
}
void CFontListView::contextMenuEvent(QContextMenuEvent *ev)
{
bool valid(indexAt(ev->pos()).isValid());
itsDeleteAct->setEnabled(valid);
bool en(false),
dis(false);
QModelIndexList selectedItems(selectedIndexes());
QModelIndex index;
foreach(index, selectedItems)
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
if((static_cast(realIndex.internalPointer())->isEnabled()))
en=true;
else
dis=true;
}
else
{
switch((static_cast(realIndex.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
en=true;
break;
case CFamilyItem::DISABLED:
dis=true;
break;
case CFamilyItem::PARTIAL:
en=dis=true;
break;
}
}
}
if(en && dis)
break;
}
itsEnableAct->setEnabled(dis);
itsDisableAct->setEnabled(en);
if(itsPrintAct)
itsPrintAct->setEnabled(en|dis);
if(itsViewAct)
itsViewAct->setEnabled(en|dis);
itsMenu->popup(ev->globalPos());
}
bool CFontListView::viewportEvent(QEvent *event)
{
executeDelayedItemsLayout();
return QTreeView::viewportEvent(event);
}
}
diff --git a/kcms/kfontinst/kcmfontinst/GroupList.cpp b/kcms/kfontinst/kcmfontinst/GroupList.cpp
index e1f6442aa..1e201fc83 100644
--- a/kcms/kfontinst/kcmfontinst/GroupList.cpp
+++ b/kcms/kfontinst/kcmfontinst/GroupList.cpp
@@ -1,1026 +1,1026 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "GroupList.h"
#include "FontList.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "FcEngine.h"
#include "Misc.h"
#include "KfiConstants.h"
namespace KFI
{
#define GROUPS_DOC "groups"
#define GROUP_TAG "group"
#define NAME_ATTR "name"
#define FAMILY_TAG "family"
enum EGroupColumns
{
COL_GROUP_NAME,
NUM_GROUP_COLS
};
CGroupListItem::CGroupListItem(const QString &name)
: itsName(name),
itsType(CUSTOM),
itsHighlighted(false),
itsStatus(CFamilyItem::ENABLED)
{
itsData.validated=false;
}
CGroupListItem::CGroupListItem(EType type, CGroupList *p)
: itsType(type),
itsHighlighted(false),
itsStatus(CFamilyItem::ENABLED)
{
switch(itsType)
{
case ALL:
itsName=i18n("All Fonts");
break;
case PERSONAL:
itsName=i18n("Personal Fonts");
break;
case SYSTEM:
itsName=i18n("System Fonts");
break;
default:
itsName=i18n("Unclassified");
}
itsData.parent=p;
}
bool CGroupListItem::hasFont(const CFontItem *fnt) const
{
switch(itsType)
{
case CUSTOM:
return itsFamilies.contains(fnt->family());
case PERSONAL:
return !fnt->isSystem();
case SYSTEM:
return fnt->isSystem();
case ALL:
return true;
case UNCLASSIFIED:
{
QList::ConstIterator it(itsData.parent->itsGroups.begin()),
end(itsData.parent->itsGroups.end());
for(; it!=end; ++it)
if((*it)->isCustom() && (*it)->families().contains(fnt->family()))
return false;
return true;
}
default:
return false;
}
return false;
}
void CGroupListItem::updateStatus(QSet &enabled, QSet &disabled, QSet &partial)
{
QSet families(itsFamilies);
if(0!=families.intersect(partial).count())
itsStatus=CFamilyItem::PARTIAL;
else
{
families=itsFamilies;
bool haveEnabled(0!=families.intersect(enabled).count());
families=itsFamilies;
bool haveDisabled(0!=families.intersect(disabled).count());
if(haveEnabled && haveDisabled)
itsStatus=CFamilyItem::PARTIAL;
else if(haveEnabled && !haveDisabled)
itsStatus=CFamilyItem::ENABLED;
else
itsStatus=CFamilyItem::DISABLED;
}
}
bool CGroupListItem::load(QDomElement &elem)
{
if(elem.hasAttribute(NAME_ATTR))
{
itsName=elem.attribute(NAME_ATTR);
addFamilies(elem);
return true;
}
return false;
}
bool CGroupListItem::addFamilies(QDomElement &elem)
{
int b4(itsFamilies.count());
for(QDomNode n=elem.firstChild(); !n.isNull(); n=n.nextSibling())
{
QDomElement ent=n.toElement();
if(FAMILY_TAG==ent.tagName())
itsFamilies.insert(ent.text());
}
return b4!=itsFamilies.count();
}
void CGroupListItem::save(QTextStream &str)
{
str << " <" GROUP_TAG " " NAME_ATTR "=\"" << Misc::encodeText(itsName, str) << "\">" << endl;
if(!itsFamilies.isEmpty())
{
QSet::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
str << " <" FAMILY_TAG ">" << Misc::encodeText(*it, str) << "" FAMILY_TAG ">" << endl;
}
str << " " GROUP_TAG ">" << endl;
}
CGroupList::CGroupList(QWidget *parent)
: QAbstractItemModel(parent),
itsTimeStamp(0),
itsModified(false),
itsParent(parent),
itsSortOrder(Qt::AscendingOrder)
{
itsSpecialGroups[CGroupListItem::ALL]=new CGroupListItem(CGroupListItem::ALL, this);
itsGroups.append(itsSpecialGroups[CGroupListItem::ALL]);
if(Misc::root())
itsSpecialGroups[CGroupListItem::PERSONAL]=
itsSpecialGroups[CGroupListItem::SYSTEM]=NULL;
else
{
itsSpecialGroups[CGroupListItem::PERSONAL]=new CGroupListItem(CGroupListItem::PERSONAL, this);
itsGroups.append(itsSpecialGroups[CGroupListItem::PERSONAL]);
itsSpecialGroups[CGroupListItem::SYSTEM]=new CGroupListItem(CGroupListItem::SYSTEM, this);
itsGroups.append(itsSpecialGroups[CGroupListItem::SYSTEM]);
}
itsSpecialGroups[CGroupListItem::UNCLASSIFIED]=
new CGroupListItem(CGroupListItem::UNCLASSIFIED, this);
// Locate groups.xml file - normall will be ~/.config/fontgroups.xml
QString path(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + '/');
if(!Misc::dExists(path))
Misc::createDir(path);
itsFileName=path+'/'+KFI_GROUPS_FILE;
rescan();
}
CGroupList::~CGroupList()
{
save();
qDeleteAll(itsGroups);
itsGroups.clear();
}
int CGroupList::columnCount(const QModelIndex &) const
{
return NUM_GROUP_COLS;
}
void CGroupList::update(const QModelIndex &unHighlight, const QModelIndex &highlight)
{
if(unHighlight.isValid())
{
CGroupListItem *grp=static_cast(unHighlight.internalPointer());
if(grp)
grp->setHighlighted(false);
emit dataChanged(unHighlight, unHighlight);
}
if(highlight.isValid())
{
CGroupListItem *grp=static_cast(highlight.internalPointer());
if(grp)
grp->setHighlighted(true);
emit dataChanged(highlight, highlight);
}
}
void CGroupList::updateStatus(QSet &enabled, QSet &disabled,
QSet &partial)
{
QList::Iterator it(itsGroups.begin()),
end(itsGroups.end());
for(; it!=end; ++it)
if((*it)->isCustom())
(*it)->updateStatus(enabled, disabled, partial);
emit layoutChanged();
}
inline QColor midColour(const QColor &a, const QColor &b)
{
return QColor((a.red()+b.red())>>1, (a.green()+b.green())>>1, (a.blue()+b.blue())>>1);
}
QVariant CGroupList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
CGroupListItem *grp=static_cast(index.internalPointer());
if(grp)
switch(index.column())
{
case COL_GROUP_NAME:
switch(role)
{
case Qt::FontRole:
if(CGroupListItem::SYSTEM==grp->type())
{
QFont font;
font.setItalic(true);
return font;
}
break;
case Qt::SizeHintRole:
{
const int s = KIconLoader::global()->currentSize(KIconLoader::Small);
return QSize(s, s + 4);
}
case Qt::EditRole:
case Qt::DisplayRole:
return grp->name();
case Qt::DecorationRole:
if(grp->highlighted())
switch(grp->type())
{
case CGroupListItem::ALL: // Removing from a group
- return SmallIcon("list-remove");
+ return QIcon::fromTheme("list-remove");
case CGroupListItem::PERSONAL: // Copying/moving
case CGroupListItem::SYSTEM: // Copying/moving
- return SmallIcon(Qt::LeftToRight==QApplication::layoutDirection()
+ return QIcon::fromTheme(Qt::LeftToRight==QApplication::layoutDirection()
? "go-next" : "go-previous");
case CGroupListItem::CUSTOM: // Adding to a group
- return SmallIcon("list-add");
+ return QIcon::fromTheme("list-add");
default:
break;
}
else
switch(grp->type())
{
case CGroupListItem::ALL:
- return SmallIcon("font");
+ return QIcon::fromTheme("font");
case CGroupListItem::PERSONAL:
- return SmallIcon("user-identity");
+ return QIcon::fromTheme("user-identity");
case CGroupListItem::SYSTEM:
- return SmallIcon("computer");
+ return QIcon::fromTheme("computer");
case CGroupListItem::UNCLASSIFIED:
- return SmallIcon("fontstatus");
+ return QIcon::fromTheme("fontstatus");
case CGroupListItem::CUSTOM:
if(0==grp->families().count())
- return SmallIcon("image-missing");
+ return QIcon::fromTheme("image-missing");
switch(grp->status())
{
case CFamilyItem::PARTIAL:
- return SmallIcon("dialog-ok", 0, KIconLoader::DisabledState);
+ return QIcon::fromTheme("dialog-ok");
case CFamilyItem::ENABLED:
- return SmallIcon("dialog-ok");
+ return QIcon::fromTheme("dialog-ok");
case CFamilyItem::DISABLED:
- return SmallIcon("dialog-cancel");
+ return QIcon::fromTheme("dialog-cancel");
}
break;
}
default:
break;
}
break;
}
return QVariant();
}
bool CGroupList::setData(const QModelIndex &index, const QVariant &value, int role)
{
if(Qt::EditRole==role && index.isValid())
{
QString name(value.toString().trimmed());
if(!name.isEmpty())
{
CGroupListItem *grp=static_cast(index.internalPointer());
if(grp && grp->isCustom() && grp->name()!=name && !exists(name, false))
{
grp->setName(name);
itsModified=true;
save();
sort(0, itsSortOrder);
return true;
}
}
}
return false;
}
Qt::ItemFlags CGroupList::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
CGroupListItem *grp=static_cast(index.internalPointer());
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled |
(grp && grp->type()==CGroupListItem::CUSTOM ? Qt::ItemIsEditable : Qt::NoItemFlags);
}
QVariant CGroupList::headerData(int section, Qt::Orientation orientation, int role) const
{
if (Qt::Horizontal==orientation && COL_GROUP_NAME==section)
switch(role)
{
case Qt::DisplayRole:
return i18n("Group");
case Qt::TextAlignmentRole:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::WhatsThisRole:
return whatsThis();
default:
break;
}
return QVariant();
}
QModelIndex CGroupList::index(int row, int column, const QModelIndex &parent) const
{
if(!parent.isValid())
{
CGroupListItem *grp=itsGroups.value(row);
if(grp)
return createIndex(row, column, grp);
}
return QModelIndex();
}
QModelIndex CGroupList::parent(const QModelIndex &) const
{
return QModelIndex();
}
int CGroupList::rowCount(const QModelIndex &) const
{
return itsGroups.count();
}
void CGroupList::rescan()
{
save();
load();
sort(0, itsSortOrder);
}
void CGroupList::load()
{
time_t ts=Misc::getTimeStamp(itsFileName);
if(!ts || ts!=itsTimeStamp)
{
clear();
itsTimeStamp=ts;
if(load(itsFileName))
itsModified=false;
}
}
bool CGroupList::load(const QString &file)
{
QFile f(file);
bool rv(false);
if(f.open(QIODevice::ReadOnly))
{
QDomDocument doc;
if(doc.setContent(&f))
for(QDomNode n=doc.documentElement().firstChild(); !n.isNull(); n=n.nextSibling())
{
QDomElement e=n.toElement();
if(GROUP_TAG==e.tagName() && e.hasAttribute(NAME_ATTR))
{
QString name(e.attribute(NAME_ATTR));
CGroupListItem *item=find(name);
if(!item)
{
item=new CGroupListItem(name);
if(!itsGroups.contains(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]))
itsGroups.append(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
itsGroups.append(item);
rv=true;
}
if(item->addFamilies(e))
rv=true;
}
}
}
return rv;
}
bool CGroupList::save()
{
if(itsModified && save(itsFileName, nullptr))
{
itsTimeStamp=Misc::getTimeStamp(itsFileName);
return true;
}
return false;
}
bool CGroupList::save(const QString &fileName, CGroupListItem *grp)
{
QSaveFile file(fileName);
if (file.open(QIODevice::WriteOnly))
{
QTextStream str(&file);
str << "<" GROUPS_DOC ">" << endl;
if(grp)
grp->save(str);
else
{
QList::Iterator it(itsGroups.begin()),
end(itsGroups.end());
for(; it!=end; ++it)
if((*it)->isCustom())
(*it)->save(str);
}
str << "" GROUPS_DOC ">" << endl;
itsModified=false;
return file.commit();
}
return false;
}
void CGroupList::merge(const QString &file)
{
if(load(file))
{
itsModified=true;
sort(0, itsSortOrder);
}
}
void CGroupList::clear()
{
beginResetModel();
itsGroups.removeFirst(); // Remove all
if(itsSpecialGroups[CGroupListItem::SYSTEM])
{
itsGroups.removeFirst(); // Remove personal
itsGroups.removeFirst(); // Remove system
}
if(itsGroups.contains(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]))
itsGroups.removeFirst(); // Remove unclassif...
qDeleteAll(itsGroups);
itsGroups.clear();
itsGroups.append(itsSpecialGroups[CGroupListItem::ALL]);
if(itsSpecialGroups[CGroupListItem::SYSTEM])
{
itsGroups.append(itsSpecialGroups[CGroupListItem::PERSONAL]);
itsGroups.append(itsSpecialGroups[CGroupListItem::SYSTEM]);
}
// Don't add 'Unclassif' until we have some user groups
endResetModel();
}
QModelIndex CGroupList::index(CGroupListItem::EType t)
{
return createIndex(t, 0, itsSpecialGroups[t]);
}
void CGroupList::createGroup(const QString &name)
{
if(!exists(name))
{
if(!itsGroups.contains(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]))
itsGroups.append(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
itsGroups.append(new CGroupListItem(name));
itsModified=true;
save();
sort(0, itsSortOrder);
}
}
bool CGroupList::removeGroup(const QModelIndex &idx)
{
if(idx.isValid())
{
CGroupListItem *grp=static_cast(idx.internalPointer());
if(grp && grp->isCustom() &&
KMessageBox::Continue==KMessageBox::warningContinueCancel(itsParent,
i18n("Do you really want to remove \'%1\'?
"
"This will only remove the group, and not "
"the actual fonts.
", grp->name()),
i18n("Remove Group"), KGuiItem(i18n("Remove"), "list-remove",
i18n("Remove group"))))
{
itsModified=true;
itsGroups.removeAll(grp);
-
+
int stdGroups=1 +// All
(itsSpecialGroups[CGroupListItem::SYSTEM] ? 2 : 0)+ // Personal, System
1; // Unclassified
if(stdGroups==itsGroups.count() && itsGroups.contains(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]))
itsGroups.removeAll(itsSpecialGroups[CGroupListItem::UNCLASSIFIED]);
delete grp;
save();
sort(0, itsSortOrder);
return true;
}
}
return false;
}
void CGroupList::removeFromGroup(const QModelIndex &group, const QSet &families)
{
if(group.isValid())
{
CGroupListItem *grp=static_cast(group.internalPointer());
if(grp && grp->isCustom())
{
QSet::ConstIterator it(families.begin()),
end(families.end());
bool update(false);
for(; it!=end; ++it)
if(removeFromGroup(grp, *it))
update=true;
if(update)
emit refresh();
}
}
}
QString CGroupList::whatsThis() const
{
return i18n("Font Groups
This list displays the font groups available on your system. "
"There are 2 main types of font groups:"
"
- Standard are special groups used by the font manager.
"
"- Custom are groups created by you. To add a font family to one of "
"these groups simply drag it from the list of fonts, and drop "
"onto the desired group. To remove a family from the group, drag "
"the font onto the \"All Fonts\" group.
"
"
",
Misc::root()
? i18n("All Fonts contains all the fonts installed on your system."
"Unclassified contains all fonts that have not yet been placed "
"within a \"Custom\" group.")
: i18n("All Fonts contains all the fonts installed on your system - "
"both \"System\" and \"Personal\"."
"System contains all fonts that are installed system-wide (i.e. "
"available to all users)."
"Personal contains your personal fonts."
"Unclassified contains all fonts that have not yet been placed "
"within a \"Custom\" group."));
}
void CGroupList::addToGroup(const QModelIndex &group, const QSet &families)
{
if(group.isValid())
{
CGroupListItem *grp=static_cast(group.internalPointer());
if(grp && grp->isCustom())
{
QSet::ConstIterator it(families.begin()),
end(families.end());
bool update(false);
for(; it!=end; ++it)
if(!grp->hasFamily(*it))
{
grp->addFamily(*it);
update=true;
itsModified=true;
}
if(update)
emit refresh();
}
}
}
void CGroupList::removeFamily(const QString &family)
{
QList::ConstIterator it(itsGroups.begin()),
end(itsGroups.end());
for(; it!=end; ++it)
removeFromGroup(*it, family);
}
bool CGroupList::removeFromGroup(CGroupListItem *grp, const QString &family)
{
if(grp && grp->isCustom() && grp->hasFamily(family))
{
grp->removeFamily(family);
itsModified=true;
return true;
}
return false;
}
static bool groupNameLessThan(const CGroupListItem *f1, const CGroupListItem *f2)
{
return f1 && f2 && (f1->type()type() ||
(f1->type()==f2->type() && QString::localeAwareCompare(f1->name(), f2->name())<0));
}
static bool groupNameGreaterThan(const CGroupListItem *f1, const CGroupListItem *f2)
{
return f1 && f2 && (f1->type()type() ||
(f1->type()==f2->type() && QString::localeAwareCompare(f1->name(), f2->name())>0));
}
void CGroupList::sort(int, Qt::SortOrder order)
{
itsSortOrder=order;
std::sort(itsGroups.begin(), itsGroups.end(),
Qt::AscendingOrder==order ? groupNameLessThan : groupNameGreaterThan);
emit layoutChanged();
}
Qt::DropActions CGroupList::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
QStringList CGroupList::mimeTypes() const
{
QStringList types;
types << KFI_FONT_DRAG_MIME;
return types;
}
CGroupListItem * CGroupList::find(const QString &name)
{
QList::ConstIterator it(itsGroups.begin()),
end(itsGroups.end());
for(; it!=end; ++it)
if((*it)->name()==name)
return (*it);
return nullptr;
}
bool CGroupList::exists(const QString &name, bool showDialog)
{
if(nullptr!=find(name))
{
if(showDialog)
KMessageBox::error(itsParent, i18n("A group named \'%1\' already "
"exists.", name));
return true;
}
return false;
}
class CGroupListViewDelegate : public QStyledItemDelegate
{
public:
CGroupListViewDelegate(QObject *p) : QStyledItemDelegate(p) { }
~CGroupListViewDelegate() override { }
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const override
{
CGroupListItem *grp=static_cast(idx.internalPointer());
QStyleOptionViewItem opt(option);
if(grp && grp->isUnclassified())
opt.rect.adjust(0, 0, 0, -1);
-
+
QStyledItemDelegate::paint(painter, opt, idx);
if(grp && grp->isUnclassified())
{
opt.rect.adjust(2, 0, -2, 1);
painter->setPen(QApplication::palette().color(QPalette::Text));
painter->drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight());
}
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &idx) const override
{
QSize sz(QStyledItemDelegate::sizeHint(option, idx));
CGroupListItem *grp=static_cast(idx.internalPointer());
if(grp && grp->isUnclassified())
sz.setHeight(sz.height()+1);
return sz;
}
static bool isCloseEvent(QKeyEvent *event)
{
return Qt::Key_Tab==event->key() || Qt::Key_Backtab==event->key() ||
Qt::Key_Enter==event->key() || Qt::Key_Return==event->key();
}
-
+
bool eventFilter(QObject *editor, QEvent *event) override
{
if(editor && event && QEvent::KeyPress==event->type() && isCloseEvent(static_cast(event)) &&
qobject_cast(editor))
{
QString text=static_cast(editor)->text().trimmed();
if(!text.isEmpty() &&
!static_cast(static_cast(parent())->model())->exists(text, false))
{
emit commitData(static_cast(editor));
emit closeEditor(static_cast(editor));
return true;
}
}
return false;
}
};
-
+
CGroupListView::CGroupListView(QWidget *parent, CGroupList *model)
: QTreeView(parent)
{
setModel(model);
setItemDelegate(new CGroupListViewDelegate(this));
sortByColumn(COL_GROUP_NAME, Qt::AscendingOrder);
setSelectionMode(QAbstractItemView::SingleSelection);
setSortingEnabled(true);
setAllColumnsShowFocus(true);
setAlternatingRowColors(true);
setAcceptDrops(true);
setDragDropMode(QAbstractItemView::DropOnly);
setDropIndicatorShown(true);
setDragEnabled(false);
header()->setSortIndicatorShown(true);
setRootIsDecorated(false);
itsMenu=new QMenu(this);
itsDeleteAct=itsMenu->addAction(QIcon::fromTheme("list-remove"), i18n("Remove"),
this, SIGNAL(del()));
itsMenu->addSeparator();
- itsEnableAct=itsMenu->addAction(QIcon::fromTheme("enablefont"), i18n("Enable"),
+ itsEnableAct=itsMenu->addAction(QIcon::fromTheme("font-enable"), i18n("Enable"),
this, SIGNAL(enable()));
- itsDisableAct=itsMenu->addAction(QIcon::fromTheme("disablefont"), i18n("Disable"),
+ itsDisableAct=itsMenu->addAction(QIcon::fromTheme("font-disable"), i18n("Disable"),
this, SIGNAL(disable()));
itsMenu->addSeparator();
itsRenameAct=itsMenu->addAction(QIcon::fromTheme("edit-rename"), i18n("Rename..."),
this, SLOT(rename()));
-
+
if(!Misc::app(KFI_PRINTER).isEmpty())
{
itsMenu->addSeparator();
itsPrintAct=itsMenu->addAction(QIcon::fromTheme("document-print"), i18n("Print..."),
this, SIGNAL(print()));
}
else
itsPrintAct= nullptr;
itsMenu->addSeparator();
itsExportAct=itsMenu->addAction(QIcon::fromTheme("document-export"), i18n("Export..."),
this, SIGNAL(zip()));
setWhatsThis(model->whatsThis());
header()->setWhatsThis(whatsThis());
connect(this, SIGNAL(addFamilies(QModelIndex,QSet)),
model, SLOT(addToGroup(QModelIndex,QSet)));
connect(this, SIGNAL(removeFamilies(QModelIndex,QSet)),
model, SLOT(removeFromGroup(QModelIndex,QSet)));
}
CGroupListItem::EType CGroupListView::getType()
{
QModelIndexList selectedItems(selectedIndexes());
if(!selectedItems.isEmpty() && selectedItems.last().isValid())
{
CGroupListItem *grp=static_cast(selectedItems.last().internalPointer());
return grp->type();
}
return CGroupListItem::ALL;
}
void CGroupListView::controlMenu(bool del, bool en, bool dis, bool p, bool exp)
{
itsDeleteAct->setEnabled(del);
itsRenameAct->setEnabled(del);
itsEnableAct->setEnabled(en);
itsDisableAct->setEnabled(dis);
if(itsPrintAct)
itsPrintAct->setEnabled(p);
itsExportAct->setEnabled(exp);
}
void CGroupListView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
QModelIndexList deselectedItems(deselected.indexes());
QAbstractItemView::selectionChanged(selected, deselected);
QModelIndexList selectedItems(selectedIndexes());
if(0==selectedItems.count() && 1==deselectedItems.count())
selectionModel()->select(deselectedItems.last(), QItemSelectionModel::Select);
else
emit itemSelected(selectedItems.count()
? selectedItems.last()
: QModelIndex());
}
void CGroupListView::rename()
{
QModelIndex index(currentIndex());
if(index.isValid())
edit(index);
}
void CGroupListView::emitMoveFonts()
{
emit moveFonts();
}
void CGroupListView::contextMenuEvent(QContextMenuEvent *ev)
{
if(indexAt(ev->pos()).isValid())
itsMenu->popup(ev->globalPos());
}
void CGroupListView::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat(KFI_FONT_DRAG_MIME))
event->acceptProposedAction();
}
void CGroupListView::dragMoveEvent(QDragMoveEvent *event)
{
if(event->mimeData()->hasFormat(KFI_FONT_DRAG_MIME))
{
QModelIndex index(indexAt(event->pos()));
if(index.isValid())
{
if(COL_GROUP_NAME!=index.column())
index=((CGroupList *)model())->createIdx(index.row(), COL_GROUP_NAME, index.internalPointer());
CGroupListItem *dest=static_cast(index.internalPointer());
CGroupListItem::EType type=getType();
if(dest)
if(!selectedIndexes().contains(index))
{
bool ok(true);
if(dest->isCustom())
emit info(i18n("Add to \"%1\".", dest->name()));
else if(CGroupListItem::CUSTOM==type && dest->isAll())
emit info(i18n("Remove from current group."));
else if(!Misc::root() && dest->isPersonal() && CGroupListItem::SYSTEM==type)
emit info(i18n("Move to personal folder."));
else if(!Misc::root() && dest->isSystem() && CGroupListItem::PERSONAL==type)
emit info(i18n("Move to system folder."));
else
ok=false;
if(ok)
{
drawHighlighter(index);
event->acceptProposedAction();
return;
}
}
}
event->ignore();
drawHighlighter(QModelIndex());
emit info(QString());
}
}
void CGroupListView::dragLeaveEvent(QDragLeaveEvent *)
{
drawHighlighter(QModelIndex());
emit info(QString());
}
void CGroupListView::dropEvent(QDropEvent *event)
{
emit info(QString());
drawHighlighter(QModelIndex());
if(event->mimeData()->hasFormat(KFI_FONT_DRAG_MIME))
{
event->acceptProposedAction();
QSet families;
QByteArray encodedData(event->mimeData()->data(KFI_FONT_DRAG_MIME));
QDataStream ds(&encodedData, QIODevice::ReadOnly);
QModelIndex from(selectedIndexes().last()),
to(indexAt(event->pos()));
ds >> families;
// Are we moving/copying, removing a font from the current group?
if(to.isValid() && from.isValid())
{
if( ((static_cast(from.internalPointer()))->isSystem() &&
(static_cast(to.internalPointer()))->isPersonal()) ||
((static_cast(from.internalPointer()))->isPersonal() &&
(static_cast(to.internalPointer()))->isSystem()))
QTimer::singleShot(0, this, SLOT(emitMoveFonts()));
else if((static_cast(from.internalPointer()))->isCustom() &&
!(static_cast(to.internalPointer()))->isCustom())
emit removeFamilies(from, families);
else
emit addFamilies(to, families);
}
if(isUnclassified())
emit unclassifiedChanged();
}
}
void CGroupListView::drawHighlighter(const QModelIndex &idx)
{
if(itsCurrentDropItem!=idx)
{
((CGroupList *)model())->update(itsCurrentDropItem, idx);
itsCurrentDropItem=idx;
}
}
bool CGroupListView::viewportEvent(QEvent *event)
{
executeDelayedItemsLayout();
return QTreeView::viewportEvent(event);
}
}
diff --git a/kcms/kfontinst/kcmfontinst/KCmFontInst.cpp b/kcms/kfontinst/kcmfontinst/KCmFontInst.cpp
index e25b39724..688ca2a9c 100644
--- a/kcms/kfontinst/kcmfontinst/KCmFontInst.cpp
+++ b/kcms/kfontinst/kcmfontinst/KCmFontInst.cpp
@@ -1,1276 +1,1270 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KCmFontInst.h"
#include "KfiConstants.h"
#include "PrintDialog.h"
#include "FcEngine.h"
#include "FontPreview.h"
#include "FontsPackage.h"
#include "Misc.h"
#include "FontList.h"
#include "DuplicatesDialog.h"
#include "FontFilter.h"
#include "PreviewSelectAction.h"
#include "PreviewList.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define CFG_GROUP "Main Settings"
#define CFG_PREVIEW_SPLITTER_SIZES "PreviewSplitterSizes"
#define CFG_GROUP_SPLITTER_SIZES "GroupSplitterSizes"
#define CFG_FONT_SIZE "FontSize"
K_PLUGIN_FACTORY(FontInstallFactory,
registerPlugin();
)
K_EXPORT_PLUGIN(FontInstallFactory("fontinst"))
namespace KFI
{
static QString partialIcon(bool load=true)
{
QString name = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/kfi/partial.png";
if(Misc::fExists(name))
{
if(!load)
QFile::remove(name);
}
else if(load)
{
QString pth;
QPixmap pix=KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::Small, KIconLoader::SizeSmall,
KIconLoader::DisabledState);
pix.save(name, "PNG");
}
return name;
}
class CPushButton : public QPushButton
{
public:
CPushButton(const KGuiItem &item, QWidget *parent)
: QPushButton(parent)
{
KGuiItem::assign(this, item);
theirHeight=qMax(theirHeight, QPushButton::sizeHint().height());
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
}
QSize sizeHint() const override
{
QSize sh(QPushButton::sizeHint());
sh.setHeight(theirHeight);
if(sh.width()addAppDir(KFI_NAME);
KAboutData *about = new KAboutData(QStringLiteral("fontinst"), i18n("Font Management"), QStringLiteral("1.0"), QString(),
KAboutLicense::GPL, i18n("(C) Craig Drummond, 2000 - 2009"));
about->addAuthor(i18n("Craig Drummond"), i18n("Developer and maintainer"), QStringLiteral("craig@kde.org"));
setAboutData(about);
KConfigGroup cg(&itsConfig, CFG_GROUP);
itsGroupSplitter=new QSplitter(this);
- itsGroupSplitter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+ itsGroupSplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
QWidget *groupWidget=new QWidget(itsGroupSplitter),
*fontWidget=new QWidget(itsGroupSplitter);
itsPreviewSplitter=new QSplitter(fontWidget);
- itsPreviewSplitter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+ itsPreviewSplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
- QWidget *toolbarWidget=new QWidget(this),
- *fontControlWidget=new QWidget(fontWidget);
- CToolBar *toolbar=new CToolBar(toolbarWidget);
+ QWidget *fontControlWidget=new QWidget(fontWidget);
QGridLayout *groupsLayout=new QGridLayout(groupWidget);
QBoxLayout *mainLayout=new QBoxLayout(QBoxLayout::TopToBottom, this),
- *toolbarLayout=new QBoxLayout(QBoxLayout::LeftToRight, toolbarWidget),
*fontsLayout=new QBoxLayout(QBoxLayout::TopToBottom, fontWidget),
*fontControlLayout=new QBoxLayout(QBoxLayout::LeftToRight, fontControlWidget);
- toolbarLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setContentsMargins(0, 0, 0, 0);
groupsLayout->setContentsMargins(0, 0, 0, 0);
fontsLayout->setContentsMargins(0, 0, 0, 0);
fontControlLayout->setContentsMargins(0, 0, 0, 0);
- // Toolbar...
- duplicateFontsAct=new QAction(QIcon::fromTheme("system-search"), i18n("Scan for Duplicate Fonts..."), this);
-// validateFontsAct=new QAction(QIcon::fromTheme("checkmark"), i18n("Validate Fonts..."), this);
-
- toolbar->addAction(duplicateFontsAct);
-// toolbar->addAction(validateFontsAct);
- toolbar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
- itsFilter=new CFontFilter(toolbarWidget);
+ itsFilter=new CFontFilter(this);
// Details - Groups...
itsGroupList=new CGroupList(groupWidget);
itsGroupListView=new CGroupListView(groupWidget, itsGroupList);
QPushButton *createGroup=new CPushButton(KGuiItem(QString(), "list-add",
i18n("Create New Group...")),
groupWidget);
itsDeleteGroupControl=new CPushButton(KGuiItem(QString(), "list-remove",
i18n("Remove Group...")),
groupWidget);
- itsEnableGroupControl=new CPushButton(KGuiItem(QString(), "enablefont",
+ itsEnableGroupControl=new CPushButton(KGuiItem(QString(), "font-enable",
i18n("Enable Fonts in Group...")),
groupWidget);
- itsDisableGroupControl=new CPushButton(KGuiItem(QString(), "disablefont",
+ itsDisableGroupControl=new CPushButton(KGuiItem(QString(), "font-disable",
i18n("Disable Fonts in Group...")),
groupWidget);
groupsLayout->addWidget(itsGroupListView, 0, 0, 1, 5);
groupsLayout->addWidget(createGroup, 1, 0);
groupsLayout->addWidget(itsDeleteGroupControl, 1, 1);
groupsLayout->addWidget(itsEnableGroupControl, 1, 2);
groupsLayout->addWidget(itsDisableGroupControl, 1, 3);
groupsLayout->addItem(new QSpacerItem(itsDisableGroupControl->width(), groupsLayout->spacing(),
QSizePolicy::Expanding, QSizePolicy::Fixed), 1, 4);
itsPreviewWidget = new QWidget(this);
QBoxLayout *previewWidgetLayout = new QBoxLayout(QBoxLayout::TopToBottom, itsPreviewWidget);
previewWidgetLayout->setContentsMargins(0, 0, 0, 0);
previewWidgetLayout->setSpacing(0);
-
+
// Preview
QFrame *previewFrame=new QFrame(itsPreviewWidget);
QBoxLayout *previewFrameLayout=new QBoxLayout(QBoxLayout::LeftToRight, previewFrame);
previewFrameLayout->setContentsMargins(0, 0, 0, 0);
previewFrameLayout->setSpacing(0);
previewFrame->setFrameShape(QFrame::StyledPanel);
previewFrame->setFrameShadow(QFrame::Sunken);
previewFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
itsPreview=new CFontPreview(previewFrame);
itsPreview->setWhatsThis(i18n("This displays a preview of the selected font."));
itsPreview->setContextMenuPolicy(Qt::CustomContextMenu);
previewFrameLayout->addWidget(itsPreview);
previewWidgetLayout->addWidget(previewFrame);
itsPreview->engine()->readConfig(itsConfig);
// List-style preview...
itsPreviewList = new CPreviewListView(itsPreview->engine(), itsPreviewWidget);
previewWidgetLayout->addWidget(itsPreviewList);
itsPreviewList->setVisible(false);
// Font List...
itsFontList=new CFontList(fontWidget);
itsFontListView=new CFontListView(itsPreviewSplitter, itsFontList);
itsFontListView->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+ itsScanDuplicateFontsControl=new CPushButton(KGuiItem(i18n("Find Duplicates..."), "edit-duplicate",
+ i18n("Scan for Duplicate Fonts...")),
+ fontControlWidget);
+
itsAddFontControl=new CPushButton(KGuiItem(i18n("Install from File..."), "document-import",
i18n("Install fonts from a local file")),
fontControlWidget);
itsGetNewFontsControl=new CPushButton(KGuiItem(i18n("Get New Fonts..."), "get-hot-new-stuff",
i18n("Download new fonts")),
fontControlWidget);
itsDeleteFontControl=new CPushButton(KGuiItem(QString(), "edit-delete",
i18n("Delete Selected Fonts...")),
fontControlWidget);
itsPreviewSplitter->addWidget(itsPreviewWidget);
itsPreviewSplitter->setCollapsible(1, true);
- itsStatusLabel = new QLabel(fontControlWidget);
+ QWidget *statusRow = new QWidget(this);
+ QBoxLayout *statusRowLayout=new QBoxLayout(QBoxLayout::LeftToRight, statusRow);
+ itsStatusLabel = new QLabel(statusRow);
itsStatusLabel->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
- itsListingProgress=new CProgressBar(fontControlWidget, itsStatusLabel->height());
+ itsListingProgress=new CProgressBar(statusRow, itsStatusLabel->height());
itsListingProgress->setRange(0, 100);
+ statusRowLayout->addWidget(itsListingProgress);
+ statusRowLayout->addWidget(itsStatusLabel);
// Layout widgets...
- toolbarLayout->addWidget(toolbar);
- toolbarLayout->addWidget(itsFilter);
- mainLayout->addWidget(toolbarWidget);
+ mainLayout->addWidget(itsFilter);
mainLayout->addWidget(itsGroupSplitter);
+ mainLayout->addWidget(statusRow);
fontControlLayout->addWidget(itsDeleteFontControl);
- fontControlLayout->addWidget(itsStatusLabel);
- fontControlLayout->addItem(new QSpacerItem(0, itsListingProgress->height()+4,
- QSizePolicy::Fixed, QSizePolicy::Fixed));
- fontControlLayout->addWidget(itsListingProgress);
+ fontControlLayout->addStretch();
+ fontControlLayout->addWidget(itsScanDuplicateFontsControl);
fontControlLayout->addWidget(itsAddFontControl);
fontControlLayout->addWidget(itsGetNewFontsControl);
fontsLayout->addWidget(itsPreviewSplitter);
fontsLayout->addWidget(fontControlWidget);
// Set size of widgets...
itsPreviewSplitter->setChildrenCollapsible(false);
itsGroupSplitter->setChildrenCollapsible(false);
itsGroupSplitter->setStretchFactor(0, 0);
itsGroupSplitter->setStretchFactor(1, 1);
itsPreviewSplitter->setStretchFactor(0, 1);
itsPreviewSplitter->setStretchFactor(1, 0);
// Set sizes for 3 views...
QList defaultSizes;
defaultSizes+=300;
defaultSizes+=220;
itsPreviewSplitter->setSizes(cg.readEntry(CFG_PREVIEW_SPLITTER_SIZES, defaultSizes));
itsPreviewHidden=itsPreviewSplitter->sizes().at(1)<8;
defaultSizes.clear();
defaultSizes+=110;
defaultSizes+=350;
itsGroupSplitter->setSizes(cg.readEntry(CFG_GROUP_SPLITTER_SIZES, defaultSizes));
// Preview widget pop-up menu
itsPreviewMenu = new QMenu(itsPreview);
QAction *zoomIn=KStandardAction::create(KStandardAction::ZoomIn, itsPreview, SLOT(zoomIn()), this),
*zoomOut=KStandardAction::create(KStandardAction::ZoomOut, itsPreview, SLOT(zoomOut()), this);
itsPreviewMenu->addAction(zoomIn);
itsPreviewMenu->addAction(zoomOut);
itsPreviewMenu->addSeparator();
CPreviewSelectAction *prevSel=new CPreviewSelectAction(itsPreviewMenu);
itsPreviewMenu->addAction(prevSel);
QAction *changeTextAct=new QAction(QIcon::fromTheme("edit-rename"), i18n("Change Preview Text..."), this);
itsPreviewMenu->addAction(changeTextAct),
itsPreviewListMenu = new QMenu(itsPreviewList);
itsPreviewListMenu->addAction(changeTextAct),
// Connect signals...
connect(itsPreview, SIGNAL(atMax(bool)), zoomIn, SLOT(setDisabled(bool)));
connect(itsPreview, SIGNAL(atMin(bool)), zoomOut, SLOT(setDisabled(bool)));
connect(prevSel, SIGNAL(range(QList)),
itsPreview, SLOT(setUnicodeRange(QList)));
connect(changeTextAct, SIGNAL(triggered(bool)), SLOT(changeText()));
- connect(itsFilter, SIGNAL(textChanged(QString)), itsFontListView, SLOT(filterText(QString)));
- connect(itsFilter, SIGNAL(criteriaChanged(int,qulonglong,QStringList)),
+ connect(itsFilter, SIGNAL(queryChanged(QString)), itsFontListView, SLOT(filterText(QString)));
+ connect(itsFilter, SIGNAL(criteriaChanged(int,qulonglong,QStringList)),
itsFontListView, SLOT(filterCriteria(int,qulonglong,QStringList)));
connect(itsGroupListView, SIGNAL(del()), SLOT(removeGroup()));
connect(itsGroupListView, SIGNAL(print()), SLOT(printGroup()));
connect(itsGroupListView, SIGNAL(enable()), SLOT(enableGroup()));
connect(itsGroupListView, SIGNAL(disable()), SLOT(disableGroup()));
connect(itsGroupListView, SIGNAL(moveFonts()), SLOT(moveFonts()));
connect(itsGroupListView, SIGNAL(zip()), SLOT(zipGroup()));
connect(itsGroupListView, SIGNAL(itemSelected(QModelIndex)),
SLOT(groupSelected(QModelIndex)));
connect(itsGroupListView, SIGNAL(info(QString)),
SLOT(showInfo(QString)));
connect(itsGroupList, SIGNAL(refresh()), SLOT(refreshFontList()));
connect(itsFontList, SIGNAL(listingPercent(int)), SLOT(listingPercent(int)));
connect(itsFontList, SIGNAL(layoutChanged()), SLOT(setStatusBar()));
connect(itsFontListView, SIGNAL(del()), SLOT(deleteFonts()));
connect(itsFontListView, SIGNAL(print()), SLOT(print()));
connect(itsFontListView, SIGNAL(enable()), SLOT(enableFonts()));
connect(itsFontListView, SIGNAL(disable()), SLOT(disableFonts()));
connect(itsFontListView, SIGNAL(fontsDropped(QSet)),
SLOT(addFonts(QSet)));
connect(itsFontListView, SIGNAL(itemsSelected(QModelIndexList)), SLOT(fontsSelected(QModelIndexList)));
connect(itsFontListView, SIGNAL(refresh()), SLOT(setStatusBar()));
connect(itsGroupListView, SIGNAL(unclassifiedChanged()), itsFontListView, SLOT(refreshFilter()));
connect(createGroup, SIGNAL(clicked()), SLOT(addGroup()));
connect(itsDeleteGroupControl, SIGNAL(clicked()), SLOT(removeGroup()));
connect(itsEnableGroupControl, SIGNAL(clicked()), SLOT(enableGroup()));
connect(itsDisableGroupControl, SIGNAL(clicked()), SLOT(disableGroup()));
connect(itsAddFontControl, SIGNAL(clicked()), SLOT(addFonts()));
connect(itsGetNewFontsControl, SIGNAL(clicked()), SLOT(downloadFonts()));
connect(itsDeleteFontControl, SIGNAL(clicked()), SLOT(deleteFonts()));
- connect(duplicateFontsAct, SIGNAL(triggered(bool)), SLOT(duplicateFonts()));
+ connect(itsScanDuplicateFontsControl, SIGNAL(clicked()), SLOT(duplicateFonts()));
//connect(validateFontsAct, SIGNAL(triggered(bool)), SLOT(validateFonts()));
connect(itsPreview, SIGNAL(customContextMenuRequested(QPoint)), SLOT(previewMenu(QPoint)));
connect(itsPreviewList, SIGNAL(showMenu(QPoint)), SLOT(previewMenu(QPoint)));
connect(itsPreviewSplitter, SIGNAL(splitterMoved(int,int)), SLOT(splitterMoved()));
selectMainGroup();
itsFontList->load();
}
CKCmFontInst::~CKCmFontInst()
{
KConfigGroup cg(&itsConfig, CFG_GROUP);
cg.writeEntry(CFG_PREVIEW_SPLITTER_SIZES, itsPreviewSplitter->sizes());
cg.writeEntry(CFG_GROUP_SPLITTER_SIZES, itsGroupSplitter->sizes());
delete itsTempDir;
partialIcon(false);
}
QString CKCmFontInst::quickHelp() const
{
return Misc::root()
? i18n("Font Installer
This module allows you to"
" install TrueType, Type1, and Bitmap"
" fonts.
You may also install fonts using Konqueror:"
" type fonts:/ into Konqueror's location bar"
" and this will display your installed fonts. To install a"
" font, simply copy one into the folder.
")
: i18n("Font Installer
This module allows you to"
" install TrueType, Type1, and Bitmap"
" fonts.
You may also install fonts using Konqueror:"
" type fonts:/ into Konqueror's location bar"
" and this will display your installed fonts. To install a"
" font, simply copy it into the appropriate folder - "
" \"%1\" for fonts available to just yourself, or "
" \"%2\" for system-wide fonts (available to all).
",
i18n(KFI_KIO_FONTS_USER), i18n(KFI_KIO_FONTS_SYS));
}
void CKCmFontInst::previewMenu(const QPoint &pos)
{
if(itsPreviewList->isHidden())
itsPreviewMenu->popup(itsPreview->mapToGlobal(pos));
else
itsPreviewListMenu->popup(itsPreviewList->mapToGlobal(pos));
}
void CKCmFontInst::splitterMoved()
{
if(itsPreviewWidget->width()>8 && itsPreviewHidden)
{
itsPreviewHidden=false;
fontsSelected(itsFontListView->getSelectedItems());
}
else if(!itsPreviewHidden && itsPreviewWidget->width()<8)
itsPreviewHidden=true;
}
void CKCmFontInst::fontsSelected(const QModelIndexList &list)
{
if(!itsPreviewHidden)
{
if(!list.isEmpty())
{
if(list.count()<2)
{
CFontModelItem *mi=static_cast(list.last().internalPointer());
CFontItem *font=mi->parent()
? static_cast(mi)
: (static_cast(mi))->regularFont();
if(font)
itsPreview->showFont(font->isEnabled() ? font->family() : font->fileName(),
font->styleInfo(), font->index());
}
else
itsPreviewList->showFonts(list);
}
itsPreviewList->setVisible(list.count()>1);
itsPreview->parentWidget()->setVisible(list.count()<2);
}
itsDeleteFontControl->setEnabled(list.count());
}
void CKCmFontInst::addFonts()
{
QFileDialog dlg(this, i18n("Add Fonts"));
dlg.setFileMode(QFileDialog::ExistingFiles);
dlg.setMimeTypeFilters(CFontList::fontMimeTypes);
QList list;
if (dlg.exec() == QDialog::Accepted)
list = dlg.selectedUrls();
if(!list.isEmpty())
{
QSet urls;
QList::Iterator it(list.begin()),
end(list.end());
for(; it!=end; ++it)
{
if(KFI_KIO_FONTS_PROTOCOL!=(*it).scheme()) // Do not try to install from fonts:/ !!!
{
auto job = KIO::mostLocalUrl(*it);
KJobWidgets::setWindow(job, this);
job->exec();
QUrl url = job->mostLocalUrl();
if(url.isLocalFile())
{
QString file(url.toLocalFile());
if(Misc::isPackage(file)) // If its a package we need to unzip 1st...
urls+=FontsPackage::extract(url.toLocalFile(), &itsTempDir);
else if(!Misc::isMetrics(url))
urls.insert(url);
}
else if(!Misc::isMetrics(url))
urls.insert(url);
}
}
if(!urls.isEmpty())
addFonts(urls);
delete itsTempDir;
itsTempDir=nullptr;
}
}
void CKCmFontInst::groupSelected(const QModelIndex &index)
{
CGroupListItem *grp=nullptr;
if(index.isValid())
grp=static_cast(index.internalPointer());
else
return;
itsFontListView->setFilterGroup(grp);
setStatusBar();
//
// Check fonts listed within group are still valid!
if(grp->isCustom() && !grp->validated())
{
QSet remList;
QSet::Iterator it(grp->families().begin()),
end(grp->families().end());
for(; it!=end; ++it)
if(!itsFontList->hasFamily(*it))
remList.insert(*it);
it=remList.begin();
end=remList.end();
for(; it!=end; ++it)
itsGroupList->removeFromGroup(grp, *it);
grp->setValidated();
}
itsGetNewFontsControl->setEnabled(grp->isPersonal() || grp->isAll());
}
void CKCmFontInst::print(bool all)
{
//
// In order to support printing of newly installed/enabled fonts, the actual printing
// is carried out by the kfontinst helper app. This way we know Qt's font list will be
// up to date.
if((!itsPrintProc || QProcess::NotRunning==itsPrintProc->state()) && !Misc::app(KFI_PRINTER).isEmpty())
{
QSet fonts;
itsFontListView->getPrintableFonts(fonts, !all);
if(!fonts.isEmpty())
{
CPrintDialog dlg(this);
KConfigGroup cg(&itsConfig, CFG_GROUP);
if(dlg.exec(cg.readEntry(CFG_FONT_SIZE, 1)))
{
static const int constSizes[]={0, 12, 18, 24, 36, 48};
QSet::ConstIterator it(fonts.begin()),
end(fonts.end());
QTemporaryFile tmpFile;
bool useFile(fonts.count()>16),
startProc(true);
QStringList args;
if(!itsPrintProc)
itsPrintProc=new QProcess(this);
else
itsPrintProc->kill();
QString title = QGuiApplication::applicationDisplayName();
if (title.isEmpty())
title = QCoreApplication::applicationName();
//
// If we have lots of fonts to print, pass kfontinst a temporary groups file to print
// instead of passing font by font...
if(useFile)
{
if(tmpFile.open())
{
QTextStream str(&tmpFile);
for(; it!=end; ++it)
str << (*it).family << endl
<< (*it).styleInfo << endl;
args << "--embed" << QString().sprintf("0x%x", (unsigned int)window()->winId())
<< "--qwindowtitle" << title
<< "--qwindowicon" << "preferences-desktop-font-installer"
<< "--size" << QString().setNum(constSizes[dlg.chosenSize() < 6 ? dlg.chosenSize() : 2])
<< "--listfile" << tmpFile.fileName()
<< "--deletefile";
}
else
{
KMessageBox::error(this, i18n("Failed to save list of fonts to print."));
startProc=false;
}
}
else
{
args << "--embed" << QString().sprintf("0x%x", (unsigned int)window()->winId())
<< "--qwindowtitle" << title
<< "--qwindowicon" << "preferences-desktop-font-installer"
<< "--size" << QString().setNum(constSizes[dlg.chosenSize()<6 ? dlg.chosenSize() : 2]);
for(; it!=end; ++it)
args << "--pfont" << QString((*it).family.toUtf8()+','+QString().setNum((*it).styleInfo));
}
if(startProc)
{
itsPrintProc->start(Misc::app(KFI_PRINTER), args);
if(itsPrintProc->waitForStarted(1000))
{
if(useFile)
tmpFile.setAutoRemove(false);
}
else
KMessageBox::error(this, i18n("Failed to start font printer."));
}
cg.writeEntry(CFG_FONT_SIZE, dlg.chosenSize());
}
}
else
KMessageBox::information(this, i18n("There are no printable fonts.\n"
"You can only print non-bitmap and enabled fonts."),
i18n("Cannot Print"));
}
}
void CKCmFontInst::deleteFonts()
{
CJobRunner::ItemList urls;
QStringList fontNames;
QSet fonts;
itsDeletedFonts.clear();
itsFontListView->getFonts(urls, fontNames, &fonts, true);
if(urls.isEmpty())
KMessageBox::information(this, i18n("You did not select anything to delete."),
i18n("Nothing to Delete"));
else
{
QSet::ConstIterator it(fonts.begin()),
end(fonts.end());
bool doIt=false;
for(; it!=end; ++it)
itsDeletedFonts.insert((*it).family);
switch(fontNames.count())
{
case 0:
break;
case 1:
doIt = KMessageBox::Continue==KMessageBox::warningContinueCancel(this,
i18n("Do you really want to "
"delete
\'%1\'?
", fontNames.first()),
i18n("Delete Font"), KStandardGuiItem::del());
break;
default:
doIt = KMessageBox::Continue==KMessageBox::warningContinueCancelList(this,
i18np("Do you really want to delete this font?",
"Do you really want to delete these %1 fonts?",
fontNames.count()),
fontNames, i18n("Delete Fonts"), KStandardGuiItem::del());
}
if(doIt)
{
itsStatusLabel->setText(i18n("Deleting font(s)..."));
doCmd(CJobRunner::CMD_DELETE, urls);
}
}
}
void CKCmFontInst::moveFonts()
{
CJobRunner::ItemList urls;
QStringList fontNames;
itsDeletedFonts.clear();
itsFontListView->getFonts(urls, fontNames, nullptr, true);
if(urls.isEmpty())
KMessageBox::information(this, i18n("You did not select anything to move."),
i18n("Nothing to Move"));
else
{
bool doIt=false;
switch(fontNames.count())
{
case 0:
break;
case 1:
doIt = KMessageBox::Continue==KMessageBox::warningContinueCancel(this,
i18n("Do you really want to "
"move
\'%1\'
from %2 to %3?
",
fontNames.first(),
itsGroupListView->isSystem() ? i18n(KFI_KIO_FONTS_SYS) : i18n(KFI_KIO_FONTS_USER),
itsGroupListView->isSystem() ? i18n(KFI_KIO_FONTS_USER) : i18n(KFI_KIO_FONTS_SYS)),
i18n("Move Font"), KGuiItem(i18n("Move")));
break;
default:
doIt = KMessageBox::Continue==KMessageBox::warningContinueCancelList(this,
i18np("Do you really want to move this font from %2 to %3?
",
"Do you really want to move these %1 fonts from %2 to %3?
",
fontNames.count(),
itsGroupListView->isSystem() ? i18n(KFI_KIO_FONTS_SYS) : i18n(KFI_KIO_FONTS_USER),
itsGroupListView->isSystem() ? i18n(KFI_KIO_FONTS_USER) : i18n(KFI_KIO_FONTS_SYS)),
fontNames, i18n("Move Fonts"), KGuiItem(i18n("Move")));
}
if(doIt)
{
itsStatusLabel->setText(i18n("Moving font(s)..."));
doCmd(CJobRunner::CMD_MOVE, urls, !itsGroupListView->isSystem());
}
}
}
void CKCmFontInst::zipGroup()
{
QModelIndex idx(itsGroupListView->currentIndex());
if(idx.isValid())
{
CGroupListItem *grp=static_cast(idx.internalPointer());
if(grp)
{
QFileDialog dlg(this, i18n("Export Group"));
dlg.setAcceptMode(QFileDialog::AcceptSave);
dlg.setDirectoryUrl(QUrl::fromLocalFile(grp->name()));
dlg.setMimeTypeFilters(QStringList() << QStringLiteral("application/zip"));
QString fileName;
if (dlg.exec() == QDialog::Accepted)
fileName = dlg.selectedFiles().value(0);
if(!fileName.isEmpty())
{
KZip zip(fileName);
if(zip.open(QIODevice::WriteOnly))
{
QSet files;
files=itsFontListView->getFiles();
if(!files.isEmpty())
{
QMap map=Misc::getFontFileMap(files);
QMap::ConstIterator it(map.constBegin()),
end(map.constEnd());
for(; it!=end; ++it)
zip.addLocalFile(it.value(), it.key());
zip.close();
}
else
KMessageBox::error(this, i18n("No files?"));
}
else
KMessageBox::error(this, i18n("Failed to open %1 for writing", fileName));
}
}
}
}
void CKCmFontInst::enableFonts()
{
toggleFonts(true);
}
void CKCmFontInst::disableFonts()
{
toggleFonts(false);
}
void CKCmFontInst::addGroup()
{
bool ok;
QString name(QInputDialog::getText(this, i18n("Create New Group"),
i18n("Name of new group:"),
QLineEdit::Normal,
i18n("New Group"), &ok));
if(ok && !name.isEmpty())
itsGroupList->createGroup(name);
}
void CKCmFontInst::removeGroup()
{
if(itsGroupList->removeGroup(itsGroupListView->currentIndex()))
selectMainGroup();
}
void CKCmFontInst::enableGroup()
{
toggleGroup(true);
}
void CKCmFontInst::disableGroup()
{
toggleGroup(false);
}
void CKCmFontInst::changeText()
{
bool status;
QString oldStr(itsPreview->engine()->getPreviewString()),
newStr(QInputDialog::getText(this, i18n("Preview Text"),
i18n("Please enter new text:"),
QLineEdit::Normal,
oldStr, &status));
if(status && oldStr!=newStr)
{
itsPreview->engine()->setPreviewString(newStr);
itsPreview->showFont();
itsPreviewList->refreshPreviews();
}
}
void CKCmFontInst::duplicateFonts()
{
CDuplicatesDialog(this, itsFontList).exec();
}
//void CKCmFontInst::validateFonts()
//{
//}
void CKCmFontInst::downloadFonts()
{
KNS3::DownloadDialog *newStuff = new KNS3::DownloadDialog("kfontinst.knsrc", this);
newStuff->exec();
if(!newStuff->changedEntries().isEmpty()) // We have new fonts, so need to reconfigure fontconfig...
{
// Ask dbus helper for the current fonts folder name...
// We then sym-link our knewstuff3 download folder into the fonts folder...
QString destFolder=CJobRunner::folderName(false);
if(!destFolder.isEmpty()) {
destFolder+="kfontinst";
if(!QFile::exists(destFolder)) {
QFile _file(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + "kfontinst");
_file.link(destFolder);
}
}
doCmd(CJobRunner::CMD_UPDATE, CJobRunner::ItemList());
}
delete newStuff;
}
void CKCmFontInst::print()
{
print(false);
}
void CKCmFontInst::printGroup()
{
print(true);
}
void CKCmFontInst::listingPercent(int p)
{
if(0==p)
{
showInfo(i18n("Scanning font list..."));
itsListingProgress->show();
}
else if(100==p && p!=itsListingProgress->value())
{
removeDeletedFontsFromGroups();
QSet foundries;
itsFontList->getFoundries(foundries);
itsFilter->setFoundries(foundries);
refreshFamilies();
itsListingProgress->hide();
itsFontListView->selectFirstFont();
}
itsListingProgress->setValue(p);
}
void CKCmFontInst::refreshFontList()
{
itsFontListView->refreshFilter();
refreshFamilies();
}
void CKCmFontInst::refreshFamilies()
{
QSet enabledFamilies,
disabledFamilies,
partialFamilies;
itsFontList->getFamilyStats(enabledFamilies, disabledFamilies, partialFamilies);
itsGroupList->updateStatus(enabledFamilies, disabledFamilies, partialFamilies);
setStatusBar();
}
void CKCmFontInst::showInfo(const QString &info)
{
if(info.isEmpty())
if(itsLastStatusBarMsg.isEmpty())
setStatusBar();
else
{
itsStatusLabel->setText(itsLastStatusBarMsg);
itsLastStatusBarMsg=QString();
}
else
{
if(itsLastStatusBarMsg.isEmpty())
itsLastStatusBarMsg=itsStatusLabel->text();
itsStatusLabel->setText(info);
}
}
void CKCmFontInst::setStatusBar()
{
if(itsFontList->slowUpdates())
return;
int enabled=0,
disabled=0,
partial=0;
bool selectedEnabled=false,
selectedDisabled=false;
itsStatusLabel->setToolTip(QString());
if(0==itsFontList->families().count())
itsStatusLabel->setText(i18n("No fonts"));
else
{
itsFontListView->stats(enabled, disabled, partial);
itsFontListView->selectedStatus(selectedEnabled, selectedDisabled);
QString text(i18np("1 Font", "%1 Fonts", enabled+disabled+partial));
if(disabled||partial)
{
text+=QString(" (%2").arg(KIconLoader::global()->iconPath("dialog-ok", -KIconLoader::SizeSmall)).arg(enabled)
+QString(" %2").arg(KIconLoader::global()->iconPath("dialog-cancel", -KIconLoader::SizeSmall)).arg(disabled);
if(partial)
text+=QString(" %2").arg(partialIcon()).arg(partial);
text+=QLatin1Char(')');
itsStatusLabel->setToolTip(partial
? i18n(""
"Enabled: | %1 |
"
"Disabled: | %2 |
"
"Partially enabled: | %3 |
"
"Total: | %4 |
"
"
", enabled, disabled, partial, enabled+disabled+partial)
: i18n(""
"Enabled: | %1 |
"
"Disabled: | %2 |
"
"Total: | %3 |
"
"
", enabled, disabled, enabled+disabled));
}
itsStatusLabel->setText(disabled||partial ? ""+text+"
" : text);
}
CGroupListItem::EType type(itsGroupListView->getType());
bool isStd(CGroupListItem::CUSTOM==type);
itsAddFontControl->setEnabled(CGroupListItem::ALL==type||CGroupListItem::UNCLASSIFIED==type||
CGroupListItem::PERSONAL==type||CGroupListItem::SYSTEM==type);
itsDeleteGroupControl->setEnabled(isStd);
itsEnableGroupControl->setEnabled(disabled||partial);
itsDisableGroupControl->setEnabled(isStd && (enabled||partial));
itsGroupListView->controlMenu(itsDeleteGroupControl->isEnabled(),
itsEnableGroupControl->isEnabled(),
itsDisableGroupControl->isEnabled(), enabled||partial, enabled||disabled);
itsDeleteFontControl->setEnabled(selectedEnabled||selectedDisabled);
}
void CKCmFontInst::addFonts(const QSet &src)
{
if(!src.isEmpty() && !itsGroupListView->isCustom())
{
bool system;
if(Misc::root())
system=true;
else
{
switch(itsGroupListView->getType())
{
case CGroupListItem::ALL:
case CGroupListItem::UNCLASSIFIED:
switch(KMessageBox::questionYesNoCancel(this,
i18n("Do you wish to install the font(s) for personal use "
"(only available to you), or "
"system-wide (available to all users)?"),
i18n("Where to Install"), KGuiItem(i18n(KFI_KIO_FONTS_USER)),
KGuiItem(i18n(KFI_KIO_FONTS_SYS))))
{
case KMessageBox::Yes:
system=false;
break;
case KMessageBox::No:
system=true;
break;
default:
case KMessageBox::Cancel:
return;
}
break;
case CGroupListItem::PERSONAL:
system=false;
break;
case CGroupListItem::SYSTEM:
system=true;
break;
default:
return;
}
}
QSet copy;
QSet::ConstIterator it,
end(src.end());
//
// Check if font has any associated AFM or PFM file...
itsStatusLabel->setText(i18n("Looking for any associated files..."));
if(!itsProgress)
{
itsProgress = new QProgressDialog(this);
itsProgress->setWindowTitle(i18n("Scanning Files..."));
itsProgress->setLabelText(i18n("Looking for additional files to install..."));
itsProgress->setModal(true);
itsProgress->setAutoReset(true);
itsProgress->setAutoClose(true);
}
itsProgress->setCancelButton(nullptr);
itsProgress->setMinimumDuration(500);
itsProgress->setRange(0, src.size());
itsProgress->setValue(0);
int steps=src.count()<200 ? 1 : src.count()/10;
for(it=src.begin(); it!=end; ++it)
{
QList associatedUrls;
itsProgress->setLabelText(i18n("Looking for files associated with %1", (*it).url()));
itsProgress->setValue(itsProgress->value()+1);
if(1==steps || 0==(itsProgress->value()%steps))
{
bool dialogVisible(itsProgress->isVisible());
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
if(dialogVisible && !itsProgress->isVisible()) // User closed dialog! re-open!!!
itsProgress->show();
}
CJobRunner::getAssociatedUrls(*it, associatedUrls, false, this);
copy.insert(*it);
QList::Iterator aIt(associatedUrls.begin()),
aEnd(associatedUrls.end());
for(; aIt!=aEnd; ++aIt)
copy.insert(*aIt);
}
itsProgress->close();
CJobRunner::ItemList installUrls;
end=copy.end();
for(it=copy.begin(); it!=end; ++it)
installUrls.append(*it);
itsStatusLabel->setText(i18n("Installing font(s)..."));
doCmd(CJobRunner::CMD_INSTALL, installUrls, system);
}
}
void CKCmFontInst::removeDeletedFontsFromGroups()
{
if(!itsDeletedFonts.isEmpty())
{
QSet::Iterator it(itsDeletedFonts.begin()),
end(itsDeletedFonts.end());
for(; it!=end; ++it)
if(!itsFontList->hasFamily(*it))
itsGroupList->removeFamily(*it);
itsDeletedFonts.clear();
}
}
-
+
void CKCmFontInst::selectGroup(CGroupListItem::EType grp)
{
QModelIndex current(itsGroupListView->currentIndex());
if(current.isValid())
{
CGroupListItem *grpItem=static_cast(current.internalPointer());
if(grpItem && grp==grpItem->type())
return;
else
itsGroupListView->selectionModel()->select(current,
QItemSelectionModel::Deselect);
}
QModelIndex idx(itsGroupList->index(grp));
itsGroupListView->selectionModel()->select(idx, QItemSelectionModel::Select);
itsGroupListView->setCurrentIndex(idx);
groupSelected(idx);
itsFontListView->refreshFilter();
setStatusBar();
}
void CKCmFontInst::toggleGroup(bool enable)
{
QModelIndex idx(itsGroupListView->currentIndex());
if(idx.isValid())
{
CGroupListItem *grp=static_cast(idx.internalPointer());
if(grp)
toggleFonts(enable, grp->name());
}
}
void CKCmFontInst::toggleFonts(bool enable, const QString &grp)
{
CJobRunner::ItemList urls;
QStringList fonts;
itsFontListView->getFonts(urls, fonts, nullptr, grp.isEmpty(), !enable, enable);
if(urls.isEmpty())
KMessageBox::information(this,
enable ? i18n("You did not select anything to enable.")
: i18n("You did not select anything to disable."),
enable ? i18n("Nothing to Enable") : i18n("Nothing to Disable"));
else
toggleFonts(urls, fonts, enable, grp);
}
void CKCmFontInst::toggleFonts(CJobRunner::ItemList &urls, const QStringList &fonts, bool enable,
const QString &grp)
{
bool doIt=false;
switch(fonts.count())
{
case 0:
break;
case 1:
doIt = KMessageBox::Continue==KMessageBox::warningContinueCancel(this,
grp.isEmpty()
? enable ? i18n("Do you really want to "
"enable
\'%1\'?
", fonts.first())
: i18n("Do you really want to "
"disable
\'%1\'?
", fonts.first())
: enable ? i18n("Do you really want to "
"enable
\'%1\', "
"contained within group \'%2\'?
",
fonts.first(), grp)
: i18n("Do you really want to "
"disable
\'%1\', "
"contained within group \'%2\'?
",
fonts.first(), grp),
enable ? i18n("Enable Font") : i18n("Disable Font"),
- enable ? KGuiItem(i18n("Enable"), "enablefont", i18n("Enable Font"))
- : KGuiItem(i18n("Disable"), "disablefont", i18n("Disable Font")));
+ enable ? KGuiItem(i18n("Enable"), "font-enable", i18n("Enable Font"))
+ : KGuiItem(i18n("Disable"), "font-disable", i18n("Disable Font")));
break;
default:
doIt = KMessageBox::Continue==KMessageBox::warningContinueCancelList(this,
grp.isEmpty()
? enable ? i18np("Do you really want to enable this font?",
"Do you really want to enable these %1 fonts?",
urls.count())
: i18np("Do you really want to disable this font?",
"Do you really want to disable these %1 fonts?",
urls.count())
: enable ? i18np("Do you really want to enable this font "
"contained within group \'%2\'?
",
"Do you really want to enable these %1 fonts "
"contained within group \'%2\'?
",
urls.count(), grp)
: i18np("Do you really want to disable this font "
"contained within group \'%2\'?
",
"Do you really want to disable these %1 fonts "
"contained within group \'%2\'?
",
urls.count(), grp),
fonts,
enable ? i18n("Enable Fonts") : i18n("Disable Fonts"),
- enable ? KGuiItem(i18n("Enable"), "enablefont", i18n("Enable Fonts"))
- : KGuiItem(i18n("Disable"), "disablefont", i18n("Disable Fonts")));
+ enable ? KGuiItem(i18n("Enable"), "font-enable", i18n("Enable Fonts"))
+ : KGuiItem(i18n("Disable"), "font-disable", i18n("Disable Fonts")));
}
if(doIt)
{
if(enable)
itsStatusLabel->setText(i18n("Enabling font(s)..."));
else
itsStatusLabel->setText(i18n("Disabling font(s)..."));
doCmd(enable ? CJobRunner::CMD_ENABLE : CJobRunner::CMD_DISABLE, urls);
}
}
void CKCmFontInst::selectMainGroup()
{
selectGroup(/*Misc::root()
? */CGroupListItem::ALL/* : CGroupListItem::PERSONAL*/);
}
void CKCmFontInst::doCmd(CJobRunner::ECommand cmd, const CJobRunner::ItemList &urls, bool system)
{
itsFontList->setSlowUpdates(true);
CJobRunner runner(this);
connect(&runner, SIGNAL(configuring()), itsFontList, SLOT(unsetSlowUpdates()));
runner.exec(cmd, urls, system);
itsFontList->setSlowUpdates(false);
refreshFontList();
if(CJobRunner::CMD_DELETE==cmd)
itsFontListView->clearSelection();
CFcEngine::setDirty();
setStatusBar();
delete itsTempDir;
itsTempDir=nullptr;
itsFontListView->repaint();
removeDeletedFontsFromGroups();
}
}
#include "KCmFontInst.moc"
diff --git a/kcms/kfontinst/kcmfontinst/KCmFontInst.h b/kcms/kfontinst/kcmfontinst/KCmFontInst.h
index 70600041d..087ee1abe 100644
--- a/kcms/kfontinst/kcmfontinst/KCmFontInst.h
+++ b/kcms/kfontinst/kcmfontinst/KCmFontInst.h
@@ -1,142 +1,142 @@
#ifndef __KCM_FONT_INST_H__
#define __KCM_FONT_INST_H__
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "GroupList.h"
#include "JobRunner.h"
#include
#include
#include
#include
#include
class QPushButton;
class QProgressDialog;
class QTemporaryDir;
class QAction;
class QLabel;
class QMenu;
class QProcess;
class QSplitter;
namespace KFI
{
class CFontFilter;
class CFontList;
class CFontPreview;
class CUpdateDialog;
class CFontListView;
class CProgressBar;
class CPreviewListView;
class CKCmFontInst : public KCModule
{
Q_OBJECT
public:
explicit CKCmFontInst(QWidget *parent=nullptr, const QVariantList &list=QVariantList());
~CKCmFontInst() override;
public Q_SLOTS:
QString quickHelp() const override;
void previewMenu(const QPoint &pos);
void splitterMoved();
void fontsSelected(const QModelIndexList &list);
void groupSelected(const QModelIndex &index);
void addFonts();
void deleteFonts();
void moveFonts();
void zipGroup();
void enableFonts();
void disableFonts();
void addGroup();
void removeGroup();
void enableGroup();
void disableGroup();
void changeText();
void duplicateFonts();
void downloadFonts();
void print();
void printGroup();
void listingPercent(int p);
void refreshFontList();
void refreshFamilies();
void showInfo(const QString &info);
void setStatusBar();
void addFonts(const QSet &src);
private:
void removeDeletedFontsFromGroups();
void selectGroup(CGroupListItem::EType grp);
void print(bool all);
void toggleGroup(bool enable);
void toggleFonts(bool enable, const QString &grp=QString());
void toggleFonts(CJobRunner::ItemList &urls, const QStringList &fonts, bool enable, const QString &grp);
void selectMainGroup();
void doCmd(CJobRunner::ECommand cmd, const CJobRunner::ItemList &urls, bool system=false);
private:
QSplitter *itsGroupSplitter,
*itsPreviewSplitter;
CFontPreview *itsPreview;
CPreviewListView *itsPreviewList;
KConfig itsConfig;
QLabel *itsStatusLabel;
CProgressBar *itsListingProgress;
CFontList *itsFontList;
CFontListView *itsFontListView;
CGroupList *itsGroupList;
CGroupListView *itsGroupListView;
QPushButton *itsDeleteGroupControl,
*itsEnableGroupControl,
*itsDisableGroupControl,
*itsAddFontControl,
*itsGetNewFontsControl,
- *itsDeleteFontControl;
+ *itsDeleteFontControl,
+ *itsScanDuplicateFontsControl;
CFontFilter *itsFilter;
QString itsLastStatusBarMsg;
KIO::Job *itsJob;
QProgressDialog *itsProgress;
CUpdateDialog *itsUpdateDialog;
QTemporaryDir *itsTempDir;
QProcess *itsPrintProc;
QSet itsDeletedFonts;
QList itsModifiedUrls;
CJobRunner *itsRunner;
QMenu *itsPreviewMenu,
*itsPreviewListMenu;
- QAction *duplicateFontsAct;
QWidget *itsPreviewWidget;
bool itsPreviewHidden;
};
}
#endif
diff --git a/kcms/kfontinst/viewpart/FontPreview.cpp b/kcms/kfontinst/viewpart/FontPreview.cpp
index 4b296e61a..8517533c1 100644
--- a/kcms/kfontinst/viewpart/FontPreview.cpp
+++ b/kcms/kfontinst/viewpart/FontPreview.cpp
@@ -1,178 +1,178 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FontPreview.h"
#include "FcEngine.h"
#include "CharTip.h"
#include
#include
#include
#include
#include
namespace KFI
{
static const int constBorder=4;
static const int constStepSize=16;
CFontPreview::CFontPreview(QWidget *parent)
: QWidget(parent),
itsCurrentFace(1),
itsLastWidth(0),
itsLastHeight(0),
itsStyleInfo(KFI_NO_STYLE_INFO),
itsTip(nullptr)
{
itsEngine=new CFcEngine;
}
CFontPreview::~CFontPreview()
{
delete itsTip;
delete itsEngine;
}
void CFontPreview::showFont(const QString &name, unsigned long styleInfo,
int face)
{
itsFontName=name;
itsStyleInfo=styleInfo;
showFace(face);
}
void CFontPreview::showFace(int face)
{
itsCurrentFace=face;
showFont();
}
void CFontPreview::showFont()
{
itsLastWidth=width()+constStepSize;
itsLastHeight=height()+constStepSize;
itsImage=itsEngine->draw(itsFontName, itsStyleInfo, itsCurrentFace,
palette().text().color(), palette().base().color(),
itsLastWidth, itsLastHeight,
false, itsRange, &itsChars);
if(!itsImage.isNull())
{
itsLastChar=CFcEngine::TChar();
setMouseTracking(itsChars.count()>0);
update();
emit status(true);
emit atMax(itsEngine->atMax());
emit atMin(itsEngine->atMin());
}
else
{
itsLastChar=CFcEngine::TChar();
setMouseTracking(false);
update();
emit status(false);
emit atMax(true);
emit atMin(true);
}
}
void CFontPreview::zoomIn()
{
itsEngine->zoomIn();
showFont();
emit atMax(itsEngine->atMax());
}
void CFontPreview::zoomOut()
{
itsEngine->zoomOut();
showFont();
emit atMin(itsEngine->atMin());
}
void CFontPreview::setUnicodeRange(const QList &r)
{
itsRange=r;
showFont();
}
void CFontPreview::paintEvent(QPaintEvent *)
{
QPainter paint(this);
paint.fillRect(rect(), palette().base());
if(!itsImage.isNull())
{
if(abs(width()-itsLastWidth)>constStepSize || abs(height()-itsLastHeight)>constStepSize)
showFont();
else
- paint.drawImage(QPoint(constBorder, constBorder), itsImage,
- QRect(0, 0, width()-(constBorder*2) * itsImage.devicePixelRatioF(),
- height()-(constBorder*2) * itsImage.devicePixelRatioF()));
+ paint.drawImage(QPointF(constBorder, constBorder), itsImage,
+ QRectF(0, 0, (width()-(constBorder*2)) * itsImage.devicePixelRatioF(),
+ (height()-(constBorder*2)) * itsImage.devicePixelRatioF()));
}
}
void CFontPreview::mouseMoveEvent(QMouseEvent *event)
{
if(!itsChars.isEmpty())
{
QList::ConstIterator end(itsChars.end());
if(itsLastChar.isNull() || !itsLastChar.contains(event->pos()))
for(QList::ConstIterator it(itsChars.begin()); it!=end; ++it)
if((*it).contains(event->pos()))
{
if(!itsTip)
itsTip=new CCharTip(this);
itsTip->setItem(*it);
itsLastChar=*it;
break;
}
}
}
void CFontPreview::wheelEvent(QWheelEvent *e)
{
if(e->delta()>0)
zoomIn();
else if(e->delta()<0)
zoomOut();
e->accept();
}
QSize CFontPreview::sizeHint() const
{
return QSize(132, 132);
}
QSize CFontPreview::minimumSizeHint() const
{
return QSize(32, 32);
}
}